From 98b0cadbe25aa390e496d8bd03184295cd105ba2 Mon Sep 17 00:00:00 2001 From: V4NSH4J <79518089+V4NSH4J@users.noreply.github.com> Date: Sat, 2 Apr 2022 02:22:54 +0530 Subject: [PATCH] Captcha bypass on DM 1) Captcha bypass on DM 2) Switched to YML for config --- config.yml | 257 ++++++----------------------------- go.mod | 1 + go.sum | 3 + main.go | 130 ++++++++---------- utilities/captcha.go | 64 ++++----- utilities/direct_messages.go | 68 ++++++++- utilities/extra.go | 12 +- utilities/files.go | 88 +++++++----- utilities/headers.go | 28 ++-- utilities/invite.go | 8 +- utilities/scrape.go | 10 +- utilities/websocket.go | 6 +- 12 files changed, 294 insertions(+), 381 deletions(-) diff --git a/config.yml b/config.yml index 2b60df7..4b30f54 100644 --- a/config.yml +++ b/config.yml @@ -1,216 +1,43 @@ -# Config for https://github.com/V4NSH4J/discord-mass-DM-GO - - -# # -# ---- UserBot Behaviour ---- # -# # - -# Duration in seconds that one account waits in between of sends 2 messages. -# Due to how discord rate limits are structured, you can only send 10 new messages every 10 minutes. -# To avoid hitting the rate limit, the recommended duration is 60, but this can be slow. -# Default: 6 -# Type: int -individual_delay: 6 - - -# Duration in seconds that the account sleeps for when rate limited. -# If you send 10 messages very quickly, this rate limit is of 600 seconds (10 minutes). -# With the recommended settings, you'd never hit it, so it's recommended to set at 60. -# Default: 650 -# Type: int -rate_limit_delay: 650 - - -# Duration in Milliseconds (1/1000th of a second) that the program waits in between of starting 2 instances. -# Perhaps one of the most important settings which is why it has it's own section. -# Recommended offset is (60/number of tokens) * 1000 but it does not matter with a few tokens and can be set to any small value like 50. -# Defaut: 100 -# Type: int -offset: 100 - - -# Program will avoid sending DMs to IDs it has already messaged. -# When someone is messaged, his ID is added to "input/completed.txt". -# Adding IDs to "input/completed.txt" will in a way blacklist them. -# Default: true -# Type: bool -skip_completed: true - - -# Program will avoid sending DMs to IDs it has already attempted to message but failed. -# When someone is attempted to be messaged but fails, his ID is added to "input/failed.txt". -# Default: true -# Type: bool -skip_failed: true - -# After completion of Mass DM, DMDGO will attempt to remove non-working tokens from input/tokens.txt -# Default: true -# Type: bool -remove_dead_tokens: true - -# After completion of Mass DM, DMDGO will attempt to remove completed members from "input/memberids.txt" leaving behind only the failed/unattempted IDs. -# This is so the user can re-run the program to target them. -# Default: true -# Type: bool -remove_completed_members: true - - -# Once a token is locked/disabled, it will stop DMing if this is set to true. -# Recommended to be true. -# Default: true -# Type: bool -stop_dead_tokens: true - - -# DMDGO will check if the user has a mutual guild with the token and also gather the user's Name and Discrim. -# This has been buggy in the past. Recommended to be set to false. -# Default: false -# Type: bool -check_mutual: false - - -# DMDGO will send a friend request to everyone in the list before attempting to DM them. Requires online_tokens and check_mutual. -# It needs online_tokens as a precautionary measure. Incase a token has never connected to gateway before and it tries sending a friend request, it will get locked. -# Default: false -# Type: bool -friend_before_DM: false - - -# DMDGO will online tokens before starting mass DM. This is a very important setting, certain functions like receive_messages, friend_before_DM and call cannot be used without it. -# But if you're not planning to use those features anyways, it can be set to false. -# Default: false -# Type: bool -online_tokens: false - - -# Time in milliseconds DMDGO will sleep between 2 consecutive scrapes to avoid being websocket-rate-limited. -# Default: 2000 -# Type: int -online_scraper_delay: 2000 - - -# After a succesful DM, DMDGO will attempt to call the user. This is unnecessary as it would make no difference. -# The calls don't "ring" if the users are not friended which they're not in most cases. So in essence, it would be a call without a ring. Recommended is false. -# Default: false -# Type: bool -call: false - - -# Number of maximum DMs you want your tokens to send. If set to 0 they will send DMs till they are locked or the list is completed. -# Default: 0 -# Type: int -max_dms_per_token: 0 - - -# If set to true, the messages from other users will be logged on console and in "input\received.txt". -# Default: false -# Type: bool -receive_messages: false - - -# If True, the program will block users after DMing them. -# Default: false -# Type: bool -block_after_dm: false - - -# If True, the program will close the user's DMs with them after DMing them. -# This won't delete the message, just hide the channel for the bot-user. -# Default: false -# Type: bool -close_dm_after_message: false - - -# Maximum attempts to rejoin token to server. Use minimum of 2. Introduced since Discord added Captchas to join servers on some tokens. -# Default: 3 -# Type: int -max_attempt_invite_rejoin: 3 - - - -# # -# ---- Proxy Settings ---- # -# # - - -# If set to true, DMDGO will use proxies from input\proxies.txt -# Default: true -# Type: bool -proxy_from_file: true - - -# What protocal to use when using proxies. -# Default: http -# Type: str -proxy_protocol: http - - -# If set to true, websocket connections will use proxy as well. Recommend keeping it at false unless you have very good proxies. -# Default: false -# Type: bool -use_proxy_for_gateway: false - - -# Whether to use your proxies for solving captchas. -# Default: false -# Type: bool -proxy_for_captcha: false - - -# Timeout for all requests in seconds. Increase if slow connection or proxies. -# Default: 60 -# Type: int -timeout: 60 - - -# Closes the underlying TCP connection after every request. Might be helpful to change IPs on every request with rotating proxies. -# Only used with proxies_from_file and not with the proxy field in config. Added because older versions of DMDGO which used only rotating proxies did this by default. -# Default: false -# Type: bool -disable_keep_alives: false - - - -# # -# ---- Captcha Settings ---- # -# # - - -# Domain of the Captcha API you wish to use. The current supported Captcha APIs are: -# - capmonster.cloud -# - anti-captcha.com -# - 2captcha.com -# - rucaptcha.com -# - deathbycaptcha.com -# - anycaptcha.com -# - azcaptcha.com -# - solvecaptcha.com -# Type: str (as url) -captcha_api: "anti-captcha.com" - - -# Your Captcha API Key with balance loaded -# Type: str -captcha_api_key: "your-captcha-key-here" - - - -# # -# ---- Scraping Settings ---- # -# # - - -# When scraping, save usernames. -# Default: false -# Type: bool -scrape_usernames: false - - -# When scraping, save avatars. -# Default: false -# Type: bool -scrape_avatars: false - - - +direct_message_settings: + individual_delay: 60 + rate_limit_delay: 60 + offset: 100 + max_dms_per_token: 0 + skip_completed: true + call: false + remove_dead_tokens: true + remove_completed_members: true + stop_dead_tokens: true + check_mutual: false + friend_before_DM: false + online_tokens: false + receive_messages: false + skip_failed: true + block_after_dm: false + close_dm_after_message: false + +proxy_settings: + proxy_from_file: true + proxy_for_captcha: true + use_proxy_for_gateway: false + proxy_protocol: "http" + timeout: 60 + +scraper_settings: + online_scraper_delay: 3000 + scrape_usernames: false + scrape_avatars: false + +captcha_settings: + captcha_api_key: "" + captcha_api: "capmonster.cloud" + +other_settings: + max_attempt_invite_rejoin: 3 + disable_keep_alives: false + +suspicion_avoidance: + random_individual_delay: 20 + random_rate_limit_delay: 20 + random_delay_before_dm: 20 diff --git a/go.mod b/go.mod index 3cd5e27..e6749d1 100644 --- a/go.mod +++ b/go.mod @@ -10,4 +10,5 @@ require ( github.com/gorilla/websocket v1.4.2 // direct github.com/zenthangplus/goccm v0.0.0-20211005163543-2f2e522aca15 golang.org/x/sys v0.0.0-20211015200801-69063c4bb744 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b ) diff --git a/go.sum b/go.sum index f81b543..06fedb1 100644 --- a/go.sum +++ b/go.sum @@ -20,3 +20,6 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211015200801-69063c4bb744 h1:KzbpndAYEM+4oHRp9JmB2ewj0NHHxO3Z0g7Gus2O1kk= golang.org/x/sys v0.0.0-20211015200801-69063c4bb744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 599329a..9f22584 100644 --- a/main.go +++ b/main.go @@ -34,7 +34,7 @@ import ( ) func main() { - version := "1.8.7" + version := "1.8.8" CaptchaServices = []string{"capmonster.cloud", "anti-captcha.com", "2captcha.com", "rucaptcha.com", "deathbycaptcha.com", "anycaptcha.com", "azcaptcha.com", "solvecaptcha.com"} rand.Seed(time.Now().UTC().UnixNano()) color.Blue(logo + " v" + version + "\n") @@ -58,27 +58,8 @@ func Options() { color.Cyan("Debug Mode") var inv string fmt.Scanln(&inv) - _, instances, err := getEverything() - if err != nil { - color.Red(err.Error()) - ExitSafely() - } - var wg sync.WaitGroup - for i := 0; i < len(instances); i++ { - wg.Add(1) - go func(i int) { - defer wg.Done() - a, b, c, err := instances[i].Inviter(inv, 0, "", "") - if err != nil { - color.Red(err.Error()) - } - if a == -1 { - instances[i].Inviter(inv, a, b, c) - } - fmt.Println(a, b, c) - }(i) - } - wg.Wait() + cfg, _, _ := getEverything() + fmt.Println(cfg) case 1: var invitechoice int @@ -176,7 +157,7 @@ func Options() { } c := goccm.New(threads) for i := 0; i < len(instances); i++ { - time.Sleep(time.Duration(cfg.Offset) * time.Millisecond) + time.Sleep(time.Duration(cfg.DirectMessage.Offset) * time.Millisecond) c.Wait() go func(i int) { for j := 0; j < len(invites); j++ { @@ -285,10 +266,10 @@ func Options() { color.Red("Error while opening completed.txt: %v", err) ExitSafely() } - if cfg.Skip { + if cfg.DirectMessage.Skip { members = utilities.RemoveSubset(members, completed) } - if cfg.SkipFailed { + if cfg.DirectMessage.SkipFailed { failedSkip, err := utilities.ReadLines("failed.txt") if err != nil { color.Red("Error while opening failed.txt: %v", err) @@ -331,7 +312,7 @@ func Options() { start := time.Now() for i := 0; i < len(instances); i++ { // Offset goroutines by a few milliseconds. Makes a big difference and allows for better concurrency - time.Sleep(time.Duration(cfg.Offset) * time.Millisecond) + time.Sleep(time.Duration(cfg.DirectMessage.Offset) * time.Millisecond) wg.Add(1) go func(i int) { defer wg.Done() @@ -343,12 +324,12 @@ func Options() { member := <-mem // Breaking loop if maximum DMs reached - if cfg.MaxDMS != 0 && instances[i].Count >= cfg.MaxDMS { + if cfg.DirectMessage.MaxDMS != 0 && instances[i].Count >= cfg.DirectMessage.MaxDMS { color.Yellow("[%v] Maximum DMs reached for %v", time.Now().Format("15:04:05"), instances[i].Token) break } // Start websocket connection if not already connected and reconnect if dead - if cfg.Websocket && instances[i].Ws == nil { + if cfg.DirectMessage.Websocket && instances[i].Ws == nil { err := instances[i].StartWS() if err != nil { color.Red("[%v] Error while opening websocket: %v", time.Now().Format("15:04:05"), err) @@ -356,7 +337,7 @@ func Options() { color.Green("[%v] Websocket opened %v", time.Now().Format("15:04:05"), instances[i].Token) } } - if cfg.Websocket && cfg.Receive && instances[i].Ws != nil && !instances[i].Receiver { + if cfg.DirectMessage.Websocket && cfg.DirectMessage.Receive && instances[i].Ws != nil && !instances[i].Receiver { instances[i].Receiver = true go func() { for { @@ -404,7 +385,7 @@ func Options() { if err != nil { fmt.Println(err) } - if cfg.Stop { + if cfg.DirectMessage.Stop { break } } @@ -439,7 +420,7 @@ func Options() { var user string user = member // Check Mutual - if cfg.Mutual { + if cfg.DirectMessage.Mutual { info, err := instances[i].UserInfo(member) if err != nil { failedCount++ @@ -464,7 +445,7 @@ func Options() { } user = info.User.Username + "#" + info.User.Discriminator // Used only if Websocket is enabled as Unwebsocketed Tokens get locked if they attempt to send friend requests. - if cfg.Friend && cfg.Websocket { + if cfg.DirectMessage.Friend && cfg.DirectMessage.Websocket { x, err := strconv.Atoi(info.User.Discriminator) if err != nil { color.Red("[%v] Error while adding friend: %v", time.Now().Format("15:04:05"), err) @@ -504,6 +485,9 @@ func Options() { failed = append(failed, member) continue } + if cfg.SuspicionAvoidance.RandomDelayOpenChannel != 0 { + time.Sleep(time.Duration(rand.Intn(cfg.SuspicionAvoidance.RandomDelayOpenChannel)) * time.Second) + } resp, err := instances[i].SendMessage(snowflake, member) if err != nil { failedCount++ @@ -547,7 +531,7 @@ func Options() { completed = append(completed, member) session = append(session, member) color.Green("[%v] Token %v sent DM to %v [%v]", time.Now().Format("15:04:05"), instances[i].Token, user, len(session)) - if cfg.Websocket && cfg.Call && instances[i].Ws != nil { + if cfg.DirectMessage.Websocket && cfg.DirectMessage.Call && instances[i].Ws != nil { err := instances[i].Call(snowflake) if err != nil { color.Red("[%v] %v Error while calling %v: %v", time.Now().Format("15:04:05"), instances[i].Token, user, err) @@ -565,7 +549,7 @@ func Options() { // } } - if cfg.Block { + if cfg.DirectMessage.Block { r, err := instances[i].BlockUser(member) if err != nil { color.Red("[%v] Error while blocking user: %v", time.Now().Format("15:04:05"), err) @@ -577,7 +561,7 @@ func Options() { } } } - if cfg.Close { + if cfg.DirectMessage.Close { r, err := instances[i].CloseDMS(snowflake) if err != nil { color.Red("[%v] Error while closing DM: %v", time.Now().Format("15:04:05"), err) @@ -596,9 +580,12 @@ func Options() { if err != nil { fmt.Println(err) } - failed = append(failed, member) - color.Yellow("[%v] Token %v sleeping for %v minutes!", time.Now().Format("15:04:05"), instances[i].Token, int(cfg.LongDelay/60)) - time.Sleep(time.Duration(cfg.LongDelay) * time.Second) + mem <- member + color.Yellow("[%v] Token %v sleeping for %v minutes!", time.Now().Format("15:04:05"), instances[i].Token, int(cfg.DirectMessage.LongDelay/60)) + time.Sleep(time.Duration(cfg.DirectMessage.LongDelay) * time.Second) + if cfg.SuspicionAvoidance.RandomRateLimitDelay != 0 { + time.Sleep(time.Duration(rand.Intn(cfg.SuspicionAvoidance.RandomRateLimitDelay)) * time.Second) + } color.Yellow("[%v] Token %v continuing!", time.Now().Format("15:04:05"), instances[i].Token) // Forbidden - DM's are closed } else if resp.StatusCode == 403 && response.Code == 50007 { @@ -620,7 +607,7 @@ func Options() { color.Red("[%v] Token %v is locked or disabled. Stopping instance. %v %v [%v]", time.Now().Format("15:04:05"), instances[i].Token, resp.StatusCode, string(body), failedCount) dead = append(dead, instances[i].Token) // Stop token if locked or disabled - if cfg.Stop { + if cfg.DirectMessage.Stop { break } // Forbidden - Invalid token @@ -646,7 +633,10 @@ func Options() { } color.Red("[%v] Token %v couldn't DM %v Error Code: %v; Status: %v; Message: %v [%v]", time.Now().Format("15:04:05"), instances[i].Token, user, response.Code, resp.Status, response.Message, failedCount) } - time.Sleep(time.Duration(cfg.Delay) * time.Second) + time.Sleep(time.Duration(cfg.DirectMessage.Delay) * time.Second) + if cfg.SuspicionAvoidance.RandomIndividualDelay != 0 { + time.Sleep(time.Duration(rand.Intn(cfg.SuspicionAvoidance.RandomIndividualDelay)) * time.Second) + } } }(i) } @@ -656,7 +646,7 @@ func Options() { elapsed := time.Since(start) color.Green("[%v] DM advertisement took %v. Successfully sent DMs to %v IDs. Failed to send DMs to %v IDs. %v tokens are dis-functional & %v tokens are functioning", time.Now().Format("15:04:05"), elapsed.Seconds(), len(completed), len(failed), len(dead), len(instances)-len(dead)) - if cfg.Remove { + if cfg.DirectMessage.Remove { var tokens []string for i := 0; i < len(instances); i++ { tokens = append(tokens, instances[i].Token) @@ -668,7 +658,7 @@ func Options() { } color.Green("Updated tokens.txt") } - if cfg.RemoveM { + if cfg.DirectMessage.RemoveM { m := utilities.RemoveSubset(members, completed) err := Truncate("input/memberids.txt", m) if err != nil { @@ -677,7 +667,7 @@ func Options() { color.Green("Updated memberids.txt") } - if cfg.Websocket { + if cfg.DirectMessage.Websocket { for i := 0; i < len(instances); i++ { if instances[i].Ws != nil { instances[i].Ws.Close() @@ -736,7 +726,7 @@ func Options() { wg.Add(len(instances)) if choice == 0 { for i := 0; i < len(instances); i++ { - time.Sleep(time.Duration(cfg.Offset) * time.Millisecond) + time.Sleep(time.Duration(cfg.DirectMessage.Offset) * time.Millisecond) go func(i int) { defer wg.Done() @@ -763,7 +753,7 @@ func Options() { } if choice == 1 { for i := 0; i < len(instances); i++ { - time.Sleep(time.Duration(cfg.Offset) * time.Millisecond) + time.Sleep(time.Duration(cfg.DirectMessage.Offset) * time.Millisecond) go func(i int) { defer wg.Done() @@ -825,7 +815,7 @@ func Options() { var send string fmt.Scanln(&emoji) for i := 0; i < len(instances); i++ { - time.Sleep(time.Duration(cfg.Offset) * time.Millisecond) + time.Sleep(time.Duration(cfg.DirectMessage.Offset) * time.Millisecond) go func(i int) { defer wg.Done() if msg.Reactions[emoji].Emojis.ID == "" { @@ -859,7 +849,7 @@ func Options() { var emoji string fmt.Scanln(&emoji) for i := 0; i < len(instances); i++ { - time.Sleep(time.Duration(cfg.Offset) * time.Millisecond) + time.Sleep(time.Duration(cfg.DirectMessage.Offset) * time.Millisecond) go func(i int) { defer wg.Done() err := instances[i].React(channel, id, emoji) @@ -990,7 +980,7 @@ func Options() { fmt.Scanln(&serverid) c := goccm.New(threads) for i := 0; i < len(instances); i++ { - time.Sleep(time.Duration(cfg.Offset) * time.Millisecond) + time.Sleep(time.Duration(cfg.DirectMessage.Offset) * time.Millisecond) c.Wait() go func(i int) { p := instances[i].Leave(serverid) @@ -1091,7 +1081,7 @@ func Options() { break } i++ - time.Sleep(time.Duration(cfg.SleepSc) * time.Millisecond) + time.Sleep(time.Duration(cfg.ScraperSettings.SleepSc) * time.Millisecond) } if Is.Ws != nil { Is.Ws.Close() @@ -1325,7 +1315,7 @@ func Options() { color.Red("[%v] Error while writing to file: %v", time.Now().Format("15:04:05"), err) continue } - if cfg.ScrapeUsernames { + if cfg.ScraperSettings.ScrapeUsernames { nom := MemberInfo.Data.Members[i].User.Username if !utilities.Contains(namesScraped, nom) { err := utilities.WriteLines("names.txt", nom) @@ -1335,7 +1325,7 @@ func Options() { } } } - if cfg.ScrapeAvatars { + if cfg.ScraperSettings.ScrapeAvatars { av := MemberInfo.Data.Members[i].User.Avatar if !utilities.Contains(avatarsScraped, av) { err := utilities.ProcessAvatar(av, id) @@ -1347,7 +1337,7 @@ func Options() { } } if len(MemberInfo.Data.Members) < 100 { - time.Sleep(time.Duration(cfg.SleepSc) * time.Millisecond) + time.Sleep(time.Duration(cfg.ScraperSettings.SleepSc) * time.Millisecond) continue } lastName := MemberInfo.Data.Members[len(MemberInfo.Data.Members)-1].User.Username @@ -1649,26 +1639,26 @@ func getEverything() (utilities.Config, []utilities.Instance, error) { return cfg, instances, err } supportedProtocols := []string{"http", "https", "socks4", "socks5"} - if cfg.ProxyProtocol != "" && !utilities.Contains(supportedProtocols, cfg.ProxyProtocol) { + if cfg.ProxySettings.ProxyProtocol != "" && !utilities.Contains(supportedProtocols, cfg.ProxySettings.ProxyProtocol) { color.Red("[!] You're using an unsupported proxy protocol. Assuming http by default") - cfg.ProxyProtocol = "http" + cfg.ProxySettings.ProxyProtocol = "http" } - if cfg.ProxyProtocol == "https" { - cfg.ProxyProtocol = "http" + if cfg.ProxySettings.ProxyProtocol == "https" { + cfg.ProxySettings.ProxyProtocol = "http" } - if cfg.CaptchaAPI == "" { + if cfg.CaptchaSettings.CaptchaAPI == "" { color.Red("[!] You're not using a Captcha API, some functionality like invite joining might be unavailable") } - if cfg.Proxy != "" && os.Getenv("HTTPS_PROXY") == "" { - os.Setenv("HTTPS_PROXY", cfg.ProxyProtocol+"://"+cfg.Proxy) + if cfg.ProxySettings.Proxy != "" && os.Getenv("HTTPS_PROXY") == "" { + os.Setenv("HTTPS_PROXY", cfg.ProxySettings.ProxyProtocol+"://"+cfg.ProxySettings.Proxy) } - if !cfg.ProxyFromFile && cfg.ProxyForCaptcha { + if !cfg.ProxySettings.ProxyFromFile && cfg.ProxySettings.ProxyForCaptcha { color.Red("[!] You must enabe proxy_from_file to use proxy_for_captcha") - cfg.ProxyForCaptcha = false + cfg.ProxySettings.ProxyForCaptcha = false } - if !utilities.Contains(CaptchaServices, cfg.CaptchaAPI) { - color.Red("[!] Captcha API %v is not supported. Please use one of the following: %v", cfg.CaptchaAPI, CaptchaServices) - cfg.CaptchaAPI = "" + if !utilities.Contains(CaptchaServices, cfg.CaptchaSettings.CaptchaAPI) { + color.Red("[!] Captcha API %v is not supported. Please use one of the following: %v", cfg.CaptchaSettings.CaptchaAPI, CaptchaServices) + cfg.CaptchaSettings.CaptchaAPI = "" } // Load instances @@ -1679,7 +1669,7 @@ func getEverything() (utilities.Config, []utilities.Instance, error) { if len(tokens) == 0 { return cfg, instances, fmt.Errorf("no tokens found in tokens.txt") } - if cfg.ProxyFromFile { + if cfg.ProxySettings.ProxyFromFile { proxies, err = utilities.ReadLines("proxies.txt") if err != nil { return cfg, instances, err @@ -1690,7 +1680,7 @@ func getEverything() (utilities.Config, []utilities.Instance, error) { } var Gproxy string for i := 0; i < len(tokens); i++ { - if cfg.ProxyFromFile { + if cfg.ProxySettings.ProxyFromFile { proxy = proxies[rand.Intn(len(proxies))] Gproxy = proxy } else { @@ -1701,7 +1691,7 @@ func getEverything() (utilities.Config, []utilities.Instance, error) { return cfg, instances, fmt.Errorf("couldn't initialize client: %v", err) } // proxy is put in struct only to be used by gateway. If proxy for gateway is disabled, it will be empty - if !cfg.GatewayProxy { + if !cfg.ProxySettings.GatewayProxy { Gproxy = "" } instances = append(instances, utilities.Instance{Client: client, Token: tokens[i], Proxy: proxy, Config: cfg, GatewayProxy: Gproxy}) @@ -1810,7 +1800,7 @@ func initClient(proxy string, cfg utilities.Config) (*http.Client, error) { if proxy == "" { return http.DefaultClient, nil } - switch cfg.ProxyProtocol { + switch cfg.ProxySettings.ProxyProtocol { case "http": if !strings.Contains(proxy, "http://") { proxy = "http://" + proxy @@ -1832,7 +1822,7 @@ func initClient(proxy string, cfg utilities.Config) (*http.Client, error) { // Creating a client and modifying the transport. Client := &http.Client{ - Timeout: time.Second * time.Duration(cfg.Timeout), + Timeout: time.Second * time.Duration(cfg.ProxySettings.Timeout), Transport: &http.Transport{ TLSClientConfig: &tls.Config{ MinVersion: tls.VersionTLS12, @@ -1840,7 +1830,7 @@ func initClient(proxy string, cfg utilities.Config) (*http.Client, error) { InsecureSkipVerify: true, CurvePreferences: []tls.CurveID{tls.CurveID(0x001d), tls.CurveID(0x0017), tls.CurveID(0x0018), tls.CurveID(0x0019), tls.CurveID(0x0100), tls.CurveID(0x0101)}, }, - DisableKeepAlives: cfg.DisableKL, + DisableKeepAlives: cfg.OtherSettings.DisableKL, ForceAttemptHTTP2: true, Proxy: http.ProxyURL(proxyURL), }, diff --git a/utilities/captcha.go b/utilities/captcha.go index 412552f..b7bcfeb 100644 --- a/utilities/captcha.go +++ b/utilities/captcha.go @@ -15,23 +15,23 @@ import ( func (in *Instance) SolveCaptcha(sitekey string, cookie string, rqData string, rqToken string) (string, error) { switch true { - case Contains([]string{"capmonster.cloud", "anti-captcha.com", "anycaptcha.com"}, in.Config.CaptchaAPI): + case Contains([]string{"capmonster.cloud", "anti-captcha.com", "anycaptcha.com"}, in.Config.CaptchaSettings.CaptchaAPI): return in.SolveCaptchaCapmonster(sitekey, cookie, rqData) - case Contains([]string{"rucaptcha.com", "azcaptcha.com", "solvecaptcha.com", "2captcha.com"}, in.Config.CaptchaAPI): + case Contains([]string{"rucaptcha.com", "azcaptcha.com", "solvecaptcha.com", "2captcha.com"}, in.Config.CaptchaSettings.CaptchaAPI): return in.SolveCaptchaRucaptcha(sitekey, rqData, rqToken) - case in.Config.CaptchaAPI == "deathbycaptcha.com": + case in.Config.CaptchaSettings.CaptchaAPI == "deathbycaptcha.com": return in.SolveCaptchaDeathByCaptcha(sitekey) default: - return "", fmt.Errorf("unsupported captcha api: %s", in.Config.CaptchaAPI) + return "", fmt.Errorf("unsupported captcha api: %s", in.Config.CaptchaSettings.CaptchaAPI) } } // Function to use a captcha solving service and return a solved captcha key func (in *Instance) SolveCaptchaCapmonster(sitekey string, cookies string, rqdata string) (string, error) { var jsonx Pload - if !in.Config.ProxyForCaptcha || in.Config.CaptchaAPI == "anycaptcha.com" { + if !in.Config.ProxySettings.ProxyForCaptcha || in.Config.CaptchaSettings.CaptchaAPI == "anycaptcha.com" { jsonx = Pload{ - ClientKey: in.Config.ClientKey, + ClientKey: in.Config.CaptchaSettings.ClientKey, Task: Task{ Type: "HCaptchaTaskProxyless", WebsiteURL: "https://discord.com/channels/@me", @@ -64,13 +64,13 @@ func (in *Instance) SolveCaptchaCapmonster(sitekey string, cookies string, rqdat } } jsonx = Pload{ - ClientKey: in.Config.ClientKey, + ClientKey: in.Config.CaptchaSettings.ClientKey, Task: Task{ Type: "HCaptchaTask", WebsiteURL: "https://discord.com/channels/@me", WebsiteKey: sitekey, UserAgent: Useragent, - ProxyType: in.Config.ProxyProtocol, + ProxyType: in.Config.ProxySettings.ProxyProtocol, ProxyAddress: address, ProxyPort: port, ProxyLogin: username, @@ -87,7 +87,7 @@ func (in *Instance) SolveCaptchaCapmonster(sitekey string, cookies string, rqdat } // Almost all solving services have similar API, so we can use the same function and replace the domain. - resp, err := http.Post("https://api."+in.Config.CaptchaAPI+"/createTask", "application/json", strings.NewReader(string(bytes))) + resp, err := http.Post("https://api."+in.Config.CaptchaSettings.CaptchaAPI+"/createTask", "application/json", strings.NewReader(string(bytes))) if err != nil { return "", fmt.Errorf("error creating the request for captcha [%v]", err) } @@ -106,7 +106,7 @@ func (in *Instance) SolveCaptchaCapmonster(sitekey string, cookies string, rqdat case 0: // Poling server for the solved captcha jsonx = Pload{ - ClientKey: in.Config.ClientKey, + ClientKey: in.Config.CaptchaSettings.ClientKey, TaskID: response.TaskID, } y, err := json.Marshal(jsonx) @@ -121,7 +121,7 @@ func (in *Instance) SolveCaptchaCapmonster(sitekey string, cookies string, rqdat // Max retries break } - resp, err := http.Post("https://api."+in.Config.CaptchaAPI+"/getTaskResult", "application/json", strings.NewReader(string(y))) + resp, err := http.Post("https://api."+in.Config.CaptchaSettings.CaptchaAPI+"/getTaskResult", "application/json", strings.NewReader(string(y))) if err != nil { return "", fmt.Errorf("error creating the request for captcha [%v]", err) } @@ -204,7 +204,7 @@ type Sol struct { } func (in *Instance) SolveCaptcha2Captcha(sitekey string) (string, error) { - client := api2captcha.NewClient(in.Config.ClientKey) + client := api2captcha.NewClient(in.Config.CaptchaSettings.ClientKey) client.DefaultTimeout = 120 client.PollingInterval = 22 @@ -213,16 +213,16 @@ func (in *Instance) SolveCaptcha2Captcha(sitekey string) (string, error) { Url: "https://discord.com/channels/@me", } var proxyType string - if in.Config.ProxyProtocol == "socks5" { + if in.Config.ProxySettings.ProxyProtocol == "socks5" { proxyType = "SOCKS5" - } else if in.Config.ProxyProtocol == "socks4" { + } else if in.Config.ProxySettings.ProxyProtocol == "socks4" { proxyType = "SOCKS4" - } else if in.Config.ProxyProtocol == "http" { + } else if in.Config.ProxySettings.ProxyProtocol == "http" { proxyType = "HTTPS" } req := cap.ToRequest() - if in.Config.ProxyForCaptcha { + if in.Config.ProxySettings.ProxyForCaptcha { req.SetProxy(proxyType, in.Proxy) } req.Params["userAgent"] = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) discord/1.0.9003 Chrome/91.0.4472.164 Electron/13.4.0 Safari/537.36" @@ -251,11 +251,11 @@ func (in *Instance) SolveCaptchaDeathByCaptcha(sitekey string) (string, error) { var proxy string var proxytype string - if strings.Contains(in.Config.ClientKey, ":") { - credentials := strings.Split(in.Config.ClientKey, ":") + if strings.Contains(in.Config.CaptchaSettings.ClientKey, ":") { + credentials := strings.Split(in.Config.CaptchaSettings.ClientKey, ":") username, password = credentials[0], credentials[1] } else { - authtoken = in.Config.ClientKey + authtoken = in.Config.CaptchaSettings.ClientKey } captchaPostEndpoint := "http://api.dbcapi.me/api/captcha" @@ -296,26 +296,26 @@ func (in *Instance) SolveCaptchaDeathByCaptcha(sitekey string) (string, error) { func (in *Instance) SolveCaptchaRucaptcha(sitekey string, rqData string, rqToken string) (string, error) { encUa := `Mozilla%2F5.0%20%28Windows%20NT%2010.0%3B%20Win64%3B%20x64%3B%20rv%3A83.0%29%20Gecko%2F20100101%20Firefox%2F83.0` var submitEndpoint string - if !in.Config.ProxyForCaptcha { - if in.Config.CaptchaAPI == "2captcha.com" { - submitEndpoint = fmt.Sprintf("http://%s/in.php?key=%s&method=hcaptcha&sitekey=%s&pageurl=%s&userAgent=%s&json=1&soft_id=12368652", in.Config.CaptchaAPI, in.Config.ClientKey, sitekey, "https://discord.com/channels/@me", encUa) + if !in.Config.ProxySettings.ProxyForCaptcha { + if in.Config.CaptchaSettings.CaptchaAPI == "2captcha.com" { + submitEndpoint = fmt.Sprintf("http://%s/in.php?key=%s&method=hcaptcha&sitekey=%s&pageurl=%s&userAgent=%s&json=1&soft_id=12368652", in.Config.CaptchaSettings.CaptchaAPI, in.Config.CaptchaSettings.ClientKey, sitekey, "https://discord.com/channels/@me", encUa) } else { - submitEndpoint = fmt.Sprintf("http://%s/in.php?key=%s&method=hcaptcha&sitekey=%s&pageurl=%s&userAgent=%sjson=1&soft_id=13615286", in.Config.CaptchaAPI, in.Config.ClientKey, sitekey, "https://discord.com/channels/@me", encUa) + submitEndpoint = fmt.Sprintf("http://%s/in.php?key=%s&method=hcaptcha&sitekey=%s&pageurl=%s&userAgent=%sjson=1&soft_id=13615286", in.Config.CaptchaSettings.CaptchaAPI, in.Config.CaptchaSettings.ClientKey, sitekey, "https://discord.com/channels/@me", encUa) } } else { var proxyType string - if in.Config.ProxyProtocol == "socks5" { + if in.Config.ProxySettings.ProxyProtocol == "socks5" { proxyType = "SOCKS5" - } else if in.Config.ProxyProtocol == "socks4" { + } else if in.Config.ProxySettings.ProxyProtocol == "socks4" { proxyType = "SOCKS4" - } else if in.Config.ProxyProtocol == "http" { + } else if in.Config.ProxySettings.ProxyProtocol == "http" { proxyType = "HTTPS" } - if in.Config.CaptchaAPI == "2captcha.com" { - submitEndpoint = fmt.Sprintf("http://%s/in.php?key=%s&method=hcaptcha&sitekey=%s&pageurl=%s&userAgent=%s&proxy=%s&proxy_type=%s&json=1&soft_id=12368652", in.Config.CaptchaAPI, in.Config.ClientKey, sitekey, "https://discord.com/channels/@me", encUa, in.Proxy, proxyType) + if in.Config.CaptchaSettings.CaptchaAPI == "2captcha.com" { + submitEndpoint = fmt.Sprintf("http://%s/in.php?key=%s&method=hcaptcha&sitekey=%s&pageurl=%s&userAgent=%s&proxy=%s&proxy_type=%s&json=1&soft_id=12368652", in.Config.CaptchaSettings.CaptchaAPI, in.Config.CaptchaSettings.ClientKey, sitekey, "https://discord.com/channels/@me", encUa, in.Proxy, proxyType) } else { - submitEndpoint = fmt.Sprintf("http://%s/in.php?key=%s&method=hcaptcha&sitekey=%s&pageurl=%s&userAgent=%s&proxy=%s&proxy_type=%s&json=1&soft_id=13615286", in.Config.CaptchaAPI, in.Config.ClientKey, sitekey, "https://discord.com/channels/@me", encUa, in.Proxy, proxyType) + submitEndpoint = fmt.Sprintf("http://%s/in.php?key=%s&method=hcaptcha&sitekey=%s&pageurl=%s&userAgent=%s&proxy=%s&proxy_type=%s&json=1&soft_id=13615286", in.Config.CaptchaSettings.CaptchaAPI, in.Config.CaptchaSettings.ClientKey, sitekey, "https://discord.com/channels/@me", encUa, in.Proxy, proxyType) } } if rqData != "" { @@ -350,13 +350,13 @@ func (in *Instance) SolveCaptchaRucaptcha(sitekey string, rqData string, rqToken var captchaIDfloat int var captchaIDString string var captchaGetEndpoint string - if in.Config.CaptchaAPI == "azcaptcha.com" { + if in.Config.CaptchaSettings.CaptchaAPI == "azcaptcha.com" { captchaIDfloat = int(response["request"].(float64)) fmt.Println(captchaIDfloat) - captchaGetEndpoint = fmt.Sprintf("https://%s/res.php?key=%s&action=get&action=get&id=%s&json=1", in.Config.CaptchaAPI, in.Config.ClientKey, strconv.Itoa(captchaIDfloat)) + captchaGetEndpoint = fmt.Sprintf("https://%s/res.php?key=%s&action=get&action=get&id=%s&json=1", in.Config.CaptchaSettings.CaptchaAPI, in.Config.CaptchaSettings.ClientKey, strconv.Itoa(captchaIDfloat)) } else { captchaIDString = response["request"].(string) - captchaGetEndpoint = fmt.Sprintf("https://%s/res.php?key=%s&action=get&action=get&id=%s&json=1", in.Config.CaptchaAPI, in.Config.ClientKey, captchaIDString) + captchaGetEndpoint = fmt.Sprintf("https://%s/res.php?key=%s&action=get&action=get&id=%s&json=1", in.Config.CaptchaSettings.CaptchaAPI, in.Config.CaptchaSettings.ClientKey, captchaIDString) } fmt.Println(captchaGetEndpoint) // time recommended in rucaptcha documentation diff --git a/utilities/direct_messages.go b/utilities/direct_messages.go index 02261b1..36f86d5 100644 --- a/utilities/direct_messages.go +++ b/utilities/direct_messages.go @@ -10,6 +10,7 @@ import ( "bytes" "encoding/json" "fmt" + "io/ioutil" // "io/ioutil" "math/rand" @@ -191,7 +192,6 @@ func (in *Instance) OpenChannel(recepientUID string) (string, error) { return "", fmt.Errorf("error while getting fingerprint %v", err) } - resp, err := in.Client.Do(in.OpenChannelHeaders(req, cookie, fingerprint)) if err != nil { @@ -266,6 +266,22 @@ func (in *Instance) SendMessage(channelSnowflake string, memberid string) (http. fmt.Printf("[%v]Error while sending http request %v \n", time.Now().Format("15:04:05"), err) return http.Response{}, fmt.Errorf("error while getting send message response %v", err) } + if res.StatusCode == 400 { + msgid, err := in.greet(channelSnowflake, cookie, fingerprint) + if err != nil { + return http.Response{}, fmt.Errorf("error while opening DM %v", err) + } + resp, err := in.SendMessage(channelSnowflake, memberid) + if err != nil { + return http.Response{}, fmt.Errorf("error while sending message %v", err) + } + err = in.ungreet(channelSnowflake, cookie, fingerprint, msgid) + if err != nil { + return http.Response{}, fmt.Errorf("error while opening DM %v", err) + } + in.Count++ + return resp, nil + } in.Count++ return *res, nil } @@ -458,3 +474,53 @@ func (in *Instance) BlockUser(userid string) (int, error) { } return resp.StatusCode, nil } + +func (in *Instance) greet(channelid, cookie, fingerprint string) (string, error) { + site := fmt.Sprintf(`https://discord.com/api/v9/channels/%s/greet`, channelid) + payload := `{"sticker_ids":["749054660769218631"]}` + req, err := http.NewRequest("POST", site, strings.NewReader(payload)) + if err != nil { + return "", err + } + req = in.SendMessageHeaders(req, cookie, fingerprint, channelid) + resp, err := in.Client.Do(req) + if err != nil { + return "", err + } + if resp.StatusCode != 200 { + return "", fmt.Errorf(`invalid status code while sending dm %v`, resp.StatusCode) + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + var response map[string]interface{} + err = json.Unmarshal(body, &response) + if err != nil { + return "", err + } + var msgid string + if strings.Contains(string(body), "id") { + msgid = response["id"].(string) + } else { + return "", fmt.Errorf(`invalid response %v`, string(body)) + } + return msgid, nil +} + +func (in *Instance) ungreet(channelid, cookie, fingerprint, msgid string) error { + site := fmt.Sprintf(`https://discord.com/api/v9/channels/%s/messages/%s`, channelid, msgid) + req, err := http.NewRequest("DELETE", site, nil) + if err != nil { + return err + } + req = in.SendMessageHeaders(req, cookie, fingerprint, channelid) + resp, err := in.Client.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 204 { + return fmt.Errorf(`invalid status code while sending dm%v`, resp.StatusCode) + } + return nil +} diff --git a/utilities/extra.go b/utilities/extra.go index 15265c9..64ac5a6 100644 --- a/utilities/extra.go +++ b/utilities/extra.go @@ -214,8 +214,8 @@ type invitePayload struct { func (in *Instance) Invite(Code string) error { var solvedKey string var payload invitePayload - for i := 0; i < in.Config.MaxInvite; i++ { - if solvedKey == "" || in.Config.CaptchaAPI == "" { + for i := 0; i < in.Config.OtherSettings.MaxInvite; i++ { + if solvedKey == "" || in.Config.CaptchaSettings.CaptchaAPI == "" { payload = invitePayload{} } else { payload = invitePayload{ @@ -269,15 +269,15 @@ func (in *Instance) Invite(Code string) error { continue } cap := resp["captcha_sitekey"].(string) - var rqData string - var rqToken string + var rqData string + var rqToken string if strings.Contains(string(body), "captcha_rqdata") { rqData = resp["captcha_rqdata"].(string) } if strings.Contains(string(body), "captcha_rqtoken") { - rqToken = resp["captcha_rqdata"].(string) + rqToken = resp["captcha_rqtoken"].(string) } - if in.Config.CaptchaAPI == "" { + if in.Config.CaptchaSettings.CaptchaAPI == "" { color.Red("[%v] Captcha detected but no API key provided %v", time.Now().Format("15:04:05"), in.Token) break } else { diff --git a/utilities/files.go b/utilities/files.go index 8c07bee..bd9e73e 100644 --- a/utilities/files.go +++ b/utilities/files.go @@ -19,8 +19,8 @@ import ( "strings" "github.com/fatih/color" - - "gopkg.in/yaml.v2" + + "gopkg.in/yaml.v3" ) func ReadLines(filename string) ([]string, error) { @@ -185,35 +185,60 @@ func GetMessage() ([]Message, error) { } type Config struct { - Delay int `yaml:"individual_delay"` - LongDelay int `yaml:"rate_limit_delay"` - Offset int `yaml:"offset"` - Skip bool `yaml:"skip_completed"` + DirectMessage DirectMessage `yaml:"direct_message_settings"` + ProxySettings ProxySettings `yaml:"proxy_settings"` + ScraperSettings ScraperSettings `yaml:"scraper_settings"` + CaptchaSettings CaptchaSettings `yaml:"captcha_settings"` + OtherSettings OtherSettings `yaml:"other_settings"` + SuspicionAvoidance SuspicionAvoidance `yaml:"suspicion_avoidance"` +} +type DirectMessage struct { + Delay int `yaml:"individual_delay"` + LongDelay int `yaml:"rate_limit_delay"` + Offset int `yaml:"offset"` + Skip bool `yaml:"skip_completed"` + Call bool `yaml:"call"` + Remove bool `yaml:"remove_dead_tokens"` + RemoveM bool `yaml:"remove_completed_members"` + Stop bool `yaml:"stop_dead_tokens"` + Mutual bool `yaml:"check_mutual"` + Friend bool `yaml:"friend_before_DM"` + Websocket bool `yaml:"online_tokens"` + MaxDMS int `yaml:"max_dms_per_token"` + Receive bool `yaml:"receive_messages"` + SkipFailed bool `yaml:"skip_failed"` + Block bool `yaml:"block_after_dm"` + Close bool `yaml:"close_dm_after_message"` +} +type ProxySettings struct { Proxy string `yaml:"proxy"` - Call bool `yaml:"call"` - Remove bool `yaml:"remove_dead_tokens"` - RemoveM bool `yaml:"remove_completed_members"` - Stop bool `yaml:"stop_dead_tokens"` - Mutual bool `yaml:"check_mutual"` - Friend bool `yaml:"friend_before_DM"` - Websocket bool `yaml:"online_tokens"` - SleepSc int `yaml:"online_scraper_delay"` ProxyFromFile bool `yaml:"proxy_from_file"` + ProxyForCaptcha bool `yaml:"proxy_for_captcha"` ProxyProtocol string `yaml:"proxy_protocol"` - MaxDMS int `yaml:"max_dms_per_token"` - Receive bool `yaml:"receive_messages"` GatewayProxy bool `yaml:"use_proxy_for_gateway"` Timeout int `yaml:"timeout"` - SkipFailed bool `yaml:"skip_failed"` - ClientKey string `yaml:"captcha_api_key"` - CaptchaAPI string `yaml:"captcha_api"` - MaxInvite int `yaml:"max_attempt_invite_rejoin"` - DisableKL bool `yaml:"disable_keep_alives"` - ScrapeUsernames bool `yaml:"scrape_usernames"` - ScrapeAvatars bool `yaml:"scrape_avatars"` - ProxyForCaptcha bool `yaml:"proxy_for_captcha"` - Block bool `yaml:"block_after_dm"` - Close bool `yaml:"close_dm_after_message"` +} + +type ScraperSettings struct { + SleepSc int `yaml:"online_scraper_delay"` + ScrapeUsernames bool `yaml:"scrape_usernames"` + ScrapeAvatars bool `yaml:"scrape_avatars"` +} + +type CaptchaSettings struct { + ClientKey string `yaml:"captcha_api_key"` + CaptchaAPI string `yaml:"captcha_api"` +} + +type OtherSettings struct { + MaxInvite int `yaml:"max_attempt_invite_rejoin"` + DisableKL bool `yaml:"disable_keep_alives"` +} + +type SuspicionAvoidance struct { + RandomIndividualDelay int `yaml:"random_individual_delay"` + RandomRateLimitDelay int `yaml:"random_rate_limit_delay"` + RandomDelayOpenChannel int `yaml:"random_delay_before_dm"` } func GetConfig() (Config, error) { @@ -223,16 +248,17 @@ func GetConfig() (Config, error) { return Config{}, err } ex = filepath.ToSlash(ex) - file, err1 := os.Open(path.Join(path.Dir(ex) + "/" + "config.yml")) - if err1 != nil { - color.Red("Error while Opening Config (tried .json + .yml)") + var file *os.File + file, err = os.Open(path.Join(path.Dir(ex) + "/" + "config.yml")) + if err != nil { + color.Red("Error while Opening Config") return Config{}, err } else { defer file.Close() var config Config bytes, _ := io.ReadAll(file) - errr := yaml.Unmarshal(bytes, &config) - if errr != nil { + err = yaml.Unmarshal(bytes, &config) + if err != nil { fmt.Println(err) return Config{}, err } diff --git a/utilities/headers.go b/utilities/headers.go index ba3494c..e3953b5 100644 --- a/utilities/headers.go +++ b/utilities/headers.go @@ -143,21 +143,21 @@ func (in *Instance) OpenChannelHeaders(req *http.Request, cookie, fingerprint st func (in *Instance) SendMessageHeaders(req *http.Request, cookie, fingerprint, recipient string) *http.Request { for k, v := range map[string]string{ - "Host": "discord.com", - "User-Agent": UserAgent, - "Accept": "*/*", - "Accept-Language": "en-US,en;q=0.5", - "Content-Type": "application/json", - "Authorization": in.Token, + "Host": "discord.com", + "User-Agent": UserAgent, + "Accept": "*/*", + "Accept-Language": "en-US,en;q=0.5", + "Content-Type": "application/json", + "Authorization": in.Token, "X-Super-Properties": XSuper, - "X-Discord-Locale": "en-US", - "X-Debug-Options": "bugReporterEnabled", - "Origin": "https://discord.com", - "Referer": fmt.Sprintf(`https://discord.com/channels/@me/%s`, recipient), - "Cookie": cookie, - "Sec-Fetch-Dest": "empty", - "Sec-Fetch-Mode": "cors", - "Sec-Fetch-Site": "same-origin", + "X-Discord-Locale": "en-US", + "X-Debug-Options": "bugReporterEnabled", + "Origin": "https://discord.com", + "Referer": fmt.Sprintf(`https://discord.com/channels/@me/%s`, recipient), + "Cookie": cookie, + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", } { req.Header.Set(k, v) } diff --git a/utilities/invite.go b/utilities/invite.go index 866c2e5..8dd0451 100644 --- a/utilities/invite.go +++ b/utilities/invite.go @@ -73,12 +73,12 @@ func (in *Instance) Inviter(invitationCode string, mode int, cookie string, fing contextProperties = generateXContext(channelID, channelType, guildID) } site = fmt.Sprintf(`https://ptb.discord.com/api/v10/invites/%v`, invitationCode) - if in.Config.MaxInvite < 2 { - in.Config.MaxInvite = 2 + if in.Config.OtherSettings.MaxInvite < 2 { + in.Config.OtherSettings.MaxInvite = 2 } var captchaKey string var req *http.Request - for i := 0; i < in.Config.MaxInvite; i++ { + for i := 0; i < in.Config.OtherSettings.MaxInvite; i++ { if captchaKey == "" { req, err = http.NewRequest(http.MethodPost, site, strings.NewReader(`{}`)) } else { @@ -107,7 +107,7 @@ func (in *Instance) Inviter(invitationCode string, mode int, cookie string, fing if strings.Contains(string(body), "captcha_sitekey") { captchaSitekey := response["captcha_sitekey"].(string) color.Yellow("[%v] Token %v Captcha Detected [%v] [%v]", time.Now().Format("15:04:05"), in.Token, captchaSitekey, i) - if in.Config.ClientKey == "" { + if in.Config.CaptchaSettings.ClientKey == "" { return -3, cookie, fingerprint, fmt.Errorf("captcha detected but no api provided") } captchaKey, err = in.SolveCaptcha(captchaSitekey, cookie, "", "") diff --git a/utilities/scrape.go b/utilities/scrape.go index a9cdf28..0f93e7c 100644 --- a/utilities/scrape.go +++ b/utilities/scrape.go @@ -19,11 +19,11 @@ func Scrape(ws *Connection, Guild string, Channel string, index int) error { } payload := Data{ - GuildId: Guild, - Typing: true, - Threads: true, - Activities: true, - Members: nil, + GuildId: Guild, + Typing: true, + Threads: true, + Activities: true, + Members: nil, ThreadMemberLists: nil, Channels: map[string]interface{}{ Channel: x, diff --git a/utilities/websocket.go b/utilities/websocket.go index 0c94efa..1768edc 100644 --- a/utilities/websocket.go +++ b/utilities/websocket.go @@ -39,15 +39,15 @@ func (in *Instance) NewConnection(fatalHandler func(err error)) (*Connection, er if in.GatewayProxy == "" { dialer = *websocket.DefaultDialer } else { - if in.Config.ProxyProtocol == "http" { + if in.Config.ProxySettings.ProxyProtocol == "http" { if !strings.Contains(in.GatewayProxy, "http://") { in.GatewayProxy = "http://" + in.GatewayProxy } - } else if in.Config.ProxyProtocol == "socks5" { + } else if in.Config.ProxySettings.ProxyProtocol == "socks5" { if !strings.Contains(in.GatewayProxy, "socks5://") { in.GatewayProxy = "socks5://" + in.GatewayProxy } - } else if in.Config.ProxyProtocol == "socks4" { + } else if in.Config.ProxySettings.ProxyProtocol == "socks4" { if !strings.Contains(in.GatewayProxy, "socks4://") { in.GatewayProxy = "socks4://" + in.GatewayProxy }