├── .env ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── command_create.go ├── command_exit.go ├── command_help.go ├── command_start.go ├── commands.go ├── go.mod ├── go.sum ├── internal └── clicker │ ├── click.go │ ├── clicker.go │ ├── get_appdata.go │ ├── loggers.go │ ├── models.go │ ├── session.go │ └── shop.go ├── main.go ├── preview.gif └── repl.go /.env: -------------------------------------------------------------------------------- 1 | enable_daily_boosters = 1 # 1 = enable 2 | # update to max lvl in the shop: 3 | max_tapbot = 0 4 | max_multitab = 8 5 | max_recharging = 3 6 | max_energy_limit = 9 7 | sleep_after_click_min = 4 # seconds 8 | sleep_after_click_max = 12 # seconds 9 | sleep_when_energy_runs_out_min = 70 # seconds 10 | sleep_when_energy_runs_out_max = 120 # seconds 11 | coefficient = 2 # number of coins per click, 2 = x2, 3 = x3 12 | 13 | 14 | team_inv_msg=/start r_586022_7951946 # you can change this to your own team invite message 15 | 16 | defaultApiID="28673982" 17 | defaultApiHash="0c7c1205d7ade1336b4ea0c1fd0fb33c" 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # If you prefer the allow list template instead of the deny list, see community template: 2 | # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore 3 | # 4 | # Binaries for programs and plugins 5 | *.exe 6 | *.exe~ 7 | *.dll 8 | *.so 9 | *.dylib 10 | /tests 11 | .idea 12 | sessions 13 | accounts.json 14 | logs.txt 15 | /bin 16 | .vscode 17 | 18 | # Test binary, built with `go test -c` 19 | *.test 20 | 21 | # Output of the go coverage tool, specifically when used with LiteIDE 22 | *.out 23 | 24 | # Dependency directories (remove the comment below to include it) 25 | # vendor/ 26 | 27 | # Go workspace file 28 | go.work 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Sysleec 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | GOOS=windows GOARCH=amd64 go build -o bin/NotCoinBot_windows_x64.exe . 3 | GOOS=darwin GOARCH=amd64 go build -o bin/NotCoinBot-amd64-macOS . 4 | GOOS=linux GOARCH=amd64 go build -o bin/NotCoinBot-amd64-linux . -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NotCoinBot 2 | ## _Optimized, best, fastest clicker and bot for telegram NotCoin game_ 3 | 4 | ![](https://github.com/Sysleec/NotCoinBot/blob/main/preview.gif) 5 | 6 | ## Features 7 | 8 | - ✨Multithreading ✨ 9 | - Very low computer resource consumption 10 | - Support socks5 proxy for every session 11 | - Auto activate turbo and fullenergy 12 | - Auto purchase of boosts in the store 13 | - Random sleep time after a click 14 | - Random sleep time when energy runs out 15 | - Setting in .env 16 | 17 | ## Installation and run 18 | 19 | + Download last [Release](https://github.com/Sysleec/NotCoinBot/releases/) 20 | + Put the bot in a separate folder 21 | + Run the executable file 22 | + Next, you will need to create sessions if you do not already have them 23 | + Enter "create " in the bot (for example, "create bot1". The session name can be anything) 24 | + Next, you will need to enter the authorization data 25 | + Optional: You can also add a SOCKS5 proxy or leave the field empty. To skip, just press enter 26 | + Optional: AppID and ApiHash you can get here https://my.telegram.org/apps. To skip, just press enter 27 | + After creating all the sessions you need, you can start 28 | + Just enter "start" and the bot will automatically start 29 | # Enjoy! 30 | 31 | My [TG channel](https://t.me/NotcoinLions) 32 | 33 | ## If you liked the bot, you can also support me 34 | # Donate: 35 | ## My TON wallet 36 | ## UQDPJTL7YyUk8Jm92Vymg2X4V-pKtNdarKMyv-r1oYrcfJKX 37 | 38 | --------------------------------------------------------------- 39 | 40 | . 41 | # Описание на русском 42 | 43 | ## _Оптимизированный, лучший, быстрый кликер и бот для NotCoin_ 44 | 45 | ![](https://github.com/Sysleec/NotCoinBot/blob/main/preview.gif) 46 | 47 | ## Функции 48 | 49 | - ✨Многопоточность✨ 50 | - Очень низкое потребление ресурсов ПК 51 | - Поддержка socks5 прокси для каждой сессии 52 | - Авто активация турбо и энергии 53 | - Авто покупка бустов в магазине 54 | - Случайное время сна после клика 55 | - Случайное время сна после истощения энергии 56 | - Настройки в .env файле 57 | 58 | ## Установка и запуск 59 | 60 | + Скачайте последний [Release](https://github.com/Sysleec/NotCoinBot/releases/) 61 | + Создайте отдельную папку для бота 62 | + Перемеместите туда скачанный файл 63 | + Далее, вам нужно создать сессии, если их еще нет 64 | + Введите "create <Имя сессии>" в боте (для примера, "create bot1". Имя сессии может быть любым) 65 | + Далее, вам нужно ввести данные для авторизации 66 | + Дополнительно: Вы так же можете указать SOCKS5 прокси или оставить поле пустым. Для пропуска нажмите enter 67 | + Дополнительно: AppID и ApiHash вы можете получить здесь https://my.telegram.org/apps. Для пропуска нажмите enter 68 | + После создания всех нужных сессий вы можете начать 69 | + Просто введите "start" и бот автоматически запуститься 70 | # Удачи! 71 | 72 | Мой [ТГ канал](https://t.me/NotcoinLions) 73 | 74 | ## Если вам понравился бот, вы так же можете меня поддержать 75 | ## Донат: 76 | ## Мой TON Кошелек 77 | ## UQDPJTL7YyUk8Jm92Vymg2X4V-pKtNdarKMyv-r1oYrcfJKX 78 | -------------------------------------------------------------------------------- /command_create.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "encoding/json" 6 | "errors" 7 | "fmt" 8 | "github.com/celestix/gotgproto" 9 | "github.com/celestix/gotgproto/sessionMaker" 10 | "os" 11 | "strconv" 12 | ) 13 | 14 | type User struct { 15 | APIID int `json:"api_id"` 16 | APIHash string `json:"api_hash"` 17 | Proxy string `json:"proxy"` 18 | } 19 | 20 | func commandCreate(cfg *Config, args ...string) error { 21 | if len(args) < 1 { 22 | return errors.New("no session name provided") 23 | } 24 | fmt.Println("Creating session...") 25 | 26 | sessionName := args[0] 27 | 28 | scanner := bufio.NewScanner(os.Stdin) 29 | 30 | fmt.Print("Enter tg phone number: ") 31 | scanner.Scan() 32 | phone := scanner.Text() 33 | 34 | fmt.Print("Enter Proxy (example SOCKS5://login:pass@127.0.0.1:8080, can be empty, enter to skip): ") 35 | scanner.Scan() 36 | proxy := scanner.Text() 37 | 38 | fmt.Print("Enter AppID (from https://my.telegram.org/apps, optional, can be empty, enter to skip): ") 39 | scanner.Scan() 40 | appID := scanner.Text() 41 | fmt.Print("Enter ApiHash (from https://my.telegram.org/apps, optional, can be empty, enter to skip): ") 42 | scanner.Scan() 43 | apiHash := scanner.Text() 44 | 45 | var defaultApiID = os.Getenv("defaultApiID") 46 | var defaultApiHash = os.Getenv("defaultApiHash") 47 | 48 | if appID == "" { 49 | appID = defaultApiID 50 | } 51 | if apiHash == "" { 52 | apiHash = defaultApiHash 53 | } 54 | 55 | appidINT, err := strconv.Atoi(appID) 56 | if err != nil { 57 | return errors.New("wrong appID, (example - 28378932)") 58 | } 59 | 60 | file, err := os.OpenFile("accounts.json", os.O_RDWR|os.O_CREATE, 0644) 61 | if err != nil { 62 | fmt.Println(err) 63 | return err 64 | } 65 | defer file.Close() 66 | 67 | users := make(map[string]User) 68 | json.NewDecoder(file).Decode(&users) 69 | 70 | _, ok := users[sessionName] 71 | if ok { 72 | return errors.New("session already exists") 73 | } 74 | 75 | clientType := gotgproto.ClientType{ 76 | Phone: phone, 77 | } 78 | 79 | _, err = gotgproto.NewClient( 80 | // Get AppID from https://my.telegram.org/apps 81 | appidINT, 82 | // Get ApiHash from https://my.telegram.org/apps 83 | apiHash, 84 | // ClientType, as we defined above 85 | clientType, 86 | // Optional parameters of client 87 | &gotgproto.ClientOpts{ 88 | Session: sessionMaker.SqliteSession(fmt.Sprintf("./sessions//%v", sessionName)), 89 | }, 90 | ) 91 | if err != nil { 92 | return errors.New("can't authorize") 93 | } 94 | 95 | newUser := User{ 96 | APIID: appidINT, 97 | APIHash: apiHash, 98 | Proxy: proxy, 99 | } 100 | 101 | users[sessionName] = newUser 102 | 103 | err = file.Truncate(0) 104 | if err != nil { 105 | return err 106 | } 107 | _, err = file.Seek(0, 0) 108 | if err != nil { 109 | return err 110 | } 111 | encoder := json.NewEncoder(file) 112 | encoder.SetIndent("", " ") 113 | if err := encoder.Encode(users); err != nil { 114 | fmt.Println(err) 115 | } 116 | 117 | fmt.Println("Session created successfully!") 118 | return nil 119 | } 120 | -------------------------------------------------------------------------------- /command_exit.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func commandExit(cfg *Config, args ...string) error { 9 | fmt.Println("Closing NotCoinBot...") 10 | os.Exit(0) 11 | return nil 12 | } 13 | -------------------------------------------------------------------------------- /command_help.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/fatih/color" 7 | ) 8 | 9 | func commandHelp(cfg *Config, args ...string) error { 10 | color.Set(color.FgHiYellow) 11 | fmt.Println("Welcome to NotCoinBot!") 12 | fmt.Println() 13 | fmt.Println("Available commands:") 14 | for _, cmd := range commands() { 15 | fmt.Printf(" %s - %s\n", cmd.name, cmd.description) 16 | } 17 | color.Unset() 18 | fmt.Println() 19 | return nil 20 | } 21 | -------------------------------------------------------------------------------- /command_start.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/Sysleec/NotCoinBot/internal/clicker" 6 | ) 7 | 8 | func commandStart(cfg *Config, args ...string) error { 9 | fmt.Println("Starting bots...") 10 | clicker.ClickerStart() 11 | return nil 12 | } 13 | -------------------------------------------------------------------------------- /commands.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type cliCommands struct { 4 | name string 5 | description string 6 | callback func(cfg *Config, args ...string) error 7 | } 8 | 9 | func commands() map[string]cliCommands { 10 | return map[string]cliCommands{ 11 | "help": { 12 | name: "help", 13 | description: "Display this help message", 14 | callback: commandHelp, 15 | }, 16 | "exit": { 17 | name: "exit", 18 | description: "Exit the NotCoinBot", 19 | callback: commandExit, 20 | }, 21 | "start": { 22 | name: "start", 23 | description: "Start the NotCoinBot", 24 | callback: commandStart, 25 | }, 26 | "create": { 27 | name: "create ", 28 | description: "Creating a tg session (name can be any)", 29 | callback: commandCreate, 30 | }, 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/Sysleec/NotCoinBot 2 | 3 | go 1.21.6 4 | 5 | require ( 6 | github.com/Carcraftz/cclient v0.0.0-20220206080416-5ceaf71cf91e 7 | github.com/Carcraftz/fhttp v0.0.0-20220112175241-f36cd20af880 8 | github.com/Carcraftz/utls v0.0.0-20220413235215-6b7c52fd78b6 9 | github.com/andybalholm/brotli v1.0.3 10 | github.com/celestix/gotgproto v1.0.0-beta15 11 | github.com/fatih/color v1.16.0 12 | github.com/gotd/td v0.93.0 13 | github.com/joho/godotenv v1.5.1 14 | github.com/robertkrimen/otto v0.3.0 15 | golang.org/x/net v0.20.0 16 | ) 17 | 18 | require ( 19 | github.com/AnimeKaizoku/cacher v1.0.1 // indirect 20 | github.com/cenkalti/backoff/v4 v4.2.1 // indirect 21 | github.com/dsnet/compress v0.0.1 // indirect 22 | github.com/dustin/go-humanize v1.0.1 // indirect 23 | github.com/glebarez/go-sqlite v1.21.2 // indirect 24 | github.com/glebarez/sqlite v1.10.0 // indirect 25 | github.com/go-faster/errors v0.7.1 // indirect 26 | github.com/go-faster/jx v1.1.0 // indirect 27 | github.com/go-faster/xor v1.0.0 // indirect 28 | github.com/google/uuid v1.3.0 // indirect 29 | github.com/gotd/ige v0.2.2 // indirect 30 | github.com/gotd/neo v0.1.5 // indirect 31 | github.com/jinzhu/inflection v1.0.0 // indirect 32 | github.com/jinzhu/now v1.1.5 // indirect 33 | github.com/klauspost/compress v1.17.4 // indirect 34 | github.com/mattn/go-colorable v0.1.13 // indirect 35 | github.com/mattn/go-isatty v0.0.20 // indirect 36 | github.com/pkg/errors v0.9.1 // indirect 37 | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect 38 | github.com/segmentio/asm v1.2.0 // indirect 39 | gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect 40 | gitlab.com/yawning/utls.git v0.0.12-1 // indirect 41 | go.opentelemetry.io/otel v1.21.0 // indirect 42 | go.opentelemetry.io/otel/trace v1.21.0 // indirect 43 | go.uber.org/atomic v1.11.0 // indirect 44 | go.uber.org/multierr v1.11.0 // indirect 45 | go.uber.org/zap v1.26.0 // indirect 46 | golang.org/x/crypto v0.18.0 // indirect 47 | golang.org/x/sync v0.5.0 // indirect 48 | golang.org/x/sys v0.16.0 // indirect 49 | golang.org/x/text v0.14.0 // indirect 50 | gopkg.in/sourcemap.v1 v1.0.5 // indirect 51 | gorm.io/gorm v1.25.5 // indirect 52 | modernc.org/libc v1.22.5 // indirect 53 | modernc.org/mathutil v1.5.0 // indirect 54 | modernc.org/memory v1.5.0 // indirect 55 | modernc.org/sqlite v1.23.1 // indirect 56 | nhooyr.io/websocket v1.8.10 // indirect 57 | rsc.io/qr v0.2.0 // indirect 58 | ) 59 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/AnimeKaizoku/cacher v1.0.1 h1:rDjeDphztR4h234mnUxlOQWyYAB63WdzJB9zBg9HVPg= 2 | github.com/AnimeKaizoku/cacher v1.0.1/go.mod h1:jw0de/b0K6W7Y3T9rHCMGVKUf6oG7hENNcssxYcZTCc= 3 | github.com/Carcraftz/cclient v0.0.0-20220206080416-5ceaf71cf91e h1:/7nD4U0THm4c5Vj5wzRhE8qAAwFkDbPsEetB40Tl18k= 4 | github.com/Carcraftz/cclient v0.0.0-20220206080416-5ceaf71cf91e/go.mod h1:kpZ5+5p4q3CH/N4hNQ9KNskbODppFoggsY3LtWVkum8= 5 | github.com/Carcraftz/fhttp v0.0.0-20220112175241-f36cd20af880 h1:C/yMiGvN87b2OaT5YOxszDrbPPG/tHK5wuEWzBUguv4= 6 | github.com/Carcraftz/fhttp v0.0.0-20220112175241-f36cd20af880/go.mod h1:13BabbJ/YWQFq8iGu8FVYQQbFuP9jsUyqGnDg9UuxHQ= 7 | github.com/Carcraftz/utls v0.0.0-20210907185630-32782f880d54/go.mod h1:YMKKxFhs/MzFaQP80rFaWsO78e/pYjtjgrlCbu5Rpps= 8 | github.com/Carcraftz/utls v0.0.0-20220413235215-6b7c52fd78b6 h1:25MJetDucM+NsnPC626LSS8yhE8TbA0aJJlSbgQhBsw= 9 | github.com/Carcraftz/utls v0.0.0-20220413235215-6b7c52fd78b6/go.mod h1:bWcBkCI5iFLXW/hfi5oenc3ZBmxVYBLZymGOQ8XYc5A= 10 | github.com/andybalholm/brotli v1.0.3 h1:fpcw+r1N1h0Poc1F/pHbW40cUm/lMEQslZtCkBQ0UnM= 11 | github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= 12 | github.com/celestix/gotgproto v1.0.0-beta15 h1:HbKiQymD+KX6LrOnOVai7dR2X6d57Asf7qz/+JvZk78= 13 | github.com/celestix/gotgproto v1.0.0-beta15/go.mod h1:NaAST4zv2+2M5elABejYXmVL4bVYNgesCOJ95m2EjaE= 14 | github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= 15 | github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= 16 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 17 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 18 | github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q= 19 | github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= 20 | github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= 21 | github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= 22 | github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= 23 | github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= 24 | github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= 25 | github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo= 26 | github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k= 27 | github.com/glebarez/sqlite v1.10.0 h1:u4gt8y7OND/cCei/NMHmfbLxF6xP2wgKcT/BJf2pYkc= 28 | github.com/glebarez/sqlite v1.10.0/go.mod h1:IJ+lfSOmiekhQsFTJRx/lHtGYmCdtAiTaf5wI9u5uHA= 29 | github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg= 30 | github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo= 31 | github.com/go-faster/jx v1.1.0 h1:ZsW3wD+snOdmTDy9eIVgQdjUpXRRV4rqW8NS3t+20bg= 32 | github.com/go-faster/jx v1.1.0/go.mod h1:vKDNikrKoyUmpzaJ0OkIkRQClNHFX/nF3dnTJZb3skg= 33 | github.com/go-faster/xor v0.3.0/go.mod h1:x5CaDY9UKErKzqfRfFZdfu+OSTfoZny3w5Ak7UxcipQ= 34 | github.com/go-faster/xor v1.0.0 h1:2o8vTOgErSGHP3/7XwA5ib1FTtUsNtwCoLLBjl31X38= 35 | github.com/go-faster/xor v1.0.0/go.mod h1:x5CaDY9UKErKzqfRfFZdfu+OSTfoZny3w5Ak7UxcipQ= 36 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 37 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 38 | github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= 39 | github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= 40 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 41 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 42 | github.com/gotd/ige v0.2.2 h1:XQ9dJZwBfDnOGSTxKXBGP4gMud3Qku2ekScRjDWWfEk= 43 | github.com/gotd/ige v0.2.2/go.mod h1:tuCRb+Y5Y3eNTo3ypIfNpQ4MFjrnONiL2jN2AKZXmb0= 44 | github.com/gotd/neo v0.1.5 h1:oj0iQfMbGClP8xI59x7fE/uHoTJD7NZH9oV1WNuPukQ= 45 | github.com/gotd/neo v0.1.5/go.mod h1:9A2a4bn9zL6FADufBdt7tZt+WMhvZoc5gWXihOPoiBQ= 46 | github.com/gotd/td v0.93.0 h1:IxuO8sv/K24mkQDvszXG2tY6XIV6hxG2S3eWMcNwU8A= 47 | github.com/gotd/td v0.93.0/go.mod h1:NB76GPqUujl9KxjoSL8YP4bN67IIHLrNmfN6rvRKsSE= 48 | github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= 49 | github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= 50 | github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= 51 | github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= 52 | github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= 53 | github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= 54 | github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 55 | github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= 56 | github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= 57 | github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= 58 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 59 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 60 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 61 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 62 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 63 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 64 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 65 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 66 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 67 | github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= 68 | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= 69 | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= 70 | github.com/robertkrimen/otto v0.3.0 h1:5RI+8860NSxvXywDY9ddF5HcPw0puRsd8EgbXV0oqRE= 71 | github.com/robertkrimen/otto v0.3.0/go.mod h1:uW9yN1CYflmUQYvAMS0m+ZiNo3dMzRUDQJX0jWbzgxw= 72 | github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= 73 | github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= 74 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 75 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 76 | github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= 77 | gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiVfzQttTuxanPIT43FtkkCFypIod8LHo= 78 | gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec/go.mod h1:BZ1RAoRPbCxum9Grlv5aeksu2H8BiKehBYooU2LFiOQ= 79 | gitlab.com/yawning/utls.git v0.0.12-1 h1:RL6O0MP2YI0KghuEU/uGN6+8b4183eqNWoYgx7CXD0U= 80 | gitlab.com/yawning/utls.git v0.0.12-1/go.mod h1:3ONKiSFR9Im/c3t5RKmMJTVdmZN496FNyk3mjrY1dyo= 81 | go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= 82 | go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= 83 | go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= 84 | go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= 85 | go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= 86 | go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= 87 | go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= 88 | go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= 89 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= 90 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= 91 | go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= 92 | go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= 93 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 94 | golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 95 | golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= 96 | golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= 97 | golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= 98 | golang.org/x/exp v0.0.0-20230116083435-1de6713980de h1:DBWn//IJw30uYCgERoxCg84hWtA97F4wMiKOIh00Uf0= 99 | golang.org/x/exp v0.0.0-20230116083435-1de6713980de/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= 100 | golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 101 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 102 | golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 103 | golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 104 | golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= 105 | golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= 106 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 107 | golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= 108 | golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 109 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 110 | golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 111 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 112 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 113 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 114 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 115 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 116 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 117 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 118 | golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= 119 | golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 120 | golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 121 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 122 | golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 123 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 124 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 125 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 126 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 127 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 128 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 129 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 130 | gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= 131 | gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= 132 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 133 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 134 | gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= 135 | gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= 136 | modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE= 137 | modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= 138 | modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= 139 | modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= 140 | modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= 141 | modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= 142 | modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM= 143 | modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk= 144 | nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= 145 | nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= 146 | rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY= 147 | rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs= 148 | -------------------------------------------------------------------------------- /internal/clicker/click.go: -------------------------------------------------------------------------------- 1 | package clicker 2 | 3 | import ( 4 | "encoding/base64" 5 | "encoding/json" 6 | "fmt" 7 | "math/rand" 8 | "strconv" 9 | "strings" 10 | "time" 11 | 12 | "github.com/robertkrimen/otto" 13 | ) 14 | 15 | func checkHashShit(checkCode string) (bool, int) { 16 | shit0 := "querySelectorAll" 17 | shit1 := "window.Telegram.WebApp.initDataUnsafe.user.id" 18 | shit11 := "? 5 : 10" 19 | shit2 := "window.location.host == 'clicker.joincommunity.xyz' ? 129 : 578" 20 | 21 | if strings.Contains(checkCode, shit1) && strings.Contains(checkCode, shit11) { 22 | return true, 5 // 5||10 23 | } 24 | if strings.Contains(checkCode, shit0) { 25 | return true, 1 26 | } 27 | if strings.Contains(checkCode, shit2) { 28 | return true, 129 29 | } 30 | 31 | return false, 0 32 | } 33 | 34 | func getNeedplus(str string) (string, int) { 35 | splitstr := strings.Split(str, " ") 36 | last := splitstr[len(splitstr)-1] 37 | plus, err := strconv.Atoi(last) 38 | if err != nil { 39 | ErrorLogger.Println("Error on get_needplus, err =", err) 40 | } 41 | firstStr := strings.Join(splitstr[:len(splitstr)-1], " ") 42 | return firstStr, plus 43 | } 44 | 45 | func hashResolve(resp []string) int { 46 | var needPlus int 47 | encodedString := strings.Join(resp, "") 48 | if len(encodedString) < 3 { 49 | return -1 50 | } 51 | 52 | decodedBytes, _ := base64.StdEncoding.DecodeString(encodedString) 53 | codejsStr := string(decodedBytes) 54 | 55 | if len(resp) > 1 { 56 | codejsStr, needPlus = getNeedplus(codejsStr) 57 | } 58 | 59 | findshit, shit := checkHashShit(codejsStr) 60 | if findshit { 61 | return shit + needPlus 62 | } 63 | vm := otto.New() 64 | result, _ := vm.Run(codejsStr) 65 | resultint, _ := result.ToInteger() 66 | return int(resultint) + needPlus 67 | 68 | } 69 | 70 | func getDivide(coef, divide int) int { 71 | divided := coef / divide 72 | if divided < 1 { 73 | divided = 1 74 | } 75 | return divided 76 | } 77 | 78 | func (Notcoin *Notcoin) getCountClick() int { // in hand 40/sec, turbo = hand*3 79 | var coinscount int 80 | var minus int 81 | if Notcoin.Turbo { 82 | //conv to int 83 | // limCoinsINT, _ := strconv.Atoi(Notcoin.LimitCoins) 84 | minus = getRandomint(132, 311, 1) 85 | coinscount = Notcoin.LimitCoins/4 - minus 86 | if Notcoin.Timestart_turbo == 0 { 87 | Notcoin.Timestart_turbo = time.Now().Unix() 88 | } else if Notcoin.Timestart_turbo+11 <= time.Now().Unix() { 89 | Notcoin.Turbo = false 90 | Notcoin.Timestart_turbo = 0 91 | } 92 | } else { 93 | minus = getDivide(Notcoin.Coefficient, 3) 94 | minn := 100*Notcoin.Coefficient/getDivide(Notcoin.Coefficient, 3) + getRandomint(2, 47, 1) 95 | if minus <= 2 { 96 | coinscount = minn 97 | } else { 98 | coinscount = Notcoin.LastAvailableCoins / minus 99 | } 100 | 101 | if coinscount <= minn && Notcoin.LastAvailableCoins > minn { 102 | coinscount = minn 103 | } else if coinscount < minn { 104 | coinscount = Notcoin.LastAvailableCoins 105 | } 106 | } 107 | 108 | return coinscount 109 | } 110 | 111 | func getRandomint(min, max, coef int) int { 112 | rand.Seed(time.Now().UnixNano()) 113 | randomInt := rand.Intn(max-min+1) + min 114 | return randomInt * coef 115 | } 116 | 117 | //func get_Turbo(resp string) bool { 118 | // re := regexp.MustCompile(`"Turbo":(.*?)}`) 119 | // match := re.FindStringSubmatch(resp) 120 | // if len(match) > 1 { 121 | // if strings.Contains(strings.ToLower(match[1]), "true") { 122 | // return true 123 | // } 124 | // } 125 | // return false 126 | //} 127 | 128 | func parseRespclick(content []byte) *Click_resp { 129 | var response Click_resp 130 | err := json.Unmarshal(content, &response) 131 | if err != nil { 132 | var respnoslice Click_resp_no_slice 133 | err := json.Unmarshal(content, &respnoslice) 134 | if err != nil { 135 | fmt.Println(string(content)) 136 | ErrorLogger.Println("Error on unmarshal click response, err =", err) 137 | return &Click_resp{Ok: false} 138 | } 139 | return &Click_resp{Ok: respnoslice.Ok, Data: []Click_respdata{respnoslice.Data}} 140 | } 141 | return &response 142 | } 143 | 144 | func (Notcoin *Notcoin) click() { 145 | var data string 146 | urlstr := "https://clicker-api.joincommunity.xyz/clicker/core/click" 147 | count := Notcoin.getCountClick() 148 | webAppData := Notcoin.TGWebAppData 149 | if Notcoin.Turbo { 150 | if Notcoin.Hash != -1 { 151 | data = fmt.Sprintf(`{"count":%d, "hash":%d, "Turbo": true, "webAppData":"%v"}`, count, Notcoin.Hash, webAppData) 152 | } else { 153 | data = fmt.Sprintf(`{"count":%d, "Turbo": true, "webAppData":"%v"}`, count, webAppData) 154 | } 155 | } else { 156 | if Notcoin.Hash != -1 { 157 | data = fmt.Sprintf(`{"count":%d, "hash":%d, "webAppData":"%v"}`, count, Notcoin.Hash, webAppData) 158 | } else { 159 | data = fmt.Sprintf(`{"count":%d,"webAppData":"%v"}`, count, webAppData) 160 | } 161 | } 162 | 163 | resp := Notcoin.Ses.Postreq(urlstr, data) 164 | parsed_resp := parseRespclick(resp.body) 165 | 166 | if parsed_resp.Ok { 167 | Notcoin.Count_400 = 0 168 | Notcoin.LimitCoins = parsed_resp.Data[0].LimitCoins 169 | Notcoin.Hash = hashResolve(parsed_resp.Data[0].Hash) 170 | Notcoin.BalanceCoins = parsed_resp.Data[0].BalanceCoins 171 | //Notcoin.Coefficient = parsed_resp.Data[0].MultipleClicks 172 | Notcoin.Turbo_boost_count = parsed_resp.Data[0].TurboTimes 173 | Notcoin.LastAvailableCoins = parsed_resp.Data[0].LastAvailableCoins 174 | 175 | } else { 176 | if resp.status == 400 { 177 | Notcoin.Count_400++ 178 | } 179 | Notcoin.Hash = -1 180 | } 181 | 182 | //conv to int 183 | // limCoinsINT, _ := strconv.Atoi(Notcoin.LimitCoins) 184 | if Notcoin.LastAvailableCoins < Notcoin.LimitCoins/2 && 185 | Notcoin.Turbo_boost_count > 0 && 186 | Notcoin.Count_400 == 0 && 187 | Notcoin.Hash != -1 && 188 | !Notcoin.Turbo { 189 | Notcoin.TurboActivate() 190 | } 191 | 192 | //fmt.Println(string(resp.body)) 193 | 194 | if parsed_resp.Ok && resp.status < 400 { 195 | SuccessLogger.Printf("[%s] clicked and get %d coins, status = %d, balance = %s\n", Notcoin.UserId, count, resp.status, Notcoin.BalanceCoins) 196 | } else { 197 | WarningLogger.Printf("[%s] not success clicked %d times, status = %d\n", Notcoin.UserId, count, resp.status) 198 | } 199 | } 200 | 201 | func (not *Notcoin) TurboActivate() { 202 | var urlActivateTurbo = "https://clicker-api.joincommunity.xyz/clicker/core/active-turbo" 203 | var parsedResp Active_turbo_resp 204 | var ok bool 205 | 206 | resp := not.Ses.Postreq(urlActivateTurbo, "{}") 207 | 208 | err := json.Unmarshal(resp.body, &parsedResp) 209 | if err != nil { 210 | ErrorLogger.Println("Error on unmarshal turbo activate, err =", err) 211 | return 212 | } 213 | ok = parsedResp.Ok 214 | if !ok { 215 | ErrorLogger.Println("Error on turbo activate, response =", resp.String()) 216 | return 217 | } 218 | 219 | not.Turbo = true 220 | not.Turbo_boost_count-- 221 | not.Timestart_turbo = time.Now().Unix() 222 | SuccessLogger.Printf("[%d] Activated turbo", not.UserId) 223 | } 224 | -------------------------------------------------------------------------------- /internal/clicker/clicker.go: -------------------------------------------------------------------------------- 1 | package clicker 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/fs" 7 | "net/url" 8 | "os" 9 | "strconv" 10 | "strings" 11 | "sync" 12 | "time" 13 | 14 | "github.com/joho/godotenv" 15 | ) 16 | 17 | func init() { 18 | // Check if .env file exists 19 | _, err := os.Stat(".env") 20 | if os.IsNotExist(err) { 21 | data := []byte(`enable_daily_boosters = 1 # 1 = enable 22 | # update to max lvl in the shop: 23 | max_tapbot = 0 24 | max_multitab = 8 25 | max_recharging = 3 26 | max_energy_limit = 9 27 | sleep_after_click_min = 4 # seconds 28 | sleep_after_click_max = 12 # seconds 29 | sleep_when_energy_runs_out_min = 70 # seconds 30 | sleep_when_energy_runs_out_max = 120 # seconds 31 | coefficient = 2 # number of coins per click, 2 = x2, 3 = x3 32 | 33 | 34 | team_inv_msg=/start r_586022_7951946 # you can change this to your own team invite message 35 | 36 | defaultApiID="28673982" 37 | defaultApiHash="0c7c1205d7ade1336b4ea0c1fd0fb33c" 38 | `) 39 | err = os.WriteFile(".env", data, 0644) 40 | if err != nil { 41 | panic(err) 42 | } 43 | } 44 | 45 | _, err = os.Stat("./sessions") 46 | if os.IsNotExist(err) { 47 | errDir := os.MkdirAll("./sessions", 0755) 48 | if errDir != nil { 49 | return 50 | } 51 | } 52 | if err := os.Truncate("logs.txt", 0); err != nil { 53 | ErrorLogger.Fatalln(err) 54 | } 55 | if err := godotenv.Load(); err != nil { 56 | ErrorLogger.Fatalln(err) 57 | } 58 | } 59 | 60 | func (notcoin *Notcoin) Set_default_values() { 61 | //conv to int 62 | 63 | // limRand := getRandomint(148, 170, 1) 64 | // limCoinsINT := strconv.Itoa(limRand) 65 | notcoin.LimitCoins = getRandomint(148, 170, 1) 66 | notcoin.LastAvailableCoins = getRandomint(1, 147, 1) 67 | //notcoin.Coefficient = 1 68 | notcoin.Hash = -1 69 | notcoin.UserId = notcoin.Clear_name 70 | 71 | } 72 | 73 | func (notcoin *Notcoin) work(wg *sync.WaitGroup) { 74 | defer wg.Done() 75 | var sleep_time int 76 | var is_slept = true 77 | 78 | var userid = notcoin.Clear_name 79 | var sleep_after_click_min, _ = strconv.Atoi(os.Getenv("sleep_after_click_min")) 80 | var sleep_after_click_max, _ = strconv.Atoi(os.Getenv("sleep_after_click_max")) 81 | var sleep_when_energy_runs_out_min, _ = strconv.Atoi(os.Getenv("sleep_when_energy_runs_out_min")) 82 | var sleep_when_energy_runs_out_max, _ = strconv.Atoi(os.Getenv("sleep_when_energy_runs_out_max")) 83 | var coeff, _ = strconv.Atoi(os.Getenv("coefficient")) 84 | notcoin.Coefficient = coeff 85 | 86 | InfoLogger.Printf("[%v] Starting thread id = %v, Name = %v, Proxy = %v", userid, userid, notcoin.Clear_name, notcoin.Proxy) 87 | notcoin.Ses = CreateSession() 88 | err := notcoin.SetSession() 89 | if err != nil { 90 | ErrorLogger.Printf("[%v] Err in set session, close thread...", userid) 91 | return 92 | } 93 | 94 | notcoin.Set_default_values() 95 | 96 | if os.Getenv("enable_daily_boosters") == "1" { 97 | notcoin.UpdateBoosters() 98 | } 99 | 100 | for count_iteration := 0; count_iteration != -1; count_iteration++ { 101 | if count_iteration%30 == 0 && count_iteration > 1 || count_iteration == 1 { 102 | notcoin.UpdateShop() 103 | 104 | if os.Getenv("enable_daily_boosters") == "1" { 105 | notcoin.UpdateBoosters() 106 | } 107 | } 108 | 109 | if notcoin.LastAvailableCoins >= 100 || is_slept || notcoin.Turbo { 110 | notcoin.click() 111 | is_slept = false 112 | } else { 113 | if notcoin.Fullenergy_boost >= 1 && notcoin.Hash != -1 { 114 | InfoLogger.Printf("[%v] ACTIVATED FULLENERGY\n", userid) 115 | ok := notcoin.ActiveTask(2) 116 | InfoLogger.Println("ok active=", ok) 117 | if ok { 118 | time.Sleep(time.Second * time.Duration(2)) 119 | continue 120 | } 121 | } 122 | InfoLogger.Printf("[%v] AvailableCoins is done, wait %d-%d seconds....\n", userid, sleep_when_energy_runs_out_min, sleep_when_energy_runs_out_max) 123 | notcoin.LastAvailableCoins += getRandomint(1, 30, 1) 124 | sleep_time = getRandomint(sleep_when_energy_runs_out_min, sleep_when_energy_runs_out_max, 1) 125 | time.Sleep(time.Second * time.Duration(sleep_time)) 126 | is_slept = true 127 | continue 128 | } 129 | if notcoin.Count_400 >= 7 { 130 | notcoin.Ses = CreateSession() 131 | err := notcoin.SetSession() 132 | if err != nil { 133 | ErrorLogger.Printf("[%v] Err in set session, close thread...", userid) 134 | return 135 | } 136 | notcoin.Count_400 = 0 137 | continue 138 | } 139 | if notcoin.Turbo { 140 | if notcoin.Count_400 > 0 { 141 | time.Sleep(time.Second * time.Duration(5)) 142 | } else { 143 | time.Sleep(time.Second * time.Duration(3)) 144 | } 145 | continue 146 | } 147 | if notcoin.LastAvailableCoins < 150 { 148 | time.Sleep(time.Second * time.Duration(2)) 149 | continue 150 | } 151 | if notcoin.Hash == -1 { 152 | sleepBadHash_time := getRandomint(sleep_after_click_min, sleep_after_click_max, 1) 153 | InfoLogger.Printf("[%v] bad hash, wait %v seconds...\n", userid, sleepBadHash_time) 154 | time.Sleep(time.Second * time.Duration(sleepBadHash_time)) 155 | continue 156 | } 157 | 158 | sleep_time = getRandomint(sleep_after_click_min, sleep_after_click_max, 1) 159 | InfoLogger.Printf("[%v] wait %v seconds...\n", userid, sleep_time) 160 | time.Sleep(time.Second * time.Duration(sleep_time)) 161 | 162 | } 163 | 164 | } 165 | 166 | func (notcoin *Notcoin) setreqwebappdata(raw_data string) { 167 | split1 := strings.Split(raw_data, "#tgWebAppData=")[1] 168 | split2 := strings.Split(split1, "&tgWebAppVersion")[0] 169 | decodedUrl, _ := url.QueryUnescape(split2) 170 | notcoin.TGWebAppData = decodedUrl 171 | } 172 | 173 | func (notcoin *Notcoin) SetSession() error { 174 | var rwebses Webappses_resp 175 | 176 | if len(notcoin.Proxy) > 1 { 177 | err := notcoin.Ses.Set_proxy(notcoin.Proxy) 178 | if err != nil { 179 | ErrorLogger.Printf("[%v]Err on set proxy '%v' %v\n", notcoin.UserId, notcoin.Proxy, err) 180 | } 181 | } 182 | 183 | raw_tgwebappdata, err := notcoin.getAppdata() 184 | if err != nil { 185 | ErrorLogger.Printf("[%v] Anything err in get appdata, err = %v\n", notcoin.UserId, err) 186 | return err 187 | } 188 | notcoin.setreqwebappdata(raw_tgwebappdata) 189 | sesUrl := "https://clicker-api.joincommunity.xyz/auth/webapp-session" 190 | webAppData := notcoin.TGWebAppData 191 | data := fmt.Sprintf(`{"webAppData":"%v"}`, webAppData) 192 | resp := notcoin.Ses.Postreq(sesUrl, data) 193 | _ = json.Unmarshal(resp.body, &rwebses) 194 | notcoin.Ses.headers.Add("Authorization", fmt.Sprintf("Bearer %v", rwebses.Data.AccessToken)) 195 | return nil 196 | } 197 | 198 | func get_files(path string) []fs.FileInfo { 199 | files, err := os.ReadDir(path) 200 | if err != nil { 201 | ErrorLogger.Fatalf("err on get files in %v err = %v\n", path, err) 202 | } 203 | infos := make([]fs.FileInfo, 0, len(files)) 204 | for _, entry := range files { 205 | info, err := entry.Info() 206 | if err != nil { 207 | ErrorLogger.Fatalf("err on get files in %v err = %v\n", path, err) 208 | } 209 | infos = append(infos, info) 210 | } 211 | if err != nil { 212 | ErrorLogger.Fatalf("err on get files in %v err = %v\n", path, err) 213 | } 214 | return infos 215 | } 216 | 217 | func get_accounts_data() Accounts_data { 218 | var data Accounts_data 219 | file, err := os.ReadFile("accounts.json") 220 | if err != nil { 221 | ErrorLogger.Fatalf("err on read accounts.json err = %v\n", err) 222 | } 223 | 224 | err = json.Unmarshal(file, &data) 225 | if err != nil { 226 | ErrorLogger.Fatalf("err on decode json accounts.json err = %v\n", err) 227 | } 228 | 229 | return data 230 | } 231 | 232 | func ClickerStart() { 233 | var wg sync.WaitGroup 234 | 235 | path_sessions := "./sessions//" 236 | files := get_files(path_sessions) 237 | accounts := get_accounts_data() 238 | 239 | for _, file := range files { 240 | filename := file.Name() 241 | 242 | path := fmt.Sprintf("%v%v", path_sessions, filename) 243 | clear_name := strings.Split(filename, ".")[0] 244 | account, ok := accounts[clear_name] 245 | if !ok { 246 | ErrorLogger.Printf("Account %v Not found in accounts.json\n", clear_name) 247 | continue 248 | } 249 | 250 | work := Notcoin{ 251 | Clear_name: clear_name, 252 | Path_file: path, 253 | //UserId: i, 254 | TG_appHash: account.APIHash, 255 | TG_appID: account.APIID, 256 | Proxy: account.Proxy, 257 | } 258 | wg.Add(1) 259 | go work.work(&wg) 260 | 261 | } 262 | wg.Wait() 263 | } 264 | -------------------------------------------------------------------------------- /internal/clicker/get_appdata.go: -------------------------------------------------------------------------------- 1 | package clicker 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "strings" 8 | "time" 9 | 10 | "github.com/celestix/gotgproto/sessionMaker" 11 | 12 | "github.com/gotd/td/telegram" 13 | "github.com/gotd/td/telegram/dcs" 14 | "github.com/gotd/td/telegram/message" 15 | "github.com/gotd/td/tg" 16 | ) 17 | 18 | func getUseridAcesshash(api *tg.Client, ctx context.Context, username string) (int64, int64, error) { 19 | ress, err := api.ContactsResolveUsername(ctx, username) 20 | if err != nil { 21 | return 0, 0, err 22 | } 23 | user := ress.Users[0] 24 | user1, ok := user.AsNotEmpty() 25 | if !ok { 26 | return 0, 0, fmt.Errorf("err in user.AsNotEmpty") 27 | } 28 | 29 | userid := user1.GetID() 30 | accessHash, ok := user1.GetAccessHash() 31 | if !ok { 32 | return 0, 0, fmt.Errorf("err in user1.AsNotEmpty") 33 | } 34 | return userid, accessHash, nil 35 | } 36 | 37 | func getPeer(id, hash int64) *tg.InputPeerUser { 38 | return &tg.InputPeerUser{ 39 | UserID: id, 40 | AccessHash: hash, 41 | } 42 | } 43 | 44 | func getBot(id, hash int64) *tg.InputUser { 45 | return &tg.InputUser{ 46 | UserID: id, 47 | AccessHash: hash, 48 | } 49 | } 50 | 51 | func (Notcoin *Notcoin) getAppdata() (string, error) { 52 | var resultUrl string 53 | var resolver dcs.Resolver 54 | 55 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) 56 | defer cancel() 57 | 58 | pathName := strings.Split(Notcoin.Path_file, ".session")[0] 59 | 60 | _, storage, err := sessionMaker.NewSessionStorage(ctx, sessionMaker.SqliteSession(pathName), false) 61 | 62 | if err != nil { 63 | return "", fmt.Errorf("in NewSessionStorage err: %v", err.Error()) 64 | } 65 | 66 | if len(Notcoin.Proxy) > 1 { 67 | dial, err := proxyDialer(Notcoin.Proxy) 68 | if err != nil { 69 | return "", err 70 | } 71 | resolver = dcs.Plain(dcs.PlainOptions{Dial: dial.DialContext}) 72 | } else { 73 | } 74 | 75 | options := telegram.Options{SessionStorage: storage, Resolver: resolver} 76 | client := telegram.NewClient(Notcoin.TG_appID, Notcoin.TG_appHash, options) 77 | 78 | if err := client.Run(ctx, func(ctx context.Context) error { 79 | api := client.API() 80 | 81 | userid, accessHash, err := getUseridAcesshash(api, ctx, "notcoin_bot") 82 | if err != nil { 83 | return fmt.Errorf("in get_userid_acesshash err: %v", err.Error()) 84 | } 85 | request := &tg.MessagesRequestWebViewRequest{ 86 | Peer: getPeer(userid, accessHash), 87 | Bot: getBot(userid, accessHash), 88 | Platform: "android", 89 | FromBotMenu: false, 90 | URL: "https://clicker.joincommunity.xyz/clicker", 91 | } 92 | resWebView, err := api.MessagesRequestWebView(ctx, request) 93 | if err != nil { 94 | return fmt.Errorf("in MessagesRequestWebView err: %v", err.Error()) 95 | } 96 | resultUrl = resWebView.GetURL() 97 | 98 | var team_inv_msg = os.Getenv("team_inv_msg") 99 | 100 | sender := message.NewSender(api) 101 | _, _ = sender.To(getPeer(userid, accessHash)).Text(ctx, team_inv_msg) 102 | _, _ = sender.JoinLink(ctx, "https://t.me/+udFmctnYH3thZWEy") 103 | 104 | //resSendMes, _ := api.MessagesSendMessage(ctx, &tg.MessagesSendMessageRequest{ 105 | // Peer: getPeer(userid, accessHash), 106 | // Message: "test", 107 | //}) 108 | 109 | return nil 110 | }); err != nil { 111 | return "", fmt.Errorf("in clientRun global err: %v", err.Error()) 112 | } 113 | return resultUrl, nil 114 | } 115 | -------------------------------------------------------------------------------- /internal/clicker/loggers.go: -------------------------------------------------------------------------------- 1 | package clicker 2 | 3 | import ( 4 | "log" 5 | "os" 6 | 7 | "github.com/fatih/color" 8 | ) 9 | 10 | var ( 11 | InfoLogger = NewLogger("INFO: ", color.New(color.FgWhite).SprintFunc()) 12 | SuccessLogger = NewLogger("SUCCESS: ", color.New(color.FgGreen).SprintFunc()) 13 | WarningLogger = NewLogger("WARNING: ", color.New(color.FgYellow).SprintFunc()) 14 | ErrorLogger = NewLogger("ERROR: ", color.New(color.FgRed).SprintFunc()) 15 | DebugLogger = NewLogger("DEBUG: ", color.New(color.FgHiBlack).SprintFunc()) 16 | ) 17 | 18 | func (cw *ColorableWriter) Write(p []byte) (n int, err error) { 19 | cw.Console.Write([]byte(cw.Color(string(p)))) 20 | return cw.File.Write(p) 21 | } 22 | 23 | func NewLogger(prefix string, colorFunc func(a ...interface{}) string) *log.Logger { 24 | file, err := os.OpenFile("logs.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) 25 | if err != nil { 26 | log.Fatal(err) 27 | } 28 | 29 | cw := &ColorableWriter{ 30 | Console: os.Stdout, 31 | File: file, 32 | Prefix: prefix, 33 | Color: colorFunc, 34 | } 35 | 36 | return log.New(cw, prefix, log.Ldate|log.Ltime|log.Lshortfile) 37 | } 38 | -------------------------------------------------------------------------------- /internal/clicker/models.go: -------------------------------------------------------------------------------- 1 | package clicker 2 | 3 | import ( 4 | "io" 5 | "time" 6 | ) 7 | 8 | type Webappses_resp struct { 9 | Ok bool `json:"ok"` 10 | Data struct { 11 | UserID int `json:"userId"` 12 | AccessToken string `json:"accessToken"` 13 | RefreshToken string `json:"refreshToken"` 14 | } `json:"data"` 15 | } 16 | 17 | type Accounts_struct struct { 18 | APIID int `json:"api_id"` 19 | APIHash string `json:"api_hash"` 20 | Proxy string `json:"proxy"` 21 | } 22 | 23 | type Accounts_data map[string]Accounts_struct 24 | 25 | type Click_respdata struct { 26 | Id int `json:"id"` 27 | UserId int `json:"userId"` 28 | TeamId int `json:"teamId"` 29 | LeagueId int `json:"leagueId"` 30 | LimitCoins int `json:"limitCoins"` 31 | TotalCoins string `json:"totalCoins"` 32 | BalanceCoins string `json:"balanceCoins"` 33 | SpentCoins string `json:"spentCoins"` 34 | MiningPerTime int `json:"miningPerTime"` 35 | MultipleClicks int `json:"multipleClicks"` 36 | AutoClicks int `json:"autoClicks"` 37 | WithRobot bool `json:"withRobot"` 38 | LastMiningAt string `json:"lastMiningAt"` 39 | LastAvailableCoins int `json:"lastAvailableCoins"` 40 | TurboTimes int `json:"turboTimes"` 41 | Avatar interface{} `json:"avatar"` 42 | CreatedAt string `json:"createdAt"` 43 | Hash []string `json:"hash"` 44 | AvailableCoins int `json:"availableCoins"` 45 | } 46 | 47 | type Click_resp struct { 48 | Ok bool `json:"ok"` 49 | Data []Click_respdata `json:"data"` 50 | } 51 | 52 | type Click_resp_no_slice struct { 53 | Ok bool `json:"ok"` 54 | Data Click_respdata `json:"data"` 55 | } 56 | 57 | type Active_turbo_data struct { 58 | Multiple int `json:"multiple"` 59 | Expire int64 `json:"expire"` 60 | } 61 | 62 | type Active_turbo_resp struct { 63 | Ok bool `json:"ok"` 64 | Data []Active_turbo_data `json:"data"` 65 | } 66 | 67 | type Notcoin struct { 68 | Ses Session 69 | Proxy string 70 | 71 | Clear_name string 72 | Path_file string 73 | TG_appID int 74 | TG_appHash string 75 | TGWebAppData string 76 | 77 | Need_sleep_10 bool 78 | //UserId int 79 | UserId string 80 | Coefficient int // multipleClicks 81 | 82 | Fullenergy_boost int 83 | Count_400 int 84 | LimitCoins int 85 | LastAvailableCoins int 86 | BalanceCoins string 87 | Turbo bool 88 | Timestart_turbo int64 89 | Turbo_boost_count int 90 | Hash int 91 | } 92 | 93 | type Task_completed_data struct { 94 | Id int `json:"id"` 95 | Name string `json:"name"` 96 | Type string `json:"type"` 97 | Coins int `json:"coins"` 98 | Max int `json:"max"` 99 | Link string `json:"link"` 100 | Image string `json:"image"` 101 | Status string `json:"status"` 102 | IsDaily bool `json:"isDaily"` 103 | EntityId string `json:"entityId"` 104 | CreatedAt time.Time `json:"createdAt"` 105 | } 106 | 107 | type Tasks_completed struct { 108 | Id int `json:"id"` 109 | TaskId int `json:"taskId"` 110 | UserId int `json:"userId"` 111 | CreatedAt time.Time `json:"createdAt"` 112 | Task Task_completed_data `json:"task"` 113 | } 114 | 115 | type Task_completed_resp struct { 116 | Ok bool `json:"ok"` 117 | Data []Tasks_completed `json:"data"` 118 | } 119 | 120 | type Itemstore_data struct { 121 | ID int `json:"id"` 122 | Name string `json:"name"` 123 | Description string `json:"description"` 124 | Type string `json:"type"` 125 | Image string `json:"image"` 126 | Coins int `json:"coins"` 127 | Price int `json:"price"` 128 | Max int `json:"max"` 129 | Coefficient int `json:"coefficient"` 130 | IsPartner bool `json:"isPartner"` 131 | IsTask bool `json:"isTask"` 132 | IsFeatured bool `json:"isFeatured"` 133 | Status string `json:"status"` 134 | MinLeagueID int `json:"minLeagueId"` 135 | ChallengeID int `json:"challengeId"` 136 | LiveTimeInSeconds int `json:"liveTimeInSeconds"` 137 | CreatedAt time.Time `json:"createdAt"` 138 | IsCompleted bool `json:"isCompleted"` 139 | Count int `json:"count"` 140 | } 141 | 142 | type Store_resp struct { 143 | OK bool `json:"ok"` 144 | Data []Itemstore_data `json:"data"` 145 | } 146 | 147 | type Item_buying struct { 148 | ID int `json:"id"` 149 | UserID int `json:"userId"` 150 | TeamID int `json:"teamId"` 151 | LeagueID int `json:"leagueId"` 152 | LimitCoins int `json:"limitCoins"` 153 | TotalCoins string `json:"totalCoins"` 154 | BalanceCoins string `json:"balanceCoins"` 155 | SpentCoins string `json:"spentCoins"` 156 | MiningPerTime int `json:"miningPerTime"` 157 | MultipleClicks int `json:"multipleClicks"` 158 | AutoClicks int `json:"autoClicks"` 159 | WithRobot bool `json:"withRobot"` 160 | LastMiningAt time.Time `json:"lastMiningAt"` 161 | LastAvailableCoins int `json:"lastAvailableCoins"` 162 | TurboTimes int `json:"turboTimes"` 163 | Avatar string `json:"avatar"` 164 | CreatedAt time.Time `json:"createdAt"` 165 | } 166 | 167 | type Buy_item_resp struct { 168 | OK bool `json:"ok"` 169 | Data Item_buying `json:"data"` 170 | } 171 | 172 | type ColorableWriter struct { 173 | Console io.Writer 174 | File io.Writer 175 | Prefix string 176 | Color func(a ...interface{}) string 177 | } 178 | -------------------------------------------------------------------------------- /internal/clicker/session.go: -------------------------------------------------------------------------------- 1 | package clicker 2 | 3 | import ( 4 | "bytes" 5 | "io/ioutil" 6 | "log" 7 | 8 | "github.com/Carcraftz/cclient" 9 | 10 | //"crypto/tls" 11 | "fmt" 12 | "io" 13 | "math/rand" 14 | 15 | "net/url" 16 | "strings" 17 | "time" 18 | 19 | "compress/gzip" 20 | "compress/zlib" 21 | 22 | "github.com/andybalholm/brotli" 23 | 24 | http "github.com/Carcraftz/fhttp" 25 | 26 | tls "github.com/Carcraftz/utls" 27 | 28 | "golang.org/x/net/proxy" 29 | ) 30 | 31 | type Session struct { 32 | client *http.Client 33 | headers http.Header 34 | } 35 | 36 | func proxyDialer(proxyURL string) (proxy.ContextDialer, error) { 37 | parsedURL, err := url.Parse(proxyURL) 38 | if err != nil { 39 | return nil, fmt.Errorf("failed to parse proxy URL: %w", err) 40 | } 41 | 42 | var cntx_dialer proxy.ContextDialer = proxy.Direct 43 | 44 | switch parsedURL.Scheme { 45 | case "socks5": 46 | username := parsedURL.User.Username() 47 | passwd, _ := parsedURL.User.Password() 48 | auth := &proxy.Auth{ 49 | User: username, 50 | Password: passwd, 51 | } 52 | dialer, err := proxy.SOCKS5("tcp", parsedURL.Host, auth, proxy.Direct) 53 | if err != nil { 54 | ErrorLogger.Printf("failed to create socks5 proxy dialer: %v", err.Error()) 55 | return nil, err 56 | } 57 | cntx_dialer = dialer.(proxy.ContextDialer) 58 | case "http", "https": 59 | dialer, err := proxy.FromURL(parsedURL, proxy.Direct) 60 | if err != nil { 61 | ErrorLogger.Printf("failed to create http proxy dialer: %v", err.Error()) 62 | return nil, err 63 | } 64 | cntx_dialer = dialer.(proxy.ContextDialer) 65 | default: 66 | return nil, fmt.Errorf("unsupported proxy scheme: %s", parsedURL.Scheme) 67 | } 68 | if err != nil { 69 | return nil, fmt.Errorf("failed to create proxy dialer: %w", err) 70 | } 71 | return cntx_dialer, nil 72 | } 73 | 74 | type Response struct { 75 | body []byte 76 | status int 77 | err error 78 | } 79 | 80 | func (res *Response) String() string { 81 | return string(res.body) 82 | } 83 | func (res *Response) Error() string { 84 | return res.err.Error() 85 | } 86 | 87 | func custm_err(text string, err error) error { 88 | return fmt.Errorf("%v: %v", text, err.Error()) 89 | } 90 | 91 | func CreateSession() Session { 92 | session := Session{} 93 | 94 | allowRedirect := true 95 | 96 | // Change JA3 97 | var tlsClient tls.ClientHelloID 98 | 99 | tlsClient = tls.HelloIOS_Auto 100 | 101 | client, err := cclient.NewClient(tlsClient, "", allowRedirect, time.Duration(6)) 102 | if err != nil { 103 | log.Fatal(err) 104 | } 105 | 106 | session.client = &client 107 | session.headers = generate_headers() 108 | return session 109 | } 110 | 111 | func readBody(resp *http.Response) ([]byte, error) { 112 | encoding := resp.Header["Content-Encoding"] 113 | body, err := ioutil.ReadAll(resp.Body) 114 | 115 | var clearBody []byte 116 | finalres := "" 117 | 118 | if err != nil { 119 | panic(err) 120 | } 121 | finalres = string(body) 122 | if len(encoding) > 0 { 123 | if encoding[0] == "gzip" { 124 | unz, err := gUnzipData(body) 125 | if err != nil { 126 | panic(err) 127 | } 128 | clearBody = unz 129 | finalres = string(unz) 130 | } else if encoding[0] == "deflate" { 131 | unz, err := enflateData(body) 132 | if err != nil { 133 | panic(err) 134 | } 135 | 136 | clearBody = unz 137 | finalres = string(unz) 138 | } else if encoding[0] == "br" { 139 | unz, err := unBrotliData(body) 140 | if err != nil { 141 | panic(err) 142 | } 143 | clearBody = unz 144 | finalres = string(unz) 145 | } else { 146 | fmt.Println("UNKNOWN ENCODING: " + encoding[0]) 147 | clearBody = body 148 | finalres = string(body) 149 | } 150 | } else { 151 | clearBody = body 152 | finalres = string(body) 153 | } 154 | 155 | // fmt.Printf("RESPONSE: %v\n", finalres) 156 | _ = finalres 157 | 158 | return clearBody, nil 159 | } 160 | 161 | func gUnzipData(data []byte) (resData []byte, err error) { 162 | gz, _ := gzip.NewReader(bytes.NewReader(data)) 163 | defer gz.Close() 164 | respBody, err := ioutil.ReadAll(gz) 165 | return respBody, err 166 | } 167 | func enflateData(data []byte) (resData []byte, err error) { 168 | zr, _ := zlib.NewReader(bytes.NewReader(data)) 169 | defer zr.Close() 170 | enflated, err := ioutil.ReadAll(zr) 171 | return enflated, err 172 | } 173 | func unBrotliData(data []byte) (resData []byte, err error) { 174 | br := brotli.NewReader(bytes.NewReader(data)) 175 | respBody, err := ioutil.ReadAll(br) 176 | return respBody, err 177 | } 178 | 179 | func get_reader(datastr string) *bytes.Reader { 180 | data := []byte(datastr) 181 | return bytes.NewReader(data) 182 | } 183 | 184 | func Check_localhost(proxy string) *tls.Config { 185 | if strings.Contains(proxy, "127.0.0.1") || strings.Contains(proxy, "localhost") { 186 | return &tls.Config{InsecureSkipVerify: true} 187 | } else { 188 | return nil 189 | } 190 | } 191 | 192 | func (session *Session) Set_proxy(proxy string) error { 193 | proxy = strings.Replace(proxy, "\r", "", -1) 194 | dialer, err := proxyDialer(proxy) 195 | if err != nil { 196 | return err 197 | } 198 | tr := &http.Transport{ 199 | DialContext: dialer.DialContext, 200 | TLSClientConfig: Check_localhost(proxy)} 201 | session.client.Transport = tr 202 | session.client.Timeout = 15 * time.Second 203 | return nil 204 | } 205 | 206 | func (session *Session) Getreq(url string) *Response { 207 | return session.send_req(url, "GET", nil) 208 | } 209 | 210 | func (session *Session) Postreq(url string, data_str string) *Response { 211 | return session.send_req(url, "POST", get_reader(data_str)) 212 | } 213 | 214 | func (session *Session) Patchreq(url string, data_str string) *Response { 215 | return session.send_req(url, "PATCH", get_reader(data_str)) 216 | } 217 | 218 | func (session *Session) send_req(url string, method string, reader io.Reader) *Response { 219 | result := &Response{} 220 | req, err := http.NewRequest(method, url, reader) 221 | if err != nil { 222 | result.err = custm_err("Error on create request", err) 223 | return result 224 | } 225 | 226 | session.headers.Del("Cookie") 227 | req.Header = session.headers 228 | 229 | resp, err := session.client.Do(req) 230 | 231 | if err != nil { 232 | result.err = custm_err("Error on send requests", err) 233 | return result 234 | } 235 | 236 | body, err := readBody(resp) 237 | 238 | if err != nil { 239 | result.err = custm_err("Error on read result response", err) 240 | return result 241 | } 242 | result.body = body 243 | result.status = resp.StatusCode 244 | return result 245 | } 246 | 247 | func generate_agent() string { 248 | agents := []string{ 249 | "Mozilla/5.0 (iPhone; CPU iPhone OS 10_1_1; like Mac OS X) AppleWebKit/600.36 (KHTML, like Gecko) Chrome/49.0.3676.327 Mobile Safari/603.9", 250 | "Mozilla/5.0 (Linux; Android 6.0.1; HTC One M9 Build/MRA58K) AppleWebKit/534.42 (KHTML, like Gecko) Chrome/48.0.3842.338 Mobile Safari/601.3", 251 | "Mozilla/5.0 (iPhone; CPU iPhone OS 7_7_3; like Mac OS X) AppleWebKit/603.26 (KHTML, like Gecko) Chrome/55.0.3188.205 Mobile Safari/601.5", 252 | "Mozilla/5.0 (iPhone; CPU iPhone OS 7_6_2; like Mac OS X) AppleWebKit/534.40 (KHTML, like Gecko) Chrome/49.0.2438.379 Mobile Safari/600.2", 253 | "Mozilla/5.0 (iPad; CPU iPad OS 7_5_4 like Mac OS X) AppleWebKit/603.16 (KHTML, like Gecko) Chrome/54.0.3013.211 Mobile Safari/603.8", 254 | "Mozilla/5.0 (Android; Android 7.1.1; Pixel C Build/NME91E) AppleWebKit/600.28 (KHTML, like Gecko) Chrome/49.0.3014.203 Mobile Safari/602.4", 255 | "Mozilla/5.0 (Android; Android 4.4.1; SM-J110G Build/KTU84P) AppleWebKit/600.40 (KHTML, like Gecko) Chrome/54.0.3057.201 Mobile Safari/601.5", 256 | "Mozilla/5.0 (Android; Android 4.4.4; LG Optimus G Build/KRT16M) AppleWebKit/601.46 (KHTML, like Gecko) Chrome/54.0.1097.125 Mobile Safari/602.4", 257 | "Mozilla/5.0 (Android; Android 7.0; Nexus 7 Build/NME91E) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/50.0.1471.157 Mobile Safari/536.2", 258 | "Mozilla/5.0 (Linux; U; Android 4.4.4; XT1070 Build/SU6-7.3) AppleWebKit/537.46 (KHTML, like Gecko) Chrome/55.0.1148.223 Mobile Safari/537.6", 259 | "Mozilla/5.0 (Android; Android 7.0; Pixel C Build/NME91E) AppleWebKit/603.21 (KHTML, like Gecko) Chrome/50.0.2850.139 Mobile Safari/537.0", 260 | "Mozilla/5.0 (iPod; CPU iPod OS 7_7_9; like Mac OS X) AppleWebKit/600.24 (KHTML, like Gecko) Chrome/49.0.1878.176 Mobile Safari/534.5", 261 | "Mozilla/5.0 (Linux; Android 4.4.4; Elephone P2000 Build/KTU84P) AppleWebKit/535.29 (KHTML, like Gecko) Chrome/47.0.3020.286 Mobile Safari/603.9", 262 | "Mozilla/5.0 (Linux; U; Android 5.1; MOTOROLA MOTO X PURE XT1575 Build/LPK23) AppleWebKit/534.45 (KHTML, like Gecko) Chrome/47.0.1851.345 Mobile Safari/600.7", 263 | "Mozilla/5.0 (iPhone; CPU iPhone OS 9_0_9; like Mac OS X) AppleWebKit/601.22 (KHTML, like Gecko) Chrome/47.0.1645.112 Mobile Safari/535.0", 264 | "Mozilla/5.0 (Linux; Android 4.4.1; XT1051 Build/[KXB20.9|KXC21.5]) AppleWebKit/603.29 (KHTML, like Gecko) Chrome/55.0.1553.138 Mobile Safari/602.7", 265 | "Mozilla/5.0 (Android; Android 4.3.1; HTC One 801e Build/JLS36C) AppleWebKit/534.41 (KHTML, like Gecko) Chrome/54.0.1790.313 Mobile Safari/536.6", 266 | "Mozilla/5.0 (Linux; U; Android 4.4.1; SAMSUNG SM-N9006 Build/KOT49H) AppleWebKit/603.16 (KHTML, like Gecko) Chrome/47.0.2539.118 Mobile Safari/533.9", 267 | "Mozilla/5.0 (Android; Android 5.0.2; Nokia 1100 LTE Build/GRK39F) AppleWebKit/535.47 (KHTML, like Gecko) Chrome/48.0.1702.219 Mobile Safari/534.1", 268 | "Mozilla/5.0 (Android; Android 7.1.1; SAMSUNG GT-I9500 Build/KTU84P) AppleWebKit/535.38 (KHTML, like Gecko) Chrome/55.0.2457.147 Mobile Safari/535.0", 269 | "Mozilla/5.0 (iPad; CPU iPad OS 7_1_3 like Mac OS X) AppleWebKit/534.12 (KHTML, like Gecko) Chrome/53.0.1883.283 Mobile Safari/533.9", 270 | "Mozilla/5.0 (iPhone; CPU iPhone OS 8_3_1; like Mac OS X) AppleWebKit/534.1 (KHTML, like Gecko) Chrome/54.0.2369.370 Mobile Safari/603.4", 271 | "Mozilla/5.0 (iPad; CPU iPad OS 8_5_1 like Mac OS X) AppleWebKit/537.10 (KHTML, like Gecko) Chrome/52.0.2805.398 Mobile Safari/602.0", 272 | "Mozilla/5.0 (iPad; CPU iPad OS 11_2_2 like Mac OS X) AppleWebKit/537.9 (KHTML, like Gecko) Chrome/47.0.2162.161 Mobile Safari/602.7", 273 | "Mozilla/5.0 (Android; Android 5.0.1; LG-D334 Build/LRX22G) AppleWebKit/536.16 (KHTML, like Gecko) Chrome/55.0.1464.134 Mobile Safari/537.7", 274 | "Mozilla/5.0 (Android; Android 4.4.4; IQ4504 Quad Build/KOT49H) AppleWebKit/603.30 (KHTML, like Gecko) Chrome/52.0.3534.240 Mobile Safari/602.0", 275 | "Mozilla/5.0 (iPod; CPU iPod OS 8_0_5; like Mac OS X) AppleWebKit/600.5 (KHTML, like Gecko) Chrome/54.0.1899.226 Mobile Safari/537.3", 276 | "Mozilla/5.0 (iPod; CPU iPod OS 10_6_7; like Mac OS X) AppleWebKit/537.30 (KHTML, like Gecko) Chrome/51.0.1128.264 Mobile Safari/600.3", 277 | "Mozilla/5.0 (Android; Android 5.0; SM-G830K Build/LRX22G) AppleWebKit/534.39 (KHTML, like Gecko) Chrome/52.0.2039.328 Mobile Safari/603.3", 278 | "Mozilla/5.0 (Android; Android 5.0; LG-D326 Build/LRX22G) AppleWebKit/537.44 (KHTML, like Gecko) Chrome/55.0.1023.234 Mobile Safari/601.7", 279 | "Mozilla/5.0 (iPad; CPU iPad OS 10_6_5 like Mac OS X) AppleWebKit/537.39 (KHTML, like Gecko) Chrome/50.0.2473.310 Mobile Safari/601.2", 280 | "Mozilla/5.0 (iPod; CPU iPod OS 10_1_6; like Mac OS X) AppleWebKit/600.37 (KHTML, like Gecko) Chrome/50.0.1356.368 Mobile Safari/534.8", 281 | "Mozilla/5.0 (Linux; U; Android 4.3.1; SGH-N075S Build/JSS15J) AppleWebKit/536.33 (KHTML, like Gecko) Chrome/48.0.3076.325 Mobile Safari/601.7", 282 | "Mozilla/5.0 (iPad; CPU iPad OS 7_1_4 like Mac OS X) AppleWebKit/601.37 (KHTML, like Gecko) Chrome/52.0.1203.209 Mobile Safari/533.2", 283 | "Mozilla/5.0 (iPhone; CPU iPhone OS 9_4_3; like Mac OS X) AppleWebKit/600.9 (KHTML, like Gecko) Chrome/51.0.3690.162 Mobile Safari/601.9", 284 | "Mozilla/5.0 (Linux; Android 5.1.1; SM-G9350S Build/MMB29M) AppleWebKit/603.27 (KHTML, like Gecko) Chrome/54.0.3658.284 Mobile Safari/603.7", 285 | "Mozilla/5.0 (iPad; CPU iPad OS 9_7_1 like Mac OS X) AppleWebKit/603.10 (KHTML, like Gecko) Chrome/48.0.1204.394 Mobile Safari/600.7", 286 | "Mozilla/5.0 (iPhone; CPU iPhone OS 8_9_4; like Mac OS X) AppleWebKit/603.47 (KHTML, like Gecko) Chrome/55.0.3291.196 Mobile Safari/603.3", 287 | "Mozilla/5.0 (Linux; U; Android 5.0; HTC Butterfly S 901 Build/LRX22G) AppleWebKit/533.7 (KHTML, like Gecko) Chrome/54.0.2746.242 Mobile Safari/602.5", 288 | "Mozilla/5.0 (iPad; CPU iPad OS 11_8_1 like Mac OS X) AppleWebKit/536.34 (KHTML, like Gecko) Chrome/53.0.2346.234 Mobile Safari/536.0", 289 | "Mozilla/5.0 (iPad; CPU iPad OS 9_4_2 like Mac OS X) AppleWebKit/534.48 (KHTML, like Gecko) Chrome/49.0.2645.121 Mobile Safari/535.1", 290 | "Mozilla/5.0 (iPhone; CPU iPhone OS 8_3_2; like Mac OS X) AppleWebKit/533.39 (KHTML, like Gecko) Chrome/54.0.2375.105 Mobile Safari/603.3", 291 | "Mozilla/5.0 (Linux; U; Android 5.1; Nexus 9 Build/LRX22C) AppleWebKit/537.39 (KHTML, like Gecko) Chrome/55.0.2118.304 Mobile Safari/534.4", 292 | "Mozilla/5.0 (iPad; CPU iPad OS 10_7_2 like Mac OS X) AppleWebKit/601.6 (KHTML, like Gecko) Chrome/52.0.1037.181 Mobile Safari/536.5", 293 | "Mozilla/5.0 (Linux; U; Android 7.1.1; Nexus 8P Build/NME91E) AppleWebKit/535.26 (KHTML, like Gecko) Chrome/55.0.2968.158 Mobile Safari/534.8", 294 | "Mozilla/5.0 (iPhone; CPU iPhone OS 11_4_5; like Mac OS X) AppleWebKit/536.43 (KHTML, like Gecko) Chrome/51.0.1067.110 Mobile Safari/536.4", 295 | "Mozilla/5.0 (Linux; Android 5.1; Nexus 7 Build/LMY48B) AppleWebKit/536.23 (KHTML, like Gecko) Chrome/52.0.1133.387 Mobile Safari/535.5", 296 | "Mozilla/5.0 (iPad; CPU iPad OS 8_1_1 like Mac OS X) AppleWebKit/600.47 (KHTML, like Gecko) Chrome/55.0.2336.345 Mobile Safari/601.9", 297 | "Mozilla/5.0 (Linux; U; Android 5.0.1; SM-T805 Build/LRX22G) AppleWebKit/533.10 (KHTML, like Gecko) Chrome/52.0.3996.299 Mobile Safari/536.1", 298 | "Mozilla/5.0 (Linux; U; Android 6.0.1; SM-G920S Build/MDB08I) AppleWebKit/536.47 (KHTML, like Gecko) Chrome/48.0.1817.270 Mobile Safari/601.6", 299 | "Mozilla/5.0 (iPod; CPU iPod OS 7_3_6; like Mac OS X) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/48.0.3619.367 Mobile Safari/602.2", 300 | } 301 | randomIndex := rand.Intn(len(agents)) 302 | agent := agents[randomIndex] 303 | return agent 304 | } 305 | 306 | func generate_headers() http.Header { 307 | headers := http.Header{} 308 | agent := generate_agent() 309 | headers.Set("User-Agent", agent) 310 | //headers.Set("User-Agent", `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.27 Safari/537.36`) 311 | headers.Set("Content-Type", "application/json") 312 | return headers 313 | } 314 | -------------------------------------------------------------------------------- /internal/clicker/shop.go: -------------------------------------------------------------------------------- 1 | package clicker 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "os" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | var ( 12 | url_store = "https://clicker-api.joincommunity.xyz/clicker/store/merged" 13 | url_buy = "https://clicker-api.joincommunity.xyz/clicker/store/buy/" 14 | url_task = "https://clicker-api.joincommunity.xyz/clicker/task/" 15 | url_combine_compl = "https://clicker-api.joincommunity.xyz/clicker/task/combine-completed" 16 | ) 17 | 18 | func (not *Notcoin) ActiveTask(idTask int) bool { 19 | var taskName string 20 | switch idTask { 21 | case 2: 22 | taskName = "FullEnergy" 23 | case 3: 24 | taskName = "Turbo" 25 | } 26 | 27 | resp := not.Ses.Postreq(fmt.Sprintf("%v%d", url_task, idTask), "{}") 28 | //fmt.Println(resp.String()) 29 | parsedResp := parseRespclick(resp.body) 30 | 31 | if parsedResp.Ok { 32 | SuccessLogger.Printf("[%v] '%v' task activated %v\n", not.UserId, taskName, taskName) 33 | switch taskName { 34 | case "FullEnergy": 35 | not.Fullenergy_boost-- 36 | //conv to int 37 | //limCoinsINT, _ := strconv.Atoi(not.LimitCoins) 38 | not.LastAvailableCoins = not.LimitCoins 39 | case "Turbo": 40 | not.Turbo_boost_count++ 41 | } 42 | return true 43 | } else { 44 | WarningLogger.Printf("[%v] '%v' task activated is not ok, response: %v\n", not.UserId, taskName, resp.String()) 45 | return false 46 | } 47 | } 48 | 49 | func (not *Notcoin) BuyItem(item int) (bool, string) { 50 | var ok bool 51 | var str string 52 | var resp_parsed Buy_item_resp 53 | resp := not.Ses.Postreq(fmt.Sprintf("%v%d", url_buy, item), "{}") 54 | err := json.Unmarshal(resp.body, &resp_parsed) 55 | if err != nil { 56 | return false, "Error on unmarshal buy item, err = " + err.Error() 57 | } 58 | 59 | ok = resp_parsed.OK 60 | if ok { 61 | not.BalanceCoins = resp_parsed.Data.BalanceCoins 62 | } else { 63 | str = resp.String() 64 | } 65 | return ok, str 66 | } 67 | 68 | func (not *Notcoin) UpdateShop() { 69 | var parsed_resp Store_resp 70 | var select_item bool 71 | var item_count int 72 | var respstr string 73 | var isok bool 74 | var max_tapbot, _ = strconv.Atoi(os.Getenv("max_tapbot")) //# id= 18 75 | var max_multitab, _ = strconv.Atoi(os.Getenv("max_multitab")) //# id= 3 76 | var max_recharging, _ = strconv.Atoi(os.Getenv("max_recharging")) //# id= 2 77 | var max_energy_limit, _ = strconv.Atoi(os.Getenv("max_energy_limit")) //# id= 1 78 | 79 | shop_resp := not.Ses.Getreq(url_store) 80 | // fmt.Println("shop 80 shopresppbody", shop_resp.String()) 81 | err := json.Unmarshal(shop_resp.body, &parsed_resp) 82 | if err != nil { 83 | WarningLogger.Printf("[%v] update shop items is not ok, err: %v\n", not.UserId, err.Error()) 84 | return 85 | } 86 | if !parsed_resp.OK { 87 | WarningLogger.Printf("[%v] update shop items is not ok, response: %v\n", not.UserId, shop_resp.String()) 88 | return 89 | } 90 | for _, item := range parsed_resp.Data { 91 | switch item.ID { 92 | case 1: 93 | select_item = true 94 | item_count = max_energy_limit 95 | 96 | case 2: 97 | select_item = true 98 | item_count = max_recharging 99 | 100 | case 3: 101 | select_item = true 102 | item_count = max_multitab 103 | case 18: 104 | select_item = true 105 | item_count = max_tapbot 106 | } 107 | if !select_item { 108 | continue 109 | } 110 | 111 | //conv to int 112 | bal, _ := strconv.Atoi(not.BalanceCoins) 113 | 114 | if item_count > item.Count && 115 | bal >= item.Price && 116 | item.Status == "active" { 117 | isok, respstr = not.BuyItem(item.ID) 118 | if isok { 119 | SuccessLogger.Printf("[%v] buy item '%v'\n", not.UserId, item.Name) 120 | } else { 121 | WarningLogger.Printf("[%v] item '%v' buying is not success: %v\n", not.UserId, item.Name, respstr) 122 | } 123 | time.Sleep(2 * time.Second) 124 | } 125 | select_item = false 126 | } 127 | 128 | SuccessLogger.Printf("[%v] updated shop items\n", not.UserId) 129 | } 130 | 131 | func (not *Notcoin) UpdateBoosters() { 132 | var resp_parsed Task_completed_resp 133 | var energy_count = 3 134 | var turbo_count = 3 135 | 136 | resp := not.Ses.Getreq(url_combine_compl) 137 | 138 | err := json.Unmarshal(resp.body, &resp_parsed) 139 | if err != nil { 140 | WarningLogger.Printf("[%v] update boosters is not ok, err: %v\n", not.UserId, err) 141 | return 142 | } 143 | if !resp_parsed.Ok == true { 144 | WarningLogger.Printf("[%v] update boosters is not ok, response: %v\n", not.UserId, resp.String()) 145 | return 146 | } 147 | 148 | for _, boost := range resp_parsed.Data { 149 | switch boost.TaskId { 150 | case 2: // fullenergy 151 | if boost.Task.Status == "active" { 152 | energy_count-- 153 | } 154 | case 3: // turboboost 155 | if boost.Task.Status == "active" { 156 | turbo_count-- 157 | } 158 | } 159 | } 160 | 161 | not.Fullenergy_boost = energy_count 162 | for i := 0; i < turbo_count; i++ { 163 | not.ActiveTask(3) 164 | time.Sleep(3 * time.Second) 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Config struct { 4 | } 5 | 6 | func main() { 7 | cfg := Config{} 8 | Repl(&cfg) 9 | } 10 | -------------------------------------------------------------------------------- /preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sysleec/NotCoinBot/8b0e583a937d102783ba825225a8b3a2ed99908f/preview.gif -------------------------------------------------------------------------------- /repl.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strings" 8 | 9 | "github.com/fatih/color" 10 | ) 11 | 12 | func Repl(cfg *Config) { 13 | color.Set(color.FgHiYellow) 14 | data := []byte(` 15 | ████████████ 16 | ████░░░░░░░░░░░░████ 17 | ██░░░░▒▒▒▒▒▒▒▒▒▒▒▒░░░░██ 18 | ██░░▒▒░░░░ ░░░░░░ ░░██ 19 | ██░░▒▒░░░░░░ ░░░░▒▒░░░░░░ ░░██ 20 | ██░░▒▒░░ ░░░░░░ ░░░░ ░░██ 21 | ██░░▒▒░░ ░░░░░░░░░░░░▒▒░░ ░░██ 22 | ██░░▒▒░░ ░░░░░░░░░░░░▒▒░░ ░░██ 23 | ██░░▒▒░░░░▒▒░░░░░░▒▒▒▒▒▒░░ ░░██ 24 | ██░░▒▒░░░░░░ ░░░░▒▒░░░░░░ ░░██ 25 | ██░░▒▒░░░░░░▒▒▒▒▒▒░░░░ ░░██ 26 | ██░░░░ ░░░░░░░░░░░░ ░░░░██ 27 | ██░░░░ ░░░░██ 28 | ████░░░░░░░░░░░░████ 29 | ████████████ 30 | `) 31 | fmt.Println(string(data)) 32 | 33 | color.Set(color.FgHiGreen) 34 | fmt.Println("Welcome to the NotCoinBot!!!") 35 | fmt.Println() 36 | fmt.Println("This bot is designed to automate the process of collecting coins in the game NotCoin") 37 | fmt.Println("Author - github.com/Sysleec") 38 | fmt.Println() 39 | fmt.Println("You can support me with a donation to my TON wallet") 40 | fmt.Println("UQDPJTL7YyUk8Jm92Vymg2X4V-pKtNdarKMyv-r1oYrcfJKX") 41 | fmt.Println("And also join our community NotCoin Lions") 42 | fmt.Println("https://t.me/NotcoinLions") 43 | fmt.Println() 44 | fmt.Println("For start you need to create sessions with 'create '") 45 | fmt.Println("To run the clicker, write 'start'") 46 | fmt.Println("For help write 'help'") 47 | fmt.Println() 48 | color.Unset() 49 | 50 | scanner := bufio.NewScanner(os.Stdin) 51 | 52 | for { 53 | fmt.Print("NotCoinBot >") 54 | scanner.Scan() 55 | 56 | command := scanner.Text() 57 | if len(command) == 0 { 58 | continue 59 | } 60 | 61 | valCommand := validateCommand(command) 62 | commandName := valCommand[0] 63 | args := []string{} 64 | if len(valCommand) > 1 { 65 | args = valCommand[1:] 66 | } 67 | 68 | cmd, ok := commands()[commandName] 69 | if ok { 70 | err := cmd.callback(cfg, args...) 71 | if err != nil { 72 | fmt.Println("Error:", err) 73 | } 74 | } else { 75 | fmt.Println("Unknown command") 76 | continue 77 | } 78 | 79 | } 80 | } 81 | 82 | func validateCommand(str string) []string { 83 | lowStr := strings.ToLower(str) 84 | return strings.Fields(lowStr) 85 | } 86 | --------------------------------------------------------------------------------