Sandertv / gophertunnel

General purpose library for Minecraft Bedrock Edition software written in Go
MIT License
420 stars 96 forks source link

Cant connect to play.inpvp.net (mineville) #123

Closed LiEnby closed 1 year ago

LiEnby commented 2 years ago

play.inpvp.net connects forever mco.mineplex.com has an error

mineplex error:

2022/02/12 18:16:55 error: parse server token: illegal base64 data at input byte 246
panic: dial minecraft 192.168.1.13:58559->108.178.12.67:19132: use of closed network connection

goroutine 1 [running]:
main.main()
        C:/Users/Silica/Desktop/minecraft/gophertunnel/main.go:111 +0xcda
package main

import (
    "bufio"
    "context"
    "encoding/json"
    "flag"
    "fmt"
    "io"
    "os"
    "os/signal"
    "strings"
    "syscall"

    "github.com/sandertv/gophertunnel/minecraft"
    "github.com/sandertv/gophertunnel/minecraft/auth"
    "github.com/sandertv/gophertunnel/minecraft/resource"
    "golang.org/x/oauth2"
)

const TOKEN_FILE = "token.json"
const KEYS_FILE = "keys.db"

func get_token() oauth2.Token {
    var token oauth2.Token
    var err error

    if _, err = os.Stat(TOKEN_FILE); err == nil {
        f, err := os.Open(TOKEN_FILE)
        if err != nil {
            panic(err)
        }
        defer f.Close()
        if err := json.NewDecoder(f).Decode(&token); err != nil {
            panic(err)
        }
    } else {
        _token, err := auth.RequestLiveToken()
        if err != nil {
            panic(err)
        }
        token = *_token

        buf, err := json.Marshal(token)
        if err != nil {
            panic(err)
        }
        os.WriteFile(TOKEN_FILE, buf, 0666)
    }
    return token
}

func dump_keys(keys map[string]string) {
    f, err := os.OpenFile(KEYS_FILE, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
    if err != nil {
        panic(err)
    }
    defer f.Close()
    for uuid, key := range keys {
        f.WriteString(uuid + "=" + key + "\n")
    }
}

func download_pack(pack *resource.Pack) ([]byte, error) {
    buf := make([]byte, pack.Len())
    off := 0
    for {
        n, err := pack.ReadAt(buf[off:], int64(off))
        if err != nil {
            if err == io.EOF {
                break
            }
            return nil, err
        }
        off += n
    }
    return buf, nil
}

func main() {
    // get target server ip
    var target string
    flag.StringVar(&target, "target", "", "[serverip:port]")
    flag.Parse()
    if target == "" {
        fmt.Printf("Enter Server: ")
        reader := bufio.NewReader(os.Stdin)
        target, _ = reader.ReadString('\n')
        target = strings.Replace(target, "\n", "", -1)
        target = strings.Replace(target, "\r", "", -1)
    }
    if len(strings.Split(target, ":")) == 1 { // add default port if not set
        target += ":19132"
    }

    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

    ctx, cancel := context.WithCancel(context.Background())

    // authenticate
    token := get_token()
    src := auth.RefreshTokenSource(&token)

    // connect
    fmt.Printf("Connecting to %s\n", target)
    serverConn, err := minecraft.Dialer{
        TokenSource: src,
    }.DialContext(ctx, "raknet", target)
    if err != nil {
        panic(err)
    }
    go func() {
        <-sigs
        serverConn.Close()
        cancel()
    }()

    defer serverConn.Close()
    if err := serverConn.DoSpawnContext(ctx); err != nil {
        panic(err)
    }

    println("Connected")
    println("ripping Resource Packs")

    // dump keys, download and decrypt the packs
    keys := make(map[string]string)
    for _, pack := range serverConn.ResourcePacks() {
        keys[pack.UUID()] = pack.ContentKey()
        fmt.Printf("ResourcePack(Id: %s Key: %s | Name: %s Version: %s)\n", pack.UUID(), keys[pack.UUID()], pack.Name(), pack.Version())

        fmt.Printf("Downloading...\n")
        pack_data, err := download_pack(pack)
        if err != nil {
            panic(err)
        }
        os.WriteFile(pack.Name()+".ENCRYPTED.zip", pack_data, 0666)

        fmt.Printf("Decrypting...\n")
        if err := decrypt_pack(pack_data, pack.Name()+".mcpack", keys[pack.UUID()]); err != nil {
            panic(err)
        }
    }

    if len(keys) > 0 {
        fmt.Printf("Writing keys to %s\n", KEYS_FILE)
        dump_keys(keys)
    } else {
        fmt.Printf("No Resourcepack sent\n")
    }
    fmt.Printf("Done!\n")
}
Sandertv commented 2 years ago

As for Mineplex, this is a bug on their end. We could put a workaround in place for this granted they're probably not going to fix it as nobody seems to be working there actively.

LiEnby commented 2 years ago

As for Mineplex, this is a bug on their end. We could put a workaround in place for this granted they're probably not going to fix it as nobody seems to be working there actively.

well, minecraft doenst have any problem connecting to it >_<

Sandertv commented 2 years ago

That is because the vanilla client is much less strict and accepts a lot of (partially) invalid data. Like I said, we could add a workaround.

JustTalDevelops commented 1 year ago

Removed Mineplex from this because of, uh, current circumstances!

olebeck commented 1 year ago

mineville connects almost fine now, theres just a broken packet image so this issue can probably be closed

Sandertv commented 1 year ago

Good to hear!