From 5eef4b0b330d610156d2d0235342e69c071e4ea2 Mon Sep 17 00:00:00 2001
From: 6uf <84757238+suffz@users.noreply.github.com>
Date: Sat, 19 Aug 2023 15:38:22 -0300
Subject: [PATCH] QOL ig?
- Removed RL bypass (noticed its patched now :skull:
- Added namemc cmd (sub cmds)
+ info (type in a name to see its searches, head/body pngs, droptimes etc)
+ skinart-png (type in a name with skinart and itll save the skins and format them into said skinart!)
- Added BEARER support (simply add your bearers to your accounts.txt nothing more or less)
Changes (not too important?)
- removed some config values that are irrelevant (like rl bypass)
- removed the self webhook building scripts (was hideous anyway how i made it)
- moved all important files i.e proxys, accounts, config, and skinarts folder into a new folder called data. this is generated upon the first runtime, you may need to put ur accounts and config values over to the new ones.
Working on the bot to use my website namemc.info some more, afaik im the only maintained namemc api out there, its free and docs can be found in the wiki.
it does use PROXYS to run, (a single IP gets blocked by CF after 1-3 days of running) so it does cost me like 3$ to run a month, but yeah! (wont need funding idrc about 3$)
hf bois.
---
go.mod | 51 +
go.sum | 144 ++
main.go | 1197 +++++++++++++++++
packages/Chrome/actions.go | 162 +++
packages/Chrome/chrome_unix.go | 177 +++
packages/Chrome/chrome_windows.go | 120 ++
packages/Chrome/config.go | 137 ++
packages/Chrome/display_unix.go | 165 +++
packages/Chrome/scripts/test.sh | 263 ++++
packages/Chrome/util/easyjson/easyjson.go | 38 +
.../Chrome/util/easyjson/easyjson_test.go | 41 +
packages/StrCmd/main.go | 286 ++++
packages/StrCmd/types.go | 34 +
packages/apiGO/mcsn.go | 319 +++++
packages/apiGO/ping.go | 20 +
packages/apiGO/proxy.go | 111 ++
packages/apiGO/send.go | 94 ++
packages/apiGO/var.go | 170 +++
packages/h2/client.go | 115 ++
packages/h2/utils.go | 384 ++++++
packages/h2/variables.go | 71 +
packages/h2/ws.go | 91 ++
packages/utils/auth.go | 841 ++++++++++++
packages/utils/config.go | 99 ++
packages/utils/proxy.go | 31 +
packages/utils/types.go | 163 +++
packages/utils/utils.go | 62 +
27 files changed, 5386 insertions(+)
create mode 100644 go.mod
create mode 100644 go.sum
create mode 100644 main.go
create mode 100644 packages/Chrome/actions.go
create mode 100644 packages/Chrome/chrome_unix.go
create mode 100644 packages/Chrome/chrome_windows.go
create mode 100644 packages/Chrome/config.go
create mode 100644 packages/Chrome/display_unix.go
create mode 100644 packages/Chrome/scripts/test.sh
create mode 100644 packages/Chrome/util/easyjson/easyjson.go
create mode 100644 packages/Chrome/util/easyjson/easyjson_test.go
create mode 100644 packages/StrCmd/main.go
create mode 100644 packages/StrCmd/types.go
create mode 100644 packages/apiGO/mcsn.go
create mode 100644 packages/apiGO/ping.go
create mode 100644 packages/apiGO/proxy.go
create mode 100644 packages/apiGO/send.go
create mode 100644 packages/apiGO/var.go
create mode 100644 packages/h2/client.go
create mode 100644 packages/h2/utils.go
create mode 100644 packages/h2/variables.go
create mode 100644 packages/h2/ws.go
create mode 100644 packages/utils/auth.go
create mode 100644 packages/utils/config.go
create mode 100644 packages/utils/proxy.go
create mode 100644 packages/utils/types.go
create mode 100644 packages/utils/utils.go
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..0ca90f3
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,51 @@
+module main
+
+go 1.21
+
+require (
+ github.com/Davincible/chromedp-undetected v1.3.5
+ github.com/PuerkitoBio/goquery v1.8.1
+ github.com/Tnze/go-mc v1.19.3
+ github.com/Xuanwo/go-locale v1.1.0
+ github.com/antchfx/htmlquery v1.3.0
+ github.com/bogdanfinn/utls v1.5.16
+ github.com/chromedp/cdproto v0.0.0-20230605001715-1e95ea08ffe6
+ github.com/chromedp/chromedp v0.9.1
+ github.com/gobwas/ws v1.2.1
+ github.com/golang-jwt/jwt v3.2.2+incompatible
+ github.com/google/uuid v1.3.0
+ github.com/iskaa02/qalam v0.3.0
+ github.com/mailru/easyjson v0.7.7
+ github.com/playwright-community/playwright-go v0.2000.1
+ github.com/stretchr/testify v1.8.1
+ golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
+ golang.org/x/net v0.10.0
+)
+
+require (
+ github.com/andybalholm/cascadia v1.3.1 // indirect
+ github.com/antchfx/xpath v1.2.3 // indirect
+ github.com/chromedp/sysutil v1.0.0 // indirect
+ github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/go-stack/stack v1.8.1 // indirect
+ github.com/gobwas/httphead v0.1.0 // indirect
+ github.com/gobwas/pool v0.2.1 // indirect
+ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+ github.com/josharian/intern v1.0.0 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ gopkg.in/square/go-jose.v2 v2.6.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+)
+
+require (
+ github.com/andybalholm/brotli v1.0.5 // indirect
+ github.com/gorilla/websocket v1.5.0
+ github.com/klauspost/compress v1.16.5 // indirect
+ github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
+ github.com/mazznoer/colorgrad v0.9.1 // indirect
+ github.com/mazznoer/csscolorparser v0.1.3 // indirect
+ golang.org/x/crypto v0.9.0 // indirect
+ golang.org/x/sys v0.8.0 // indirect
+ golang.org/x/text v0.9.0 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..5977b10
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,144 @@
+github.com/Davincible/chromedp-undetected v1.3.5 h1:OUla17uvqobu8atvhKEbvaT85TsLZEhrDUEgs65H7bo=
+github.com/Davincible/chromedp-undetected v1.3.5/go.mod h1:A8RL39TZqwzjliEkXFieMSIerNsP2TiJxRePFx79jr4=
+github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
+github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
+github.com/Tnze/go-mc v1.19.3 h1:vRRJSlqsN65+4Wgy/Sx9+Z1W3+S5BaQ1ZPcCp0TaXgs=
+github.com/Tnze/go-mc v1.19.3/go.mod h1:uNMPHRugYj2nXIHbmm8XTQJ1NpQAC2p214es9BIC5Rc=
+github.com/Xuanwo/go-locale v1.1.0 h1:51gUxhxl66oXAjI9uPGb2O0qwPECpriKQb2hl35mQkg=
+github.com/Xuanwo/go-locale v1.1.0/go.mod h1:UKrHoZB3FPIk9wIG2/tVSobnHgNnceGSH3Y8DY5cASs=
+github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
+github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
+github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
+github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
+github.com/antchfx/htmlquery v1.3.0 h1:5I5yNFOVI+egyia5F2s/5Do2nFWxJz41Tr3DyfKD25E=
+github.com/antchfx/htmlquery v1.3.0/go.mod h1:zKPDVTMhfOmcwxheXUsx4rKJy8KEY/PU6eXr/2SebQ8=
+github.com/antchfx/xpath v1.2.3 h1:CCZWOzv5bAqjVv0offZ2LVgVYFbeldKQVuLNbViZdes=
+github.com/antchfx/xpath v1.2.3/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
+github.com/bogdanfinn/utls v1.5.16 h1:NhhWkegEcYETBMj9nvgO4lwvc6NcLH+znrXzO3gnw4M=
+github.com/bogdanfinn/utls v1.5.16/go.mod h1:mHeRCi69cUiEyVBkKONB1cAbLjRcZnlJbGzttmiuK4o=
+github.com/chromedp/cdproto v0.0.0-20230220211738-2b1ec77315c9/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
+github.com/chromedp/cdproto v0.0.0-20230605001715-1e95ea08ffe6 h1:lH/2I023SRn9+1SaCEQk0iax3HKq8bJ6aj4Iyq4VwjM=
+github.com/chromedp/cdproto v0.0.0-20230605001715-1e95ea08ffe6/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
+github.com/chromedp/chromedp v0.9.1 h1:CC7cC5p1BeLiiS2gfNNPwp3OaUxtRMBjfiw3E3k6dFA=
+github.com/chromedp/chromedp v0.9.1/go.mod h1:DUgZWRvYoEfgi66CgZ/9Yv+psgi+Sksy5DTScENWjaQ=
+github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
+github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
+github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
+github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
+github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
+github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
+github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
+github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
+github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
+github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
+github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk=
+github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
+github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
+github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
+github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/h2non/filetype v1.1.1/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
+github.com/iskaa02/qalam v0.3.0 h1:yA7+MXkXbkP0HRDpkODC3bgQG0e5mjsYOsawwYP2v5k=
+github.com/iskaa02/qalam v0.3.0/go.mod h1:BRa4ht8cMjl27tNzhtuach90dBTma5seOzjpMGA5MY4=
+github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
+github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
+github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
+github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
+github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
+github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
+github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
+github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/mazznoer/colorgrad v0.9.1 h1:MB80JYVndKWSMEM1beNqnuOowWGhoQc3DXWXkFp6JlM=
+github.com/mazznoer/colorgrad v0.9.1/go.mod h1:WX2R9wt9B47+txJZVVpM9LY+LAGIdi4lTI5wIyreDH4=
+github.com/mazznoer/csscolorparser v0.1.2/go.mod h1:Aj22+L/rYN/Y6bj3bYqO3N6g1dtdHtGfQ32xZ5PJQic=
+github.com/mazznoer/csscolorparser v0.1.3 h1:vug4zh6loQxAUxfU1DZEu70gTPufDPspamZlHAkKcxE=
+github.com/mazznoer/csscolorparser v0.1.3/go.mod h1:Aj22+L/rYN/Y6bj3bYqO3N6g1dtdHtGfQ32xZ5PJQic=
+github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
+github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
+github.com/playwright-community/playwright-go v0.2000.1 h1:2JViSHpJQ/UL/PO1Gg6gXV5IcXAAsoBJ3KG9L3wKXto=
+github.com/playwright-community/playwright-go v0.2000.1/go.mod h1:1y9cM9b9dVHnuRWzED1KLM7FtbwTJC8ibDjI6MNqewU=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v1.6.7 h1:I6tZjLXD2Q1kjvNbIzB1wvQBsXmKXiVrhpRE8ZjP5jY=
+github.com/smartystreets/goconvey v1.6.7/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
+golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
+golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
+golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211023085530-d6a326fbbf70/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
+gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..781bec1
--- /dev/null
+++ b/main.go
@@ -0,0 +1,1197 @@
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "context"
+ "crypto/tls"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "image"
+ "image/png"
+ "io"
+ "main/packages/utils"
+ "math/rand"
+ "net/http"
+ "os"
+ "os/exec"
+ "regexp"
+ "runtime"
+ "strings"
+ "sync"
+ "time"
+
+ cu "main/packages/Chrome"
+ "main/packages/StrCmd"
+ "main/packages/apiGO"
+
+ "github.com/PuerkitoBio/goquery"
+ html "github.com/antchfx/htmlquery"
+ "github.com/chromedp/cdproto/emulation"
+ "github.com/chromedp/cdproto/network"
+ "github.com/chromedp/chromedp"
+ "github.com/google/uuid"
+ "github.com/playwright-community/playwright-go"
+)
+
+type Target struct {
+ UUID string
+ URL string
+ Hits int
+}
+
+func TempCalc(interval, accamt int) time.Duration {
+ amt := interval / accamt
+ if amt < 10 {
+ return time.Duration(amt) * time.Millisecond
+ }
+ return time.Duration(amt) * time.Millisecond
+}
+
+var Cookie string
+
+type Namemc struct {
+ Key string
+ DisplayName string
+ Accounts []UUIDS
+}
+
+type UUIDS struct {
+ Name string
+ URLPath string
+ IconPNG string
+}
+
+var (
+ Session Namemc
+)
+
+func init() {
+ utils.Roots.AppendCertsFromPEM(utils.ProxyByte)
+ apiGO.Clear()
+ utils.Con.LoadState()
+
+ var reloadifnill bool
+ if utils.Con.Settings.GC_ReqAmt == 0 {
+ utils.Con.Settings.GC_ReqAmt = 1
+ reloadifnill = true
+ }
+
+ if utils.Con.Settings.MFA_ReqAmt == 0 {
+ utils.Con.Settings.MFA_ReqAmt = 1
+ reloadifnill = true
+ }
+
+ if reloadifnill {
+ utils.Con.SaveConfig()
+ utils.Con.LoadState()
+ }
+
+ for _, rgb := range utils.Con.Gradient {
+ utils.RGB = append(utils.RGB, fmt.Sprintf("rgb(%v,%v,%v)", rgb.R, rgb.G, rgb.B))
+ }
+
+ if !utils.Con.Bools.DownloadedPW {
+ if err := playwright.Install(&playwright.RunOptions{Verbose: true}); err == nil {
+ utils.Con.Bools.DownloadedPW = true
+ utils.Con.SaveConfig()
+ utils.Con.LoadState()
+ }
+ if utils.Con.NMC.UseNMC {
+ if runtime.GOOS != "windows" {
+ fmt.Println("Installing google chrome...")
+ if _, err := os.Stat("google-chrome-stable_current_amd64.deb"); os.IsNotExist(err) {
+ exec.Command("wget", "https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb").Run()
+ if err := exec.Command("/bin/sh", "-c", "sudo dpkg -i google-chrome-stable_current_amd64.deb").Run(); err != nil {
+ exec.Command("/bin/sh", "-c", "sudo apt update").Run()
+ exec.Command("/bin/sh", "-c", "sudo apt upgrade").Run()
+ exec.Command("/bin/sh", "-c", "sudo dpkg --configure -a").Run()
+ exec.Command("/bin/sh", "-c", "sudo apt --fix-broken install -y").Run()
+ exec.Command("/bin/sh", "-c", "sudo apt install xvfb").Run()
+ }
+ }
+ exec.Command("/bin/sh", "-c", "Xvfb :1 -screen 0 800x600x24").Run()
+ exec.Command("/bin/sh", "-c", "sudo apt-get install -f").Run()
+ fmt.Println("Please rerun the program with this command: DISPLAY=:1 go run . *OR* DISPLAY=:1 ./the-name-of-this-executable")
+ }
+ os.Exit(0)
+ }
+ }
+
+ fmt.Print(utils.Logo(`
+ ,-----. ,--. ,--.
+' .--./,--.--.,--.,--.,--,--,--.| |-. | | ,---.
+| | | .--'| || || || .-. '| || .-. :
+' '--'\| | ' '' '| | | || '-' || |\ --.
+ '-----''--' '----' '--'--'--' '---' '--' '----'
+
+`))
+
+ if utils.Con.Bools.FirstUse {
+ fmt.Print(utils.Logo("Use proxys for authentication? : [YES/NO] > "))
+ var ProxyAuth string
+ fmt.Scan(&ProxyAuth)
+ utils.Con.Bools.FirstUse = false
+ utils.Con.Bools.UseProxyDuringAuth = strings.Contains(strings.ToLower(ProxyAuth), "y")
+ utils.Con.SaveConfig()
+ utils.Con.LoadState()
+ }
+
+ if _, err := os.Stat("/data/skinarts"); errors.Is(err, os.ErrNotExist) {
+ os.Mkdir("data/skinarts", os.ModePerm)
+ }
+
+ if _, err := os.Stat("data"); errors.Is(err, os.ErrNotExist) {
+ os.MkdirAll("data", os.ModePerm)
+ os.Create("data/config.json")
+ os.Create("data/accounts.txt")
+ os.Create("data/proxys.txt")
+ os.Create("data/invalids.txt")
+ }
+
+ utils.Proxy.GetProxys(false, nil)
+ utils.Proxy.Setup()
+ utils.AuthAccs()
+ utils.Regenerateallaccs()
+ go utils.CheckAccs()
+ var use_proxy, gcamt, mfaamt int
+
+ for _, bearer := range utils.Bearer.Details {
+ if use_proxy >= len(utils.Proxy.Proxys) && len(utils.Proxy.Proxys) < len(utils.Bearer.Details) {
+ break
+ }
+ switch bearer.AccountType {
+ case "Microsoft":
+ if utils.First_mfa {
+ utils.Accs["Microsoft"] = []utils.Proxys_Accs{{Proxy: utils.Proxy.Proxys[use_proxy]}}
+ utils.First_mfa = false
+ use_proxy++
+ }
+ var am int = utils.Con.Settings.AccountsPerMfa
+ if am == 0 {
+ am = 1
+ }
+ if len(utils.Accs["Microsoft"][utils.Use_mfa].Accs) != am {
+ utils.Accs["Microsoft"][utils.Use_mfa].Accs = append(utils.Accs["Microsoft"][utils.Use_mfa].Accs, bearer)
+ utils.Accamt++
+ mfaamt++
+ } else {
+ utils.Use_mfa++
+ utils.Accamt++
+ mfaamt++
+ utils.Accs["Microsoft"] = append(utils.Accs["Microsoft"], utils.Proxys_Accs{Proxy: utils.Proxy.Proxys[use_proxy], Accs: []apiGO.Info{bearer}})
+ use_proxy++
+ }
+ case "Giftcard":
+ if utils.First_gc {
+ utils.Accs["Giftcard"] = []utils.Proxys_Accs{{Proxy: utils.Proxy.Proxys[use_proxy]}}
+ utils.First_gc = false
+ use_proxy++
+ }
+ var am int = utils.Con.Settings.AccountsPerGc
+ if am == 0 {
+ am = 1
+ }
+ if len(utils.Accs["Giftcard"][utils.Use_gc].Accs) != am {
+ utils.Accs["Giftcard"][utils.Use_gc].Accs = append(utils.Accs["Giftcard"][utils.Use_gc].Accs, bearer)
+ utils.Accamt++
+ gcamt++
+ } else {
+ utils.Use_gc++
+ utils.Accamt++
+ gcamt++
+ utils.Accs["Giftcard"] = append(utils.Accs["Giftcard"], utils.Proxys_Accs{Proxy: utils.Proxy.Proxys[use_proxy], Accs: []apiGO.Info{bearer}})
+ use_proxy++
+ }
+ }
+ }
+
+ if gcamt == 0 {
+ gcamt = 1
+ }
+ if mfaamt == 0 {
+ mfaamt = 1
+ }
+
+ if utils.Con.NMC.UseNMC {
+ if utils.Con.CF.Tokens != "" && time.Now().Unix() < utils.Con.CF.GennedAT {
+ Cookie = utils.Con.CF.Tokens
+ go func() {
+ for {
+ time.Sleep(time.Until(time.Unix(utils.Con.CF.GennedAT, 0)))
+ if status, cookies := Get_CF_Clearance(); status == 200 {
+ for _, cookies := range cookies {
+ if cookies.Name == "cf_clearance" {
+ utils.Con.CF = utils.CF{
+ Tokens: fmt.Sprintf("%v=%v", cookies.Name, cookies.Value),
+ GennedAT: time.Now().Add(time.Second * 1800).Unix(),
+ }
+ Cookie = utils.Con.CF.Tokens
+ utils.Con.SaveConfig()
+ utils.Con.LoadState()
+ break
+ }
+ }
+ }
+ time.Sleep(10 * time.Second)
+ }
+ }()
+ } else {
+ if status, cookies := Get_CF_Clearance(); status == 200 {
+ for _, cookies := range cookies {
+ if cookies.Name == "cf_clearance" {
+ utils.Con.CF = utils.CF{
+ Tokens: fmt.Sprintf("%v=%v", cookies.Name, cookies.Value),
+ GennedAT: time.Now().Add(time.Second * 1800).Unix(),
+ }
+ Cookie = utils.Con.CF.Tokens
+ utils.Con.SaveConfig()
+ utils.Con.LoadState()
+ break
+ }
+ }
+ go func() {
+ for {
+ time.Sleep(time.Until(time.Unix(utils.Con.CF.GennedAT, 0)))
+ if status, cookies := Get_CF_Clearance(); status == 200 {
+ for _, cookies := range cookies {
+ if cookies.Name == "cf_clearance" {
+ utils.Con.CF = utils.CF{
+ Tokens: fmt.Sprintf("%v=%v", cookies.Name, cookies.Value),
+ GennedAT: time.Now().Add(time.Second * 1800).Unix(),
+ }
+ Cookie = utils.Con.CF.Tokens
+ utils.Con.SaveConfig()
+ utils.Con.LoadState()
+ break
+ }
+ }
+ }
+ time.Sleep(10 * time.Second)
+ }
+ }()
+ }
+ }
+ if !(time.Now().Unix() < utils.Con.NMC.NamemcLoginData.LastAuthed) {
+ if utils.Con.NMC.Key != "" {
+ acc := strings.Split(utils.Con.NMC.Key, ":")
+ req, _ := http.NewRequest("POST", "https://namemc.com/login", bytes.NewBuffer([]byte(fmt.Sprintf(`email=%v&password=%v`, acc[0], acc[1]))))
+ req.AddCookie(&http.Cookie{Name: strings.Split(Cookie, "=")[0], Value: strings.Split(Cookie, "=")[1]})
+ req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36")
+ req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
+ req.Header.Add("Origin", "https://namemc.com")
+ req.Header.Add("Referer", "https://namemc.com/login")
+ Cl := http.Client{
+ CheckRedirect: func(req *http.Request, via []*http.Request) error {
+ for _, name := range req.Response.Cookies() {
+ if name.Name == "session_id" {
+ Session.Key = name.Value
+ }
+ }
+ return nil
+ },
+ }
+ r, _ := Cl.Do(req)
+ if r.StatusCode == 401 {
+ fmt.Println(utils.Logo(fmt.Sprintf("<%v> Email and password invalid for namemc..", time.Now().Format("05.000"))))
+ } else {
+ if Session.Key != "" {
+ utils.Con.NMC.NamemcLoginData = utils.NMC{
+ Token: Session.Key,
+ LastAuthed: time.Now().Add(time.Second * 86400).Unix(),
+ }
+ utils.Con.SaveConfig()
+ utils.Con.LoadState()
+ }
+ }
+ }
+ } else {
+ Session.Key = utils.Con.NMC.NamemcLoginData.Token
+ }
+ getProfiles()
+ }
+ /*
+ fmt.Print(utils.Logo(fmt.Sprintf(`
+ i Accounts Loaded > <%v>
+ i Proxies Loaded > <%v>
+ i Proxys in use > <%v>
+ i Recoverys Done > <%v>
+ i Accounts Details:
+ - GC's Per Proxy > <%v>
+ - MFA's Per Proxy > <%v>
+ - Req per GC > <%v>
+ - Req per MFA > <%v>
+ - Spread GC > <%v>
+ - Spread MFA > <%v>
+ i Namemc Info:
+ - Using NameMC > <%v>
+ - Accounts Loaded > <%v>
+ - Display Name > <%v>
+
+ `,
+ len(utils.Bearer.Details),
+ len(utils.Proxy.Proxys),
+ use_proxy,
+ len(utils.Con.Recovery),
+ utils.Con.Settings.AccountsPerGc,
+ utils.Con.Settings.AccountsPerMfa,
+ utils.Con.Settings.GC_ReqAmt,
+ utils.Con.Settings.MFA_ReqAmt,
+ TempCalc((utils.Con.Settings.SleepAmtPerGc), gcamt),
+ TempCalc((utils.Con.Settings.SleepAmtPerMfa), mfaamt),
+ utils.Con.NMC.UseNMC,
+ len(Session.Accounts),
+ Session.DisplayName,
+ )))
+ */
+}
+
+func main() {
+ app := StrCmd.App{
+ Display: utils.Logo("@Crumble/root: "),
+ Version: "v1.5.15-CR",
+ AppDescription: "Crumble is a open source minecraft turbo!",
+ Commands: map[string]StrCmd.Command{
+ "namemc": {
+ Description: "The command that can handle FUN commands related to NAMEMC!",
+ Subcommand: map[string]StrCmd.SubCmd{
+ "info": {
+ Action: func() {
+ if utils.Con.CF.Tokens == "" {
+ return
+ }
+ req, _ := http.NewRequest("GET", "https://namemc.com/search?q="+StrCmd.String("-name"), nil)
+ req.AddCookie(&http.Cookie{Name: strings.Split(Cookie, "=")[0], Value: strings.Split(Cookie, "=")[1]})
+ req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36")
+ req.Header.Add("Origin", "https://namemc.com")
+ req.Header.Add("X-Forwarded-For", X_Forwarded_For())
+ req.Header.Add("Referer", "https://namemc.com/")
+ if resp, err := http.DefaultClient.Do(req); err == nil {
+ resp_body, _ := io.ReadAll(resp.Body)
+ namemc := GetInfo(resp_body)
+ fmt.Println(utils.Logo(fmt.Sprintf(`
+ Name: %v
+ Views: %v
+HeadURL: %v
+BodyURL: %v
+ Start: %v
+ End: %v
+ Status: %v
+`, StrCmd.String("-name"), namemc.Searches, namemc.HeadURL, namemc.BodyUrl, namemc.Start, namemc.End, namemc.Status)))
+ }
+ },
+ Args: []string{"-name"},
+ },
+ "get-skins": {
+ Action: func() {
+
+ if utils.Con.CF.Tokens == "" {
+ return
+ }
+
+ req, _ := http.NewRequest("GET", "https://namemc.com/minecraft-skins", nil)
+ req.AddCookie(&http.Cookie{Name: strings.Split(Cookie, "=")[0], Value: strings.Split(Cookie, "=")[1]})
+ req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36")
+ req.Header.Add("Origin", "https://namemc.com")
+ req.Header.Add("X-Forwarded-For", X_Forwarded_For())
+ req.Header.Add("Referer", "https://namemc.com/")
+ if resp, err := http.DefaultClient.Do(req); err == nil {
+ resp_body, _ := io.ReadAll(resp.Body)
+ fmt.Println(GetAllSkinsOnPage(string(resp_body)))
+ }
+ },
+ },
+ },
+ },
+ "key": {
+ Action: func() {
+ var account string
+ fmt.Print(utils.Logo("Account [email:password]: "))
+ fmt.Scan(&account)
+ if details := strings.Split(account, ":"); len(details) >= 2 {
+ if info := apiGO.MS_authentication(details[0], details[1], nil); info.Error == "" {
+ fmt.Println(utils.Namemc_key(info.Bearer))
+ } else {
+ fmt.Println(utils.Logo(info.Error))
+ }
+ }
+ },
+ },
+ "skinart-png": {
+ Action: func() {
+ var name string
+ fmt.Print(utils.Logo("Name of the profile you wanna scrape: "))
+ fmt.Scan(&name)
+ resp, _ := http.Get("https://namemc.info/data/namemc/skinart/logo/" + name)
+ img, _, _ := image.Decode(resp.Body)
+ path := "data/skinarts/" + strings.ReplaceAll(uuid.NewString(), "-", "") + "_" + name + ".png"
+ out, _ := os.Create(path)
+ png.Encode(out, img)
+ },
+ },
+ "recover": {Action: func() {
+ force := StrCmd.Bool("--force")
+ use := []apiGO.Info{}
+ if force {
+ use = utils.Bearer.Details
+ } else {
+ if _, err := os.Stat("data/invalids.txt"); !os.IsNotExist(err) {
+ body, _ := os.ReadFile("data/invalids.txt")
+ scanner := bufio.NewScanner(bytes.NewBuffer(body))
+ var a []string
+ for scanner.Scan() {
+ a = append(a, scanner.Text())
+ }
+ for _, acc := range a {
+ var Found bool
+ for _, accs := range utils.Con.Recovery {
+ if strings.EqualFold(accs.Email, strings.Split(acc, ":")[0]) {
+ Found = true
+ break
+ }
+ }
+ if !Found {
+ use = append(use, apiGO.Info{
+ Email: strings.Split(acc, ":")[0],
+ Password: strings.Split(acc, ":")[1],
+ })
+ }
+ }
+ }
+ }
+ AddRecoveryEmails(use)
+ }, Args: []string{"--force"}},
+ "snipe": {
+ Description: "Main sniper command, targets only one ign that is passed through with -u",
+ Action: func() {
+ if len(utils.Bearer.Details) != 0 {
+ cl, name, Changed, EmailClaimed := false, StrCmd.String("-u"), false, ""
+ var start, end int64 = int64(StrCmd.Int("-start")), int64(StrCmd.Int("-end"))
+ if utils.Con.NMC.UseNMC {
+ start, end, _, _ = utils.GetDroptimes(name)
+ } else if !utils.Con.NMC.UseNMC || start == 0 || end == 0 {
+ if utils.Con.Settings.AskForUnixPrompt {
+ fmt.Println(utils.Logo("Timestamp to Unix: [https://www.epochconverter.com/] (make sure to remove the • on the namemc timestamp!)"))
+ fmt.Print(utils.Logo("Use your own unix timestamps [y/n]: "))
+ var Use string
+ fmt.Scan(&Use)
+ if strings.Contains(strings.ToLower(Use), "y") {
+ fmt.Print(utils.Logo("Start: "))
+ fmt.Scan(&start)
+ fmt.Print(utils.Logo("End: "))
+ fmt.Scan(&end)
+ }
+ }
+ }
+ drop := time.Unix(int64(start), 0)
+ for time.Now().Before(drop) {
+ fmt.Print(utils.Logo((fmt.Sprintf("[%v] %v \r", name, time.Until(drop).Round(time.Second)))))
+ time.Sleep(time.Second * 1)
+ }
+ go func() {
+ Exit:
+ for {
+ if utils.IsAvailable(name) {
+ Changed = true
+ cl = true
+ break Exit
+ }
+ if start != 0 && end != 0 && time.Now().After(time.Unix(int64(end), 0)) {
+ Changed = true
+ cl = true
+ break Exit
+ }
+ time.Sleep(10 * time.Second)
+ }
+ }()
+ go func() {
+ type Proxys struct {
+ Conn *tls.Conn
+ Accounts []apiGO.Info
+ Proxy string
+ }
+ var Payloads []Proxys
+ var wg_a sync.WaitGroup
+ for _, Acc := range append(utils.Accs["Giftcard"], utils.Accs["Microsoft"]...) {
+ wg_a.Add(1)
+ go func(Acc utils.Proxys_Accs) {
+ if P, ok := utils.Connect(Acc.Proxy); ok {
+ fmt.Println(utils.Logo(fmt.Sprintf("<%v> %v [OK] > %v accs..", time.Now().Format("05.000"), strings.Split(Acc.Proxy, ":")[0], len(Acc.Accs))))
+ Payloads = append(Payloads, Proxys{
+ Conn: P,
+ Accounts: Acc.Accs,
+ Proxy: Acc.Proxy,
+ })
+ } else {
+ fmt.Println(utils.Logo(fmt.Sprintf("<%v> %v Proxy timed out or couldnt connect.. ", time.Now().Format("05.000"), strings.Split(Acc.Proxy, ":")[0])))
+ }
+ wg_a.Done()
+ }(Acc)
+ }
+
+ wg_a.Wait()
+
+ go func() {
+ for {
+ var wg sync.WaitGroup
+ for i, c := range Payloads {
+ wg.Add(1)
+ go func(i int, c Proxys) {
+ if P, ok := utils.Connect(c.Proxy); ok {
+ Payloads[i].Conn = P
+ }
+ wg.Done()
+ }(i, c)
+ }
+ wg.Wait()
+ time.Sleep(5 * time.Second)
+ }
+ }()
+ for !cl || !Changed {
+ for _, c := range Payloads {
+ for _, accs := range c.Accounts {
+ if !cl {
+ go func(Config apiGO.Info, c Proxys) {
+ reqamt := 1
+ switch Config.AccountType {
+ case "Giftcard":
+ reqamt = utils.Con.Settings.GC_ReqAmt
+ case "Microsoft":
+ reqamt = utils.Con.Settings.MFA_ReqAmt
+ }
+
+ if P, ok := utils.Connect(c.Proxy); ok {
+ var wg sync.WaitGroup
+ for i := 0; i < reqamt; i++ {
+ wg.Add(1)
+ go func() {
+ var status string
+ defer wg.Done()
+ Req := apiGO.Details{ResponseDetails: apiGO.SocketSending(P, ReturnPayload(Config.AccountType, Config.Bearer, name)), Bearer: Config.Bearer, Email: Config.Email, Type: Config.AccountType}
+ switch true {
+ case strings.Contains(Req.ResponseDetails.Body, "DUPLICATE"):
+ status = "DUPLICATE"
+ case strings.Contains(Req.ResponseDetails.Body, "ALREADY_REGISTERED"):
+ status = "ALREADY_REGISTERED"
+ //InvalidAccs(Config.Email + ":" + Config.Password)
+ case strings.Contains(Req.ResponseDetails.Body, "NOT_ENTITLED"):
+ status = "NOT_ENTITLED"
+ //InvalidAccs(Config.Email + ":" + Config.Password)
+ default:
+ switch Req.ResponseDetails.StatusCode {
+ case "429":
+ status = "RATE_LIMITED"
+ //proxy = utils.Proxy.CompRand()
+ case "200":
+ if utils.Con.SkinChange.Link != "" {
+ apiGO.ChangeSkin(apiGO.JsonValue(utils.Con.SkinChange), Config.Bearer)
+ }
+
+ NMC := utils.Namemc_key(Config.Bearer)
+ if utils.Con.NMC.UseNMC {
+ Claim_NAMEMC(NMC)
+ SendFollow(name)
+ }
+ EmailClaimed = utils.Logo(fmt.Sprintf("✓ %v claimed %v @ %v [%v]\n", Config.Email, name, time.Now().Format("05.0000"), NMC))
+ cl = true
+ status = "CLAIMED"
+ }
+ }
+ fmt.Println(utils.Logo(fmt.Sprintf(`✗ <%v> [%v] %v %v ⑇ %v ↪ %v`, time.Now().Format("15:04:05.0000"), Req.ResponseDetails.StatusCode, status, name, utils.HashEmailClean(Config.Email), strings.Split(c.Proxy, ":")[0])))
+ }()
+ }
+ wg.Wait()
+ }
+ }(accs, c)
+ }
+ }
+ Spread := time.Millisecond
+ if utils.Con.Settings.UseCustomSpread {
+ Spread = time.Duration(utils.Con.Settings.Spread) * time.Millisecond
+ } else {
+ Spread = TempCalc(utils.Con.Settings.SleepAmtPerGc, utils.Accamt)
+ }
+ time.Sleep(Spread)
+ }
+ }
+ }()
+
+ for {
+ if cl || Changed {
+ if EmailClaimed == "" {
+ EmailClaimed = utils.Logo("No account has sniped the name.")
+ }
+ fmt.Printf(EmailClaimed)
+ break
+ }
+ time.Sleep(1 * time.Second)
+ }
+ } else {
+ if len(utils.Con.Bearers) == 0 && len(utils.Bearer.Details) == 0 {
+ return
+ }
+ }
+ },
+ Args: []string{
+ "-u",
+ "-start",
+ "-end",
+ },
+ },
+ "find_name": {
+ Action: func() {
+ if len(utils.Con.Bearers) != 0 {
+ var detected bool
+ var detected_string string
+ var wg sync.WaitGroup
+ var Name string = StrCmd.String("-name")
+ body, _ := os.ReadFile("data/accounts.txt")
+ scanner := bufio.NewScanner(bytes.NewBuffer(body))
+ var accs []string
+ for scanner.Scan() {
+ accs = append(accs, scanner.Text())
+ }
+
+ var use_proxy, gcamt int
+ var gc_a int
+ var fgc bool = true
+ var data map[string][]utils.Proxys_Accs = make(map[string][]utils.Proxys_Accs)
+ for _, bearer := range accs {
+ P := strings.Split(bearer, ":")
+ if use_proxy >= len(utils.Proxy.Proxys) && len(utils.Proxy.Proxys) < len(accs) {
+ break
+ }
+ if fgc {
+ data["Account"] = []utils.Proxys_Accs{{Proxy: utils.Proxy.Proxys[use_proxy]}}
+ fgc = false
+ use_proxy++
+ }
+ var am int = 3
+ if len(data["Account"][gc_a].Accs) != am {
+ data["Account"][gc_a].Accs = append(data["Account"][gc_a].Accs, apiGO.Info{
+ Email: P[0], Password: P[1],
+ })
+ gcamt++
+ } else {
+ gc_a++
+ gcamt++
+ data["Account"] = append(data["Account"], utils.Proxys_Accs{Proxy: utils.Proxy.Proxys[use_proxy], Accs: []apiGO.Info{{
+ Email: P[0], Password: P[1],
+ }}})
+ use_proxy++
+ }
+ }
+ for _, acc := range data["Account"] {
+ ip, port, user, pass := "", "", "", ""
+ switch data := strings.Split(acc.Proxy, ":"); len(data) {
+ case 2:
+ ip = data[0]
+ port = data[1]
+ case 4:
+ ip = data[0]
+ port = data[1]
+ user = data[2]
+ pass = data[3]
+ }
+ for _, acc := range acc.Accs {
+ wg.Add(1)
+ go func(acc apiGO.Info, ip, port, user, pass string) {
+ defer wg.Done()
+ info := apiGO.MS_authentication(acc.Email, acc.Password, &apiGO.ProxyMS{IP: ip, Port: port, User: user, Password: pass})
+ if info.Info.Name == "" {
+ info.Info.Name = "null"
+ }
+ if strings.EqualFold(info.Info.Name, Name) {
+ detected = true
+ detected_string = utils.Logo(fmt.Sprintf("<%v> %v - %v >> %v, %v", time.Now().Format("05.000"), info.Email, info.Password, info.Info.Name, info.AccountType))
+ }
+ fmt.Println(utils.Logo(fmt.Sprintf("<%v> %v >> %v, %v", time.Now().Format("05.000"), utils.HashEmailClean(info.Email), info.Info.Name, info.AccountType)))
+ }(acc, ip, port, user, pass)
+ }
+ }
+ wg.Wait()
+ if detected {
+ fmt.Println(detected_string)
+ }
+ }
+ },
+ Args: []string{
+ "-name",
+ },
+ },
+ },
+ }
+ if len(os.Args) > 1 {
+ app.Input(strings.Join(os.Args[1:], " "))
+ } else {
+ app.Run()
+ }
+}
+
+type NamemcSkins struct {
+ Emoji string `json:"emoji"`
+ NamemcUsername string `json:"owner"`
+ Number string `json:"number"`
+ Stars string `json:"stars"`
+ Time string `json:"time"`
+ BodyURL string `json:"bodyurl"`
+ HeadURL string `json:"headurl"`
+ SkinDownload string `json:"skindownload"`
+}
+
+func GetAllSkinsOnPage(html string) (Return []NamemcSkins) {
+ Body := strings.Split(strings.Split(html, `
`)[1], `
")]
+ for _, packs := range strings.Split(Resp, `")[0]
+ if strings.Contains(Content, "card-header") {
+ ID := strings.Split(Content, `"`)[0]
+ var emoji string
+ Data := strings.Split(strings.Split(Content, `")[1]
+ if strings.Contains(Data, "img") {
+ emoji = strings.Split(strings.Split(Data, `alt="`)[1], `"`)[0]
+ Data = strings.Split(Data, "#`)[1], "")[0]
+ Stars := strings.Split(Content, "★<")[0]
+ Stars = Stars[strings.LastIndex(Stars, ">")+1:] + "★"
+ base_time := strings.Split(strings.Split(Content, "★<")[1], `normal-sm">`)[1]
+ time := strings.Split(base_time, "")[0] + strings.Split(strings.Split(base_time, "")[1], "")[0]
+ Return = append(Return, NamemcSkins{
+ Emoji: emoji,
+ Time: time,
+ NamemcUsername: Name,
+ Stars: Stars,
+ Number: SkinNum,
+ HeadURL: fmt.Sprintf(`https://s.namemc.com/2d/skin/face.png?id=%v&scale=4`, ID),
+ BodyURL: fmt.Sprintf("https://s.namemc.com/3d/skin/body.png?id=%v&model=classic&width=150&height=200", ID),
+ SkinDownload: fmt.Sprintf(`https://s.namemc.com/i/%v.png`, ID),
+ })
+ }
+ }
+ return
+}
+
+type NameRequest struct {
+ Status string `json:"status,omitempty"`
+ Searches string `json:"searches,omitempty"`
+ Start_Unix int64 `json:"begin,omitempty"`
+ End_Unix int64 `json:"end,omitempty"`
+ Start *time.Time `json:"start_date,omitempty"`
+ End *time.Time `json:"end_date,omitempty"`
+ HeadURL string `json:"headurl,omitempty"`
+ BodyUrl string `json:"bodyurl,omitempty"`
+ Error string `json:"error,omitempty"`
+}
+
+func GetInfo(body []byte) (Req NameRequest) {
+ doc, _ := goquery.NewDocumentFromReader(bytes.NewBuffer(body))
+ if d, err := html.Parse(strings.NewReader(string(body))); err == nil {
+ if b, ok := doc.Find(`#availability-time`).Attr("datetime"); ok {
+ if e, ok := doc.Find(`#availability-time2`).Attr("datetime"); ok {
+ if t1, err := time.Parse(time.RFC3339, b); err == nil {
+ if t2, err := time.Parse(time.RFC3339, e); err == nil {
+ if status, searches := html.FindOne(d, `//*[@id="status-bar"]/div/div[1]/div[2]`), html.FindOne(d, `//*[@id="status-bar"]/div/div[2]/div[2]`); status.FirstChild != nil && searches.FirstChild != nil {
+ var h string
+ if head := html.FindOne(d, `/html/body/main/div/div/div[3]/div[1]/div/div[2]/img`); head != nil && head.Attr != nil {
+ h = head.Attr[1].Val
+ }
+ Req = NameRequest{
+ Status: status.FirstChild.Data,
+ Searches: strings.Split(searches.FirstChild.Data, " / month")[0],
+ Start: &t1,
+ End: &t2,
+ Start_Unix: t1.Unix(),
+ End_Unix: t2.Unix(),
+ HeadURL: h,
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if status, searches := html.FindOne(d, `//*[@id="status-bar"]/div/div[1]/div[2]`), html.FindOne(d, `//*[@id="status-bar"]/div/div[2]/div[2]`); status.FirstChild != nil && searches.FirstChild != nil {
+ var HeadUrl string
+ if head := html.FindOne(d, `/html/body/main/div/div/div[3]/div[1]/div/div[2]/img`); head != nil && head.Attr != nil {
+ HeadUrl = head.Attr[1].Val
+ }
+ body := ""
+ if HeadUrl != "" {
+ body = fmt.Sprintf("https://s.namemc.com/3d/skin/body.png?id=%v&model=classic&width=150&height=200", strings.Split(strings.Split(HeadUrl, "?id=")[1], "&")[0])
+ }
+ Req = NameRequest{
+ Status: status.FirstChild.Data,
+ Searches: strings.Split(searches.FirstChild.Data, " / month")[0],
+ HeadURL: HeadUrl,
+ BodyUrl: body,
+ }
+ }
+ }
+ }
+ return
+}
+
+type Images struct {
+ Image image.Image
+ Url string
+ Row int
+}
+
+func SendFollow(name string) {
+ for _, acc := range Session.Accounts {
+ if strings.EqualFold(acc.Name, utils.Con.NMC.Display) {
+ Swapprofile(acc.URLPath)
+ break
+ }
+ }
+
+ req, _ := http.NewRequest("GET", "https://namemc.com/profile/"+name, nil)
+ req.AddCookie(&http.Cookie{Name: strings.Split(Cookie, "=")[0], Value: strings.Split(Cookie, "=")[1]})
+ req.AddCookie(&http.Cookie{Name: "session_id", Value: Session.Key})
+ req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36")
+ var redirect string
+ Client := http.Client{CheckRedirect: func(req *http.Request, via []*http.Request) error { redirect = req.URL.String(); return nil }}
+ resp, _ := Client.Do(req)
+ if body, err := io.ReadAll(resp.Body); err == nil && resp.StatusCode == 200 {
+ (&Target{
+ UUID: strings.Split(strings.Split(string(body), `order-lg-2 col-lg" style="font-size: 90%">`)[1], ``)[0],
+ URL: redirect,
+ }).Send()
+ }
+}
+
+func ReturnPayload(acc, bearer, name string) string {
+ if acc == "Giftcard" {
+ var JSON string = fmt.Sprintf(`{"profileName":"%v"}`, name)
+ return fmt.Sprintf("POST /minecraft/profile HTTP/1.1\r\nHost: minecraftapi-bef7bxczg0amd8ef.z01.azurefd.net\r\nConnection: open\r\nContent-Length:%v\r\nContent-Type: application/json\r\nAccept: application/json\r\nAuthorization: Bearer %v\r\n\r\n%v\r\n", len(JSON), bearer, JSON)
+ } else {
+ return "PUT /minecraft/profile/name/" + name + " HTTP/1.1\r\nHost: minecraftapi-bef7bxczg0amd8ef.z01.azurefd.net\r\nConnection: open\r\nUser-Agent: MCSN/1.0\r\nContent-Length:0\r\nAuthorization: Bearer " + bearer + "\r\n"
+ }
+}
+
+func AddRecoveryEmails(accs_used []apiGO.Info) {
+ resp, _ := http.Get("https://www.1secmail.com/api/v1/?action=getDomainList")
+ body, _ := io.ReadAll(resp.Body)
+ var Domains []string
+ json.Unmarshal(body, &Domains)
+
+ if pw, err := playwright.Run(); err == nil {
+ if browser, err := pw.Chromium.Launch(playwright.BrowserTypeLaunchOptions{
+ Channel: &[]string{"chrome"}[0],
+ Headless: &[]bool{true}[0],
+ }); err == nil {
+ for _, acc := range accs_used {
+ go func(email, password string) {
+ if page, err := browser.NewPage(playwright.BrowserNewContextOptions{
+ UserAgent: &[]string{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"}[0],
+ }); err == nil {
+ page.SetDefaultTimeout(2500)
+ if _, err := page.Goto("https://www.microsoft.com/rpsauth/v1/account/SignIn?ru=https%3A%2F%2Fwww.microsoft.com%2Fen-gb%2F"); err == nil {
+ defer page.Close()
+ time.Sleep(2 * time.Second)
+ page.WaitForSelector("#i0116")
+ page.Fill("#i0116", email)
+ time.Sleep(2 * time.Second)
+ page.WaitForSelector("#idSIButton9")
+ page.Click("#idSIButton9")
+ time.Sleep(2 * time.Second)
+ page.WaitForSelector("#i0118")
+ page.Fill("#i0118", password)
+ time.Sleep(2 * time.Second)
+ page.WaitForSelector("#idSIButton9")
+ page.Click("#idSIButton9")
+
+ if c, err := page.WaitForSelector("#iLandingViewAction"); err == nil {
+ c.Click()
+ }
+
+ page.WaitForSelector("#idBtn_Back")
+ page.Click("#idBtn_Back")
+
+ if _, err := page.Goto("https://account.live.com/proofs/manage/additional?mkt=en-US&refd=account.microsoft.com&refp=security"); err == nil {
+ if c, err := page.WaitForSelector("#Add_email"); err == nil {
+ if err := c.Click(); err != nil {
+ fmt.Println(err, email)
+ page.Close()
+ return
+ }
+ } else if eval, err := page.WaitForSelector("#iLandingViewTitle"); err == nil {
+ if content, err := eval.TextContent(); err == nil {
+ if strings.EqualFold(content, "You can't access this site right now") {
+ page.Close()
+ return
+ }
+ }
+ } else if _, err := page.WaitForSelector("#idDiv_SAOTCS_Proofs > div > div > div > div.table-cell.text-left.content"); err == nil {
+ page.Close()
+ fmt.Println(utils.Logo(fmt.Sprintf("<%v> %v page required email verification to login..", time.Now().Format("05.000"), email)))
+ return
+ } else if _, err := page.WaitForSelector("body > pre"); err == nil {
+ page.Close()
+ return
+ }
+ email_code := GenerateEmail(Domains)
+ if _, err := page.WaitForSelector("#EmailAddress"); err == nil {
+ if err := page.Fill("#EmailAddress", email_code); err == nil {
+ if err := page.Click("#iNext"); err == nil {
+ Exit:
+ for i := 0; i < 100; i++ {
+ if resp, err := http.Get(fmt.Sprintf("https://www.1secmail.com/api/v1/?action=getMessages&login=%v&domain=%v", strings.Split(email_code, "@")[0], strings.Split(email_code, "@")[1])); err == nil {
+ body, _ := io.ReadAll(resp.Body)
+ var Body []struct {
+ ID int `json:"id"`
+ From string `json:"from"`
+ Subject string `json:"subject"`
+ }
+ json.Unmarshal(body, &Body)
+ for _, sub := range Body {
+ if sub.Subject == "Microsoft account security code" {
+ resp, _ := http.Get(fmt.Sprintf("https://www.1secmail.com/api/v1/?action=readMessage&login=%v&domain=%v&id=%v", strings.Split(email_code, "@")[0], strings.Split(email_code, "@")[1], sub.ID))
+ body, _ := io.ReadAll(resp.Body)
+ var Body struct {
+ Body string `json:"body"`
+ }
+ json.Unmarshal(body, &Body)
+ code := regexp.MustCompile("Security code: [0-9]+").FindAllStringSubmatch(string(body), -1)[0][0][15:]
+ page.Fill("#iOttText", code)
+ page.Click("#iNext")
+
+ fmt.Println(utils.Logo(fmt.Sprintf("<%v> i Added recovery onto "+email+" >> "+email_code, time.Now().Format("05.000"))))
+ utils.Con.Recovery = append(utils.Con.Recovery, utils.Succesful{
+ Email: email,
+ Recovery: email_code,
+ Code_Used: code,
+ })
+ utils.Con.SaveConfig()
+ utils.Con.LoadState()
+ page.Close()
+ break Exit
+ }
+ }
+ }
+ fmt.Println(utils.Logo(fmt.Sprintf("<%v> Attempt %v/100 to find a email code for %v >> %v", time.Now().Format("05.000"), i, email, email_code)))
+ time.Sleep(5 * time.Second)
+ }
+ }
+ }
+ } else {
+ if utils.Con.Bools.ApplyNewRecoveryToExistingEmails {
+ if _, err := page.WaitForSelector("#idA_SAOTCS_LostProofs"); err == nil {
+ page.Click("#idA_SAOTCS_LostProofs")
+ page.WaitForSelector("#idSubmit_SAOTCS_SendCode")
+ page.Click("#idSubmit_SAOTCS_SendCode")
+ page.WaitForSelector("#EmailAddress")
+ page.Fill("#EmailAddress", email_code)
+ page.Click("#iCollectProofAction")
+ }
+ Exit2:
+ for i := 0; i < 100; i++ {
+ if resp, err := http.Get(fmt.Sprintf("https://www.1secmail.com/api/v1/?action=getMessages&login=%v&domain=%v", strings.Split(email_code, "@")[0], strings.Split(email_code, "@")[1])); err == nil {
+ body, _ := io.ReadAll(resp.Body)
+ var Body []struct {
+ ID int `json:"id"`
+ From string `json:"from"`
+ Subject string `json:"subject"`
+ }
+ json.Unmarshal(body, &Body)
+ for _, sub := range Body {
+ if sub.Subject == "Microsoft account security info" {
+ resp, _ := http.Get(fmt.Sprintf("https://www.1secmail.com/api/v1/?action=readMessage&login=%v&domain=%v&id=%v", strings.Split(email_code, "@")[0], strings.Split(email_code, "@")[1], sub.ID))
+ body, _ := io.ReadAll(resp.Body)
+ var Body struct {
+ Body string `json:"body"`
+ }
+ json.Unmarshal(body, &Body)
+ page.Goto(strings.Split(strings.Split(Body.Body, `href="`)[1], `"`)[0])
+ time.Sleep(2 * time.Second)
+ page.Fill("#AccountNameInput", email)
+ page.Click("#iCollectMembernameAction")
+ fmt.Println(utils.Logo(fmt.Sprintf("<%v> i Changed recovery for "+email+" >> "+email_code, time.Now().Format("05.000"))))
+ utils.Con.Recovery = append(utils.Con.Recovery, utils.Succesful{
+ Email: email,
+ Recovery: email_code,
+ Code_Used: "nil",
+ })
+ utils.Con.SaveConfig()
+ utils.Con.LoadState()
+ page.Close()
+ break Exit2
+ }
+ }
+ }
+ fmt.Println(utils.Logo(fmt.Sprintf("<%v> Attempt %v/100 to find a email code for %v >> %v", time.Now().Format("05.000"), i, email, email_code)))
+ time.Sleep(10 * time.Second)
+ }
+ }
+ }
+ }
+ }
+ }
+ }(acc.Email, acc.Password)
+
+ if len(browser.Contexts()) == 15 {
+ for {
+ if len(browser.Contexts()) < 5 {
+ break
+ }
+ }
+ }
+ time.Sleep(1 * time.Second)
+ }
+ } else {
+ fmt.Println(utils.Logo(err.Error()))
+ }
+ } else {
+ fmt.Println(utils.Logo(err.Error()))
+ }
+}
+
+var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789")
+
+func GenerateEmail(domains []string) string {
+ rand.Seed(time.Now().UnixMicro())
+ return RandStringRunes(64) + "@" + domains[rand.Intn(len(domains))]
+}
+
+func RandStringRunes(n int) string {
+ rand.Seed(time.Now().UnixMicro())
+ b := make([]rune, n)
+ for i := range b {
+ b[i] = letterRunes[rand.Intn(len(letterRunes))]
+ }
+ return string(b)
+}
+
+func X_Forwarded_For() string {
+ rand.Seed(time.Now().UnixNano())
+ return fmt.Sprintf("%v.%v.%v.%v", rand.Intn(300-256)+256, rand.Intn(255), rand.Intn(255), rand.Intn(9))
+}
+
+func Get_CF_Clearance() (status int64, cookies []*network.Cookie) {
+ if ctx, cancel, err := cu.New(cu.NewConfig(
+ cu.WithChromeFlags(append(chromedp.DefaultExecAllocatorOptions[:],
+ chromedp.Flag("disable-gpu", false),
+ chromedp.Flag("headless", false),
+ chromedp.Flag("enable-automation", false),
+ chromedp.Flag("window-size", "800,600"),
+ chromedp.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"),
+ )...),
+ cu.WithTimeout(time.Second*60),
+ )); err == nil {
+ defer cancel()
+ if err := chromedp.Run(ctx, Perform_chrome(ctx, &status, &cookies)); err != nil {
+ if runtime.GOOS != "windows" {
+
+ } else {
+ fmt.Println("Please install chrome..")
+ os.Exit(0)
+ }
+ }
+ }
+ return
+}
+
+func Perform_chrome(c context.Context, st *int64, cookies *[]*network.Cookie) chromedp.Tasks {
+ chromedp.ListenTarget(c, func(ev interface{}) {
+ switch r := ev.(type) {
+ case *network.EventResponseReceived:
+ resp := r.Response
+ if resp.URL == "https://namemc.com/login" {
+ *st = resp.Status
+ }
+ }
+ })
+ return chromedp.Tasks{
+ network.Enable(),
+ emulation.SetTouchEmulationEnabled(true),
+ emulation.SetEmitTouchEventsForMouse(true),
+ chromedp.Navigate("https://namemc.com/login"),
+ chromedp.ActionFunc(func(ctx context.Context) error {
+ go func(ctx context.Context) {
+ var Cont bool
+ for !Cont {
+ go func() {
+ err := chromedp.MouseClickXY(68, 294, chromedp.ButtonLeft).Do(ctx)
+ if err != nil {
+ Cont = true
+ }
+ }()
+ time.Sleep(1 * time.Second)
+ }
+ }(ctx)
+ return nil
+ }),
+ chromedp.WaitVisible("#search-box"),
+ chromedp.ActionFunc(func(ctx context.Context) error { *cookies, _ = network.GetCookies().Do(ctx); return nil }),
+ }
+}
+
+func Swapprofile(Profile string) {
+ req, _ := http.NewRequest("GET", Profile, nil)
+ req.AddCookie(&http.Cookie{Name: strings.Split(Cookie, "=")[0], Value: strings.Split(Cookie, "=")[1]})
+ req.AddCookie(&http.Cookie{Name: "session_id", Value: Session.Key})
+ req.AddCookie(&http.Cookie{Name: "referrer", Value: Profile})
+ req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36")
+ req.Header.Add("Origin", "https://namemc.com")
+ req.Header.Add("Referer", Profile)
+ http.DefaultClient.Do(req)
+}
+
+func Claim_NAMEMC(url string) {
+ req, _ := http.NewRequest("GET", url, nil)
+ req.AddCookie(&http.Cookie{Name: strings.Split(Cookie, "=")[0], Value: strings.Split(Cookie, "=")[1]})
+ req.AddCookie(&http.Cookie{Name: "session_id", Value: Session.Key})
+ req.AddCookie(&http.Cookie{Name: "referrer", Value: url})
+ req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36")
+ req.Header.Add("Origin", "https://namemc.com")
+ req.Header.Add("Referer", url)
+ http.DefaultClient.Do(req)
+}
+
+func (Data *Target) Send() {
+ req, _ := http.NewRequest("POST", Data.URL, bytes.NewBuffer([]byte(fmt.Sprintf(`profile=%v&task=follow`, Data.UUID))))
+ req.AddCookie(&http.Cookie{Name: strings.Split(Cookie, "=")[0], Value: strings.Split(Cookie, "=")[1]})
+ req.AddCookie(&http.Cookie{Name: "session_id", Value: Session.Key})
+ req.AddCookie(&http.Cookie{Name: "referrer", Value: Data.URL})
+ req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36")
+ req.Header.Add("Origin", "https://namemc.com")
+ req.Header.Add("Referer", Data.URL)
+ req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
+ req.Header.Add("X-Forwarded-For", X_Forwarded_For())
+ if resp, err := http.DefaultClient.Do(req); err == nil {
+ b, _ := io.ReadAll(resp.Body)
+ if strings.Contains(string(b), "Following") {
+ fmt.Println(utils.Logo(fmt.Sprintf("<%v> Followed %v [%v]\n", time.Now().Format("05.000"), Data.URL, strings.Split(strings.Split(string(b), ``)[1], ``) && strings.Contains(string(body), `/my-profile/switch?`) {
+ Session.DisplayName = strings.Split(strings.Split(string(body), ``)[1], ``)[1], ``)[0], ``)[1], ``)[0],
+ IconPNG: strings.Split(strings.Split(acc, `src="`)[1], `"`)[0],
+ URLPath: "https://namemc.com" + strings.Split(strings.Split(acc, `href="`)[1], `"`)[0],
+ })
+ }
+ }
+ }
+ }
+}
diff --git a/packages/Chrome/actions.go b/packages/Chrome/actions.go
new file mode 100644
index 0000000..75fe56c
--- /dev/null
+++ b/packages/Chrome/actions.go
@@ -0,0 +1,162 @@
+package chromedpundetected
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+ "time"
+
+ "github.com/Davincible/chromedp-undetected/util/easyjson"
+ "github.com/chromedp/cdproto/cdp"
+ "github.com/chromedp/cdproto/emulation"
+ "github.com/chromedp/cdproto/network"
+ "github.com/chromedp/chromedp"
+)
+
+// Cookie is used to set browser cookies.
+type Cookie struct {
+ Name string `json:"name" yaml:"name"`
+ Value string `json:"value" yaml:"value"`
+ Domain string `json:"domain" yaml:"domain"`
+ Path string `json:"path" yaml:"path"`
+ Expires float64 `json:"expires" yaml:"expires"`
+ HTTPOnly bool `json:"httpOnly" yaml:"httpOnly"`
+ Secure bool `json:"secure" yaml:"secure"`
+}
+
+// UserAgentOverride overwrites the Chrome user agent.
+//
+// It's better to use this method than emulation.UserAgentOverride.
+func UserAgentOverride(userAgent string) chromedp.ActionFunc {
+ return func(ctx context.Context) error {
+ return cdp.Execute(ctx, "Network.setUserAgentOverride",
+ emulation.SetUserAgentOverride(userAgent), nil)
+ }
+}
+
+// LoadCookiesFromFile takes a file path to a json file containing cookies, and
+// loads in the cookies into the browser.
+func LoadCookiesFromFile(path string) chromedp.ActionFunc {
+ return chromedp.ActionFunc(func(ctx context.Context) error {
+ f, err := os.Open(path) //nolint:gosec
+ if err != nil {
+ return fmt.Errorf("failed to open file '%s': %w", path, err)
+ }
+
+ data, err := io.ReadAll(f)
+ if err != nil {
+ return err
+ }
+
+ if err := f.Close(); err != nil {
+ return err
+ }
+
+ var cookies []Cookie
+ if err := json.Unmarshal(data, &cookies); err != nil {
+ return fmt.Errorf("unmarshal cookies from json: %w", err)
+ }
+
+ return LoadCookies(cookies)(ctx)
+ })
+}
+
+// LoadCookies will load a set of cookies into the browser.
+func LoadCookies(cookies []Cookie) chromedp.ActionFunc {
+ return chromedp.ActionFunc(func(ctx context.Context) error {
+ for _, cookie := range cookies {
+ expiry := cdp.TimeSinceEpoch(time.Unix(int64(cookie.Expires), 0))
+ if err := network.SetCookie(cookie.Name, cookie.Value).
+ WithHTTPOnly(cookie.HTTPOnly).
+ WithSecure(cookie.Secure).
+ WithDomain(cookie.Domain).
+ WithPath(cookie.Path).
+ WithExpires(&expiry).
+ Do(ctx); err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+}
+
+// SaveCookies extracts the cookies from the current URL and appends them to
+// provided array.
+func SaveCookies(cookies *[]Cookie) chromedp.ActionFunc {
+ return chromedp.ActionFunc(func(ctx context.Context) error {
+ c, err := network.GetCookies().Do(ctx)
+ if err != nil {
+ return err
+ }
+
+ for _, cookie := range c {
+ *cookies = append(*cookies, Cookie{
+ Name: cookie.Name,
+ Value: cookie.Value,
+ Domain: cookie.Domain,
+ Path: cookie.Path,
+ Expires: cookie.Expires,
+ HTTPOnly: cookie.HTTPOnly,
+ Secure: cookie.HTTPOnly,
+ })
+ }
+
+ return nil
+ })
+}
+
+// SaveCookiesTo extracts the cookies from the current page and saves them
+// as JSON to the provided path.
+func SaveCookiesTo(path string) chromedp.ActionFunc {
+ return chromedp.ActionFunc(func(ctx context.Context) error {
+ var c []Cookie
+
+ if err := SaveCookies(&c).Do(ctx); err != nil {
+ return err
+ }
+
+ b, err := json.Marshal(c)
+ if err != nil {
+ return err
+ }
+
+ if err := os.WriteFile(path, b, 0644); err != nil { //nolint:gosec
+ return err
+ }
+
+ return nil
+ })
+}
+
+// RunCommandWithRes runs any Chrome Dev Tools command, with any params and
+// sets the result to the res parameter. Make sure it is a pointer.
+//
+// In contrast to the native method of chromedp, with this method you can directly
+// pass in a map with the data passed to the command.
+func RunCommandWithRes(method string, params, res any) chromedp.ActionFunc {
+ return chromedp.ActionFunc(func(ctx context.Context) error {
+ i := easyjson.New(params)
+ o := easyjson.New(res)
+
+ return cdp.Execute(ctx, method, i, o)
+ })
+}
+
+// RunCommand runs any Chrome Dev Tools command, with any params.
+//
+// In contrast to the native method of chromedp, with this method you can directly
+// pass in a map with the data passed to the command.
+func RunCommand(method string, params any) chromedp.ActionFunc {
+ return chromedp.ActionFunc(func(ctx context.Context) error {
+ i := easyjson.New(params)
+
+ return cdp.Execute(ctx, method, i, nil)
+ })
+}
+
+// BlockURLs blocks a set of URLs in Chrome.
+func BlockURLs(url ...string) chromedp.ActionFunc {
+ return RunCommand("Network.setBlockedURLs", map[string][]string{"urls": url})
+}
diff --git a/packages/Chrome/chrome_unix.go b/packages/Chrome/chrome_unix.go
new file mode 100644
index 0000000..70e19bc
--- /dev/null
+++ b/packages/Chrome/chrome_unix.go
@@ -0,0 +1,177 @@
+//go:build unix
+
+// Package chromedpundetected provides a chromedp context with an undetected
+// Chrome browser.
+package chromedpundetected
+
+import (
+ "context"
+ "net"
+ "os"
+ "os/exec"
+ "path"
+ "strconv"
+ "strings"
+ "syscall"
+
+ "github.com/Xuanwo/go-locale"
+ "github.com/chromedp/chromedp"
+ "github.com/google/uuid"
+ "golang.org/x/exp/slog"
+)
+
+var (
+ // DefaultUserDirPrefix Defaults.
+ DefaultUserDirPrefix = "chromedp-undetected-"
+)
+
+// New creates a context with an undetected Chrome executor.
+func New(config Config) (context.Context, context.CancelFunc, error) {
+ var opts []chromedp.ExecAllocatorOption
+
+ userDataDir := path.Join(os.TempDir(), DefaultUserDirPrefix+uuid.NewString())
+ if len(config.ChromePath) > 0 {
+ userDataDir = config.ChromePath
+ }
+
+ headlessOpts, closeFrameBuffer, err := headlessFlag(config)
+ if err != nil {
+ return nil, func() {}, err
+ }
+
+ opts = append(opts, localeFlag())
+ opts = append(opts, supressWelcomeFlag()...)
+ opts = append(opts, logLevelFlag(config))
+ opts = append(opts, debuggerAddrFlag(config)...)
+ opts = append(opts, noSandboxFlag(config)...)
+ opts = append(opts, chromedp.UserDataDir(userDataDir))
+ opts = append(opts, headlessOpts...)
+ opts = append(opts, config.ChromeFlags...)
+
+ ctx := context.Background()
+ if config.Ctx != nil {
+ ctx = config.Ctx
+ }
+
+ cancelT := func() {}
+ if config.Timeout > 0 {
+ ctx, cancelT = context.WithTimeout(ctx, config.Timeout)
+ }
+
+ ctx, cancelA := chromedp.NewExecAllocator(ctx, opts...)
+ ctx, cancelC := chromedp.NewContext(ctx, config.ContextOptions...)
+
+ cancel := func() {
+ cancelT()
+ cancelA()
+ cancelC()
+
+ if err := closeFrameBuffer(); err != nil {
+ slog.Error("failed to close Xvfb", err)
+ }
+
+ if len(config.ChromePath) == 0 {
+ _ = os.RemoveAll(userDataDir) //nolint:errcheck
+ }
+ }
+
+ return ctx, cancel, nil
+}
+
+func supressWelcomeFlag() []chromedp.ExecAllocatorOption {
+ return []chromedp.ExecAllocatorOption{
+ chromedp.Flag("no-first-run", true),
+ chromedp.Flag("no-default-browser-check", true),
+ }
+}
+
+func debuggerAddrFlag(config Config) []chromedp.ExecAllocatorOption {
+ port := strconv.Itoa(config.Port)
+ if config.Port == 0 {
+ port = getRandomPort()
+ }
+
+ return []chromedp.ExecAllocatorOption{
+ chromedp.Flag("remote-debugging-host", "127.0.0.1"),
+ chromedp.Flag("remote-debugging-port", port),
+ }
+}
+
+func localeFlag() chromedp.ExecAllocatorOption {
+ lang := "en-US"
+ if tag, err := locale.Detect(); err != nil && len(tag.String()) > 0 {
+ lang = tag.String()
+ }
+
+ return chromedp.Flag("lang", lang)
+}
+
+func noSandboxFlag(config Config) []chromedp.ExecAllocatorOption {
+ var opts []chromedp.ExecAllocatorOption
+
+ if config.NoSandbox {
+ opts = append(opts,
+ chromedp.Flag("no-sandbox", true),
+ chromedp.Flag("test-type", true))
+ }
+
+ return opts
+}
+
+func logLevelFlag(config Config) chromedp.ExecAllocatorOption {
+ return chromedp.Flag("log-level", strconv.Itoa(config.LogLevel))
+}
+
+func headlessFlag(config Config) ([]chromedp.ExecAllocatorOption, func() error, error) {
+ var opts []chromedp.ExecAllocatorOption
+
+ cleanup := func() error { return nil }
+
+ if config.Headless {
+ // Create virtual display
+ frameBuffer, err := newFrameBuffer("1920x1080x24")
+ if err != nil {
+ return nil, nil, err
+ }
+
+ cleanup = frameBuffer.Stop
+
+ opts = append(opts,
+ // chromedp.Flag("headless", true),
+ chromedp.Flag("window-size", "1920,1080"),
+ chromedp.Flag("start-maximized", true),
+ chromedp.Flag("no-sandbox", true),
+ chromedp.ModifyCmdFunc(func(cmd *exec.Cmd) {
+ cmd.Env = append(cmd.Env, "DISPLAY=:"+frameBuffer.Display)
+ cmd.Env = append(cmd.Env, "XAUTHORITY="+frameBuffer.AuthPath)
+
+ // Default modify command per chromedp
+ if _, ok := os.LookupEnv("LAMBDA_TASK_ROOT"); ok {
+ // do nothing on AWS Lambda
+ return
+ }
+
+ if cmd.SysProcAttr == nil {
+ cmd.SysProcAttr = new(syscall.SysProcAttr)
+ }
+
+ // When the parent process dies (Go), kill the child as well.
+ cmd.SysProcAttr.Pdeathsig = syscall.SIGKILL
+ }),
+ )
+ }
+
+ return opts, cleanup, nil
+}
+
+func getRandomPort() string {
+ l, err := net.Listen("tcp", "127.0.0.1:0")
+ if err == nil {
+ addr := l.Addr().String()
+ _ = l.Close() //nolint:errcheck,gosec
+
+ return strings.Split(addr, ":")[1]
+ }
+
+ return "42069"
+}
diff --git a/packages/Chrome/chrome_windows.go b/packages/Chrome/chrome_windows.go
new file mode 100644
index 0000000..f660dd1
--- /dev/null
+++ b/packages/Chrome/chrome_windows.go
@@ -0,0 +1,120 @@
+// Package chromedpundetected provides a chromedp context with an undetected
+// Chrome browser.
+package chromedpundetected
+
+import (
+ "context"
+ "net"
+ "os"
+ "path"
+ "strconv"
+ "strings"
+
+ "github.com/Xuanwo/go-locale"
+ "github.com/chromedp/chromedp"
+ "github.com/google/uuid"
+)
+
+var (
+ // DefaultUserDirPrefix Defaults.
+ DefaultUserDirPrefix = "chromedp-undetected-"
+)
+
+// New creates a context with an undetected Chrome executor.
+func New(config Config) (context.Context, context.CancelFunc, error) {
+ var opts []chromedp.ExecAllocatorOption
+
+ userDataDir := path.Join(os.TempDir(), DefaultUserDirPrefix+uuid.NewString())
+ if len(config.ChromePath) > 0 {
+ userDataDir = config.ChromePath
+ }
+
+ opts = append(opts, localeFlag())
+ opts = append(opts, supressWelcomeFlag()...)
+ opts = append(opts, logLevelFlag(config))
+ opts = append(opts, debuggerAddrFlag(config)...)
+ opts = append(opts, noSandboxFlag(config)...)
+ opts = append(opts, chromedp.UserDataDir(userDataDir))
+ opts = append(opts, config.ChromeFlags...)
+
+ ctx := context.Background()
+ if config.Ctx != nil {
+ ctx = config.Ctx
+ }
+
+ cancelT := func() {}
+ if config.Timeout > 0 {
+ ctx, cancelT = context.WithTimeout(ctx, config.Timeout)
+ }
+
+ ctx, cancelA := chromedp.NewExecAllocator(ctx, opts...)
+ ctx, cancelC := chromedp.NewContext(ctx, config.ContextOptions...)
+
+ cancel := func() {
+ cancelT()
+ cancelA()
+ cancelC()
+
+ if len(config.ChromePath) == 0 {
+ _ = os.RemoveAll(userDataDir) //nolint:errcheck
+ }
+ }
+
+ return ctx, cancel, nil
+}
+
+func supressWelcomeFlag() []chromedp.ExecAllocatorOption {
+ return []chromedp.ExecAllocatorOption{
+ chromedp.Flag("no-first-run", true),
+ chromedp.Flag("no-default-browser-check", true),
+ }
+}
+
+func debuggerAddrFlag(config Config) []chromedp.ExecAllocatorOption {
+ port := strconv.Itoa(config.Port)
+ if config.Port == 0 {
+ port = getRandomPort()
+ }
+
+ return []chromedp.ExecAllocatorOption{
+ chromedp.Flag("remote-debugging-host", "127.0.0.1"),
+ chromedp.Flag("remote-debugging-port", port),
+ }
+}
+
+func localeFlag() chromedp.ExecAllocatorOption {
+ lang := "en-US"
+ if tag, err := locale.Detect(); err != nil && len(tag.String()) > 0 {
+ lang = tag.String()
+ }
+
+ return chromedp.Flag("lang", lang)
+}
+
+func noSandboxFlag(config Config) []chromedp.ExecAllocatorOption {
+ var opts []chromedp.ExecAllocatorOption
+
+ if config.NoSandbox {
+ opts = append(opts,
+ chromedp.Flag("no-sandbox", true),
+ chromedp.Flag("test-type", true))
+ }
+
+ return opts
+}
+
+func logLevelFlag(config Config) chromedp.ExecAllocatorOption {
+ return chromedp.Flag("log-level", strconv.Itoa(config.LogLevel))
+}
+
+func getRandomPort() string {
+ l, err := net.Listen("tcp", "127.0.0.1:0")
+ if err == nil {
+ addr := l.Addr().String()
+ _ = l.Close() //nolint:errcheck,gosec
+
+ return strings.Split(addr, ":")[1]
+ }
+
+ return "42069"
+}
diff --git a/packages/Chrome/config.go b/packages/Chrome/config.go
new file mode 100644
index 0000000..dd55f13
--- /dev/null
+++ b/packages/Chrome/config.go
@@ -0,0 +1,137 @@
+package chromedpundetected
+
+import (
+ "context"
+ "time"
+
+ "github.com/chromedp/chromedp"
+)
+
+const (
+ // DefaultNoSandbox enables the 'no-sandbox' flag by default.
+ DefaultNoSandbox = true
+)
+
+// Option is a functional option.
+type Option func(*Config)
+
+// Config is a undetected Chrome config.
+type Config struct {
+ // Ctx is the base context to use. By default, a background context will be used.
+ Ctx context.Context `json:"-" yaml:"-"`
+
+ // ContextOptions are chromedp context option.
+ ContextOptions []chromedp.ContextOption `json:"-" yaml:"-"`
+
+ // ChromeFlags are additional Chrome flags to pass to the browser.
+ //
+ // NOTE: adding additional flags can make the detection unstable, so test,
+ // and be careful of what flags you add. Mostly intended to configure things
+ // like a proxy. Also check if the flags you want to set are not already set
+ // by this library.
+ ChromeFlags []chromedp.ExecAllocatorOption
+
+ // UserDataDir is the path to the directory where Chrome user data is stored.
+ //
+ // By default a temporary directory will be used.
+ UserDataDir string `json:"userDataDir" yaml:"userDataDir"`
+
+ // LogLevel is the Chrome log level, 0 by default.
+ LogLevel int `json:"logLevel" yaml:"logLevel"`
+
+ // NoSandbox dictates whether the no-sanbox flag is added. Defaults to true.
+ NoSandbox bool `json:"noSandbox" yaml:"noSandbox"`
+
+ // ChromePath is a specific binary path for Chrome.
+ //
+ // By default the chrome or chromium on your PATH will be used.
+ ChromePath string `json:"chromePath" yaml:"chromePath"`
+
+ // Port is the Chrome debugger port. By default a random port will be used.
+ Port int `json:"port" yaml:"port"`
+
+ // Timeout is the context timeout.
+ Timeout time.Duration `json:"timeout" yaml:"timeout"`
+
+ // Headless dicates whether Chrome will start headless (without a visible window)
+ //
+ // It will NOT use the '--headless' option, rather it will use a virtual display.
+ // Requires Xvfb to be installed, only available on Linux.
+ Headless bool `json:"headless" yaml:"headless"`
+}
+
+// NewConfig creates a new config object with defaults.
+func NewConfig(opts ...Option) Config {
+ c := Config{
+ NoSandbox: DefaultNoSandbox,
+ }
+
+ for _, o := range opts {
+ o(&c)
+ }
+
+ return c
+}
+
+// WithContext adds a base context.
+func WithContext(ctx context.Context) Option {
+ return func(c *Config) {
+ c.Ctx = ctx
+ }
+}
+
+// WithUserDataDir sets the user data directory to a custom path.
+func WithUserDataDir(dir string) Option {
+ return func(c *Config) {
+ c.UserDataDir = dir
+ }
+}
+
+// WithChromeBinary sets the chrome binary path.
+func WithChromeBinary(path string) Option {
+ return func(c *Config) {
+ c.ChromePath = path
+ }
+}
+
+// WithTimeout sets the context timeout.
+func WithTimeout(timeout time.Duration) Option {
+ return func(c *Config) {
+ c.Timeout = timeout
+ }
+}
+
+// WithHeadless creates a headless chrome instance.
+func WithHeadless() Option {
+ return func(c *Config) {
+ c.Headless = true
+ }
+}
+
+// WithNoSandbox enable/disable sandbox. Disabled by default.
+func WithNoSandbox(b bool) Option {
+ return func(c *Config) {
+ c.NoSandbox = b
+ }
+}
+
+// WithPort sets the chrome debugger port.
+func WithPort(port int) Option {
+ return func(c *Config) {
+ c.Port = port
+ }
+}
+
+// WithLogLevel sets the chrome log level.
+func WithLogLevel(level int) Option {
+ return func(c *Config) {
+ c.LogLevel = level
+ }
+}
+
+// WithChromeFlags add chrome flags.
+func WithChromeFlags(opts ...chromedp.ExecAllocatorOption) Option {
+ return func(c *Config) {
+ c.ChromeFlags = append(c.ChromeFlags, opts...)
+ }
+}
diff --git a/packages/Chrome/display_unix.go b/packages/Chrome/display_unix.go
new file mode 100644
index 0000000..6509f6d
--- /dev/null
+++ b/packages/Chrome/display_unix.go
@@ -0,0 +1,165 @@
+//go:build unix
+
+package chromedpundetected
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "os"
+ "os/exec"
+ "regexp"
+ "strconv"
+ "strings"
+ "syscall"
+ "time"
+
+ "golang.org/x/exp/slog"
+)
+
+// Errors.
+var (
+ ErrXvfbNotFound = errors.New("xvfb not found. Please install (Linux only)")
+)
+
+// frameBuffer controls an X virtual frame buffer running as a background
+// process.
+type frameBuffer struct {
+ // Display is the X11 display number that the Xvfb process is hosting
+ // (without the preceding colon).
+ Display string
+
+ // AuthPath is the path to the X11 authorization file that permits X clients
+ // to use the X server. This is typically provided to the client via the
+ // XAUTHORITY environment variable.
+ AuthPath string
+
+ cmd *exec.Cmd
+}
+
+// newFrameBuffer starts an X virtual frame buffer running in the background.
+// FrameBufferOptions may be populated to change the behavior of the frame buffer.
+func newFrameBuffer(screenSize string) (*frameBuffer, error) { //nolint:funlen
+ if err := exec.Command("which", "Xvfb").Run(); err != nil {
+ return nil, ErrXvfbNotFound
+ }
+
+ pipeReader, pipeWriter, err := os.Pipe()
+ if err != nil {
+ return nil, err
+ }
+
+ defer func() {
+ if err = pipeReader.Close(); err != nil {
+ slog.Error("failed to close pipe reader", err)
+ }
+ }()
+
+ authPath, err := tempFile("chromedp-xvfb")
+ if err != nil {
+ return nil, err
+ }
+
+ // Xvfb will print the display on which it is listening to file descriptor 3,
+ // for which we provide a pipe.
+ arguments := []string{"-displayfd", "3", "-nolisten", "tcp"}
+
+ if screenSize != "" {
+ screenSizeExpression := regexp.MustCompile(`^\d+x\d+(?:x\d+)$`)
+ if !screenSizeExpression.MatchString(screenSize) {
+ return nil, fmt.Errorf("invalid screen size: expected 'WxH[xD]', got %q", screenSize)
+ }
+
+ arguments = append(arguments, "-screen", "0", screenSize)
+ }
+
+ xvfb := exec.Command("Xvfb", arguments...)
+ xvfb.ExtraFiles = []*os.File{pipeWriter}
+ xvfb.Env = append(xvfb.Env, "XAUTHORITY="+authPath)
+
+ if xvfb.SysProcAttr == nil {
+ xvfb.SysProcAttr = new(syscall.SysProcAttr)
+ }
+
+ xvfb.SysProcAttr.Pdeathsig = syscall.SIGKILL
+
+ if err := xvfb.Start(); err != nil {
+ return nil, err
+ }
+
+ if err := pipeWriter.Close(); err != nil {
+ return nil, err
+ }
+
+ type resp struct {
+ display string
+ err error
+ }
+
+ ch := make(chan resp)
+
+ go func() {
+ bufr := bufio.NewReader(pipeReader)
+ s, err := bufr.ReadString('\n')
+ ch <- resp{s, err}
+ }()
+
+ var display string
+ select {
+ case resp := <-ch:
+ if resp.err != nil {
+ return nil, resp.err
+ }
+
+ display = strings.TrimSpace(resp.display)
+ if _, err := strconv.Atoi(display); err != nil {
+ return nil, errors.New("xvfb did not print the display number")
+ }
+
+ case <-time.After(10 * time.Second):
+ return nil, errors.New("timeout waiting for Xvfb")
+ }
+
+ xauth := exec.Command("xauth", "generate", ":"+display, ".", "trusted") //nolint:gosec
+ xauth.Env = append(xauth.Env, "XAUTHORITY="+authPath)
+ // Make this conditional?
+ xauth.Stderr = os.Stderr
+ xauth.Stdout = os.Stdout
+
+ if err := xauth.Run(); err != nil {
+ return nil, err
+ }
+
+ return &frameBuffer{display, authPath, xvfb}, nil
+}
+
+// Stop kills the background frame buffer process and removes the X
+// authorization file.
+func (f frameBuffer) Stop() error {
+ if err := f.cmd.Process.Kill(); err != nil {
+ return err
+ }
+
+ _ = os.Remove(f.AuthPath) //nolint:errcheck
+
+ if err := f.cmd.Wait(); err != nil && err.Error() != "signal: killed" {
+ return err
+ }
+
+ return nil
+}
+
+func tempFile(pattern string) (string, error) {
+ tempFile, err := os.CreateTemp("", pattern)
+ if err != nil {
+ return "", err
+ }
+
+ fileName := tempFile.Name()
+
+ if err := tempFile.Close(); err != nil {
+ return "", err
+ }
+
+ return fileName, nil
+}
diff --git a/packages/Chrome/scripts/test.sh b/packages/Chrome/scripts/test.sh
new file mode 100644
index 0000000..44bb364
--- /dev/null
+++ b/packages/Chrome/scripts/test.sh
@@ -0,0 +1,263 @@
+#!/bin/bash
+
+GO_TEST_FLAGS="-v -race -cover -bench=."
+
+RED='\033[0;31m'
+NC='\033[0m'
+GREEN='\033[0;32m'
+BAR="-------------------------------------------------------------------------------"
+HAS_DEPS=()
+
+export RICHGO_FORCE_COLOR="true"
+
+# Print a green colored message to the screen.
+function print_msg() {
+ printf "\n\n${GREEN}${BAR}${NC}\n"
+ printf "${GREEN}| > ${1}${NC}\n"
+ printf "${GREEN}${BAR}${NC}\n\n"
+ sleep 1
+}
+
+# Print a red colored message to the screen.
+function print_red() {
+ printf "\n\n${RED}${BAR}${NC}\n"
+ printf "${RED}| > ${1}${NC}\n"
+ printf "${RED}${BAR}${NC}\n\n"
+ sleep 1
+}
+
+# Print the contents of the directory array.
+function print_list() {
+ dirs=$1
+
+ print_msg "Found ${#dirs[@]} directories to test"
+ echo "Changed dirs:"
+ printf '%s \n' "${dirs[@]}"
+ printf '\n\n'
+ sleep 1
+}
+
+# Add a job summary to GitHub Actions.
+function add_summary() {
+ printf "${1}\n" >>$GITHUB_STEP_SUMMARY
+}
+
+# Install dependencies, usually servers.
+#
+# Can can be used to run an script needed to complete tests.
+#
+# To run a script add it to the HAS_DEPS variable, e.g.: ("redis" "nats").
+# And make sure to add a script to deps/.sh
+function install_deps() {
+ for dep in "${HAS_DEPS[@]}"; do
+ if grep -q "${dep}" <<<"${1}"; then
+ script="scripts/deps/${dep}.sh"
+
+ # Check if script exists
+ if [[ -f ${script} ]]; then
+ echo "Installing depencies for $dep"
+ bash "${script}"
+ echo "$dep"
+ return 0
+ fi
+ fi
+ done
+}
+
+# Kill all PIDs of setups.
+function kill_deps() {
+ for dep in "${HAS_DEPS[@]}"; do
+ if grep -q "${dep}" <<<"${1}"; then
+ # Itterate over all PIDs and kill them.
+ pids=($(pgrep "$dep"))
+ if [[ ${#pids[@]} -ne 0 ]]; then
+ echo "Killing:"
+ fi
+
+ for dep_pid in "${pids[@]}"; do
+ ps -aux | grep -v "grep" | grep "${dep_pid}"
+
+ kill "${dep_pid}"
+ return 0
+ done
+ fi
+ done
+}
+
+# Find directories that contain changes.
+function find_changes() {
+ # Find all directories that have changed files.
+ changes=($(git diff --name-only origin/main | xargs -d'\n' -I{} dirname {} | sort -u))
+
+ # Filter out directories without go.mod files.
+ changes=($(find "${changes[@]}" -maxdepth 1 -name 'go.mod' -printf '%h\n'))
+
+ echo "${changes[@]}"
+}
+
+# Find all go directories.
+function find_all() {
+ find . -name 'go.mod' -printf '%h\n'
+}
+
+# Get the dir list based on command type.
+function get_dirs() {
+ if [[ $1 == "all" ]]; then
+ find_all
+ else
+ find_changes
+ fi
+}
+
+# Run GoLangCi Linters.
+function run_linter() {
+ curl -sSfL "https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh" | sh -s -- -b $(go env GOPATH)/bin
+
+ echo
+ golangci-lint --version
+
+ cwd=$(pwd)
+ dirs=$1
+ failed="false"
+ for dir in "${dirs[@]}"; do
+ pushd "${dir}" >/dev/null
+ print_msg "Running linter on ${dir}"
+
+ golangci-lint run --out-format github-actions -c "${cwd}/.golangci.yaml"
+
+ # Keep track of exit code of linter
+ if [[ $? -ne 0 ]]; then
+ failed="true"
+ fi
+
+ popd >/dev/null
+ done
+
+ if [[ $failed == "true" ]]; then
+ add_summary "## Autofix Linting Issues"
+ add_summary "The linter can sometimes autofix some of the issues, if it is supported."
+ add_summary "\`\`\`bash\ncd \ngolangci-lint run -c /.golangci.yaml --fix\n\`\`\`"
+ print_red "Linter failed"
+ exit 1
+ else
+ print_msg "Linter found no issues"
+ fi
+}
+
+# Run Unit tests with RichGo for pretty output.
+function run_test() {
+ cwd=$(pwd)
+ dirs=$1
+ failed="false"
+
+ print_msg "Downloading dependencies..."
+
+ go install github.com/kyoh86/richgo@latest
+
+ for dir in "${dirs[@]}"; do
+ bash -c "cd ${dir}; go mod tidy &>/dev/null"
+ done
+
+ for dir in "${dirs[@]}"; do
+ print_msg "Running unit tests for $dir"
+
+ # Install dependencies if required.
+ install_deps "${dir}"
+
+ pushd "${dir}" >/dev/null
+
+ # Download all modules.
+ go get -v -t -d ./...
+
+ # Run tests.
+ richgo test $GO_TEST_FLAGS ./...
+
+ # Keep track of exit code.
+ if [[ $? -ne 0 ]]; then
+ failed="true"
+ fi
+
+ popd >/dev/null
+
+ # Kill all depdency processes.
+ kill_deps "${dir}"
+ done
+
+ if [[ $failed == "true" ]]; then
+ print_red "Tests failed"
+ exit 1
+ fi
+}
+
+# Run unit tests with tparse to create a summary.
+function create_summary() {
+ go install github.com/mfridman/tparse@latest
+
+ add_summary "## Test Summary"
+
+ cwd=$(pwd)
+ dirs=$1
+ failed="false"
+ for dir in "${dirs[@]}"; do
+ # Install dependencies if required.
+ install_deps "${dir}"
+
+ pushd "${dir}" >/dev/null
+ print_msg "Creating summary for $dir"
+
+ add_summary "\n### ${dir}\n"
+
+ # Download all modules.
+ go get -v -t -d ./...
+
+ go test $GO_TEST_FLAGS -json ./... |
+ tparse -notests -format=markdown >>$GITHUB_STEP_SUMMARY
+
+ if [[ $? -ne 0 ]]; then
+ failed="true"
+ fi
+
+ popd >/dev/null
+
+ # Kill all depdency processes.
+ kill_deps "${dir}"
+ done
+
+ if [[ $failed == "true" ]]; then
+ print_red "Tests failed"
+ exit 1
+ fi
+}
+
+case $1 in
+"lint")
+ dirs=($(get_dirs "${2}"))
+ [[ ${#dirs[@]} -eq 0 ]] && print_red "No changed Go files detected" && exit 0
+
+ print_list "${dirs[@]}"
+ run_linter "${dirs[@]}"
+ ;;
+"test")
+ dirs=($(get_dirs "${2}"))
+ [[ ${#dirs[@]} -eq 0 ]] && print_red "No changed Go files detected" && exit 0
+
+ print_list "${dirs[@]}"
+
+ run_test "${dirs[@]}"
+ ;;
+"summary")
+ dirs=($(get_dirs "${2}"))
+ [[ ${#dirs[@]} -eq 0 ]] && print_red "No changed Go files detected" && exit 0
+
+ print_list "${dirs[@]}"
+ create_summary "${dirs[@]}"
+ ;;
+"")
+ printf "Please provide a command [lint, test, summary]."
+ exit 1
+ ;;
+*)
+ printf "Command not found: $1. Select one of [lint, test, summary]"
+ exit 1
+ ;;
+esac
diff --git a/packages/Chrome/util/easyjson/easyjson.go b/packages/Chrome/util/easyjson/easyjson.go
new file mode 100644
index 0000000..cacaa48
--- /dev/null
+++ b/packages/Chrome/util/easyjson/easyjson.go
@@ -0,0 +1,38 @@
+// Package easyjson provides utilities for use with easyjson.
+package easyjson
+
+import (
+ "encoding/json"
+
+ "github.com/mailru/easyjson"
+ "github.com/mailru/easyjson/jlexer"
+ "github.com/mailru/easyjson/jwriter"
+)
+
+var _ easyjson.MarshalerUnmarshaler = (*GenericEJ[any])(nil)
+
+// New creates a new geneic EasyJSON container.
+func New[T any](data T) *GenericEJ[T] {
+ return &GenericEJ[T]{data}
+}
+
+// GenericEJ is a type that uses the stdlib json (un)marshaler to make any
+// type compatible with easyjson by implementing the EasyJSON interfaces.
+type GenericEJ[T any] struct {
+ Data T
+}
+
+// MarshalEasyJSON marshals any type to json with use of the stdlib json pkg.
+func (t *GenericEJ[T]) MarshalEasyJSON(w *jwriter.Writer) {
+ b, err := json.Marshal(t.Data)
+
+ w.Buffer.AppendBytes(b)
+ w.Error = err
+}
+
+// UnmarshalEasyJSON unmarshals any type from json with use of the stdlib json pkg.
+func (t *GenericEJ[T]) UnmarshalEasyJSON(w *jlexer.Lexer) {
+ if err := json.Unmarshal(w.Data, &t.Data); err != nil {
+ w.AddError(err)
+ }
+}
diff --git a/packages/Chrome/util/easyjson/easyjson_test.go b/packages/Chrome/util/easyjson/easyjson_test.go
new file mode 100644
index 0000000..f2e8150
--- /dev/null
+++ b/packages/Chrome/util/easyjson/easyjson_test.go
@@ -0,0 +1,41 @@
+package easyjson
+
+import (
+ "testing"
+
+ "github.com/mailru/easyjson"
+ "github.com/stretchr/testify/require"
+)
+
+func TestEasyJSONMap(t *testing.T) {
+ a := map[string]any{
+ "one": 1.8,
+ "two": "two",
+ }
+
+ b := New(a)
+
+ j, err := easyjson.Marshal(b)
+ require.NoError(t, err, "marshal")
+ t.Log(string(j))
+
+ n := New(map[string]any{})
+
+ require.NoError(t, easyjson.Unmarshal(j, n))
+ require.Equal(t, a, n.Data)
+}
+
+func TestEasyJSONSlice(t *testing.T) {
+ a := []string{"a", "b", "c", "d"}
+
+ b := New(a)
+
+ j, err := easyjson.Marshal(b)
+ require.NoError(t, err, "marshal")
+ t.Log(string(j))
+
+ n := New([]string{})
+
+ require.NoError(t, easyjson.Unmarshal(j, n))
+ require.Equal(t, a, n.Data)
+}
diff --git a/packages/StrCmd/main.go b/packages/StrCmd/main.go
new file mode 100644
index 0000000..3612e6e
--- /dev/null
+++ b/packages/StrCmd/main.go
@@ -0,0 +1,286 @@
+package StrCmd
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "strconv"
+ "strings"
+)
+
+var Current CommandArgs
+
+func (Data *App) ParseCommand(Text string) error {
+ var Args CommandArgs
+ var Default Command
+ var Names string
+ var ParsedNames []string = strings.Split(Text, " ")
+ var GennedArg = []GennedArgs{}
+
+ for _, names := range ParsedNames {
+ if d, ok := Data.Commands[names]; ok {
+ Default = d
+ Names = names
+ }
+ }
+ if len(Default.Args) > 0 {
+ var l int
+ for _, a := range Default.Args {
+ if strings.Contains(Text, a) {
+ l++
+ }
+ }
+ for i, Args := range Default.Args {
+ if strings.Contains(Text, Args) {
+ if strings.Contains(Args, "--") {
+ GennedArg = append(GennedArg, GennedArgs{
+ Name: Args,
+ Value: "true",
+ IsBool: strings.Contains(Args, "--"),
+ })
+ } else {
+ var Name string
+ if l <= len(Default.Args) && i+1 != len(Default.Args) && i+1 <= l {
+ Name = strings.TrimSpace(strings.Split(strings.Split(Text, Args)[1], Default.Args[i+1])[0])
+ } else {
+ Name = strings.TrimSpace(strings.Split(Text, Args)[1])
+ }
+ for _, d := range Default.Args {
+ if strings.Contains(Name, d) {
+ Name = strings.TrimRight(strings.ReplaceAll(Name, d, ""), " ")
+ }
+ }
+ GennedArg = append(GennedArg, GennedArgs{
+ Name: Args,
+ Value: Name,
+ IsBool: strings.Contains(Name, "--"),
+ })
+ }
+ }
+ }
+ Args = CommandArgs{
+ Name: Names,
+ Args: GennedArg,
+ }
+ }
+
+ var UsingSub bool
+
+ if Default.Subcommand != nil {
+ var UptoDate SubCmd
+ for _, names := range ParsedNames {
+ if d, ok := Default.Subcommand[names]; ok {
+ UptoDate = d
+ UsingSub = true
+ Names = names
+ break
+ }
+ }
+ if UsingSub {
+ if len(UptoDate.Args) > 0 {
+ var l int
+ for _, a := range UptoDate.Args {
+ if strings.Contains(Text, a) {
+ l++
+ }
+ }
+ for i, Args := range UptoDate.Args {
+ if strings.Contains(Text, Args) {
+ if strings.Contains(Args, "--") {
+ GennedArg = append(GennedArg, GennedArgs{
+ Name: Args,
+ Value: "true",
+ IsBool: strings.Contains(Args, "--"),
+ })
+ } else {
+ var Name string
+ if l <= len(UptoDate.Args) && i+1 != len(UptoDate.Args) && i+1 <= l {
+ Name = strings.TrimSpace(strings.Split(strings.Split(Text, Args)[1], UptoDate.Args[i+1])[0])
+ } else {
+ Name = strings.TrimSpace(strings.Split(Text, Args)[1])
+ }
+ for _, d := range UptoDate.Args {
+ if strings.Contains(Name, d) {
+ Name = strings.TrimRight(strings.ReplaceAll(Name, d, ""), " ")
+ }
+ }
+ GennedArg = append(GennedArg, GennedArgs{
+ Name: Args,
+ Value: Name,
+ IsBool: strings.Contains(Name, "--"),
+ })
+ }
+ }
+ }
+ Args = CommandArgs{
+ Name: Names,
+ Args: GennedArg,
+ }
+ }
+ }
+
+ Current = Args
+ if UptoDate.Action != nil {
+ UptoDate.Action()
+ }
+ }
+
+ if !UsingSub {
+ if !Data.DontUseBuiltinHelpCmd {
+ if strings.HasPrefix(Text, "help") {
+ fmt.Println(Data.FormatHelpText())
+ }
+ }
+ Current = Args
+ if Default.Action != nil {
+ Default.Action()
+ }
+ }
+
+ return nil
+}
+
+func (Data *App) FormatHelpText() (Base string) {
+ if Data.Version != "" {
+ Base += fmt.Sprintf("VERSION: %v\n\n", Data.Version)
+ } else {
+ Base += "VERSION: 1.0.0\n\n"
+ }
+ if Data.AppDescription != "" {
+ Base += "Description: " + Data.AppDescription + "\n\n"
+ }
+ Base += ReturnCommandInfo(Data.Commands, " [ARGS")
+ return
+}
+
+func ReturnCommandInfo(Value map[string]Command, Format string) (Base string) {
+ for name, key := range Value {
+ if key.Description == "" {
+ key.Description = "A global command that is parsed through StrCmd (Description was empty!)"
+ }
+
+ var B string = Format
+ D := " SUBCMD(S)\n"
+ var S string = D
+ if len(key.Args) > 0 {
+ for _, name := range key.Args {
+ B += " " + name
+ }
+ B += "]"
+ }
+
+ for name, key := range key.Subcommand {
+ if key.Description == "" {
+ key.Description = "A global command that is parsed through StrCmd (Description was empty!)"
+ }
+
+ var B string = Format
+ if len(key.Args) > 0 {
+ for _, name := range key.Args {
+ B += " " + name
+ }
+ B += "]"
+ }
+
+ if B != Format {
+ S += fmt.Sprintf(" + %v | %v%v\n", name, key.Description, B)
+ } else {
+ S += fmt.Sprintf(" + %v | %v\n", name, key.Description)
+ }
+ }
+
+ switch {
+ case B != Format && S != D:
+ Base += fmt.Sprintf("- %v | %v%v\n%v", name, key.Description, B, S)
+ case S != D:
+ Base += fmt.Sprintf("- %v | %v\n%v", name, key.Description, S)
+ case B != Format:
+ Base += fmt.Sprintf("- %v | %v%v\n", name, key.Description, B)
+ default:
+ Base += fmt.Sprintf("- %v | %v\n", name, key.Description)
+ }
+ }
+ return
+}
+
+func (D *App) Run() error {
+ for {
+ if err := D.ParseCommand(Listen(true, D.Display)); err != nil {
+ return err
+ }
+ }
+}
+
+func (D *App) Input(inputin string) error {
+ if err := D.ParseCommand(inputin); err != nil {
+ return err
+ }
+ return nil
+}
+
+func Listen(show bool, input string) string {
+ fmt.Print(input)
+ scanner := bufio.NewScanner(os.Stdin)
+ scanner.Scan()
+ return scanner.Text()
+}
+
+func String(Arg string) string {
+ for _, arg := range Current.Args {
+ if arg.Name == Arg {
+ return arg.Value
+ }
+ }
+ return ""
+}
+
+func Int(Arg string) int {
+ for _, arg := range Current.Args {
+ if arg.Name == Arg {
+ if value, err := strconv.Atoi(arg.Value); err == nil {
+ return value
+ }
+ }
+ }
+ return 0
+}
+
+func Bool(Arg string) bool {
+ for _, arg := range Current.Args {
+ if arg.Name == Arg && arg.IsBool {
+ return true
+ }
+ }
+ return false
+}
+
+func Interface(Arg string) interface{} {
+ for _, arg := range Current.Args {
+ if arg.Name == Arg {
+ return arg.Value
+ }
+ }
+ return nil
+}
+
+func Float64(Arg string) float64 {
+ for _, arg := range Current.Args {
+ if arg.Name == Arg {
+ if s, err := strconv.ParseFloat(arg.Value, 64); err == nil {
+ return s
+ }
+ }
+ }
+ return 0
+}
+
+func Float32(Arg string) float64 {
+ for _, arg := range Current.Args {
+ if arg.Name == Arg {
+ if s, err := strconv.ParseFloat(arg.Value, 32); err == nil {
+ return s
+ }
+ }
+ }
+ return 0
+}
diff --git a/packages/StrCmd/types.go b/packages/StrCmd/types.go
new file mode 100644
index 0000000..6418508
--- /dev/null
+++ b/packages/StrCmd/types.go
@@ -0,0 +1,34 @@
+package StrCmd
+
+type App struct {
+ Display string
+ Commands map[string]Command
+ Version string
+ AppDescription string
+ DontUseBuiltinHelpCmd bool
+ Args []CommandArgs
+}
+
+type Command struct {
+ Description string
+ Subcommand map[string]SubCmd
+ Args []string
+ Action func()
+}
+
+type SubCmd struct {
+ Description string
+ Args []string
+ Action func()
+}
+
+type CommandArgs struct {
+ Name string
+ Args []GennedArgs
+}
+
+type GennedArgs struct {
+ Name string
+ Value string
+ IsBool bool
+}
diff --git a/packages/apiGO/mcsn.go b/packages/apiGO/mcsn.go
new file mode 100644
index 0000000..02f5ebc
--- /dev/null
+++ b/packages/apiGO/mcsn.go
@@ -0,0 +1,319 @@
+package apiGO
+
+import (
+ "bytes"
+ "crypto/tls"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "net/http/cookiejar"
+ "net/url"
+ "os"
+ "os/exec"
+ "regexp"
+ "runtime"
+ "strconv"
+ "strings"
+ "time"
+
+ "main/packages/h2"
+
+ tls2 "github.com/bogdanfinn/utls"
+)
+
+func (accountBearer MCbearers) CreatePayloads(name string) (Data Payload) {
+ for _, bearer := range accountBearer.Details {
+ if bearer.AccountType == "Giftcard" {
+ Data.Payload = append(Data.Payload, fmt.Sprintf("POST /minecraft/profile HTTP/1.1\r\nHost: api.minecraftservices.com\r\nConnection: open\r\nContent-Length:%s\r\nContent-Type: application/json\r\nAccept: application/json\r\nAuthorization: Bearer %s\r\n\r\n"+string([]byte(`{"profileName":"`+name+`"}`))+"\r\n", strconv.Itoa(len(string([]byte(`{"profileName":"`+name+`"}`)))), bearer.Bearer))
+ } else {
+ Data.Payload = append(Data.Payload, "PUT /minecraft/profile/name/"+name+" HTTP/1.1\r\nHost: api.minecraftservices.com\r\nUser-Agent: MCSN/1.0\r\nContent-Length:0\r\nAuthorization: bearer "+bearer.Bearer+"\r\n\r\n")
+ }
+ }
+
+ return
+}
+
+func Sleep(dropTime int64, delay float64) {
+ time.Sleep(time.Until(time.Unix(dropTime, 0).Add(time.Millisecond * time.Duration(0-delay)).Add(time.Duration(-float64(time.Since(time.Now()).Nanoseconds())/1000000.0) * time.Millisecond)))
+}
+
+func GetConfig(owo []byte) (Config map[string]interface{}) {
+ json.Unmarshal(owo, &Config)
+ return
+}
+
+func Sum(array []float64) (sum float64) {
+ for _, ammount := range array {
+ sum = sum + ammount
+ }
+
+ return
+}
+
+func CheckChange(bearer string, PS *h2.ProxyAuth) bool {
+ var Conn h2.Conn
+ var err error
+ if PS != nil {
+ Conn, err = (&h2.Client{Config: h2.GetDefaultConfig()}).Connect("https://api.minecraftservices.com/minecraft/profile/namechange", h2.ReqConfig{ID: 1, BuildID: tls2.HelloChrome_112, DataBodyMaxLength: 1609382, Proxy: PS})
+ } else {
+ Conn, err = (&h2.Client{Config: h2.GetDefaultConfig()}).Connect("https://api.minecraftservices.com/minecraft/profile/namechange", h2.ReqConfig{ID: 1, BuildID: tls2.HelloChrome_112, DataBodyMaxLength: 1609382})
+ }
+ if err != nil {
+ return false
+ } else {
+ Conn.AddHeader("Authorization", "Bearer "+bearer)
+ if resp, err := Conn.Do("GET", "", "", nil); err == nil {
+ switch resp.Status {
+ case "200":
+ var Data struct {
+ NC bool `json:"nameChangeAllowed"`
+ }
+ json.Unmarshal(resp.Data, &Data)
+ return Data.NC
+ case "404":
+ return true
+ default:
+ return false
+ }
+ } else {
+ return false
+ }
+ }
+}
+
+func SocketSending(conn *tls.Conn, payload string) Resp {
+ fmt.Fprintln(conn, payload)
+ sendTime := time.Now()
+ recvd := make([]byte, 4069)
+ conn.Read(recvd)
+ return Resp{
+ RecvAt: time.Now(),
+ StatusCode: string(recvd[9:12]),
+ SentAt: sendTime,
+ Body: string(recvd),
+ }
+}
+
+func ChangeSkin(body []byte, bearer string) (Req *http.Response, err error) {
+ resp, err := http.NewRequest("POST", "https://api.minecraftservices.com/minecraft/profile/skins", bytes.NewBuffer(body))
+ if err != nil {
+ return nil, err
+ }
+
+ resp.Header.Set("Authorization", "bearer "+bearer)
+
+ Req, err = http.DefaultClient.Do(resp)
+ if err != nil {
+ return nil, err
+ }
+
+ return
+}
+
+var (
+ UrlPost = regexp.MustCompile(`urlPost:'(.+?)'`)
+ Value = regexp.MustCompile(`value="(.*?)"`)
+ User_Authenticate = `{"Properties": {"AuthMethod": "RPS", "SiteName": "user.auth.xboxlive.com", "RpsTicket": "%v"}, "RelyingParty": "http://auth.xboxlive.com", "TokenType": "JWT"}`
+ Xsts_Authenticate = `{"Properties": {"SandboxId": "RETAIL", "UserTokens": ["%v"]}, "RelyingParty": "rp://api.minecraftservices.com/", "TokenType": "JWT"}`
+ Login_With_Xbox = `{"identityToken" : "XBL3.0 x=%v;%v", "ensureLegacyEnabled" : true}`
+)
+
+type ProxyMS struct {
+ IP string
+ Port string
+ User string
+ Password string
+}
+
+func MS_authentication(e, p string, PS *ProxyMS) (returnDetails Info) {
+ redirect, bearerMS := "", mojangData{}
+ if jar, err := cookiejar.New(nil); err == nil {
+ Client := &http.Client{CheckRedirect: func(req *http.Request, via []*http.Request) error { redirect = req.URL.String(); return nil }, Transport: &http.Transport{TLSClientConfig: &tls.Config{Renegotiation: tls.RenegotiateFreelyAsClient}}, Jar: jar}
+ if resp, err := Client.Get("https://login.live.com/oauth20_authorize.srf?client_id=000000004C12AE6F&redirect_uri=https://login.live.com/oauth20_desktop.srf&scope=service::user.auth.xboxlive.com::MBI_SSL&display=touch&response_type=token&locale=en"); err == nil {
+ jar.Cookies(resp.Request.URL)
+ body := ReturnJustString(io.ReadAll(resp.Body))
+ var v, u string
+ if Data := Value.FindAllStringSubmatch(string(body), -1); len(Data) > 0 && len(Data[0]) > 0 {
+ v = Data[0][1]
+ } else {
+ fmt.Println("entered reauth for "+e, "Error occured From VALUE find")
+ returnDetails = MS_authentication(e, p, PS)
+ }
+ if Data := UrlPost.FindAllStringSubmatch(string(body), -1); len(Data) > 0 && len(Data[0]) > 0 {
+ u = Data[0][1]
+ } else {
+ fmt.Println("entered reauth for "+e, "Error occured from getting UrlPost")
+ returnDetails = MS_authentication(e, p, PS)
+ }
+ Client.Post(u, "application/x-www-form-urlencoded", bytes.NewReader([]byte(fmt.Sprintf("login=%v&loginfmt=%v&passwd=%v&PPFT=%v", url.QueryEscape(e), url.QueryEscape(e), url.QueryEscape(p), v))))
+ if strings.Contains(redirect, "access_token") {
+ if d, err := Client.Post("https://user.auth.xboxlive.com/user/authenticate", "application/json", bytes.NewBuffer([]byte(fmt.Sprintf(User_Authenticate, strings.Split(strings.Split(strings.Split(redirect, "#")[1], "&")[0], "=")[1])))); err == nil {
+ var TOKEN string
+ Body := ReturnJustString(io.ReadAll(d.Body))
+ if strings.Contains(Body, `"Token":"`) {
+ TOKEN = strings.Split(strings.Split(Body, `"Token":"`)[1], `"`)[0]
+ if x, err := Client.Post("https://xsts.auth.xboxlive.com/xsts/authorize", "application/json", bytes.NewBuffer([]byte(fmt.Sprintf(Xsts_Authenticate, TOKEN)))); err == nil {
+ x_data := ReturnJustString(io.ReadAll(x.Body))
+ if x.StatusCode == 401 && strings.Contains(string(x_data), "XErr") {
+ switch true {
+ case strings.Contains(string(x_data), "2148916238"):
+ returnDetails = Info{Email: e, Password: p, Error: "Account belongs to someone under 18 and needs to be added to a family"}
+ return
+ case strings.Contains(string(x_data), "2148916233"):
+ returnDetails = Info{Email: e, Password: p, Error: "Account has no Xbox account, you must sign up for one first"}
+ return
+ }
+ } else {
+ if PS != nil {
+ var UHS, TOKEN string
+ if strings.Contains(string(x_data), `"uhs":"`) {
+ UHS = strings.Split(strings.Split(string(x_data), `"uhs":"`)[1], `"`)[0]
+ } else {
+ returnDetails = MS_authentication(e, p, PS)
+ return
+ }
+ if strings.Contains(string(x_data), `"Token":"`) {
+ TOKEN = strings.Split(strings.Split(string(x_data), `"Token":"`)[1], `"`)[0]
+ } else {
+ returnDetails = MS_authentication(e, p, PS)
+ return
+ }
+ req, _ := http.NewRequest("POST", "https://api.minecraftservices.com/authentication/login_with_xbox", bytes.NewBufferString(fmt.Sprintf(Login_With_Xbox, UHS, TOKEN)))
+ if resp, err := (&http.Client{Timeout: time.Second * 60, Transport: &http.Transport{Proxy: http.ProxyURL(&url.URL{Scheme: "http", Host: PS.IP + ":" + PS.Port, User: url.UserPassword(PS.User, PS.Password)})}}).Do(req); err == nil {
+ switch resp.StatusCode {
+ case 200:
+ body, _ := io.ReadAll(resp.Body)
+ json.Unmarshal([]byte(ReturnJustString(io.ReadAll(bytes.NewBuffer(body)))), &bearerMS)
+ Info_MCINFO, AccT := ReturnAll(bearerMS.Bearer_MS, PS)
+ returnDetails = Info{Info: Info_MCINFO, Bearer: bearerMS.Bearer_MS, AccessToken: strings.Split(strings.Split(redirect, "access_token=")[1], "&")[0], RefreshToken: strings.Split(strings.Split(redirect, "refresh_token=")[1], "&")[0], Expires: ReturnJustInt(strconv.Atoi(strings.Split(strings.Split(redirect, "expires_in=")[1], "&")[0])), Email: e, Password: p, AccountType: AccT}
+ case 429:
+ fmt.Printf("[%v] %v Has been ratelimited, sleeping for 1 minute..\n", resp.Status, e)
+ time.Sleep(60 * time.Second)
+ returnDetails = MS_authentication(e, p, PS)
+ default:
+ body, _ := io.ReadAll(resp.Body)
+ returnDetails = Info{Email: e, Password: p, Error: fmt.Sprintf("[%v] Unknown status code while authenticating.\n%v", resp.Status, string(body))}
+ }
+ } else {
+ returnDetails = Info{Email: e, Password: p, Error: err.Error()}
+ }
+ } else {
+ var UHS, TOKEN string
+ if strings.Contains(string(x_data), `"uhs":"`) {
+ UHS = strings.Split(strings.Split(string(x_data), `"uhs":"`)[1], `"`)[0]
+ } else {
+ returnDetails = MS_authentication(e, p, PS)
+ return
+ }
+ if strings.Contains(string(x_data), `"Token":"`) {
+ TOKEN = strings.Split(strings.Split(string(x_data), `"Token":"`)[1], `"`)[0]
+ } else {
+ returnDetails = MS_authentication(e, p, PS)
+ return
+ }
+ if resp, err := http.Post("https://api.minecraftservices.com/authentication/login_with_xbox", "application/json", bytes.NewBuffer([]byte(fmt.Sprintf(Login_With_Xbox, UHS, TOKEN)))); err == nil {
+ switch resp.StatusCode {
+ case 200:
+ body, _ := io.ReadAll(resp.Body)
+ json.Unmarshal([]byte(ReturnJustString(io.ReadAll(bytes.NewBuffer(body)))), &bearerMS)
+ Info_MCINFO, AccT := ReturnAll(bearerMS.Bearer_MS, nil)
+ returnDetails = Info{Info: Info_MCINFO, Bearer: bearerMS.Bearer_MS, AccessToken: strings.Split(strings.Split(redirect, "access_token=")[1], "&")[0], RefreshToken: strings.Split(strings.Split(redirect, "refresh_token=")[1], "&")[0], Expires: ReturnJustInt(strconv.Atoi(strings.Split(strings.Split(redirect, "expires_in=")[1], "&")[0])), Email: e, Password: p, AccountType: AccT}
+ case 429:
+ fmt.Printf("[%v] %v Has been ratelimited, sleeping for 1 minute..\n", resp.Status, e)
+ time.Sleep(60 * time.Second)
+ returnDetails = MS_authentication(e, p, PS)
+ default:
+ body, _ := io.ReadAll(resp.Body)
+ returnDetails = Info{Email: e, Password: p, Error: fmt.Sprintf("[%v] Unknown status code while authenticating.\n%v", resp.Status, string(body))}
+ }
+ } else {
+ returnDetails = Info{Email: e, Password: p, Error: err.Error()}
+ }
+ }
+ }
+ } else {
+ returnDetails = Info{Email: e, Password: p, Error: err.Error()}
+ }
+ } else {
+ returnDetails = MS_authentication(e, p, PS)
+ }
+ } else {
+ returnDetails = Info{Email: e, Password: p, Error: err.Error()}
+ }
+ } else {
+ returnDetails = Info{Email: e, Password: p, Error: "Unable to authorize, access_token missing from request."}
+ }
+ }
+ } else {
+ returnDetails = MS_authentication(e, p, PS)
+ }
+ return
+}
+
+func ReturnJustInt(i int, e error) int {
+ return i
+}
+
+func ReturnJustString(data []byte, err error) string {
+ return string(data)
+}
+
+type Headers struct {
+ Name string
+ Value string
+}
+
+func GetReqStartedAndBuildHeaders(method, url string, body io.Reader, headers ...Headers) *http.Request {
+ req, _ := http.NewRequest(method, url, body)
+ for _, name := range headers {
+ req.Header.Add(name.Name, name.Value)
+ }
+ return req
+}
+
+type UserINFO struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+}
+
+func ReturnAll(bearer string, PS *ProxyMS) (Data UserINFO, Accounttype string) {
+ if PS != nil {
+ req, _ := http.NewRequest("GET", "https://api.minecraftservices.com/minecraft/profile", nil)
+ req.Header.Add("Authorization", "Bearer "+bearer)
+ if resp, err := (&http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(&url.URL{Scheme: "http", Host: PS.IP + ":" + PS.Port, User: url.UserPassword(PS.User, PS.Password)})}}).Do(req); err == nil {
+ switch resp.StatusCode {
+ case 200:
+ json.Unmarshal([]byte(ReturnJustString(io.ReadAll(resp.Body))), &Data)
+ Accounttype = "Microsoft"
+ case 404:
+ Accounttype = "Giftcard"
+ }
+ }
+ } else {
+ req, _ := http.NewRequest("GET", "https://api.minecraftservices.com/minecraft/profile", nil)
+ req.Header.Add("Authorization", "Bearer "+bearer)
+ if resp, err := http.DefaultClient.Do(req); err == nil {
+ switch resp.StatusCode {
+ case 200:
+ json.Unmarshal([]byte(ReturnJustString(io.ReadAll(resp.Body))), &Data)
+ Accounttype = "Microsoft"
+ case 404:
+ Accounttype = "Giftcard"
+ }
+ }
+ }
+ return
+}
+
+func Clear() {
+ if runtime.GOOS == "windows" {
+ cmd := exec.Command("cmd", "/c", "cls")
+ cmd.Stdout = os.Stdout
+ cmd.Run()
+ } else {
+ cmd := exec.Command("clear")
+ cmd.Stdout = os.Stdout
+ cmd.Run()
+ }
+}
diff --git a/packages/apiGO/ping.go b/packages/apiGO/ping.go
new file mode 100644
index 0000000..29aedf6
--- /dev/null
+++ b/packages/apiGO/ping.go
@@ -0,0 +1,20 @@
+package apiGO
+
+import (
+ "crypto/tls"
+ "time"
+)
+
+func PingMC() float64 {
+ var pingTimes float64
+ conn, _ := tls.Dial("tcp", "api.minecraftservices.com:443", nil)
+ defer conn.Close()
+ for i := 0; i < 10; i++ {
+ recv := make([]byte, 4096)
+ time1 := time.Now()
+ conn.Write([]byte("PUT /minecraft/profile/name/test HTTP/1.1\r\nHost: api.minecraftservices.com\r\nAuthorization: Bearer TestToken\r\n\r\n"))
+ conn.Read(recv)
+ pingTimes += float64(time.Since(time1).Milliseconds())
+ }
+ return float64(pingTimes/10000) * 5000
+}
diff --git a/packages/apiGO/proxy.go b/packages/apiGO/proxy.go
new file mode 100644
index 0000000..af2d63d
--- /dev/null
+++ b/packages/apiGO/proxy.go
@@ -0,0 +1,111 @@
+package apiGO
+
+import (
+ "bufio"
+ "crypto/tls"
+ "crypto/x509"
+ "fmt"
+ "math/rand"
+ "os"
+ "strings"
+ "sync"
+ "time"
+
+ "golang.org/x/net/proxy"
+)
+
+func (Proxy *Proxys) GetProxys(uselist bool, list []string) {
+ Proxy.Proxys = []string{}
+ if uselist {
+ Proxy.Proxys = append(Proxy.Proxys, list...)
+ } else {
+ file, err := os.Open("data/proxys.txt")
+ if err == nil {
+ defer file.Close()
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ Proxy.Proxys = append(Proxy.Proxys, scanner.Text())
+ }
+ }
+ }
+}
+
+func (Proxy *Proxys) CompRand() string {
+ rand.Seed(time.Now().UnixNano())
+ time.Sleep(10 * time.Millisecond)
+ return Proxy.Proxys[rand.Intn(len(Proxy.Proxys))]
+}
+
+func (Proxy *Proxys) Setup() {
+ Proxy.Used = make(map[string]bool)
+ for _, proxy := range Proxy.Proxys {
+ Proxy.Used[proxy] = false
+ }
+}
+
+func (Proxy *Proxys) RandProxy() string {
+ for _, proxy := range Proxy.Proxys {
+ if !Proxy.Used[proxy] {
+ Proxy.Used[proxy] = true
+ return proxy
+ }
+ }
+
+ Proxy.Setup()
+
+ return ""
+}
+
+func (Bearers *MCbearers) GenSocketConns(Proxy ReqConfig) (pro []Proxys) {
+ var Accs [][]Info
+ var incr int
+ var use int
+ roots := x509.NewCertPool()
+ roots.AppendCertsFromPEM(ProxyByte)
+
+ for _, Acc := range Bearers.Details {
+ if len(Accs) == 0 {
+ Accs = append(Accs, []Info{
+ Acc,
+ })
+ } else {
+ if incr == 3 {
+ incr = 0
+ use++
+ Accs = append(Accs, []Info{})
+ }
+ Accs[use] = append(Accs[use], Acc)
+ }
+ incr++
+ }
+
+ var wg sync.WaitGroup
+ for _, Accs := range Accs {
+ wg.Add(1)
+ go func(Accs []Info) {
+ var user, pass, ip, port string
+ auth := strings.Split(Proxy.Proxys.RandProxy(), ":")
+ ip, port = auth[0], auth[1]
+ if len(auth) > 2 {
+ user, pass = auth[2], auth[3]
+ }
+ req, err := proxy.SOCKS5("tcp", fmt.Sprintf("%v:%v", ip, port), &proxy.Auth{
+ User: user,
+ Password: pass,
+ }, proxy.Direct)
+ if err == nil {
+ conn, err := req.Dial("tcp", "api.minecraftservices.com:443")
+ if err == nil {
+ pro = append(pro, Proxys{
+ Accounts: Accs,
+ Conn: tls.Client(conn, &tls.Config{RootCAs: roots, InsecureSkipVerify: true, ServerName: "api.minecraftservices.com"}),
+ })
+ }
+ }
+ wg.Done()
+ }(Accs)
+ }
+
+ wg.Wait()
+ return
+}
diff --git a/packages/apiGO/send.go b/packages/apiGO/send.go
new file mode 100644
index 0000000..4cc86fd
--- /dev/null
+++ b/packages/apiGO/send.go
@@ -0,0 +1,94 @@
+package apiGO
+
+import (
+ "crypto/tls"
+ "encoding/json"
+ "fmt"
+ "sort"
+ "sync"
+ "time"
+)
+
+func (Data *ReqConfig) SnipeReq(Acc Config) (data SentRequests) {
+ var wg sync.WaitGroup
+
+ for time.Now().Before(time.Unix(Data.Droptime, 0).Add(-time.Second * 10)) {
+ time.Sleep(time.Second * 1)
+ }
+
+ if Data.Proxy {
+ Clients := Data.Bearers.GenSocketConns(*Data)
+ time.Sleep(time.Until(time.Unix(Data.Droptime, 0).Add(time.Millisecond * time.Duration(0-Data.Delay)).Add(time.Duration(-float64(time.Since(time.Now()).Nanoseconds())/1000000.0) * time.Millisecond)))
+ for _, config := range Clients {
+ wg.Add(1)
+ go func(config Proxys) {
+ var wgs sync.WaitGroup
+ for _, Acc := range config.Accounts {
+ if Acc.AccountType == "Giftcard" {
+ for i := 0; i < Acc.Requests; i++ {
+ wgs.Add(1)
+ go func(Account Info, payloads string) {
+ data.Requests = append(data.Requests, Details{
+ ResponseDetails: SocketSending(config.Conn, payloads),
+ Bearer: Account.Bearer,
+ Email: Account.Email,
+ Type: Account.AccountType,
+ })
+ wgs.Done()
+ }(Acc, fmt.Sprintf("POST /minecraft/profile HTTP/1.1\r\nHost: api.minecraftservices.com\r\nConnection: open\r\nContent-Length:%v\r\nContent-Type: application/json\r\nAccept: application/json\r\nAuthorization: Bearer %v\r\n\r\n{\"profileName\":\"%v\"}\r\n", len(`{"profileName":"`+Data.Name+`"}`), Acc.Bearer, Data.Name))
+ }
+ } else {
+ for i := 0; i < Acc.Requests; i++ {
+ wgs.Add(1)
+ go func(Account Info, payloads string) {
+ data.Requests = append(data.Requests, Details{
+ ResponseDetails: SocketSending(config.Conn, payloads),
+ Bearer: Account.Bearer,
+ Email: Account.Email,
+ Type: Account.AccountType,
+ Password: Account.Password,
+ })
+ wgs.Done()
+ }(Acc, "PUT /minecraft/profile/name/"+Data.Name+" HTTP/1.1\r\nHost: api.minecraftservices.com\r\nConnection: open\r\nUser-Agent: MCSN/1.0\r\nAuthorization: bearer "+Acc.Bearer+"\r\n\r\n")
+ }
+ }
+ }
+ wgs.Wait()
+ wg.Done()
+ }(config)
+ }
+ } else {
+ payload := Data.Bearers.CreatePayloads(Data.Name)
+ conn, _ := tls.Dial("tcp", "api.minecraftservices.com:443", nil)
+ time.Sleep(time.Until(time.Unix(Data.Droptime, 0).Add(time.Millisecond * time.Duration(0-Data.Delay)).Add(time.Duration(-float64(time.Since(time.Now()).Nanoseconds())/1000000.0) * time.Millisecond)))
+ for e, Account := range Data.Bearers.Details {
+ for i := 0; i < Account.Requests; i++ {
+ wg.Add(1)
+ go func(e int, Account Info) {
+ data.Requests = append(data.Requests, Details{
+ ResponseDetails: SocketSending(conn, payload.Payload[e]),
+ Bearer: Account.Bearer,
+ Email: Account.Email,
+ Type: Account.AccountType,
+ })
+ wg.Done()
+ }(e, Account)
+ time.Sleep(time.Duration(Acc.SpreadPerReq) * time.Microsecond)
+ }
+ }
+ }
+
+ wg.Wait()
+ fmt.Println()
+
+ sort.Slice(data.Requests, func(i, j int) bool {
+ return data.Requests[i].ResponseDetails.SentAt.Before(data.Requests[j].ResponseDetails.SentAt)
+ })
+
+ return
+}
+
+func JsonValue(f interface{}) []byte {
+ g, _ := json.Marshal(f)
+ return g
+}
diff --git a/packages/apiGO/var.go b/packages/apiGO/var.go
new file mode 100644
index 0000000..7e648d8
--- /dev/null
+++ b/packages/apiGO/var.go
@@ -0,0 +1,170 @@
+package apiGO
+
+import (
+ "crypto/tls"
+ "time"
+)
+
+var (
+ ProxyByte = []byte(`
+ -- GlobalSign Root R2, valid until Dec 15, 2021
+ -----BEGIN CERTIFICATE-----
+ MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
+ A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
+ Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
+ MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
+ A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+ hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
+ v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
+ eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
+ tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
+ C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
+ zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
+ mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
+ V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
+ bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
+ 3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
+ J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
+ 291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
+ ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
+ AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
+ TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
+ -----END CERTIFICATE-----`)
+)
+
+type Name struct {
+ Names string `json:"name"`
+ Drop float64 `json:"droptime"`
+}
+
+type Proxys struct {
+ Proxys []string
+ Used map[string]bool
+ Accounts []Info
+ Conn *tls.Conn
+}
+
+type Resp struct {
+ SentAt time.Time
+ RecvAt time.Time
+ StatusCode string
+ Body string
+}
+
+type Payload struct {
+ Payload []string
+ Conns []*tls.Conn
+
+ Start int64 `json:"unix"`
+ End int64 `json:"unix_end"`
+}
+
+type ServerInfo struct {
+ Webhook string
+ SkinUrl string
+}
+
+type mojangData struct {
+ Bearer_MS string `json:"access_token"`
+ Expires int `json:"expires_in"`
+}
+
+type MCbearers struct {
+ Details []Info
+}
+
+type Info struct {
+ Bearer string
+ RefreshToken string
+ AccessToken string
+ Expires int
+ AccountType string
+ Email string
+ Password string
+ Requests int
+ Error string
+ Info UserINFO
+}
+
+type Config struct {
+ ChangeSkinLink string `json:"ChangeSkinLink"`
+ ChangeskinOnSnipe bool `json:"ChangeskinOnSnipe"`
+ GcReq int `json:"GcReq"`
+ MFAReq int `json:"MFAReq"`
+ ManualBearer bool `json:"ManualBearer"`
+ SpreadPerReq int `json:"SpreadPerReq"`
+ SendMCSNAd bool `json:"SendMCSN_MsgUponBMJoin"`
+ AlwaysUseUnix bool `json:"forceuseunix"`
+
+ Bearers []Bearers `json:"Bearers"`
+ Logs []Logs `json:"logs"`
+}
+
+type Logs struct {
+ Email string `json:"email"`
+ Password string `json:"password"`
+ Send time.Time `json:"send"`
+ Recv time.Time `json:"recv"`
+ Success bool `json:"success"`
+ Name string `json:"name"`
+}
+
+type Bearers struct {
+ Bearer string `json:"Bearer"`
+ Email string `json:"Email"`
+ Password string `json:"Password"`
+ AuthInterval int64 `json:"AuthInterval"`
+ AuthedAt int64 `json:"AuthedAt"`
+ Type string `json:"Type"`
+ NameChange bool `json:"NameChange"`
+}
+
+type Bux2 struct {
+ Action string `json:"action"`
+ Desc string `json:"desc"`
+ Code string `json:"code"`
+ ID string `json:"id"`
+ Error string `json:"error"`
+ Data []NameRequest `json:"data"`
+}
+
+type Bux struct {
+ Action string `json:"action"`
+ Desc string `json:"desc"`
+ Code string `json:"code"`
+ ID string `json:"id"`
+ Error string `json:"error"`
+ Data NameRequest `json:"data"`
+}
+
+type NameRequest struct {
+ Status string `json:"status,omitempty"`
+ Searches string `json:"searches,omitempty"`
+ Start int64 `json:"begin,omitempty"`
+ End int64 `json:"end,omitempty"`
+ HeadURL string `json:"headurl,omitempty"`
+ Error string `json:"error,omitempty"`
+}
+
+type ReqConfig struct {
+ Name string
+ Delay float64
+ Droptime int64
+ Proxys Proxys
+ Bearers MCbearers
+ UseUnix bool
+
+ Proxy bool
+}
+
+type SentRequests struct {
+ Requests []Details
+}
+
+type Details struct {
+ ResponseDetails Resp
+ Bearer string
+ Email string
+ Password string
+ Type string
+}
diff --git a/packages/h2/client.go b/packages/h2/client.go
new file mode 100644
index 0000000..81aaaa8
--- /dev/null
+++ b/packages/h2/client.go
@@ -0,0 +1,115 @@
+package h2
+
+import (
+ "fmt"
+ "net/url"
+ "strings"
+
+ tls "github.com/bogdanfinn/utls"
+ "golang.org/x/net/http2"
+)
+
+type Conn struct {
+ Url *url.URL
+ Conn *http2.Framer
+ UnderlyingConn *tls.UConn
+ Config ReqConfig
+ Client *Client
+ FirstUse bool
+}
+
+// Connects to the url you supply, and stores it inside the Client struct.
+func (Data *Client) Connect(addr string, config ReqConfig) (Connection Conn, err error) {
+ Connection.Url = GrabUrl(addr)
+ Connection.Client = Data
+ Connection.Config = config
+ if err := Connection.GenerateConn(config); err != nil {
+ return Conn{}, err
+ }
+ return Connection, nil
+}
+
+// Does a request, since http2 doesnt like to resent new headers. after the first request it will reconnect to the server
+// and make a new http2 framer variable to use.
+func (Data *Conn) Do(method, json, content_type string, cookies *[]string) (Config Response, err error) {
+ if !Data.FirstUse {
+ Data.FirstUse = true
+ } else {
+ if err = Data.GenerateConn(Data.Config); err != nil {
+ return Response{}, err
+ }
+ }
+
+ if cookies != nil {
+ Data.Client.Config.Headers["cookie"] += TurnCookieHeader(*cookies)
+ }
+
+ var FoundAndSent bool
+
+ Headers := Data.GetHeaders(method)
+
+ if method != "GET" {
+ var FoundType, FoundLength, FoundEither bool
+ for _, header := range Headers {
+ if strings.Contains(header, "content-type") {
+ FoundType = true
+ }
+ if strings.Contains(header, "content-length") {
+ FoundLength = true
+ }
+ }
+ if !FoundLength {
+ Data.AddHeader("content-length", fmt.Sprintf("%v", len(json)))
+ FoundEither = true
+ }
+ if !FoundType {
+ if content_type != "" {
+ Data.AddHeader("content-type", content_type)
+ }
+ FoundEither = true
+ }
+ if FoundEither {
+ Headers = Data.GetHeaders(method)
+ Data.SendHeaders(Headers, method == "GET")
+ FoundAndSent = true
+ }
+ Data.DataSend([]byte(json))
+ }
+ if !FoundAndSent {
+ Data.SendHeaders(Headers, method == "GET")
+ }
+ resp, err := Data.FindData()
+ if err != nil {
+ return resp, err
+ }
+ if resp.Status == "302" || resp.Status == "301" {
+ Data.Url.Path = GetHeaderVal("location", resp.Headers).Value
+ if err = Data.GenerateConn(Data.Config); err != nil {
+ return Response{}, err
+ }
+ Data.SendHeaders(Data.GetHeaders(method), method == "GET")
+ return Data.FindData()
+ }
+ return resp, err
+}
+
+func (Data *Conn) ChangeProxy(proxy *ProxyAuth) {
+ Data.Config.Proxy = proxy
+}
+
+// Changes the url path, so you can send to different locations under one variable.
+func (Data *Conn) ChangeURL(url *url.URL) {
+ Data.Url = url
+}
+
+// adds a header to the client struct
+func (Data *Conn) AddHeader(name, value string) {
+ Data.Client.Config.Headers[name] = value
+}
+
+// deletes headers from a client struct
+func (Data *Conn) DeleteHeader(headernames ...string) {
+ for _, val := range headernames {
+ delete(Data.Client.Config.Headers, val)
+ }
+}
diff --git a/packages/h2/utils.go b/packages/h2/utils.go
new file mode 100644
index 0000000..bb13e6f
--- /dev/null
+++ b/packages/h2/utils.go
@@ -0,0 +1,384 @@
+package h2
+
+import (
+ "bytes"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "net"
+ "net/url"
+ "strings"
+
+ tls "github.com/bogdanfinn/utls"
+ "golang.org/x/net/http2"
+ "golang.org/x/net/http2/hpack"
+)
+
+func (Data *Conn) Connect(config ReqConfig) (net.Conn, bool, error) {
+ if conn, err := net.Dial("tcp", fmt.Sprintf("%v:%v", config.Proxy.IP, config.Proxy.Port)); err == nil {
+ Conn_URL := CheckAddr(Data.Url)
+ if config.Proxy.User != "" && config.Proxy.Password != "" {
+ conn.Write([]byte(fmt.Sprintf("CONNECT %v HTTP/1.1\r\nHost: %v\r\nProxy-Authorization: Basic %v\r\nProxy-Connection: keep-alive\r\nUser-Agent: MCSN/1.1\r\n\r\n", Conn_URL, Conn_URL, base64.RawStdEncoding.EncodeToString([]byte(fmt.Sprintf("%v:%v", config.Proxy.User, config.Proxy.Password))))))
+ } else {
+ conn.Write([]byte(fmt.Sprintf("CONNECT %v HTTP/1.1\r\nHost: %v\r\nProxy-Connection: keep-alive\r\nUser-Agent: MCSN/1.1\r\n\r\n", Conn_URL, Conn_URL)))
+ }
+ var junk = make([]byte, 4096)
+ conn.Read(junk)
+ switch Status := string(junk); Status[9:12] {
+ case "200":
+ return conn, true, nil
+ case "407":
+ return nil, false, errors.New(fmt.Sprintf("[%v] Proxy <%v> Failed to authorize: Username/Password invalid.\n", Status[9:12], config.Proxy.IP))
+ default:
+ return nil, false, errors.New(fmt.Sprintf("[%v] Proxy <%v> Failed to authorize: Unknown Statuscode.\n", Status[9:12], config.Proxy.IP))
+ }
+ }
+ return nil, false, errors.New(fmt.Sprintf("Proxy <%v> Failed to authorize: Unknown Error EOF\n", config.Proxy.IP))
+}
+
+// Generate conn performs a conn to the url you supply.
+func (Data *Conn) GenerateConn(config ReqConfig) (err error) {
+ if config.DataBodyMaxLength == 0 {
+ return errors.New("error: [DataBodyMaxLength] cannot be 0, suggested value to be above 130000")
+ }
+
+ var conn net.Conn
+ var tlsConn *tls.UConn
+ if config.Proxy != nil {
+ var ok bool
+ var err error
+ conn, ok, err = Data.Connect(config)
+ if !ok && err != nil {
+ return err
+ }
+ } else {
+ conn, err = net.Dial("tcp", CheckAddr(Data.Url))
+ if err != nil {
+ return err
+ }
+ }
+
+ tlsConn = tls.UClient(conn, &tls.Config{
+ ServerName: Data.Url.Host,
+ NextProtos: Data.Client.Config.Protocols,
+ InsecureSkipVerify: config.InsecureSkipVerify,
+ Renegotiation: config.Renegotiation,
+ PreferServerCipherSuites: config.PreferServerCipherSuites,
+ RootCAs: config.RootCAs,
+ ClientCAs: config.ClientCAs,
+ }, config.BuildID, true, config.UseHTTP1)
+
+ if config.SaveCookies {
+ if Data.Client.Cookies == nil || len(Data.Client.Cookies) == 0 {
+ Data.Client.Cookies = make(map[string][]hpack.HeaderField)
+ }
+ }
+
+ fmt.Fprintf(tlsConn, http2.ClientPreface)
+
+ if err = tlsConn.Handshake(); err != nil {
+ return err
+ }
+
+ Data.Conn = http2.NewFramer(tlsConn, tlsConn)
+ Data.Conn.SetReuseFrames()
+ Data.WriteSettings(config.DataBodyMaxLength)
+ Data.Windows_Update()
+ Data.Send_Prio_Frames()
+ Data.UnderlyingConn = tlsConn
+ return nil
+}
+
+// gets a selected cookie based on the cookie_name variable
+//
+// e.g. "__vf_bm" > "__vf_bm=awdawd223reqfqh32rqrf32qr"
+func (Data *Conn) GetCookie(cookie_name, url string) string {
+ for _, val := range Data.Client.Cookies[url] {
+ if strings.Contains(val.Value, cookie_name) {
+ Cookie := strings.Split(val.Value, "=")
+ return fmt.Sprintf("%v=%v", Cookie[0], Cookie[1])
+ }
+ }
+
+ return ""
+}
+
+// Gets a header value based on the name you supply.
+func GetHeaderVal(name string, headers []hpack.HeaderField) hpack.HeaderField {
+ for _, data := range headers {
+ if data.Name == name {
+ return data
+ }
+ }
+ return hpack.HeaderField{}
+}
+
+// This is a helper function that gets all the cookies from a
+// cached url and returns them in a format that works with the cookie: header.
+func (Data *Conn) TransformCookies(url string) string {
+ var cookies []string
+ for _, val := range Data.Client.Cookies[url] {
+ cookie_name := strings.Split(strings.Split(val.Value, ";")[0], "=")
+ cookies = append(cookies, fmt.Sprintf("%v=%v", cookie_name[0], cookie_name[1]))
+ }
+ return strings.Join(cookies, "; ")
+}
+
+// strings.Join shortcut to turn your list of coookies into a cookie: header format.
+func TurnCookieHeader(Cookies []string) string {
+ return strings.Join(Cookies, "; ")
+}
+
+// Sends data through the framer
+func (Data *Conn) DataSend(body []byte) {
+ Data.Conn.WriteData(uint32(Data.Config.ID), true, body)
+}
+
+// Sends priority frames, this ensures the right data is sent in the correct order.
+func (Data *Conn) Send_Prio_Frames() {
+ Data.Conn.WritePriority(3, http2.PriorityParam{
+ StreamDep: 0,
+ Weight: 200,
+ Exclusive: false,
+ })
+
+ Data.Conn.WritePriority(5, http2.PriorityParam{
+ StreamDep: 0,
+ Weight: 100,
+ Exclusive: false,
+ })
+
+ Data.Conn.WritePriority(7, http2.PriorityParam{
+ StreamDep: 0,
+ Weight: 0,
+ Exclusive: false,
+ })
+
+ Data.Conn.WritePriority(9, http2.PriorityParam{
+ StreamDep: 7,
+ Weight: 0,
+ Exclusive: false,
+ })
+
+ Data.Conn.WritePriority(11, http2.PriorityParam{
+ StreamDep: 3,
+ Weight: 0,
+ Exclusive: false,
+ })
+
+ Data.Conn.WritePriority(13, http2.PriorityParam{
+ StreamDep: 0,
+ Weight: 240,
+ Exclusive: false,
+ })
+}
+
+// Loops over the Config headers and applies them to the Client []string variable.
+// Method for example "GET".
+func (Data *Conn) GetHeaders(method string) (headers []string) {
+ for _, name := range Data.Client.Config.HeaderOrder {
+ switch name {
+ case ":authority":
+ headers = append(headers, name+": "+Data.Url.Host)
+ case ":method":
+ headers = append(headers, name+": "+method)
+ case ":path":
+ headers = append(headers, name+": "+CheckQuery(Data.Url))
+ case ":scheme":
+ headers = append(headers, name+": "+Data.Url.Scheme)
+ default:
+ if val, exists := Data.Client.Config.Headers[name]; exists {
+ headers = append(headers, name+": "+val)
+ }
+ }
+ }
+
+ for name, val := range Data.Client.Config.Headers {
+ if !strings.Contains(strings.Join(Data.Client.Config.HeaderOrder, ","), name) {
+ headers = append(headers, name+": "+val)
+ }
+ }
+
+ return
+}
+
+// Writes the headers to the http2 framer.
+// this function also encodes the headers into a []byte
+// Endstream is also called in this function, only use true values when performing GET requests.
+func (Data *Conn) SendHeaders(headers []string, endStream bool) {
+ Data.Conn.WriteHeaders(
+ http2.HeadersFrameParam{
+ StreamID: uint32(Data.Config.ID),
+ BlockFragment: Data.FormHeaderBytes(headers),
+ EndHeaders: true,
+ EndStream: endStream,
+ },
+ )
+}
+
+// Writes the window update frame to the http2 framer.
+func (Data *Conn) Windows_Update() {
+ Data.Conn.WriteWindowUpdate(0, 12517377)
+}
+
+// Write settings writes the default chrome settings to the framer
+func (Data *Conn) WriteSettings(ResponseDataSize uint32) {
+ Data.Conn.WriteSettings(
+ http2.Setting{
+ ID: http2.SettingHeaderTableSize, Val: 65536,
+ },
+ http2.Setting{
+ ID: http2.SettingEnablePush, Val: 1,
+ },
+ http2.Setting{
+ ID: http2.SettingMaxConcurrentStreams, Val: 1000,
+ },
+ http2.Setting{
+ ID: http2.SettingInitialWindowSize, Val: ResponseDataSize,
+ },
+ http2.Setting{
+ ID: http2.SettingMaxFrameSize, Val: 16384,
+ },
+ http2.Setting{
+ ID: http2.SettingMaxHeaderListSize, Val: 262144,
+ },
+ )
+}
+
+// Find data is called after the prior settings/window/prio frames are performed, it goes through the
+// framer and returns its data, any errors and also headers / status codes.
+func (Datas *Conn) FindData() (Config Response, err error) {
+ for {
+ f, err := Datas.Conn.ReadFrame()
+ if err != nil {
+ return Config, err
+ }
+ switch f := f.(type) {
+ case *http2.DataFrame:
+ Config.Data = append(Config.Data, f.Data()...)
+ if f.FrameHeader.Flags.Has(http2.FlagDataEndStream) {
+ return Config, nil
+ }
+ case *http2.HeadersFrame:
+ Config.Headers, err = hpack.NewDecoder(Datas.Config.DataBodyMaxLength, nil).DecodeFull(f.HeaderBlockFragment())
+ if err != nil {
+ return Config, err
+ }
+ for _, Data := range Config.Headers {
+ switch Data.Name {
+ case ":status":
+ Config.Status = Data.Value
+ case "set-cookie":
+ if Datas.Config.SaveCookies {
+ Datas.Client.Cookies[Datas.Url.String()] = append(Datas.Client.Cookies[Datas.Url.String()], Data)
+ }
+ }
+ }
+ if f.FrameHeader.Flags.Has(http2.FlagDataEndStream) && f.FrameHeader.Flags.Has(http2.FlagHeadersEndStream) {
+ return Config, nil
+ }
+ case *http2.RSTStreamFrame:
+ return Config, errors.New(f.ErrCode.String())
+ case *http2.GoAwayFrame:
+ return Config, errors.New(f.ErrCode.String())
+ }
+ }
+}
+
+// Turns the addr into a url.URL variable.
+func GrabUrl(addr string) *url.URL {
+ URL, _ := url.Parse(addr)
+ if URL.Path == "" {
+ URL.Path = "/"
+ }
+ return URL
+}
+
+// Checks if there are params in your url and adds it to your path.
+//
+// e.g. "/api/name?code=12343&scope=1234"
+func CheckQuery(Data *url.URL) string {
+ if Data.Query().Encode() != "" {
+ return Data.Path + "?" + Data.Query().Encode()
+ }
+ return Data.Path
+}
+
+// Form header bytes takes the []string of headers and turns it into []byte data
+// this is so it can be compatiable for the http2 headers.
+func (Data *Conn) FormHeaderBytes(headers []string) []byte {
+ var val []string
+ hbuf := bytes.NewBuffer([]byte{})
+ encoder := hpack.NewEncoder(hbuf)
+ for _, header := range headers {
+ switch data := strings.Split(header, ":"); len(data) {
+ case 3:
+ val = data[1:]
+ val[0] = fmt.Sprintf(":%v", val[0])
+ default:
+ val = data[0:]
+ }
+ encoder.WriteField(hpack.HeaderField{Name: strings.TrimSpace(val[0]), Value: strings.TrimSpace(val[1])})
+ }
+ return hbuf.Bytes()
+}
+
+// Takes in the url and returns the host + port of the url.
+//
+// e.g. "www.google.com:443"
+func CheckAddr(url *url.URL) string {
+ switch url.Scheme {
+ case "https":
+ return url.Host + ":443"
+ default:
+ return url.Host + ":80"
+ }
+}
+
+// This returns the default config variables.
+// header order, chrome like headers and protocols.
+func GetDefaultConfig() Config {
+ return Config{
+ HeaderOrder: []string{
+ ":authority",
+ ":method",
+ ":path",
+ ":scheme",
+ "accept",
+ "accept-encoding",
+ "accept-language",
+ "cache-control",
+ "content-length",
+ "content-type",
+ "cookie",
+ "origin",
+ "referer",
+ "sec-ch-ua",
+ "sec-ch-ua-mobile",
+ "sec-ch-ua-platform",
+ "sec-ch-ua-platform-version",
+ "upgrade-insecure-requests",
+ "user-agent",
+ "sec-fetch-site",
+ "sec-fetch-mode",
+ "sec-fetch-user",
+ "sec-fetch-dest",
+ },
+ Headers: map[string]string{
+ "cache-control": "max-age=0",
+ "upgrade-insecure-requests": "1",
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
+ "accept": "application/json, text/javascript, text/html, application/xhtml+xml, application/xml;q=0.9, image/avif, image/webp, image/apng, */*;q=0.8, application/signed-exchange;v=b3",
+ "sec-fetch-site": "same-origin",
+ "sec-fetch-mode": "cors",
+ "sec-fetch-user": "?1",
+ "sec-fetch-dest": "empty",
+ "sec-ch-ua": `"Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"`,
+ "sec-ch-ua-mobile": "?0",
+ "sec-ch-ua-platform": "\\\"Windows\\",
+ "sec-ch-ua-platform-version": "14.0.0",
+ "accept-language": "en-US,en;q=0.9",
+ },
+ Protocols: []string{"h2", "h1", "http/1.1"},
+ }
+}
diff --git a/packages/h2/variables.go b/packages/h2/variables.go
new file mode 100644
index 0000000..39173da
--- /dev/null
+++ b/packages/h2/variables.go
@@ -0,0 +1,71 @@
+package h2
+
+import (
+ "crypto/x509"
+
+ tls "github.com/bogdanfinn/utls"
+
+ "golang.org/x/net/http2"
+ "golang.org/x/net/http2/hpack"
+)
+
+const (
+ MethodGet = "GET"
+ MethodPost = "POST"
+ MethodPut = "PUT"
+ MethodOptions = "OPTIONS"
+ MethodDelete = "DELETE"
+ MethodConnect = "CONNECT"
+)
+
+type Client struct {
+ Config Config
+ Cookies map[string][]hpack.HeaderField // Used to store the data of websites cookies
+}
+
+type Debug struct {
+ Headers []string `json:"sentheaders"`
+ HeadersRecv []string `json:"recvheaders"`
+ SentFrames []Frames `json:"send"`
+ RecvFrames []Frames `json:"recv"`
+}
+
+type Frames struct {
+ StreamID uint32 `json:"streamid"`
+ Setting string `json:"name"`
+ Length uint32 `json:"len"`
+}
+
+type Website struct {
+ Conn *http2.Framer
+ Config ReqConfig
+ HasDoneFirstReq bool
+}
+
+type Config struct {
+ HeaderOrder, Protocols []string
+ Headers map[string]string
+}
+
+type Response struct {
+ Data []byte
+ Status string
+ Headers []hpack.HeaderField
+}
+
+type ReqConfig struct {
+ ID int64 // StreamID for requests (Multiplexing)
+ BuildID tls.ClientHelloID // HelloChrome_100 etc
+ DataBodyMaxLength uint32
+ Renegotiation tls.RenegotiationSupport
+ InsecureSkipVerify bool
+ Proxy *ProxyAuth
+ SaveCookies bool
+ PreferServerCipherSuites bool
+ RootCAs, ClientCAs *x509.CertPool
+ UseHTTP1 bool
+}
+
+type ProxyAuth struct {
+ IP, Port, User, Password string
+}
diff --git a/packages/h2/ws.go b/packages/h2/ws.go
new file mode 100644
index 0000000..6fd8af6
--- /dev/null
+++ b/packages/h2/ws.go
@@ -0,0 +1,91 @@
+package h2
+
+import (
+ "bufio"
+ "crypto/rand"
+ "encoding/base64"
+ "errors"
+ "io"
+ "net"
+ "net/http"
+
+ tls "github.com/bogdanfinn/utls"
+ "github.com/gobwas/ws"
+ "github.com/gorilla/websocket"
+)
+
+type WebsocketOptions struct {
+ URL string
+ ServerName string
+ Origin string
+ Host string
+ Extensions string
+ UserAgent string
+}
+
+func (Info *WebsocketOptions) Websocket() (*tls.UConn, *http.Response, error) {
+
+ k, err := generateKey()
+ if err != nil {
+ return nil, nil, err
+ }
+
+ resp, err := http.NewRequest("GET", Info.URL, nil)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ addmaddHeaders(resp, map[string]string{
+ "Sec-WebSocket-Key": k,
+ "Origin": Info.Origin,
+ "Upgrade": "websocket",
+ "Connection": "Upgrade",
+ "Host": Info.Host,
+ "Sec-WebSocket-Extensions": Info.Extensions,
+ "Sec-WebSocket-Version": "13",
+ "User-Agent": Info.UserAgent,
+ })
+
+ if conn, err := net.Dial("tcp", Info.ServerName+":443"); err == nil {
+ tlsC := tls.UClient(conn, &tls.Config{
+ ServerName: Info.ServerName,
+ }, tls.HelloChrome_112, true, true)
+ if websocket.IsWebSocketUpgrade(resp) {
+ resp.Write(tlsC)
+ resp, err := http.ReadResponse(bufio.NewReader(tlsC), resp)
+ return tlsC, resp, err
+ } else {
+ return nil, nil, errors.New("Request doesnt look like a websocket upgrade.")
+ }
+ } else {
+ return nil, nil, err
+ }
+}
+
+func addmaddHeaders(resp *http.Request, Headers map[string]string) {
+ for key, value := range Headers {
+ resp.Header.Add(key, value)
+ }
+}
+
+func generateKey() (string, error) {
+ // 1. 16-byte value
+ p := make([]byte, 16)
+
+ // 2. Randomly selected
+ if _, err := io.ReadFull(rand.Reader, p); err != nil {
+ return "", err
+ }
+
+ // 3. Base64-encoded
+ return base64.StdEncoding.EncodeToString(p), nil
+}
+
+func SendMessage(conn *tls.UConn, messages []string) error {
+ for _, msgs := range messages {
+ if err := ws.WriteFrame(conn, ws.MaskFrame(ws.NewTextFrame([]byte(msgs)))); err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/packages/utils/auth.go b/packages/utils/auth.go
new file mode 100644
index 0000000..f553688
--- /dev/null
+++ b/packages/utils/auth.go
@@ -0,0 +1,841 @@
+package utils
+
+import (
+ "bufio"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "os"
+ "strings"
+ "sync"
+ "time"
+ "unicode"
+
+ "main/packages/apiGO"
+
+ "github.com/Tnze/go-mc/bot"
+ "github.com/Tnze/go-mc/bot/basic"
+ "github.com/Tnze/go-mc/bot/msg"
+ "github.com/Tnze/go-mc/bot/playerlist"
+ "github.com/Tnze/go-mc/bot/screen"
+ "github.com/Tnze/go-mc/bot/world"
+ "github.com/Tnze/go-mc/chat"
+ "github.com/golang-jwt/jwt"
+)
+
+type Proxys_Accs struct {
+ Proxy string
+ Accs []apiGO.Info
+}
+
+var Accs map[string][]Proxys_Accs = make(map[string][]Proxys_Accs)
+var Use_gc, Use_mfa, Accamt int
+var First_gc bool = true
+var First_mfa bool = true
+
+func AuthAccs() {
+ grabDetails()
+ if len(Con.Bearers) == 0 {
+ if len(Bearer.Details) == 0 {
+ fmt.Println(Logo("No Bearers have been found, please check your details."))
+ }
+ } else {
+ checkifValid()
+ for _, Accs := range Con.Bearers {
+ if Accs.NameChange {
+ Bearer.Details = append(Bearer.Details, apiGO.Info{
+ Bearer: Accs.Bearer,
+ AccountType: Accs.Type,
+ Email: Accs.Email,
+ Password: Accs.Password,
+ Info: apiGO.UserINFO(Accs.Info),
+ })
+ }
+ }
+ }
+ fmt.Println()
+}
+
+func grabDetails() {
+
+ var AccountsVer []string
+ file, _ := os.Open("data/accounts.txt")
+
+ scanner := bufio.NewScanner(file)
+
+ for scanner.Scan() {
+ checkbearer := scanner.Text()
+
+ t, _ := jwt.Parse(checkbearer, func(t *jwt.Token) (interface{}, error) {
+ return t, nil
+ })
+
+ if strings.Contains(fmt.Sprintf("%v", t), "minecraft_net") && strings.Contains(fmt.Sprintf("%v", t), "xuid:") {
+ var Data apiGO.UserINFO
+ var Accounttype string
+ if len(Proxy.Proxys) > 0 {
+ p := Proxy.CompRand()
+ info := strings.Split(p, ":")
+ var ip, port, user, pass string
+ switch len(info) {
+ case 2:
+ ip = info[0]
+ port = info[1]
+ case 4:
+ ip = info[0]
+ port = info[1]
+ user = info[2]
+ pass = info[3]
+ }
+ Data, Accounttype = ReturnAll(checkbearer, &apiGO.ProxyMS{IP: ip, Port: port, User: user, Password: pass})
+ } else {
+ Data, Accounttype = ReturnAll(checkbearer, &apiGO.ProxyMS{})
+ }
+ Bearer.Details = append(Bearer.Details, apiGO.Info{
+ Bearer: checkbearer,
+ Email: checkbearer[0:16] + "@gmail.com",
+ AccountType: Accounttype,
+ Info: Data,
+ })
+ fmt.Println(Logo(fmt.Sprintf(`✓ (Bearer): %v`, Data.Name)))
+ } else {
+ AccountsVer = append(AccountsVer, checkbearer)
+ }
+ }
+
+ if len(AccountsVer) == 0 {
+ if len(Bearer.Details) == 0 {
+ fmt.Println(Logo("Unable to continue, you have no Accounts added."))
+ }
+ return
+ }
+ P := Payload(AccountsVer)
+ CheckDupes(AccountsVer)
+ if Con.Bearers == nil {
+ P_Auth(P, false)
+ } else if len(Con.Bearers) < len(AccountsVer) {
+ var auth []string
+ check := make(map[string]bool)
+ for _, Acc := range Con.Bearers {
+ check[Acc.Email+":"+Acc.Password] = true
+ }
+ for _, Accs := range AccountsVer {
+ if !check[Accs] {
+ auth = append(auth, Accs)
+ }
+ }
+ P_Auth(Payload(auth), false)
+ } else if len(AccountsVer) < len(Con.Bearers) {
+ var New []Bearers
+ for _, Accs := range AccountsVer {
+ for _, num := range Con.Bearers {
+ if Accs == num.Email+":"+num.Password {
+ New = append(New, num)
+ break
+ }
+ }
+ }
+ Con.Bearers = New
+ }
+
+ Con.SaveConfig()
+ Con.LoadState()
+}
+
+func checkifValid() {
+ var reAuth []string
+ var wgs sync.WaitGroup
+ for _, Accs := range Con.Bearers {
+ if time.Now().Unix() > Accs.AuthedAt+Accs.AuthInterval {
+ reAuth = append(reAuth, Accs.Email+":"+Accs.Password)
+ } else {
+ if Accs.NameChange {
+ wgs.Add(1)
+ go func(Accs Bearers) {
+ f, _ := http.NewRequest("GET", "https://api.minecraftservices.com/minecraft/profile/name/boom/available", nil)
+ f.Header.Set("Authorization", "Bearer "+Accs.Bearer)
+ if j, err := http.DefaultClient.Do(f); err == nil {
+ if j.StatusCode == 401 {
+ reAuth = append(reAuth, Accs.Email+":"+Accs.Password)
+ }
+ }
+ wgs.Done()
+ }(Accs)
+ }
+ }
+ }
+ wgs.Wait()
+ if len(reAuth) != 0 {
+ P_Auth(Payload(reAuth), true)
+ }
+ Con.SaveConfig()
+ Con.LoadState()
+}
+
+// _diamondburned_#4507 thanks to them for the epic example below.
+
+func CheckDupes(strs []string) []string {
+ dedup := strs[:0] // re-use the backing array
+ track := make(map[string]bool, len(strs))
+
+ for _, str := range strs {
+ if track[str] {
+ continue
+ }
+ dedup = append(dedup, str)
+ track[str] = true
+ }
+
+ return dedup
+}
+
+func CheckAccs() {
+ for {
+ time.Sleep(10 * time.Second)
+ var reauth []string
+ for _, acc := range Con.Bearers {
+ if time.Now().Unix() > acc.AuthedAt+acc.AuthInterval && acc.NameChange {
+ reauth = append(reauth, acc.Email+":"+acc.Password)
+ }
+ }
+ if len(reauth) > 0 {
+ P_Auth(Payload(reauth), true)
+ }
+ Con.SaveConfig()
+ Con.LoadState()
+ }
+}
+
+type Payload_auth struct {
+ Proxy string
+ Accounts []string
+}
+
+func Payload(accounts []string) (Data []Payload_auth) {
+ var use_proxy, ug int
+ var f bool = true
+ for _, bearer := range accounts {
+ if use_proxy >= len(Proxy.Proxys) && len(Proxy.Proxys) < len(Bearer.Details) {
+ break
+ }
+
+ if f {
+ Data = append(Data, Payload_auth{Proxy: Proxy.Proxys[use_proxy]})
+ f = false
+ use_proxy++
+ }
+ if len(Data[ug].Accounts) != 3 {
+ Data[ug].Accounts = append(Data[ug].Accounts, bearer)
+ } else {
+ ug++
+ Data = append(Data, Payload_auth{Proxy: Proxy.Proxys[use_proxy], Accounts: []string{bearer}})
+ use_proxy++
+ }
+ }
+ return
+}
+
+var (
+ client *bot.Client
+ player *basic.Player
+ chatHandler *msg.Manager
+ worldManager *world.World
+ screenManager *screen.Manager
+)
+
+func Namemc_key(bearer string) string {
+
+ var Info_Acc apiGO.UserINFO
+
+ if len(Proxy.Proxys) > 0 {
+ p := Proxy.CompRand()
+ info := strings.Split(p, ":")
+ var ip, port, user, pass string
+ switch len(info) {
+ case 2:
+ ip = info[0]
+ port = info[1]
+ case 4:
+ ip = info[0]
+ port = info[1]
+ user = info[2]
+ pass = info[3]
+ }
+ Info_Acc, _ = apiGO.ReturnAll(bearer, &apiGO.ProxyMS{IP: ip, Port: port, User: user, Password: pass})
+ } else {
+ Info_Acc, _ = apiGO.ReturnAll(bearer, nil)
+ }
+
+ client = bot.NewClient()
+ client.Auth = bot.Auth{
+ Name: Info_Acc.Name,
+ UUID: Info_Acc.ID,
+ AsTk: bearer,
+ }
+
+ var P *basic.Player
+ L := basic.NewPlayer(client, basic.DefaultSettings, basic.EventsListener{
+ GameStart: func() error {
+
+ return nil
+ },
+ Disconnect: func(reason chat.Message) error {
+ return nil
+ },
+ Death: func() error {
+ return P.Respawn()
+ },
+ })
+ P = L
+ chatHandler = msg.New(client, P, playerlist.New(client), msg.EventsHandler{
+ SystemChat: func(c chat.Message, overlay bool) error {
+ if Text := c.ClearString(); NotWhiteSpace(Text) {
+ if strings.Contains(Text, Info_Acc.Name+" joined the game.") {
+ if err := chatHandler.SendMessage("/namemc"); err != nil {
+ client.Close()
+ return err
+ }
+ } else if strings.Contains(Text, "https://namemc.com/claim?key=") {
+ key := Text
+ client.Close()
+ return errors.New("got-key:" + key)
+ }
+ }
+ return nil
+ },
+ PlayerChatMessage: func(msg chat.Message, validated bool) error {
+ return nil
+ },
+ DisguisedChat: func(msg chat.Message) error {
+ return nil
+ },
+ })
+ if err := client.JoinServer("blockmania.com"); err == nil {
+ for {
+ if err := client.HandleGame(); err == nil {
+ panic("HandleGame never return nil")
+ } else if strings.Contains(err.Error(), "got-key") {
+ return strings.Split(err.Error(), "got-key:")[1]
+ }
+ }
+ } else {
+ return err.Error()
+ }
+}
+
+func NotWhiteSpace(str string) bool {
+ for _, c := range str {
+ if !unicode.IsSpace(c) {
+ return true
+ }
+ }
+ return false
+}
+
+func ReturnAll(bearer string, PS *apiGO.ProxyMS) (Data apiGO.UserINFO, Accounttype string) {
+ if PS != nil {
+ req, _ := http.NewRequest("GET", "https://api.minecraftservices.com/minecraft/profile", nil)
+ req.Header.Add("Authorization", "Bearer "+bearer)
+ if resp, err := (&http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(&url.URL{Scheme: "http", Host: PS.IP + ":" + PS.Port, User: url.UserPassword(PS.User, PS.Password)})}}).Do(req); err == nil {
+ switch resp.StatusCode {
+ case 200:
+ json.Unmarshal([]byte(ReturnJustString(io.ReadAll(resp.Body))), &Data)
+ Accounttype = "Microsoft"
+ case 404:
+ Accounttype = "Giftcard"
+ }
+ }
+ } else {
+ req, _ := http.NewRequest("GET", "https://api.minecraftservices.com/minecraft/profile", nil)
+ req.Header.Add("Authorization", "Bearer "+bearer)
+ if resp, err := http.DefaultClient.Do(req); err == nil {
+ switch resp.StatusCode {
+ case 200:
+ json.Unmarshal([]byte(ReturnJustString(io.ReadAll(resp.Body))), &Data)
+ Accounttype = "Microsoft"
+ case 404:
+ Accounttype = "Giftcard"
+ }
+ }
+ }
+ return
+}
+
+func ReturnJustString(data []byte, err error) string {
+ return string(data)
+}
+
+func P_Auth(P []Payload_auth, reauth bool) {
+ var wg sync.WaitGroup
+ var Invalids []string
+ var invalidproxys []string
+ for _, acc_1 := range P {
+ for _, p := range acc_1.Accounts {
+ if acc := strings.Split(p, ":"); len(acc) > 1 {
+ if len(Proxy.Proxys) > 0 && Con.Bools.UseProxyDuringAuth {
+ wg.Add(1)
+ go func(proxy string, acc []string) {
+ ip, port, user, pass := "", "", "", ""
+ switch data := strings.Split(proxy, ":"); len(data) {
+ case 2:
+ ip = data[0]
+ port = data[1]
+ case 4:
+ ip = data[0]
+ port = data[1]
+ user = data[2]
+ pass = data[3]
+ }
+ var Authed bool
+ go func() {
+ for !Authed {
+ time.Sleep(80 * time.Second)
+ if !Authed {
+ New := Proxy.CompRand()
+ fmt.Println(Logo(fmt.Sprintf("<%v> %v under the ip %v has timed out, suspected dead proxy. reauthing under %v now..", time.Now().Format("05.000"), HashEmailClean(acc[0]), ip, strings.Split(New, ":")[0])))
+
+ invalidproxys = append(invalidproxys, fmt.Sprintf("%v:%v:%v:%v", ip, port, user, pass))
+
+ switch data := strings.Split(New, ":"); len(data) {
+ case 2:
+ ip = data[0]
+ port = data[1]
+ case 4:
+ ip = data[0]
+ port = data[1]
+ user = data[2]
+ pass = data[3]
+ }
+ info := apiGO.MS_authentication(acc[0], acc[1], &apiGO.ProxyMS{IP: ip, Port: port, User: user, Password: pass})
+ if info.Error != "" {
+ Authed = true
+ fmt.Println(Logo(fmt.Sprintf("Account %v came up Invalid: %v", HashEmailClean(info.Email), info.Error)))
+ Invalids = append(Invalids, acc[0]+":"+acc[1])
+ } else if info.Bearer != "" {
+ if IsChangeable(proxy, info.Bearer) {
+ Authed = true
+ fmt.Println(Logo(fmt.Sprintf("[%v] Succesfully authed %v", time.Now().Format("15:04:05.0000"), HashEmailClean(info.Email))))
+ if reauth {
+ for point, bf := range Con.Bearers {
+ if strings.EqualFold(bf.Email, info.Email) {
+ Con.Bearers[point] = Bearers{
+ Bearer: info.Bearer,
+ NameChange: true,
+ Type: info.AccountType,
+ Password: info.Password,
+ Email: info.Email,
+ AuthedAt: time.Now().Unix(),
+ AuthInterval: 54000,
+ Info: UserINFO{
+ ID: info.Info.ID,
+ Name: info.Info.Name,
+ },
+ }
+ break
+ }
+ }
+ for i, Bearers := range Bearer.Details {
+ if strings.EqualFold(Bearers.Email, info.Email) {
+ Bearer.Details[i] = info
+ break
+ }
+ }
+ var Found bool
+ E1:
+ for i, accs := range Accs["Giftcard"] {
+ for e, b := range accs.Accs {
+ if strings.EqualFold(b.Email, info.Email) {
+ Accs["Giftcard"][i].Accs[e] = info
+ Found = true
+ break E1
+ }
+ }
+ }
+ if !Found {
+ E2:
+ for i, accs := range Accs["Microsoft"] {
+ for e, b := range accs.Accs {
+ if strings.EqualFold(b.Email, info.Email) {
+ Accs["Microsoft"][i].Accs[e] = info
+ Found = true
+ break E2
+ }
+ }
+ }
+ }
+ } else {
+ Con.Bearers = append(Con.Bearers, Bearers{
+ Bearer: info.Bearer,
+ AuthInterval: 54000,
+ AuthedAt: time.Now().Unix(),
+ Type: info.AccountType,
+ Email: info.Email,
+ Password: info.Password,
+ NameChange: true,
+ Info: UserINFO{
+ ID: info.Info.ID,
+ Name: info.Info.Name,
+ },
+ })
+ }
+ } else {
+ fmt.Println(Logo(fmt.Sprintf("Account %v cannot name change.. %v", acc[0], info.Info.Name)))
+ for point, bf := range Con.Bearers {
+ if strings.EqualFold(bf.Email, info.Email) {
+ Con.Bearers[point] = Bearers{
+ Type: info.AccountType,
+ Bearer: info.Bearer,
+ NameChange: false,
+ Password: info.Password,
+ Email: info.Email,
+ AuthedAt: time.Now().Unix(),
+ AuthInterval: 54000,
+ Info: UserINFO(info.Info),
+ }
+ break
+ }
+ }
+ for i, Bearers := range Bearer.Details {
+ if strings.EqualFold(Bearers.Email, info.Email) {
+ Bearer.Details[i] = info
+ break
+ }
+ }
+ var Found bool
+ E13:
+ for i, accs := range Accs["Giftcard"] {
+ for e, b := range accs.Accs {
+ if strings.EqualFold(b.Email, info.Email) {
+ Accs["Giftcard"][i].Accs[e] = info
+ Found = true
+ break E13
+ }
+ }
+ }
+ if !Found {
+ E23:
+ for i, accs := range Accs["Microsoft"] {
+ for e, b := range accs.Accs {
+ if strings.EqualFold(b.Email, info.Email) {
+ Accs["Microsoft"][i].Accs[e] = info
+ Found = true
+ break E23
+ }
+ }
+ }
+ }
+ Invalids = append(Invalids, acc[0]+":"+acc[1])
+ }
+ }
+ wg.Done()
+ }
+ }
+ }()
+ info := apiGO.MS_authentication(acc[0], acc[1], &apiGO.ProxyMS{IP: ip, Port: port, User: user, Password: pass})
+ if info.Error != "" {
+ Authed = true
+ fmt.Println(Logo(fmt.Sprintf("Account %v came up Invalid: %v", HashEmailClean(info.Email), info.Error)))
+ Invalids = append(Invalids, acc[0]+":"+acc[1])
+ } else if info.Bearer != "" {
+ if IsChangeable(proxy, info.Bearer) {
+ Authed = true
+ fmt.Println(Logo(fmt.Sprintf("[%v] Succesfully authed %v", time.Now().Format("15:04:05.0000"), HashEmailClean(info.Email))))
+ if reauth {
+ for point, bf := range Con.Bearers {
+ if strings.EqualFold(bf.Email, info.Email) {
+ Con.Bearers[point] = Bearers{
+ Bearer: info.Bearer,
+ NameChange: true,
+ Type: info.AccountType,
+ Password: info.Password,
+ Email: info.Email,
+ AuthedAt: time.Now().Unix(),
+ AuthInterval: 54000,
+ Info: UserINFO{
+ ID: info.Info.ID,
+ Name: info.Info.Name,
+ },
+ }
+ break
+ }
+ }
+ for i, Bearers := range Bearer.Details {
+ if strings.EqualFold(Bearers.Email, info.Email) {
+ Bearer.Details[i] = info
+ break
+ }
+ }
+ var Found bool
+ E1:
+ for i, accs := range Accs["Giftcard"] {
+ for e, b := range accs.Accs {
+ if strings.EqualFold(b.Email, info.Email) {
+ Accs["Giftcard"][i].Accs[e] = info
+ Found = true
+ break E1
+ }
+ }
+ }
+ if !Found {
+ E2:
+ for i, accs := range Accs["Microsoft"] {
+ for e, b := range accs.Accs {
+ if strings.EqualFold(b.Email, info.Email) {
+ Accs["Microsoft"][i].Accs[e] = info
+ Found = true
+ break E2
+ }
+ }
+ }
+ }
+ } else {
+ Con.Bearers = append(Con.Bearers, Bearers{
+ Bearer: info.Bearer,
+ AuthInterval: 54000,
+ AuthedAt: time.Now().Unix(),
+ Type: info.AccountType,
+ Email: info.Email,
+ Password: info.Password,
+ NameChange: true,
+ Info: UserINFO{
+ ID: info.Info.ID,
+ Name: info.Info.Name,
+ },
+ })
+ }
+ } else {
+ fmt.Println(Logo(fmt.Sprintf("Account %v cannot name change.. %v", acc[0], info.Info.Name)))
+ for point, bf := range Con.Bearers {
+ if strings.EqualFold(bf.Email, info.Email) {
+ Con.Bearers[point] = Bearers{
+ Type: info.AccountType,
+ Bearer: info.Bearer,
+ NameChange: false,
+ Password: info.Password,
+ Email: info.Email,
+ AuthedAt: time.Now().Unix(),
+ AuthInterval: 54000,
+ Info: UserINFO(info.Info),
+ }
+ break
+ }
+ }
+ for i, Bearers := range Bearer.Details {
+ if strings.EqualFold(Bearers.Email, info.Email) {
+ Bearer.Details[i] = info
+ break
+ }
+ }
+ var Found bool
+ E13:
+ for i, accs := range Accs["Giftcard"] {
+ for e, b := range accs.Accs {
+ if strings.EqualFold(b.Email, info.Email) {
+ Accs["Giftcard"][i].Accs[e] = info
+ Found = true
+ break E13
+ }
+ }
+ }
+ if !Found {
+ E23:
+ for i, accs := range Accs["Microsoft"] {
+ for e, b := range accs.Accs {
+ if strings.EqualFold(b.Email, info.Email) {
+ Accs["Microsoft"][i].Accs[e] = info
+ Found = true
+ break E23
+ }
+ }
+ }
+ }
+ Invalids = append(Invalids, acc[0]+":"+acc[1])
+ }
+ }
+ wg.Done()
+ }(acc_1.Proxy, acc)
+ } else {
+ switch info := apiGO.MS_authentication(acc[0], acc[1], nil); true {
+ case info.Error != "":
+ fmt.Println(Logo(fmt.Sprintf("Account %v came up Invalid: %v", HashEmailClean(info.Email), info.Error)))
+ Invalids = append(Invalids, acc[0]+":"+acc[1])
+ case info.Bearer != "" && IsChangeable("", info.Bearer):
+ fmt.Println(Logo(fmt.Sprintf("[%v] Succesfully authed %v", time.Now().Format("15:04:05.0000"), HashEmailClean(info.Email))))
+ if reauth {
+ for point, bf := range Con.Bearers {
+ if strings.EqualFold(bf.Email, info.Email) {
+ Con.Bearers[point] = Bearers{
+ Bearer: info.Bearer,
+ NameChange: true,
+ Type: info.AccountType,
+ Password: info.Password,
+ Email: info.Email,
+ AuthedAt: time.Now().Unix(),
+ AuthInterval: 54000,
+ Info: UserINFO{
+ ID: info.Info.ID,
+ Name: info.Info.Name,
+ },
+ }
+ break
+ }
+ }
+ for i, Bearers := range Bearer.Details {
+ if strings.EqualFold(Bearers.Email, info.Email) {
+ Bearer.Details[i] = info
+ break
+ }
+ }
+ var Found bool
+ E1:
+ for i, accs := range Accs["Giftcard"] {
+ for e, b := range accs.Accs {
+ if strings.EqualFold(b.Email, info.Email) {
+ Accs["Giftcard"][i].Accs[e] = info
+ Found = true
+ break E1
+ }
+ }
+ }
+ if !Found {
+ E2:
+ for i, accs := range Accs["Microsoft"] {
+ for e, b := range accs.Accs {
+ if strings.EqualFold(b.Email, info.Email) {
+ Accs["Microsoft"][i].Accs[e] = info
+ Found = true
+ break E2
+ }
+ }
+ }
+ }
+ } else {
+ Con.Bearers = append(Con.Bearers, Bearers{
+ Bearer: info.Bearer,
+ AuthInterval: 54000,
+ AuthedAt: time.Now().Unix(),
+ Type: info.AccountType,
+ Email: info.Email,
+ Password: info.Password,
+ NameChange: true,
+ })
+ }
+ default:
+ fmt.Println(Logo(fmt.Sprintf("Account %v Bearer is nil or it cannot name change.. [%v]", HashEmailClean(acc[0]), acc[1])))
+ Invalids = append(Invalids, acc[0]+":"+acc[1])
+ }
+ }
+ }
+ }
+ }
+ wg.Wait()
+ if len(Invalids) != 0 {
+ if _, err := os.Stat("data/accounts.txt"); os.IsNotExist(err) {
+ os.Create("data/accounts.txt")
+ }
+
+ os.WriteFile("data/accounts.txt", []byte(strings.Join(Invalids, "\n")), 0644)
+
+ scanner := bufio.NewScanner(strings.NewReader(strings.Join(Invalids, "\n")))
+ for scanner.Scan() {
+ for i, acc := range Con.Bearers {
+ if strings.EqualFold(acc.Email, strings.Split(scanner.Text(), ":")[0]) {
+ Con.Bearers[i].NameChange = false
+ Con.SaveConfig()
+ Con.LoadState()
+ break
+ }
+ }
+ }
+ }
+ if len(invalidproxys) != 0 {
+ if body, err := os.ReadFile("data/proxys.txt"); err == nil {
+ strings.ReplaceAll(string(body), strings.Join(invalidproxys, "\n"), "")
+ fmt.Println(strings.ReplaceAll(string(body), strings.Join(invalidproxys, "\n"), ""))
+ }
+ }
+}
+
+func IsChangeable(proxy, bearer string) bool {
+ data := strings.Split(proxy, ":")
+ var Client http.Client
+ switch len(data) {
+ case 4:
+ Client = http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(&url.URL{Scheme: "http", User: url.UserPassword(data[2], data[3]), Host: data[0] + ":" + data[1]})}}
+ case 2:
+ Client = http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(&url.URL{Scheme: "http", Host: data[0] + ":" + data[1]})}}
+ }
+ req, _ := http.NewRequest("GET", "https://api.minecraftservices.com/minecraft/profile/namechange", nil)
+ req.Header.Add("Authorization", "Bearer "+bearer)
+ if resp, err := Client.Do(req); err == nil {
+ body, _ := io.ReadAll(resp.Body)
+ switch resp.StatusCode {
+ case 200:
+ var Data struct {
+ NC bool `json:"nameChangeAllowed"`
+ }
+ json.Unmarshal(body, &Data)
+ return Data.NC
+ case 404:
+ return true
+ }
+ }
+ return false
+}
+
+func Regenerateallaccs() {
+ var use_proxy, ug int
+ var f bool = true
+ var Data []Payload_auth
+ for i, bearer := range Con.Bearers {
+ if !bearer.NOT_ENTITLED_CHECKED {
+ Con.Bearers[i].NOT_ENTITLED_CHECKED = true
+ if use_proxy >= len(Proxy.Proxys) && len(Proxy.Proxys) < len(Bearer.Details) {
+ break
+ }
+
+ if f {
+ Data = append(Data, Payload_auth{Proxy: Proxy.Proxys[use_proxy]})
+ f = false
+ use_proxy++
+ }
+ if len(Data[ug].Accounts) != 3 {
+ Data[ug].Accounts = append(Data[ug].Accounts, bearer.Bearer)
+ } else {
+ ug++
+ Data = append(Data, Payload_auth{Proxy: Proxy.Proxys[use_proxy], Accounts: []string{bearer.Bearer}})
+ use_proxy++
+ }
+ }
+ }
+
+ for _, proxy := range Data {
+ go func(proxy Payload_auth) {
+ for _, account := range proxy.Accounts {
+ req, _ := http.NewRequest("GET", "https://api.minecraftservices.com/entitlements/mcstore", nil)
+ req.Header.Add("Authorization", "Bearer "+account)
+ p := strings.Split(proxy.Proxy, ":")
+ var P_url *url.URL
+ switch len(p) {
+ case 2:
+ P_url = &url.URL{
+ Scheme: "http",
+ Host: p[0] + ":" + p[1],
+ }
+ case 4:
+ P_url = &url.URL{
+ Scheme: "http",
+ Host: p[0] + ":" + p[1],
+ User: url.UserPassword(p[2], p[3]),
+ }
+ }
+ (&http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(P_url)}}).Do(req)
+ }
+ }(proxy)
+ }
+ Con.SaveConfig()
+ Con.LoadState()
+}
diff --git a/packages/utils/config.go b/packages/utils/config.go
new file mode 100644
index 0000000..a44f986
--- /dev/null
+++ b/packages/utils/config.go
@@ -0,0 +1,99 @@
+package utils
+
+import (
+ "encoding/json"
+ "io"
+ "os"
+ "strings"
+)
+
+var (
+ ProxyByte = []byte(`
+ -- GlobalSign Root R2, valid until Dec 15, 2021
+ -----BEGIN CERTIFICATE-----
+ MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
+ A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
+ Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
+ MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
+ A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+ hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
+ v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
+ eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
+ tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
+ C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
+ zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
+ mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
+ V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
+ bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
+ 3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
+ J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
+ 291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
+ ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
+ AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
+ TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
+ -----END CERTIFICATE-----`)
+)
+
+func (s *Config) ToJson() (Data []byte, err error) {
+ return json.MarshalIndent(s, "", " ")
+}
+
+func (config *Config) SaveConfig() {
+ if Json, err := config.ToJson(); err == nil {
+ WriteFile("data/config.json", string(Json))
+ }
+}
+
+func (s *Config) LoadState() {
+ data, err := ReadFile("data/config.json")
+ if err != nil {
+ s.LoadFromFile()
+ s.Settings = AccountSettings{
+ GC_ReqAmt: 1,
+ MFA_ReqAmt: 1,
+ AccountsPerGc: 5,
+ AccountsPerMfa: 1,
+ SleepAmtPerGc: 15000,
+ SleepAmtPerMfa: 10000,
+ Spread: 0,
+ UseCustomSpread: false,
+ }
+ s.Bools = Bools{
+ FirstUse: true,
+ UseProxyDuringAuth: false,
+ DownloadedPW: false,
+ UseWebhook: false,
+ }
+ s.SkinChange.Variant = "slim"
+ s.SkinChange.Link = "https://textures.minecraft.net/texture/516accb84322ca168a8cd06b4d8cc28e08b31cb0555eee01b64f9175cefe7b75"
+ s.Gradient = []Values{{R: "125", G: "110", B: "221"}, {R: "90%", G: "45%", B: "97%"}}
+ s.SaveConfig()
+ return
+ }
+
+ json.Unmarshal([]byte(data), s)
+ s.LoadFromFile()
+}
+
+func (c *Config) LoadFromFile() {
+ jsonFile, err := os.Open("data/config.json")
+ if err != nil {
+ jsonFile, _ = os.Create("data/config.json")
+ }
+
+ byteValue, _ := io.ReadAll(jsonFile)
+ json.Unmarshal(byteValue, &c)
+}
+
+func WriteFile(path string, content string) {
+ os.WriteFile(path, []byte(content), 0644)
+}
+
+func ReadFile(path string) ([]byte, error) {
+ return os.ReadFile(path)
+}
+
+func HashEmailClean(email string) string {
+ e := strings.Split(email, "@")[0] // stfu
+ return e[0:2] + strings.Repeat("⋅", 2) + e[len(e)-5:]
+}
diff --git a/packages/utils/proxy.go b/packages/utils/proxy.go
new file mode 100644
index 0000000..06f3c32
--- /dev/null
+++ b/packages/utils/proxy.go
@@ -0,0 +1,31 @@
+package utils
+
+import (
+ "crypto/tls"
+ "encoding/base64"
+ "fmt"
+ "net"
+ "strings"
+)
+
+func Connect(proxy string) (*tls.Conn, bool) {
+ ip := strings.Split(proxy, ":")
+ if conn, err := net.Dial("tcp", ip[0]+":"+ip[1]); err == nil {
+ if len(ip) > 2 {
+ conn.Write([]byte(fmt.Sprintf("CONNECT minecraftapi-bef7bxczg0amd8ef.z01.azurefd.net:443 HTTP/1.1\r\nHost: minecraftapi-bef7bxczg0amd8ef.z01.azurefd.net:443\r\nProxy-Authorization: Basic %v\r\nProxy-Connection: keep-alive\r\nUser-Agent: MCSN/1.1\r\n\r\n", base64.RawStdEncoding.EncodeToString([]byte(ip[2]+":"+ip[3])))))
+ } else {
+ conn.Write([]byte("CONNECT minecraftapi-bef7bxczg0amd8ef.z01.azurefd.net:443 HTTP/1.1\r\nHost: minecraftapi-bef7bxczg0amd8ef.z01.azurefd.net:443\r\nProxy-Connection: keep-alive\r\nUser-Agent: MCSN/1.1\r\n\r\n"))
+ }
+ var junk = make([]byte, 4096)
+ conn.Read(junk)
+ switch Status := string(junk); Status[9:12] {
+ case "200":
+ return tls.Client(conn, &tls.Config{RootCAs: Roots, InsecureSkipVerify: true, ServerName: "minecraftapi-bef7bxczg0amd8ef.z01.azurefd.net"}), true
+ case "407":
+ fmt.Println(Logo(fmt.Sprintf("[%v] Proxy <%v> Failed to authorize: Username/Password invalid.", Status[9:12], ip[0])))
+ default:
+ return nil, false
+ }
+ }
+ return nil, false
+}
diff --git a/packages/utils/types.go b/packages/utils/types.go
new file mode 100644
index 0000000..6ab1338
--- /dev/null
+++ b/packages/utils/types.go
@@ -0,0 +1,163 @@
+package utils
+
+import (
+ "crypto/x509"
+ "time"
+
+ "main/packages/apiGO"
+)
+
+var (
+ Roots *x509.CertPool = x509.NewCertPool()
+ Con Config
+ Proxy apiGO.Proxys
+ Bearer apiGO.MCbearers
+ RGB []string
+)
+
+type NameMCInfo struct {
+ Action string `json:"action"`
+ Desc string `json:"desc"`
+ Code string `json:"code"`
+ Data NameMCData `json:"data"`
+}
+type NameMCData struct {
+ Status string `json:"status"`
+ Searches string `json:"searches"`
+ Begin int `json:"begin"`
+ End int `json:"end"`
+ StartDate time.Time `json:"start_date"`
+ EndDate time.Time `json:"end_date"`
+ Headurl string `json:"headurl"`
+}
+
+type NameMCHead struct {
+ Bodyurl string `json:"bodyurl"`
+ Headurl string `json:"headurl"`
+ ID string `json:"id"`
+}
+
+type Names struct {
+ Name string
+ Taken bool
+}
+
+type Proxies struct {
+ IP, Port, User, Password string
+}
+
+type Status struct {
+ Data struct {
+ Status string `json:"status"`
+ } `json:"details"`
+}
+
+type CF struct {
+ Tokens string `json:"tokens"`
+ GennedAT int64 `json:"unix_of_creation"`
+}
+
+type Config struct {
+ Gradient []Values `json:"gradient"`
+ NMC Namemc_Data `json:"namemc_settings"`
+ Settings AccountSettings `json:"settings"`
+ Bools Bools `json:"sniper_config"`
+ SkinChange Skin `json:"skin_config"`
+ CF CF `json:"cf_tokens"`
+ Bearers []Bearers `json:"Bearers"`
+ Recovery []Succesful `json:"recovery"`
+}
+
+type Namemc_Data struct {
+ UseNMC bool `json:"usenamemc_fordroptime_andautofollow"`
+ Display string `json:"name_to_use_for_follows"`
+ Key string `json:"namemc_email:pass"`
+ NamemcLoginData NMC `json:"namemc_login_data"`
+ P []Profiles `json:"genned_profiles"`
+}
+
+type Profiles struct {
+ Session_ID string `json:"session_id"`
+ Email string `json:"email"`
+ Password string `json:"password"`
+}
+
+type NMC struct {
+ Token string `json:"token"`
+ LastAuthed int64 `json:"last_unix_auth_timestamp"`
+}
+
+type Bearers struct {
+ Bearer string `json:"Bearer"`
+ Email string `json:"Email"`
+ Password string `json:"Password"`
+ AuthInterval int64 `json:"AuthInterval"`
+ AuthedAt int64 `json:"AuthedAt"`
+ Type string `json:"Type"`
+ NameChange bool `json:"NameChange"`
+ Info UserINFO `json:"Info"`
+ NOT_ENTITLED_CHECKED bool `json:"checked_entitled"`
+}
+
+type Succesful struct {
+ Email string
+ Recovery string
+ Code_Used string
+}
+type Data struct {
+ Info []Succesful
+}
+
+type Refresh struct {
+ Time_since_last_gen int64 `json:"last_entitled_prevention"`
+}
+
+type AccountSettings struct {
+ AskForUnixPrompt bool `json:"ask_for_unix_prompt"`
+ AccountsPerGc int `json:"accounts_per_gc_proxy"`
+ AccountsPerMfa int `json:"accounts_per_mfa_proxy"`
+ GC_ReqAmt int `json:"amt_reqs_per_gc_acc"`
+ MFA_ReqAmt int `json:"amt_reqs_per_mfa_acc"`
+ SleepAmtPerGc int `json:"sleep_for_gc"`
+ SleepAmtPerMfa int `json:"sleep_for_mfa"`
+ UseCustomSpread bool `json:"use_own_spread_value"`
+ Spread int64 `json:"spread_ms"`
+}
+
+type Bools struct {
+ UseCF bool `json:"use_cf_token"`
+ UseProxyDuringAuth bool `json:"useproxysduringauth"`
+ UseWebhook bool `json:"sendpersonalwhonsnipe"`
+ FirstUse bool `json:"firstuse_IGNORETHIS"`
+ DownloadedPW bool `json:"pwinstalled_IGNORETHIS"`
+ ApplyNewRecoveryToExistingEmails bool `json:"applynewemailstoexistingrecoveryemails"`
+}
+
+type Values struct {
+ R string `json:"r"`
+ G string `json:"g"`
+ B string `json:"b"`
+}
+
+type Info struct {
+ Bearer string
+ RefreshToken string
+ AccessToken string
+ Expires int
+ AccountType string
+ Email string
+ Password string
+ Requests int
+ Info UserINFO `json:"Info"`
+ Error string
+}
+
+type UserINFO struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+}
+
+type Skin struct {
+ Link string `json:"url"`
+ Variant string `json:"variant"`
+}
diff --git a/packages/utils/utils.go b/packages/utils/utils.go
new file mode 100644
index 0000000..eaf3cb3
--- /dev/null
+++ b/packages/utils/utils.go
@@ -0,0 +1,62 @@
+package utils
+
+import (
+ "crypto/tls"
+ "encoding/json"
+ "errors"
+ "io"
+ "net/http"
+ "os"
+ "time"
+
+ "github.com/iskaa02/qalam/gradient"
+)
+
+func CheckForValidFile(input string) bool {
+ _, err := os.Stat(input)
+ return errors.Is(err, os.ErrNotExist)
+}
+
+type SniperProxy struct {
+ Proxy *tls.Conn
+ UsedAt time.Time
+ Alive bool
+ ProxyDetails Proxies
+}
+
+func IsAvailable(name string) bool {
+ resp, err := http.Get("https://account.mojang.com/available/minecraft/" + name)
+ if err == nil {
+ return resp.StatusCode == 200
+ } else {
+ return false
+ }
+}
+
+func Logo(Data string) string {
+ g, _ := gradient.NewGradientBuilder().
+ HtmlColors(RGB...).
+ Mode(gradient.BlendRgb).
+ Build()
+ return g.Mutline(Data)
+}
+
+func GetHeadUrl(name string) (string, string) {
+ if resp, err := http.Get("https://namemc.info/data/namemc/head/" + name); err == nil {
+ res, _ := io.ReadAll(resp.Body)
+ var Data NameMCHead
+ json.Unmarshal(res, &Data)
+ return Data.Headurl, Data.Bodyurl
+ }
+ return "", ""
+}
+
+func GetDroptimes(name string) (int64, int64, string, string) {
+ if resp, err := http.Get("https://namemc.info/data/info/" + name); err == nil {
+ res, _ := io.ReadAll(resp.Body)
+ var Data NameMCInfo
+ json.Unmarshal(res, &Data)
+ return int64(Data.Data.Begin), int64(Data.Data.End), Data.Data.Status, Data.Data.Searches
+ }
+ return 0, 0, "", ""
+}