From 39be9c678b458a9ecdb711c7ec279a19209445e2 Mon Sep 17 00:00:00 2001 From: olebeck <31539311+olebeck@users.noreply.github.com> Date: Sat, 15 Jul 2023 14:30:32 +0200 Subject: [PATCH] experimental transfer handler --- go.mod | 3 +- go.sum | 6 + subcommands/resourcepack-d/resourcepack-d.go | Bin 6993 -> 7112 bytes utils/proxy.go | 153 +++++++++++-------- utils/skin.go | 31 ++-- utils/skinpack.go | 7 +- utils/transfer.go | 53 +++++++ 7 files changed, 181 insertions(+), 72 deletions(-) create mode 100644 utils/transfer.go diff --git a/go.mod b/go.mod index fd644f4..5f60210 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/bedrock-tool/bedrocktool go 1.20 //replace github.com/sandertv/gophertunnel => ./gophertunnel -replace github.com/sandertv/gophertunnel => github.com/olebeck/gophertunnel v1.30.0-3 +replace github.com/sandertv/gophertunnel => github.com/olebeck/gophertunnel v1.31.0-2 //replace github.com/df-mc/dragonfly => ./dragonfly replace github.com/df-mc/dragonfly => github.com/olebeck/dragonfly v0.9.6-2 @@ -66,6 +66,7 @@ require ( github.com/muhammadmuzzammil1998/jsonc v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/segmentio/fasthash v1.0.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect github.com/tklauser/numcpus v0.6.1 // indirect diff --git a/go.sum b/go.sum index ae85e44..f9b7233 100644 --- a/go.sum +++ b/go.sum @@ -96,6 +96,10 @@ github.com/olebeck/gophertunnel v1.30.0-2 h1:JbkADJTfpCfC7nL9O08LON0k8OBahfmOdBy github.com/olebeck/gophertunnel v1.30.0-2/go.mod h1:HxQfl/8mZzvjzhekEH8RO6xLAgan9i/wIyrQzw0tIPY= github.com/olebeck/gophertunnel v1.30.0-3 h1:D3PP7ttzZWgyHmacVMiPslWsTj3UNeRvO1x+5kA97wE= github.com/olebeck/gophertunnel v1.30.0-3/go.mod h1:HxQfl/8mZzvjzhekEH8RO6xLAgan9i/wIyrQzw0tIPY= +github.com/olebeck/gophertunnel v1.31.0-1 h1:MeBwKKFT9SAe8FoeAT8o53TgrkPRJL5uAxLqWY3at5A= +github.com/olebeck/gophertunnel v1.31.0-1/go.mod h1:HxQfl/8mZzvjzhekEH8RO6xLAgan9i/wIyrQzw0tIPY= +github.com/olebeck/gophertunnel v1.31.0-2 h1:m/rUr/gjMTs/pSS5jPKlSxBJlC1WVjnxu8MHrVWfdkc= +github.com/olebeck/gophertunnel v1.31.0-2/go.mod h1:HxQfl/8mZzvjzhekEH8RO6xLAgan9i/wIyrQzw0tIPY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -114,6 +118,8 @@ github.com/sanbornm/go-selfupdate v0.0.0-20210106163404-c9b625feac49 h1:LuxslTBx github.com/sanbornm/go-selfupdate v0.0.0-20210106163404-c9b625feac49/go.mod h1:fY313ZGG810aWruFYcyq3coFpHDrWJVoMfSRI81y1r4= github.com/sandertv/go-raknet v1.12.0 h1:olUzZlIJyX/pgj/mrsLCZYjKLNDsYiWdvQ4NIm3z0DA= github.com/sandertv/go-raknet v1.12.0/go.mod h1:Gx+WgZBMQ0V2UoouGoJ8Wj6CDrMBQ4SB2F/ggpl5/+Y= +github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= +github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= github.com/shirou/gopsutil/v3 v3.23.5 h1:5SgDCeQ0KW0S4N0znjeM/eFHXXOKyv2dVNgRq/c9P6Y= github.com/shirou/gopsutil/v3 v3.23.5/go.mod h1:Ng3Maa27Q2KARVJ0SPZF5NdrQSC3XHKP8IIWrHgMeLY= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= diff --git a/subcommands/resourcepack-d/resourcepack-d.go b/subcommands/resourcepack-d/resourcepack-d.go index 571045a7ecebac589fc61ee7599a62005c25aa51..f137daec4e118988c2db4552e3ab5fbe8e7b9b40 100644 GIT binary patch literal 7112 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 literal 6993 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 diff --git a/utils/proxy.go b/utils/proxy.go index bcdee75..ca31e27 100644 --- a/utils/proxy.go +++ b/utils/proxy.go @@ -16,7 +16,6 @@ import ( "github.com/bedrock-tool/bedrocktool/locale" "github.com/bedrock-tool/bedrocktool/ui/messages" - "github.com/repeale/fp-go" "github.com/sandertv/gophertunnel/minecraft" "github.com/sandertv/gophertunnel/minecraft/protocol" "github.com/sandertv/gophertunnel/minecraft/protocol/login" @@ -95,6 +94,8 @@ type ProxyContext struct { commands map[string]IngameCommand handlers []*ProxyHandler + + reconnectHandler *ProxyHandler } func NewProxy() (*ProxyContext, error) { @@ -103,6 +104,7 @@ func NewProxy() (*ProxyContext, error) { AlwaysGetPacks: false, WithClient: true, IgnoreDisconnect: false, + reconnectHandler: NewTransferHandler(), } if Options.PathCustomUserData != "" { if err := p.LoadCustomUserData(Options.PathCustomUserData); err != nil { @@ -247,6 +249,8 @@ func (p *ProxyContext) proxyLoop(ctx context.Context, toServer bool) error { c2 = p.Client } + var transferingErr error = nil + for { if ctx.Err() != nil { return ctx.Err() @@ -262,7 +266,12 @@ func (p *ProxyContext) proxyLoop(ctx context.Context, toServer bool) error { if handler.PacketCB != nil { pk, err = handler.PacketCB(pk, toServer, time.Now()) if err != nil { - return err + if errors.Is(err, transferingErr) { + transferingErr = err + err = nil + } else { + return err + } } if pk == nil { logrus.Tracef("Dropped Packet: %s", pkName) @@ -279,6 +288,10 @@ func (p *ProxyContext) proxyLoop(ctx context.Context, toServer bool) error { return err } } + + if transferingErr != nil { + return transferingErr + } } } @@ -354,27 +367,19 @@ func (p *ProxyContext) connectClient(ctx context.Context, serverAddress string, return nil } -func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err error) { - if Options.Debug || Options.ExtraDebug { - p.AddHandler(NewDebugLogger(Options.ExtraDebug)) +func (p *ProxyContext) packetFunc(header packet.Header, payload []byte, src, dst net.Addr) { + if header.PacketID == packet.IDRequestNetworkSettings { + p.clientAddr = src } - if Options.Capture { - p.AddHandler(NewPacketCapturer()) - } - p.AddHandler(&ProxyHandler{ - Name: "Commands", - PacketCB: p.CommandHandlerPacketCB, - }) - for _, handler := range p.handlers { - if handler.AddressAndName != nil { - handler.AddressAndName(serverAddress, name) - } - if handler.ProxyRef != nil { - handler.ProxyRef(p) + if handler.PacketFunc == nil { + continue } + handler.PacketFunc(header, payload, src, dst) } +} +func (p *ProxyContext) connect(ctx context.Context, serverAddress string) (err error) { defer func() { for _, handler := range p.handlers { if handler.OnEnd != nil { @@ -410,7 +415,6 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err if p.Client != nil { p.Listener.Disconnect(p.Client.(*minecraft.Conn), DisconnectReason) } - p.Listener.Close() } }() } @@ -426,25 +430,13 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err handler.OnClientConnect(p.Client) } - packetFunc := func(header packet.Header, payload []byte, src, dst net.Addr) { - if header.PacketID == packet.IDRequestNetworkSettings { - p.clientAddr = src - } - for _, handler := range p.handlers { - if handler.PacketFunc == nil { - continue - } - handler.PacketFunc(header, payload, src, dst) - } - } - if isReplay { - p.Server, err = createReplayConnector(serverAddress[5:], packetFunc) + p.Server, err = createReplayConnector(serverAddress[5:], p.packetFunc) if err != nil { return err } } else { - p.Server, err = connectServer(ctx, serverAddress, cdp, p.AlwaysGetPacks, packetFunc, tokenSource) + p.Server, err = connectServer(ctx, serverAddress, cdp, p.AlwaysGetPacks, p.packetFunc, tokenSource) } if err != nil { for _, handler := range p.handlers { @@ -498,51 +490,92 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err } } + ctx2, cancel := context.WithCancelCause(ctx) + wg := sync.WaitGroup{} - doProxy := func(client bool, onErr func()) { + doProxy := func(client bool) { defer wg.Done() - if err := p.proxyLoop(ctx, client); err != nil { - logrus.Error(err) + if err := p.proxyLoop(ctx2, client); err != nil { + cancel(err) return } } // server to client wg.Add(1) - go doProxy(false, func() { - p.DisconnectClient() - }) + go doProxy(false) // client to server if p.Client != nil { wg.Add(1) - go doProxy(true, func() { - p.DisconnectServer() - }) + go doProxy(true) + } + go func() { + wg.Wait() + if ctx.Err() == nil { + cancel(nil) + } + }() + + /* + wantSecondary := fp.Filter(func(handler *ProxyHandler) bool { + return handler.SecondaryClientCB != nil + })(p.handlers) + + if len(wantSecondary) > 0 { + go func() { + for { + c, err := p.Listener.Accept() + if err != nil { + logrus.Error(err) + return + } + + for _, handler := range wantSecondary { + go handler.SecondaryClientCB(c.(*minecraft.Conn)) + } + } + }() + } + */ + + <-ctx2.Done() + err = ctx2.Err() + if err, ok := err.(*transferingErr); ok { + logrus.Infof("Redirect to %s", err.To) + if p.Client != nil { + p.Listener.Disconnect(p.Client.(*minecraft.Conn), "please reconnect") + } + return p.connect(ctx, err.To) } - wantSecondary := fp.Filter(func(handler *ProxyHandler) bool { - return handler.SecondaryClientCB != nil - })(p.handlers) + return nil +} - if len(wantSecondary) > 0 { - go func() { - for { - c, err := p.Listener.Accept() - if err != nil { - logrus.Error(err) - return - } +func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err error) { + if Options.Debug || Options.ExtraDebug { + p.AddHandler(NewDebugLogger(Options.ExtraDebug)) + } + if Options.Capture { + p.AddHandler(NewPacketCapturer()) + } + p.AddHandler(&ProxyHandler{ + Name: "Commands", + PacketCB: p.CommandHandlerPacketCB, + }) - for _, handler := range wantSecondary { - go handler.SecondaryClientCB(c.(*minecraft.Conn)) - } - } - }() + p.AddHandler(p.reconnectHandler) + + for _, handler := range p.handlers { + if handler.AddressAndName != nil { + handler.AddressAndName(serverAddress, name) + } + if handler.ProxyRef != nil { + handler.ProxyRef(p) + } } - wg.Wait() - return err + return p.connect(ctx, serverAddress) } func DecodePacket(pool packet.Pool, header packet.Header, payload []byte) packet.Packet { diff --git a/utils/skin.go b/utils/skin.go index 1c757e5..5024a00 100644 --- a/utils/skin.go +++ b/utils/skin.go @@ -18,12 +18,22 @@ type Skin struct { } type SkinGeometry struct { + SkinGeometryDescription + Bones []any `json:"bones"` +} + +type SkinGeometryDescription struct { + Identifier string `json:"identifier,omitempty"` Texturewidth int `json:"texturewidth"` Textureheight int `json:"textureheight"` VisibleBoundsWidth float64 `json:"visible_bounds_width"` VisibleBoundsHeight float64 `json:"visible_bounds_height"` VisibleBoundsOffset []float64 `json:"visible_bounds_offset,omitempty"` - Bones []any `json:"bones"` +} + +type SkinGeometry_1_12 struct { + Description SkinGeometryDescription `json:"description"` + Bones []any `json:"bones"` } func (skin *Skin) Hash() uuid.UUID { @@ -31,7 +41,7 @@ func (skin *Skin) Hash() uuid.UUID { return uuid.NewSHA1(uuid.NameSpaceURL, h) } -func (skin *Skin) getGeometry() (*SkinGeometry, string, error) { +func (skin *Skin) getGeometry() (*SkinGeometry_1_12, string, error) { if !skin.HaveGeometry() { return nil, "", errors.New("no geometry") } @@ -65,13 +75,16 @@ func (skin *Skin) getGeometry() (*SkinGeometry, string, error) { visible_bounds_height, _ := desc["visible_bounds_height"].(float64) visibleOffset, _ := desc["visible_bounds_offset"].([]float64) - return &SkinGeometry{ - Texturewidth: int(texture_width), - Textureheight: int(texture_height), - VisibleBoundsWidth: visible_bounds_width, - VisibleBoundsHeight: visible_bounds_height, - VisibleBoundsOffset: visibleOffset, - Bones: geom["bones"].([]any), + return &SkinGeometry_1_12{ + Description: SkinGeometryDescription{ + Identifier: desc["identifier"].(string), + Texturewidth: int(texture_width), + Textureheight: int(texture_height), + VisibleBoundsWidth: visible_bounds_width, + VisibleBoundsHeight: visible_bounds_height, + VisibleBoundsOffset: visibleOffset, + }, + Bones: geom["bones"].([]any), }, desc["identifier"].(string), nil } diff --git a/utils/skinpack.go b/utils/skinpack.go index 81ffbba..e58c08f 100644 --- a/utils/skinpack.go +++ b/utils/skinpack.go @@ -113,13 +113,16 @@ func (s *SkinPack) Save(fpath, serverName string) error { e.SetIndent("", "\t") if err := e.Encode(map[string]any{ "format_version": "1.12.0", - "minecraft:geometry": geometry, + "minecraft:geometry": []*SkinGeometry_1_12{geometry}, }); err != nil { f.Close() return err } f.Close() - geometryJson[geometryName] = *geometry + geometryJson[geometryName] = SkinGeometry{ + SkinGeometryDescription: geometry.Description, + Bones: geometry.Bones, + } entry.Geometry = geometryName } } diff --git a/utils/transfer.go b/utils/transfer.go new file mode 100644 index 0000000..3aea2a0 --- /dev/null +++ b/utils/transfer.go @@ -0,0 +1,53 @@ +package utils + +import ( + "fmt" + "net" + "strconv" + "time" + + "github.com/sandertv/gophertunnel/minecraft/protocol/packet" +) + +type transferingErr struct { + To string +} + +func (transferingErr) Error() string { + return "transferingErr" +} + +type transferHandler struct { + p *ProxyContext +} + +func NewTransferHandler() *ProxyHandler { + t := &transferHandler{} + return &ProxyHandler{ + Name: "transfer", + ProxyRef: func(pc *ProxyContext) { + t.p = pc + }, + PacketCB: t.packetCB, + } +} + +func (t *transferHandler) packetCB(pk packet.Packet, toServer bool, timeReceived time.Time) (packet.Packet, error) { + switch pk := pk.(type) { + case *packet.Transfer: + var pk2 packet.Packet = nil + if t.p.Client != nil { + host, port, err := net.SplitHostPort(t.p.Client.ClientData().ServerAddress) + if err != nil { + return nil, err + } + _port, _ := strconv.Atoi(port) + pk2 = &packet.Transfer{Address: host, Port: uint16(_port)} + } + + return pk2, &transferingErr{ + To: fmt.Sprintf("%s:%d", pk.Address, pk.Port), + } + } + return pk, nil +}