Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
V4NSH4J
GitHub Repository: V4NSH4J/discord-mass-DM-GO
Path: blob/main/instance/instance.go
310 views
1
// Copyright (C) 2021 github.com/V4NSH4J
2
//
3
// This source code has been released under the GNU Affero General Public
4
// License v3.0. A copy of this license is available at
5
// https://www.gnu.org/licenses/agpl-3.0.en.html
6
7
package instance
8
9
import (
10
"encoding/base64"
11
"encoding/json"
12
"fmt"
13
"io/ioutil"
14
"math/rand"
15
"os"
16
"regexp"
17
"strings"
18
"sync"
19
"time"
20
21
gohttp "net/http"
22
23
http "github.com/Danny-Dasilva/fhttp"
24
"github.com/V4NSH4J/discord-mass-dm-GO/client"
25
"github.com/V4NSH4J/discord-mass-dm-GO/utilities"
26
"github.com/gorilla/websocket"
27
)
28
29
type Instance struct {
30
Token string
31
Proxy string
32
Cookie string
33
Client *http.Client
34
UserAgent string
35
XSuper string
36
JA3 string
37
ProxyProt string
38
Email string
39
Password string
40
Fingerprint string
41
Messages []Message
42
Count int
43
LastQuery string
44
LastCount int
45
Members []User
46
AllMembers []User
47
Retry int
48
ScrapeCount int
49
ID string
50
Receiver bool
51
Config Config
52
GatewayProxy string
53
WG *sync.WaitGroup
54
Ws *Connection
55
fatal chan error
56
Invited bool
57
TimeServerCheck time.Time
58
ChangedName bool
59
ChangedAvatar bool
60
LastID int
61
LastIDstr string
62
Mode int
63
Reacted []ReactInfo
64
ReactChannel chan (ReactInfo)
65
MessageNumber int
66
Version string
67
Quarantined bool
68
}
69
70
func (in *Instance) StartWS() error {
71
ws, err := in.NewConnection(in.wsFatalHandler)
72
if err != nil {
73
return fmt.Errorf("failed to create websocket connection: %s", err)
74
}
75
in.Ws = ws
76
return nil
77
}
78
79
func (in *Instance) wsFatalHandler(err error) {
80
if closeErr, ok := err.(*websocket.CloseError); ok && closeErr.Code == 4004 {
81
in.fatal <- fmt.Errorf("websocket closed: authentication failed, try using a new token")
82
return
83
}
84
if strings.Contains(err.Error(), "4004") {
85
utilities.LogLocked("Error while opening websocket, Authentication failed %v", in.Token)
86
return
87
}
88
utilities.LogSuccess("Websocket closed %v %v", err, in.Token)
89
in.Receiver = false
90
in.Ws, err = in.NewConnection(in.wsFatalHandler)
91
if err != nil {
92
in.fatal <- fmt.Errorf("failed to create websocket connection: %s", err)
93
return
94
}
95
utilities.LogSuccess("Reconnected To Websocket %v", in.Token)
96
}
97
98
func GetEverything() (Config, []Instance, error) {
99
var cfg Config
100
var Instances []Instance
101
var err error
102
var proxies []string
103
var tokens []string
104
var fingerprints []Fingerprints
105
106
// Getting the config
107
cfg, err = GetConfig()
108
if err != nil {
109
return cfg, Instances, fmt.Errorf(`error while getting config %s`, err)
110
}
111
if cfg.CaptchaSettings.CaptchaAPI == "invisifox.com" {
112
utilities.LogWarn("You're using invisifox's downloadable solver. Make sure you're using port 8888 (default) and that you're running the application. Otherwise this wouldn't work.")
113
}
114
// Getting proxies & removing empty lines
115
if cfg.ProxySettings.ProxyFromFile {
116
proxies, err = utilities.ReadLines("proxies.txt")
117
if err != nil {
118
return cfg, Instances, fmt.Errorf(`error while getting proxies %s`, err)
119
}
120
var p []string
121
for j := 0; j < len(proxies); j++ {
122
if proxies[j] != "" {
123
p = append(p, proxies[j])
124
}
125
}
126
proxies = p
127
if len(proxies) == 0 {
128
cfg.ProxySettings.ProxyFromFile = false
129
utilities.LogWarn("No proxies found in proxies.txt, disabling proxy from file")
130
}
131
}
132
// Getting the tokens
133
tokens, err = utilities.ReadLines("tokens.txt")
134
if err != nil {
135
return cfg, Instances, err
136
}
137
var v []string
138
for j := 0; j < len(tokens); j++ {
139
if tokens[j] != "" {
140
v = append(v, tokens[j])
141
}
142
}
143
tokens = v
144
if len(tokens) == 0 {
145
return cfg, Instances, fmt.Errorf("no tokens found in tokens.txt")
146
}
147
// Getting fingerprints - Prioritizing from file so multiple can be loaded.
148
fingerprints, err = GetFingerprints()
149
if err != nil {
150
utilities.LogWarn("Error while getting fingerprints %s", err)
151
}
152
if len(fingerprints) == 0 {
153
// Getting fingerprint from config if none are found in file
154
if cfg.OtherSettings.JA3 != "" && cfg.OtherSettings.XSuperProperties != "" && cfg.OtherSettings.Useragent != "" {
155
fingerprints = append(fingerprints, Fingerprints{
156
JA3: cfg.OtherSettings.JA3,
157
XSuperProperties: cfg.OtherSettings.XSuperProperties,
158
Useragent: cfg.OtherSettings.Useragent,
159
})
160
// Getting fingerprint from Dolfies' API if none are set in config
161
} else {
162
xsuper, ua, _, err := DolfiesXsuper()
163
if err != nil {
164
// Hardcoding a fingerprint if Dolfies' API is down
165
xsuper, ua = "eyJvcyI6Ik1hYyBPUyBYIiwiYnJvd3NlciI6IkZpcmVmb3giLCJkZXZpY2UiOiIiLCJzeXN0ZW1fbG9jYWxlIjoiZW4tVVMiLCJicm93c2VyX3VzZXJfYWdlbnQiOiJNb3ppbGxhLzUuMCAoTWFjaW50b3NoOyBJbnRlbCBNYWMgT1MgWCAxMC4xNTsgcnY6MTAzLjApIEdlY2tvLzIwMTAwMTAxIEZpcmVmb3gvMTAzLjAiLCJicm93c2VyX3ZlcnNpb24iOiIxMDMuMCIsIm9zX3ZlcnNpb24iOiIxMC4xNSIsInJlZmVycmVyIjoiIiwicmVmZXJyaW5nX2RvbWFpbiI6IiIsInJlZmVycmVyX2N1cnJlbnQiOiIiLCJyZWZlcnJpbmdfZG9tYWluX2N1cnJlbnQiOiIiLCJyZWxlYXNlX2NoYW5uZWwiOiJzdGFibGUiLCJjbGllbnRfYnVpbGRfbnVtYmVyIjoxNDAwOTEsImNsaWVudF9ldmVudF9zb3VyY2UiOm51bGx9", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0"
166
}
167
fingerprints = append(fingerprints, Fingerprints{
168
JA3: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0",
169
XSuperProperties: xsuper,
170
Useragent: ua,
171
})
172
}
173
}
174
175
// Checking empty JA3s & setting according to same priority order as fingerprints as having a JA3 is important
176
var ja3s []string
177
for i := 0; i < len(fingerprints); i++ {
178
if fingerprints[i].JA3 != "" {
179
ja3s = append(ja3s, fingerprints[i].JA3)
180
}
181
}
182
var j []string
183
for i := 0; i < len(ja3s); i++ {
184
if ja3s[i] != "" {
185
j = append(j, ja3s[i])
186
}
187
}
188
ja3s = j
189
for i := 0; i < len(fingerprints); i++ {
190
if fingerprints[i].JA3 == "" {
191
if cfg.OtherSettings.JA3 != "" {
192
fingerprints[i].JA3 = cfg.OtherSettings.JA3
193
} else if len(ja3s) != 0 {
194
fingerprints[i].JA3 = ja3s[rand.Intn(len(ja3s))]
195
} else {
196
fingerprints[i].JA3 = "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0"
197
}
198
}
199
}
200
r := regexp.MustCompile(`(.+):(.+):(.+)`)
201
for i := 0; i < len(tokens); i++ {
202
var email, password, token string
203
if r.MatchString(tokens[i]) {
204
p := strings.Split(tokens[i], ":")
205
email = p[0]
206
password = p[1]
207
token = p[2]
208
} else {
209
token = tokens[i]
210
}
211
var proxy, Gproxy, proxyProt string
212
if cfg.ProxySettings.ProxyFromFile {
213
proxy = proxies[rand.Intn(len(proxies))]
214
Gproxy = proxy
215
proxyProt = "http://" + proxy
216
} else {
217
proxy = ""
218
proxyProt = ""
219
}
220
index := rand.Intn(len(fingerprints))
221
httpclient, err := client.NewClient(client.Browser{JA3: fingerprints[index].JA3, UserAgent: fingerprints[index].Useragent, Cookies: nil}, cfg.ProxySettings.Timeout, false, fingerprints[index].Useragent, proxyProt)
222
if err != nil {
223
return cfg, Instances, err
224
}
225
// proxy is put in struct only to be used by gateway. If proxy for gateway is disabled, it will be empty
226
if !cfg.ProxySettings.GatewayProxy {
227
Gproxy = ""
228
}
229
Instances = append(Instances, Instance{Client: httpclient, Token: token, Proxy: proxyProt, Config: cfg, GatewayProxy: Gproxy, Email: email, Password: password, UserAgent: fingerprints[index].Useragent, XSuper: fingerprints[index].XSuperProperties, JA3: fingerprints[index].JA3, ProxyProt: proxyProt})
230
}
231
if len(Instances) == 0 {
232
utilities.LogErr(" You may be using 0 tokens")
233
}
234
235
return cfg, Instances, nil
236
237
}
238
239
func OldGetEverything() (Config, []Instance, error) {
240
var cfg Config
241
var instances []Instance
242
var err error
243
var tokens []string
244
var proxies []string
245
var proxy string
246
var xsuper string
247
var ua string
248
var v string
249
var ja3 string
250
var proxyProt string
251
252
// Load config
253
cfg, err = GetConfig()
254
if err != nil {
255
return cfg, instances, err
256
}
257
if !cfg.ProxySettings.ProxyFromFile && cfg.ProxySettings.ProxyForCaptcha {
258
utilities.LogErr(" You must enabe proxy_from_file to use proxy_for_captcha")
259
cfg.ProxySettings.ProxyForCaptcha = false
260
}
261
if cfg.OtherSettings.XSuperProperties == "" && cfg.OtherSettings.Useragent == "" {
262
xsuper, ua, v, err = DolfiesXsuper()
263
if err != nil {
264
utilities.LogErr(" Failed to get useragent and xsuper %s Turn off Dolfies mode or try again, otherwise program will be continued with hardcoded chrome emulation", err)
265
xsuper, ua = "eyJvcyI6Ik1hYyBPUyBYIiwiYnJvd3NlciI6IkZpcmVmb3giLCJkZXZpY2UiOiIiLCJzeXN0ZW1fbG9jYWxlIjoiZW4tVVMiLCJicm93c2VyX3VzZXJfYWdlbnQiOiJNb3ppbGxhLzUuMCAoTWFjaW50b3NoOyBJbnRlbCBNYWMgT1MgWCAxMC4xNTsgcnY6MTAzLjApIEdlY2tvLzIwMTAwMTAxIEZpcmVmb3gvMTAzLjAiLCJicm93c2VyX3ZlcnNpb24iOiIxMDMuMCIsIm9zX3ZlcnNpb24iOiIxMC4xNSIsInJlZmVycmVyIjoiIiwicmVmZXJyaW5nX2RvbWFpbiI6IiIsInJlZmVycmVyX2N1cnJlbnQiOiIiLCJyZWZlcnJpbmdfZG9tYWluX2N1cnJlbnQiOiIiLCJyZWxlYXNlX2NoYW5uZWwiOiJzdGFibGUiLCJjbGllbnRfYnVpbGRfbnVtYmVyIjoxNDAwOTEsImNsaWVudF9ldmVudF9zb3VyY2UiOm51bGx9", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0"
266
v = "103"
267
} else {
268
utilities.LogSuccess("Successfully obtained build number, useragent and latest chrome version")
269
}
270
} else {
271
xsuper, ua = cfg.OtherSettings.XSuperProperties, cfg.OtherSettings.Useragent
272
}
273
if cfg.OtherSettings.JA3 == "" {
274
ja3 = "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0"
275
} else {
276
ja3 = cfg.OtherSettings.JA3
277
}
278
ja32 := "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-24-25-256-257,0"
279
ja3s := []string{ja32, ja3}
280
// Load instances
281
tokens, err = utilities.ReadLines("tokens.txt")
282
if err != nil {
283
return cfg, instances, err
284
}
285
if len(tokens) == 0 {
286
return cfg, instances, fmt.Errorf("no tokens found in tokens.txt")
287
}
288
289
if cfg.ProxySettings.ProxyFromFile {
290
proxies, err = utilities.ReadLines("proxies.txt")
291
if err != nil {
292
return cfg, instances, err
293
}
294
if len(proxies) == 0 {
295
return cfg, instances, fmt.Errorf("no proxies found in proxies.txt")
296
}
297
}
298
var Gproxy string
299
var instanceToken string
300
var email string
301
var password string
302
reg := regexp.MustCompile(`(.+):(.+):(.+)`)
303
for i := 0; i < len(tokens); i++ {
304
if tokens[i] == "" {
305
continue
306
}
307
if reg.MatchString(tokens[i]) {
308
parts := strings.Split(tokens[i], ":")
309
instanceToken = parts[2]
310
email = parts[0]
311
password = parts[1]
312
} else {
313
instanceToken = tokens[i]
314
}
315
if cfg.ProxySettings.ProxyFromFile {
316
proxy = proxies[rand.Intn(len(proxies))]
317
Gproxy = proxy
318
proxyProt = "http://" + proxy
319
} else {
320
proxy = ""
321
proxyProt = ""
322
}
323
httpclient, err := client.NewClient(client.Browser{JA3: ja3, UserAgent: ua, Cookies: nil}, cfg.ProxySettings.Timeout, false, ua, proxyProt)
324
if err != nil {
325
return cfg, instances, err
326
}
327
// proxy is put in struct only to be used by gateway. If proxy for gateway is disabled, it will be empty
328
if !cfg.ProxySettings.GatewayProxy {
329
Gproxy = ""
330
}
331
instances = append(instances, Instance{Client: httpclient, Token: instanceToken, Proxy: proxyProt, Config: cfg, GatewayProxy: Gproxy, Email: email, Password: password, UserAgent: ua, XSuper: xsuper, Version: v, JA3: ja3s[rand.Intn(len(ja3s))], ProxyProt: proxyProt})
332
}
333
if len(instances) == 0 {
334
utilities.LogErr(" You may be using 0 tokens")
335
}
336
337
return cfg, instances, nil
338
339
}
340
341
func SetMessages(instances []Instance, messages []Message) error {
342
var err error
343
if len(messages) == 0 {
344
messages, err = GetMessage()
345
if err != nil {
346
return err
347
}
348
if len(messages) == 0 {
349
return fmt.Errorf("no messages found in messages.txt")
350
}
351
for i := 0; i < len(instances); i++ {
352
instances[i].Messages = messages
353
}
354
} else {
355
for i := 0; i < len(instances); i++ {
356
instances[i].Messages = messages
357
}
358
}
359
360
return nil
361
}
362
363
func (in *Instance) CensorToken() string {
364
if len(in.Token) == 0 {
365
return ""
366
}
367
if in.Config.OtherSettings.CensorToken {
368
var censored string
369
l := len(in.Token)
370
uncensoredPart := int(2 * l / 3)
371
for i := 0; i < l; i++ {
372
if i < uncensoredPart {
373
censored += string(in.Token[i])
374
} else {
375
censored += "*"
376
}
377
}
378
return censored
379
} else {
380
return in.Token
381
}
382
383
}
384
385
func (in *Instance) WriteInstanceToFile(path string) {
386
var line string
387
if in.Email != "" && in.Password != "" {
388
line = fmt.Sprintf("%s:%s:%s", in.Email, in.Password, in.Token)
389
} else {
390
line = in.Token
391
}
392
_ = utilities.WriteLinesPath(path, line)
393
}
394
395
func DolfiesXsuper() (string, string, string, error) {
396
apiLink := "https://discord-user-api.cf/api/v1/properties/web"
397
req, err := gohttp.NewRequest("GET", apiLink, nil)
398
if err != nil {
399
return "", "", "", err
400
}
401
resp, err := gohttp.DefaultClient.Do(req)
402
if err != nil {
403
return "", "", "", err
404
}
405
defer resp.Body.Close()
406
body, err := ioutil.ReadAll(resp.Body)
407
if err != nil {
408
return "", "", "", err
409
}
410
fmt.Println(string(body))
411
var Info DolfiesResponse
412
err = json.Unmarshal(body, &Info)
413
if err != nil {
414
return "", "", "", err
415
}
416
if Info.ChromeUserAgent == "" || Info.ChromeVersion == "" || Info.ClientBuildNumber == 0 {
417
return "", "", "", fmt.Errorf("couldn't get xsuper from Dolfies")
418
}
419
r := regexp.MustCompile(`Chrome/(.+) Safari`)
420
chromeVersion := r.FindStringSubmatch(Info.ChromeUserAgent)
421
if len(chromeVersion) == 0 {
422
return "", "", "", fmt.Errorf("couldn't get xsuper from Dolfies")
423
}
424
locales := []string{"af", "af-NA", "af-ZA", "agq", "agq-CM", "ak", "ak-GH", "am", "am-ET", "ar", "ar-001", "ar-AE", "ar-BH", "ar-DJ", "ar-DZ", "ar-EG", "ar-EH", "ar-ER", "ar-IL", "ar-IQ", "ar-JO", "ar-KM", "ar-KW", "ar-LB", "ar-LY", "ar-MA", "ar-MR", "ar-OM", "ar-PS", "ar-QA", "ar-SA", "ar-SD", "ar-SO", "ar-SS", "ar-SY", "ar-TD", "ar-TN", "ar-YE", "as", "as-IN", "asa", "asa-TZ", "ast", "ast-ES", "az", "az-Cyrl", "az-Cyrl-AZ", "az-Latn", "az-Latn-AZ", "bas", "bas-CM", "be", "be-BY", "bem", "bem-ZM", "bez", "bez-TZ", "bg", "bg-BG", "bm", "bm-ML", "bn", "bn-BD", "bn-IN", "bo", "bo-CN", "bo-IN", "br", "br-FR", "brx", "brx-IN", "bs", "bs-Cyrl", "bs-Cyrl-BA", "bs-Latn", "bs-Latn-BA", "ca", "ca-AD", "ca-ES", "ca-FR", "ca-IT", "ccp", "ccp-BD", "ccp-IN", "ce", "ce-RU", "cgg", "cgg-UG", "chr", "chr-US", "ckb", "ckb-IQ", "ckb-IR", "cs", "cs-CZ", "cy", "cy-GB", "da", "da-DK", "da-GL", "dav", "dav-KE", "de", "de-AT", "de-BE", "de-CH", "de-DE", "de-IT", "de-LI", "de-LU", "dje", "dje-NE", "dsb", "dsb-DE", "dua", "dua-CM", "dyo", "dyo-SN", "dz", "dz-BT", "ebu", "ebu-KE", "ee", "ee-GH", "ee-TG", "el", "el-CY", "el-GR", "en", "en-001", "en-150", "en-AG", "en-AI", "en-AS", "en-AT", "en-AU", "en-BB", "en-BE", "en-BI", "en-BM", "en-BS", "en-BW", "en-BZ", "en-CA", "en-CC", "en-CH", "en-CK", "en-CM", "en-CX", "en-CY", "en-DE", "en-DG", "en-DK", "en-DM", "en-ER", "en-FI", "en-FJ", "en-FK", "en-FM", "en-GB", "en-GD", "en-GG", "en-GH", "en-GI", "en-GM", "en-GU", "en-GY", "en-HK", "en-IE", "en-IL", "en-IM", "en-IN", "en-IO", "en-JE", "en-JM", "en-KE", "en-KI", "en-KN", "en-KY", "en-LC", "en-LR", "en-LS", "en-MG", "en-MH", "en-MO", "en-MP", "en-MS", "en-MT", "en-MU", "en-MW", "en-MY", "en-NA", "en-NF", "en-NG", "en-NL", "en-NR", "en-NU", "en-NZ", "en-PG", "en-PH", "en-PK", "en-PN", "en-PR", "en-PW", "en-RW", "en-SB", "en-SC", "en-SD", "en-SE", "en-SG", "en-SH", "en-SI", "en-SL", "en-SS", "en-SX", "en-SZ", "en-TC", "en-TK", "en-TO", "en-TT", "en-TV", "en-TZ", "en-UG", "en-UM", "en-US", "en-US-POSIX", "en-VC", "en-VG", "en-VI", "en-VU", "en-WS", "en-ZA", "en-ZM", "en-ZW", "eo", "es", "es-419", "es-AR", "es-BO", "es-BR", "es-BZ", "es-CL", "es-CO", "es-CR", "es-CU", "es-DO", "es-EA", "es-EC", "es-ES", "es-GQ", "es-GT", "es-HN", "es-IC", "es-MX", "es-NI", "es-PA", "es-PE", "es-PH", "es-PR", "es-PY", "es-SV", "es-US", "es-UY", "es-VE", "et", "et-EE", "eu", "eu-ES", "ewo", "ewo-CM", "fa", "fa-AF", "fa-IR", "ff", "ff-CM", "ff-GN", "ff-MR", "ff-SN", "fi", "fi-FI", "fil", "fil-PH", "fo", "fo-DK", "fo-FO", "fr", "fr-BE", "fr-BF", "fr-BI", "fr-BJ", "fr-BL", "fr-CA", "fr-CD", "fr-CF", "fr-CG", "fr-CH", "fr-CI", "fr-CM", "fr-DJ", "fr-DZ", "fr-FR", "fr-GA", "fr-GF", "fr-GN", "fr-GP", "fr-GQ", "fr-HT", "fr-KM", "fr-LU", "fr-MA", "fr-MC", "fr-MF", "fr-MG", "fr-ML", "fr-MQ", "fr-MR", "fr-MU", "fr-NC", "fr-NE", "fr-PF", "fr-PM", "fr-RE", "fr-RW", "fr-SC", "fr-SN", "fr-SY", "fr-TD", "fr-TG", "fr-TN", "fr-VU", "fr-WF", "fr-YT", "fur", "fur-IT", "fy", "fy-NL", "ga", "ga-IE", "gd", "gd-GB", "gl", "gl-ES", "gsw", "gsw-CH", "gsw-FR", "gsw-LI", "gu", "gu-IN", "guz", "guz-KE", "gv", "gv-IM", "ha", "ha-GH", "ha-NE", "ha-NG", "haw", "haw-US", "he", "he-IL", "hi", "hi-IN", "hr", "hr-BA", "hr-HR", "hsb", "hsb-DE", "hu", "hu-HU", "hy", "hy-AM", "id", "id-ID", "ig", "ig-NG", "ii", "ii-CN", "is", "is-IS", "it", "it-CH", "it-IT", "it-SM", "it-VA", "ja", "ja-JP", "jgo", "jgo-CM", "jmc", "jmc-TZ", "ka", "ka-GE", "kab", "kab-DZ", "kam", "kam-KE", "kde", "kde-TZ", "kea", "kea-CV", "khq", "khq-ML", "ki", "ki-KE", "kk", "kk-KZ", "kkj", "kkj-CM", "kl", "kl-GL", "kln", "kln-KE", "km", "km-KH", "kn", "kn-IN", "ko", "ko-KP", "ko-KR", "kok", "kok-IN", "ks", "ks-IN", "ksb", "ksb-TZ", "ksf", "ksf-CM", "ksh", "ksh-DE", "kw", "kw-GB", "ky", "ky-KG", "lag", "lag-TZ", "lb", "lb-LU", "lg", "lg-UG", "lkt", "lkt-US", "ln", "ln-AO", "ln-CD", "ln-CF", "ln-CG", "lo", "lo-LA", "lrc", "lrc-IQ", "lrc-IR", "lt", "lt-LT", "lu", "lu-CD", "luo", "luo-KE", "luy", "luy-KE", "lv", "lv-LV", "mas", "mas-KE", "mas-TZ", "mer", "mer-KE", "mfe", "mfe-MU", "mg", "mg-MG", "mgh", "mgh-MZ", "mgo", "mgo-CM", "mk", "mk-MK", "ml", "ml-IN", "mn", "mn-MN", "mr", "mr-IN", "ms", "ms-BN", "ms-MY", "ms-SG", "mt", "mt-MT", "mua", "mua-CM", "my", "my-MM", "mzn", "mzn-IR", "naq", "naq-NA", "nb", "nb-NO", "nb-SJ", "nd", "nd-ZW", "nds", "nds-DE", "nds-NL", "ne", "ne-IN", "ne-NP", "nl", "nl-AW", "nl-BE", "nl-BQ", "nl-CW", "nl-NL", "nl-SR", "nl-SX", "nmg", "nmg-CM", "nn", "nn-NO", "nnh", "nnh-CM", "nus", "nus-SS", "nyn", "nyn-UG", "om", "om-ET", "om-KE", "or", "or-IN", "os", "os-GE", "os-RU", "pa", "pa-Arab", "pa-Arab-PK", "pa-Guru", "pa-Guru-IN", "pl", "pl-PL", "ps", "ps-AF", "pt", "pt-AO", "pt-BR", "pt-CH", "pt-CV", "pt-GQ", "pt-GW", "pt-LU", "pt-MO", "pt-MZ", "pt-PT", "pt-ST", "pt-TL", "qu", "qu-BO", "qu-EC", "qu-PE", "rm", "rm-CH", "rn", "rn-BI", "ro", "ro-MD", "ro-RO", "rof", "rof-TZ", "ru", "ru-BY", "ru-KG", "ru-KZ", "ru-MD", "ru-RU", "ru-UA", "rw", "rw-RW", "rwk", "rwk-TZ", "sah", "sah-RU", "saq", "saq-KE", "sbp", "sbp-TZ", "se", "se-FI", "se-NO", "se-SE", "seh", "seh-MZ", "ses", "ses-ML", "sg", "sg-CF", "shi", "shi-Latn", "shi-Latn-MA", "shi-Tfng", "shi-Tfng-MA", "si", "si-LK", "sk", "sk-SK", "sl", "sl-SI", "smn", "smn-FI", "sn", "sn-ZW", "so", "so-DJ", "so-ET", "so-KE", "so-SO", "sq", "sq-AL", "sq-MK", "sq-XK", "sr", "sr-Cyrl", "sr-Cyrl-BA", "sr-Cyrl-ME", "sr-Cyrl-RS", "sr-Cyrl-XK", "sr-Latn", "sr-Latn-BA", "sr-Latn-ME", "sr-Latn-RS", "sr-Latn-XK", "sv", "sv-AX", "sv-FI", "sv-SE", "sw", "sw-CD", "sw-KE", "sw-TZ", "sw-UG", "ta", "ta-IN", "ta-LK", "ta-MY", "ta-SG", "te", "te-IN", "teo", "teo-KE", "teo-UG", "tg", "tg-TJ", "th", "th-TH", "ti", "ti-ER", "ti-ET", "to", "to-TO", "tr", "tr-CY", "tr-TR", "tt", "tt-RU", "twq", "twq-NE", "tzm", "tzm-MA", "ug", "ug-CN", "uk", "uk-UA", "ur", "ur-IN", "ur-PK", "uz", "uz-Arab", "uz-Arab-AF", "uz-Cyrl", "uz-Cyrl-UZ", "uz-Latn", "uz-Latn-UZ", "vai", "vai-Latn", "vai-Latn-LR", "vai-Vaii", "vai-Vaii-LR", "vi", "vi-VN", "vun", "vun-TZ", "wae", "wae-CH", "wo", "wo-SN", "xog", "xog-UG", "yav", "yav-CM", "yi", "yi-001", "yo", "yo-BJ", "yo-NG", "yue", "yue-Hans", "yue-Hans-CN", "yue-Hant", "yue-Hant-HK", "zgh", "zgh-MA", "zh", "zh-Hans", "zh-Hans-CN", "zh-Hans-HK", "zh-Hans-MO", "zh-Hans-SG", "zh-Hant", "zh-Hant-HK", "zh-Hant-MO", "zh-Hant-TW", "zu", "zu-ZA"}
425
xsuper := fmt.Sprintf(`{"os":"Windows","browser":"Chrome","device":"","system_locale":"%s","browser_user_agent":"%s","browser_version":"%s","os_version":"10","referrer":"","referring_domain":"","referrer_current":"","referring_domain_current":"","release_channel":"stable","client_build_number":%d,"client_event_source":null}`, locales[rand.Intn(len(locales))], Info.ChromeUserAgent, chromeVersion[1], Info.ClientBuildNumber)
426
return base64.StdEncoding.EncodeToString([]byte(xsuper)), Info.ChromeUserAgent, strings.Split(chromeVersion[1], ".")[0], nil
427
428
}
429
430
type XSuperProperties struct {
431
OS string `json:"os,omitempty"`
432
Browser string `json:"browser,omitempty"`
433
Device string `json:"device,omitempty"`
434
SystemLocale string `json:"system_locale,omitempty"`
435
BrowserVersion string `json:"browser_version,omitempty"`
436
BrowserUserAgent string `json:"browser_user_agent,omitempty"`
437
OSVersion string `json:"os_version,omitempty"`
438
Referrer string `json:"referrer,omitempty"`
439
ReferringDomain string `json:"referring_domain,omitempty"`
440
ReferrerCurrent string `json:"referrer_current,omitempty"`
441
ReferringDomainCurrent string `json:"referring_domain_current,omitempty"`
442
ReleaseChannel string `json:"release_channel,omitempty"`
443
ClientBuildNumber int `json:"client_build_number,omitempty"`
444
}
445
446
type PastebinResponse []struct {
447
Ua string `json:"ua,omitempty"`
448
Xs string `json:"xs,omitempty"`
449
}
450
451
type DolfiesResponse struct {
452
ChromeUserAgent string `json:"chrome_user_agent,omitempty"`
453
ChromeVersion string `json:"chrome_version,omitempty"`
454
ClientBuildNumber int `json:"client_build_number,omitempty"`
455
}
456
457
func GetFingerprints() ([]Fingerprints, error) {
458
file, err := os.Open("fingerprints.json")
459
if err != nil {
460
return nil, err
461
}
462
defer file.Close()
463
var fingerprints []Fingerprints
464
bytes, err := ioutil.ReadAll(file)
465
if err != nil {
466
return nil, err
467
}
468
err = json.Unmarshal(bytes, &fingerprints)
469
if err != nil {
470
return nil, err
471
}
472
return fingerprints, nil
473
}
474
475