experimental transfer handler
This commit is contained in:
parent
f3d1a80985
commit
39be9c678b
3
go.mod
3
go.mod
|
@ -3,7 +3,7 @@ module github.com/bedrock-tool/bedrocktool
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
//replace github.com/sandertv/gophertunnel => ./gophertunnel
|
//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 => ./dragonfly
|
||||||
replace github.com/df-mc/dragonfly => github.com/olebeck/dragonfly v0.9.6-2
|
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/muhammadmuzzammil1998/jsonc v1.0.0 // indirect
|
||||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
||||||
github.com/rogpeppe/go-internal v1.10.0 // 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/shoenig/go-m1cpu v0.1.6 // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||||
|
|
6
go.sum
6
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-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 h1:D3PP7ttzZWgyHmacVMiPslWsTj3UNeRvO1x+5kA97wE=
|
||||||
github.com/olebeck/gophertunnel v1.30.0-3/go.mod h1:HxQfl/8mZzvjzhekEH8RO6xLAgan9i/wIyrQzw0tIPY=
|
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.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 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
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/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 h1:olUzZlIJyX/pgj/mrsLCZYjKLNDsYiWdvQ4NIm3z0DA=
|
||||||
github.com/sandertv/go-raknet v1.12.0/go.mod h1:Gx+WgZBMQ0V2UoouGoJ8Wj6CDrMBQ4SB2F/ggpl5/+Y=
|
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 h1:5SgDCeQ0KW0S4N0znjeM/eFHXXOKyv2dVNgRq/c9P6Y=
|
||||||
github.com/shirou/gopsutil/v3 v3.23.5/go.mod h1:Ng3Maa27Q2KARVJ0SPZF5NdrQSC3XHKP8IIWrHgMeLY=
|
github.com/shirou/gopsutil/v3 v3.23.5/go.mod h1:Ng3Maa27Q2KARVJ0SPZF5NdrQSC3XHKP8IIWrHgMeLY=
|
||||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||||
|
|
Binary file not shown.
153
utils/proxy.go
153
utils/proxy.go
|
@ -16,7 +16,6 @@ import (
|
||||||
|
|
||||||
"github.com/bedrock-tool/bedrocktool/locale"
|
"github.com/bedrock-tool/bedrocktool/locale"
|
||||||
"github.com/bedrock-tool/bedrocktool/ui/messages"
|
"github.com/bedrock-tool/bedrocktool/ui/messages"
|
||||||
"github.com/repeale/fp-go"
|
|
||||||
"github.com/sandertv/gophertunnel/minecraft"
|
"github.com/sandertv/gophertunnel/minecraft"
|
||||||
"github.com/sandertv/gophertunnel/minecraft/protocol"
|
"github.com/sandertv/gophertunnel/minecraft/protocol"
|
||||||
"github.com/sandertv/gophertunnel/minecraft/protocol/login"
|
"github.com/sandertv/gophertunnel/minecraft/protocol/login"
|
||||||
|
@ -95,6 +94,8 @@ type ProxyContext struct {
|
||||||
|
|
||||||
commands map[string]IngameCommand
|
commands map[string]IngameCommand
|
||||||
handlers []*ProxyHandler
|
handlers []*ProxyHandler
|
||||||
|
|
||||||
|
reconnectHandler *ProxyHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProxy() (*ProxyContext, error) {
|
func NewProxy() (*ProxyContext, error) {
|
||||||
|
@ -103,6 +104,7 @@ func NewProxy() (*ProxyContext, error) {
|
||||||
AlwaysGetPacks: false,
|
AlwaysGetPacks: false,
|
||||||
WithClient: true,
|
WithClient: true,
|
||||||
IgnoreDisconnect: false,
|
IgnoreDisconnect: false,
|
||||||
|
reconnectHandler: NewTransferHandler(),
|
||||||
}
|
}
|
||||||
if Options.PathCustomUserData != "" {
|
if Options.PathCustomUserData != "" {
|
||||||
if err := p.LoadCustomUserData(Options.PathCustomUserData); err != nil {
|
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
|
c2 = p.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var transferingErr error = nil
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if ctx.Err() != nil {
|
if ctx.Err() != nil {
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
|
@ -262,7 +266,12 @@ func (p *ProxyContext) proxyLoop(ctx context.Context, toServer bool) error {
|
||||||
if handler.PacketCB != nil {
|
if handler.PacketCB != nil {
|
||||||
pk, err = handler.PacketCB(pk, toServer, time.Now())
|
pk, err = handler.PacketCB(pk, toServer, time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
if errors.Is(err, transferingErr) {
|
||||||
|
transferingErr = err
|
||||||
|
err = nil
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if pk == nil {
|
if pk == nil {
|
||||||
logrus.Tracef("Dropped Packet: %s", pkName)
|
logrus.Tracef("Dropped Packet: %s", pkName)
|
||||||
|
@ -279,6 +288,10 @@ func (p *ProxyContext) proxyLoop(ctx context.Context, toServer bool) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if transferingErr != nil {
|
||||||
|
return transferingErr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,27 +367,19 @@ func (p *ProxyContext) connectClient(ctx context.Context, serverAddress string,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err error) {
|
func (p *ProxyContext) packetFunc(header packet.Header, payload []byte, src, dst net.Addr) {
|
||||||
if Options.Debug || Options.ExtraDebug {
|
if header.PacketID == packet.IDRequestNetworkSettings {
|
||||||
p.AddHandler(NewDebugLogger(Options.ExtraDebug))
|
p.clientAddr = src
|
||||||
}
|
}
|
||||||
if Options.Capture {
|
|
||||||
p.AddHandler(NewPacketCapturer())
|
|
||||||
}
|
|
||||||
p.AddHandler(&ProxyHandler{
|
|
||||||
Name: "Commands",
|
|
||||||
PacketCB: p.CommandHandlerPacketCB,
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, handler := range p.handlers {
|
for _, handler := range p.handlers {
|
||||||
if handler.AddressAndName != nil {
|
if handler.PacketFunc == nil {
|
||||||
handler.AddressAndName(serverAddress, name)
|
continue
|
||||||
}
|
|
||||||
if handler.ProxyRef != nil {
|
|
||||||
handler.ProxyRef(p)
|
|
||||||
}
|
}
|
||||||
|
handler.PacketFunc(header, payload, src, dst)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ProxyContext) connect(ctx context.Context, serverAddress string) (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
for _, handler := range p.handlers {
|
for _, handler := range p.handlers {
|
||||||
if handler.OnEnd != nil {
|
if handler.OnEnd != nil {
|
||||||
|
@ -410,7 +415,6 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err
|
||||||
if p.Client != nil {
|
if p.Client != nil {
|
||||||
p.Listener.Disconnect(p.Client.(*minecraft.Conn), DisconnectReason)
|
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)
|
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 {
|
if isReplay {
|
||||||
p.Server, err = createReplayConnector(serverAddress[5:], packetFunc)
|
p.Server, err = createReplayConnector(serverAddress[5:], p.packetFunc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} 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 {
|
if err != nil {
|
||||||
for _, handler := range p.handlers {
|
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{}
|
wg := sync.WaitGroup{}
|
||||||
doProxy := func(client bool, onErr func()) {
|
doProxy := func(client bool) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err := p.proxyLoop(ctx, client); err != nil {
|
if err := p.proxyLoop(ctx2, client); err != nil {
|
||||||
logrus.Error(err)
|
cancel(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// server to client
|
// server to client
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go doProxy(false, func() {
|
go doProxy(false)
|
||||||
p.DisconnectClient()
|
|
||||||
})
|
|
||||||
|
|
||||||
// client to server
|
// client to server
|
||||||
if p.Client != nil {
|
if p.Client != nil {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go doProxy(true, func() {
|
go doProxy(true)
|
||||||
p.DisconnectServer()
|
}
|
||||||
})
|
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 nil
|
||||||
return handler.SecondaryClientCB != nil
|
}
|
||||||
})(p.handlers)
|
|
||||||
|
|
||||||
if len(wantSecondary) > 0 {
|
func (p *ProxyContext) Run(ctx context.Context, serverAddress, name string) (err error) {
|
||||||
go func() {
|
if Options.Debug || Options.ExtraDebug {
|
||||||
for {
|
p.AddHandler(NewDebugLogger(Options.ExtraDebug))
|
||||||
c, err := p.Listener.Accept()
|
}
|
||||||
if err != nil {
|
if Options.Capture {
|
||||||
logrus.Error(err)
|
p.AddHandler(NewPacketCapturer())
|
||||||
return
|
}
|
||||||
}
|
p.AddHandler(&ProxyHandler{
|
||||||
|
Name: "Commands",
|
||||||
|
PacketCB: p.CommandHandlerPacketCB,
|
||||||
|
})
|
||||||
|
|
||||||
for _, handler := range wantSecondary {
|
p.AddHandler(p.reconnectHandler)
|
||||||
go handler.SecondaryClientCB(c.(*minecraft.Conn))
|
|
||||||
}
|
for _, handler := range p.handlers {
|
||||||
}
|
if handler.AddressAndName != nil {
|
||||||
}()
|
handler.AddressAndName(serverAddress, name)
|
||||||
|
}
|
||||||
|
if handler.ProxyRef != nil {
|
||||||
|
handler.ProxyRef(p)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
return p.connect(ctx, serverAddress)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func DecodePacket(pool packet.Pool, header packet.Header, payload []byte) packet.Packet {
|
func DecodePacket(pool packet.Pool, header packet.Header, payload []byte) packet.Packet {
|
||||||
|
|
|
@ -18,12 +18,22 @@ type Skin struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type SkinGeometry struct {
|
type SkinGeometry struct {
|
||||||
|
SkinGeometryDescription
|
||||||
|
Bones []any `json:"bones"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SkinGeometryDescription struct {
|
||||||
|
Identifier string `json:"identifier,omitempty"`
|
||||||
Texturewidth int `json:"texturewidth"`
|
Texturewidth int `json:"texturewidth"`
|
||||||
Textureheight int `json:"textureheight"`
|
Textureheight int `json:"textureheight"`
|
||||||
VisibleBoundsWidth float64 `json:"visible_bounds_width"`
|
VisibleBoundsWidth float64 `json:"visible_bounds_width"`
|
||||||
VisibleBoundsHeight float64 `json:"visible_bounds_height"`
|
VisibleBoundsHeight float64 `json:"visible_bounds_height"`
|
||||||
VisibleBoundsOffset []float64 `json:"visible_bounds_offset,omitempty"`
|
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 {
|
func (skin *Skin) Hash() uuid.UUID {
|
||||||
|
@ -31,7 +41,7 @@ func (skin *Skin) Hash() uuid.UUID {
|
||||||
return uuid.NewSHA1(uuid.NameSpaceURL, h)
|
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() {
|
if !skin.HaveGeometry() {
|
||||||
return nil, "", errors.New("no geometry")
|
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)
|
visible_bounds_height, _ := desc["visible_bounds_height"].(float64)
|
||||||
visibleOffset, _ := desc["visible_bounds_offset"].([]float64)
|
visibleOffset, _ := desc["visible_bounds_offset"].([]float64)
|
||||||
|
|
||||||
return &SkinGeometry{
|
return &SkinGeometry_1_12{
|
||||||
Texturewidth: int(texture_width),
|
Description: SkinGeometryDescription{
|
||||||
Textureheight: int(texture_height),
|
Identifier: desc["identifier"].(string),
|
||||||
VisibleBoundsWidth: visible_bounds_width,
|
Texturewidth: int(texture_width),
|
||||||
VisibleBoundsHeight: visible_bounds_height,
|
Textureheight: int(texture_height),
|
||||||
VisibleBoundsOffset: visibleOffset,
|
VisibleBoundsWidth: visible_bounds_width,
|
||||||
Bones: geom["bones"].([]any),
|
VisibleBoundsHeight: visible_bounds_height,
|
||||||
|
VisibleBoundsOffset: visibleOffset,
|
||||||
|
},
|
||||||
|
Bones: geom["bones"].([]any),
|
||||||
}, desc["identifier"].(string), nil
|
}, desc["identifier"].(string), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,13 +113,16 @@ func (s *SkinPack) Save(fpath, serverName string) error {
|
||||||
e.SetIndent("", "\t")
|
e.SetIndent("", "\t")
|
||||||
if err := e.Encode(map[string]any{
|
if err := e.Encode(map[string]any{
|
||||||
"format_version": "1.12.0",
|
"format_version": "1.12.0",
|
||||||
"minecraft:geometry": geometry,
|
"minecraft:geometry": []*SkinGeometry_1_12{geometry},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
f.Close()
|
f.Close()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
f.Close()
|
f.Close()
|
||||||
geometryJson[geometryName] = *geometry
|
geometryJson[geometryName] = SkinGeometry{
|
||||||
|
SkinGeometryDescription: geometry.Description,
|
||||||
|
Bones: geometry.Bones,
|
||||||
|
}
|
||||||
entry.Geometry = geometryName
|
entry.Geometry = geometryName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue