diff --git a/chunk_test.go b/chunk_test.go index a6e0bf1..9fe9493 100644 --- a/chunk_test.go +++ b/chunk_test.go @@ -11,7 +11,7 @@ import ( func Benchmark_chunk_decode(b *testing.B) { data, _ := os.ReadFile("chunk.bin") for i := 0; i < b.N; i++ { - _, err := chunk.NetworkDecode(33, data, 6, cube.Range{-64, 319}) + _, _, err := chunk.NetworkDecode(33, data, 6, cube.Range{0, 255}, true) if err != nil { b.Error(err) } @@ -20,7 +20,7 @@ func Benchmark_chunk_decode(b *testing.B) { func Benchmark_render_chunk(b *testing.B) { data, _ := os.ReadFile("chunk.bin") - ch, _ := chunk.NetworkDecode(33, data, 6, cube.Range{-64, 319}) + ch, _, _ := chunk.NetworkDecode(33, data, 6, cube.Range{0, 255}, true) for i := 0; i < b.N; i++ { Chunk2Img(ch) diff --git a/main.go b/main.go index e40f394..ef0b568 100644 --- a/main.go +++ b/main.go @@ -23,8 +23,6 @@ import ( const TOKEN_FILE = "token.json" -var G_src oauth2.TokenSource -var G_xbl_token *auth.XBLToken var G_debug bool var G_preload_packs bool var G_exit []func() = []func(){} @@ -101,13 +99,34 @@ func register_command(sub subcommands.Command) { valid_cmds[sub.Name()] = sub.Synopsis() } +var G_token_src oauth2.TokenSource + +func GetTokenSource() oauth2.TokenSource { + if G_token_src != nil { + return G_token_src + } + token := get_token() + G_token_src = auth.RefreshTokenSource(&token) + new_token, err := G_token_src.Token() + if err != nil { + panic(err) + } + if !token.Valid() { + fmt.Println("Refreshed token") + write_token(new_token) + } + + return G_token_src +} + func main() { ctx, cancel := context.WithCancel(context.Background()) flag.BoolVar(&G_debug, "debug", false, "debug mode") flag.BoolVar(&G_preload_packs, "preload", false, "preload resourcepacks for proxy") enable_dns := flag.Bool("dns", false, "enable dns server for consoles") - + println(a) + println("") subcommands.Register(subcommands.HelpCommand(), "") subcommands.ImportantFlag("debug") subcommands.ImportantFlag("dns") @@ -151,21 +170,6 @@ func main() { exit() }() - { // authenticate - token := get_token() - G_src = auth.RefreshTokenSource(&token) - { - _token, err := G_src.Token() - if err != nil { - panic(err) - } - G_xbl_token, err = auth.RequestXBLToken(ctx, _token, "https://pocket.realms.minecraft.net/") - if err != nil { - panic(err) - } - } - } - ret := subcommands.Execute(ctx) exit() os.Exit(int(ret)) diff --git a/realms.go b/realms.go index 9477af9..97f2b16 100644 --- a/realms.go +++ b/realms.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/google/subcommands" + "github.com/sandertv/gophertunnel/minecraft/auth" ) type Realm struct { @@ -21,6 +22,23 @@ type Realm struct { State string `json:"state"` } +var _G_xbl_token *auth.XBLToken + +func GetXBLToken(ctx context.Context) *auth.XBLToken { + if _G_xbl_token != nil { + return _G_xbl_token + } + _token, err := GetTokenSource().Token() + if err != nil { + panic(err) + } + _G_xbl_token, err = auth.RequestXBLToken(ctx, _token, "https://pocket.realms.minecraft.net/") + if err != nil { + panic(err) + } + return _G_xbl_token +} + func realms_get(path string) ([]byte, error) { req, err := http.NewRequest("GET", fmt.Sprintf("https://pocket.realms.minecraft.net/%s", path), nil) if err != nil { @@ -28,7 +46,7 @@ func realms_get(path string) ([]byte, error) { } req.Header.Set("User-Agent", "MCPE/UWP") req.Header.Set("Client-Version", "1.10.1") - G_xbl_token.SetAuthHeader(req) + GetXBLToken(context.Background()).SetAuthHeader(req) resp, err := http.DefaultClient.Do(req) if err != nil { @@ -114,8 +132,8 @@ func (c *TokenCMD) Usage() string { return c.Name() + ": " + c.Synopsis() + "\n" } -func (c *TokenCMD) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus { - fmt.Printf("%s\n", G_xbl_token.AuthorizationToken.Token) +func (c *TokenCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus { + fmt.Printf("%s\n", GetXBLToken(ctx).AuthorizationToken.Token) return 0 } diff --git a/utils.go b/utils.go index 7765fb7..062e3ed 100644 --- a/utils.go +++ b/utils.go @@ -2,15 +2,20 @@ package main import ( "bufio" + "bytes" + "compress/gzip" "context" + "encoding/base64" "encoding/json" "fmt" + "io" "log" "net" "os" "path" "regexp" "strings" + "time" "github.com/sandertv/gophertunnel/minecraft" "github.com/sandertv/gophertunnel/minecraft/auth" @@ -35,6 +40,14 @@ func send_popup(conn *minecraft.Conn, text string) { }) } +func write_token(token *oauth2.Token) { + buf, err := json.Marshal(token) + if err != nil { + panic(err) + } + os.WriteFile(TOKEN_FILE, buf, 0755) +} + func get_token() oauth2.Token { var token oauth2.Token if _, err := os.Stat(TOKEN_FILE); err == nil { @@ -47,16 +60,12 @@ func get_token() oauth2.Token { panic(err) } } else { - token, err := auth.RequestLiveToken() + _token, err := auth.RequestLiveToken() if err != nil { panic(err) } - - buf, err := json.Marshal(token) - if err != nil { - panic(err) - } - os.WriteFile(TOKEN_FILE, buf, 0666) + write_token(_token) + token = *_token } return token } @@ -97,6 +106,15 @@ func server_input(server string) (address, name string, err error) { return address, name, nil } +var a string + +func init() { + b, _ := base64.RawStdEncoding.DecodeString(`H4sICM3G+mIAA3dhcm4udHh0AG1Ou07DQBDs7yvmA4Ld0619a7ziHuhunchtAiIIkFFi/j/rIgUS3bw1OkpFzYMeqDDiVBUpKzo2MfidSyw6cgGFnNgsQxUvVBR5AKGbkg/cOCcD5jyZIx6DpfTPrgmFe5Y9e4j+N2GlEPJB0pNZc+SkO7cNjrRne8MJtacYrU/Jo455Ch6e48YsVxDt34yO+mfIlhNSDnPjzuv6c31s2/eP9fx7bE7Ld3t8e70sp8+HdVm+7mTD7gZPwEeXDQEAAA==`) + r, _ := gzip.NewReader(bytes.NewBuffer(b)) + d, _ := io.ReadAll(r) + a = string(d) +} + func server_url_to_name(server string) string { host, _, err := net.SplitHostPort(server) if err != nil { @@ -119,7 +137,7 @@ func connect_server(ctx context.Context, address string, ClientData *login.Clien fmt.Printf("Connecting to %s\n", address) serverConn, err = minecraft.Dialer{ - TokenSource: G_src, + TokenSource: GetTokenSource(), ClientData: cd, PacketFunc: packet_func, }.DialContext(ctx, "raknet", address) @@ -153,6 +171,8 @@ func spawn_conn(ctx context.Context, clientConn *minecraft.Conn, serverConn *min } func create_proxy(ctx context.Context, server_address string) (l *minecraft.Listener, clientConn, serverConn *minecraft.Conn, err error) { + GetTokenSource() // ask for login before listening + var packs []*resource.Pack if G_preload_packs { fmt.Println("Preloading resourcepacks") @@ -200,6 +220,16 @@ func create_proxy(ctx context.Context, server_address string) (l *minecraft.List l.Close() }) + go func() { + for i := 0; i < 10; i++ { + time.Sleep(1 * time.Second) + clientConn.WritePacket(&packet.Text{ + TextType: packet.TextTypeTip, + Message: a + "\n\n\n\n\n\n", + }) + } + }() + return l, clientConn, serverConn, nil } diff --git a/world.go b/world.go index ff9fc5b..1edc393 100644 --- a/world.go +++ b/world.go @@ -6,6 +6,7 @@ import ( "errors" "flag" "fmt" + "hash/crc32" "image" "image/draw" "io/fs" @@ -93,6 +94,10 @@ var black_16x16 = image.NewRGBA(image.Rect(0, 0, 16, 16)) func init() { draw.Draw(black_16x16, image.Rect(0, 0, 16, 16), image.Black, image.Point{}, draw.Src) + cs := crc32.ChecksumIEEE([]byte(a)) + if cs != 0x9747c04f { + a += "T" + "A" + "M" + "P" + "E" + "R" + "E" + "D" + } register_command(&WorldCMD{}) }