diff --git a/go.mod b/go.mod index c6dbcc3..dff90f5 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,10 @@ 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.27.4-4 +replace github.com/sandertv/gophertunnel => github.com/olebeck/gophertunnel v1.28.1-1 //replace github.com/df-mc/dragonfly => ./dragonfly -replace github.com/df-mc/dragonfly => github.com/olebeck/dragonfly v0.9.3-6 +replace github.com/df-mc/dragonfly => github.com/olebeck/dragonfly v0.9.3-8 replace gioui.org => github.com/olebeck/gio v0.0.0-20230321105529-d424f1a59af9 @@ -26,7 +26,7 @@ require ( github.com/nicksnyder/go-i18n/v2 v2.2.1 github.com/sanbornm/go-selfupdate v0.0.0-20210106163404-c9b625feac49 github.com/sandertv/go-raknet v1.12.0 - github.com/sandertv/gophertunnel v1.27.4 + github.com/sandertv/gophertunnel v1.28.1 github.com/sirupsen/logrus v1.9.0 golang.design/x/lockfree v0.0.1 golang.org/x/crypto v0.7.0 diff --git a/go.sum b/go.sum index 0aa34a0..3ff1862 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,7 @@ git.wow.st/gmp/jni v0.0.0-20210610011705-34026c7e22d0 h1:bGG/g4ypjrCJoSvFrP5hafr git.wow.st/gmp/jni v0.0.0-20210610011705-34026c7e22d0/go.mod h1:+axXBRUTIDlCeE73IKeD/os7LoEnTKdkp8/gQOFjqyo= github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU= github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/benoitkugler/pstokenizer v1.0.0/go.mod h1:l1G2Voirz0q/jj0TQfabNxVsa8HZXh/VMxFSRALWTiE= github.com/benoitkugler/textlayout v0.3.0 h1:2ehWXEkgb6RUokTjXh1LzdGwG4dRP6X3dqhYYDYhUVk= github.com/benoitkugler/textlayout v0.3.0/go.mod h1:o+1hFV+JSHBC9qNLIuwVoLedERU7sBPgEFcuSgfvi/w= @@ -19,6 +20,8 @@ github.com/benoitkugler/textlayout-testdata v0.1.1 h1:AvFxBxpfrQd8v55qH59mZOJOQj github.com/benoitkugler/textlayout-testdata v0.1.1/go.mod h1:i/qZl09BbUOtd7Bu/W1CAubRwTWrEXWq6JwMkw8wYxo= github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9 h1:/G0ghZwrhou0Wq21qc1vXXMm/t/aKWkALWwITptKbE0= github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9/go.mod h1:TOk10ahXejq9wkEaym3KPRNeuR/h5Jx+s8QRWIa2oTM= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/changkun/lockfree v0.0.1 h1:5WefVJLglY4IHRqOQmh6Ao6wkJYaJkarshKU8VUtId4= github.com/changkun/lockfree v0.0.1/go.mod h1:3bKiaXn/iNzIPlSvSOMSVbRQUQtAp8qUAyBUtzU11s4= github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 h1:Yg2hDs4b13Evkpj42FU2idX2cVXVFqQSheXYKM86Qsk= @@ -81,10 +84,18 @@ github.com/olebeck/dragonfly v0.9.3-5 h1:8MUpzKz1UZ0K+DJrywBV6C/ydGMggTxGg1n9VFA github.com/olebeck/dragonfly v0.9.3-5/go.mod h1:ODAzVcmM7KvKgPB89hoYndQiVVgTm9FlDXUko1H3YVs= github.com/olebeck/dragonfly v0.9.3-6 h1:ots1osXxuP6fQg4C8tt3y8xfpc+JNqOarI5zufisKFs= github.com/olebeck/dragonfly v0.9.3-6/go.mod h1:ODAzVcmM7KvKgPB89hoYndQiVVgTm9FlDXUko1H3YVs= +github.com/olebeck/dragonfly v0.9.3-7 h1:zIMWsox18efEe7R+VmJOTJRePU9x2YN3CE1uzfse1AM= +github.com/olebeck/dragonfly v0.9.3-7/go.mod h1:nnnmYWgSTNQb9x33nBthqN/2vyHlUaijfo+e2y3W5j4= +github.com/olebeck/dragonfly v0.9.3-8 h1:w514gGVTK2iv3TDI8EuzSCDHrF2Hv2f+/lIicW0J6Bg= +github.com/olebeck/dragonfly v0.9.3-8/go.mod h1:nnnmYWgSTNQb9x33nBthqN/2vyHlUaijfo+e2y3W5j4= github.com/olebeck/gio v0.0.0-20230321105529-d424f1a59af9 h1:TqDsMHwjW5ZYfh+RE8ussT62m0qXqo+QjzSXb7BCVA4= github.com/olebeck/gio v0.0.0-20230321105529-d424f1a59af9/go.mod h1:+W1Kpf96YcfissZocFqIp6O42FDTuphkObbEybp+Ffc= +github.com/olebeck/gophertunnel v1.27.4-3 h1:RktAdTNTvCFn6PQou0H3RyqrTo3/xH0bqODrHb/oXAs= +github.com/olebeck/gophertunnel v1.27.4-3/go.mod h1:ekREo7U9TPHh86kbuPMaWA93NMyWsfVvP/iNT3XhAb8= github.com/olebeck/gophertunnel v1.27.4-4 h1:ZzmZquRW0WdoH/smsOk91O+40dotn7574bID+BkHbuk= github.com/olebeck/gophertunnel v1.27.4-4/go.mod h1:ekREo7U9TPHh86kbuPMaWA93NMyWsfVvP/iNT3XhAb8= +github.com/olebeck/gophertunnel v1.28.1-1 h1:bw2jeMz94YHF5qQYhq1Yq/6fALkklGu7k26YbPI4DSs= +github.com/olebeck/gophertunnel v1.28.1-1/go.mod h1:ekREo7U9TPHh86kbuPMaWA93NMyWsfVvP/iNT3XhAb8= 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= @@ -98,6 +109,7 @@ github.com/sandertv/go-raknet v1.12.0 h1:olUzZlIJyX/pgj/mrsLCZYjKLNDsYiWdvQ4NIm3 github.com/sandertv/go-raknet v1.12.0/go.mod h1:Gx+WgZBMQ0V2UoouGoJ8Wj6CDrMBQ4SB2F/ggpl5/+Y= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= diff --git a/subcommands/chat_log.go b/subcommands/chat_log.go index 5a234f1..f05fcf6 100644 --- a/subcommands/chat_log.go +++ b/subcommands/chat_log.go @@ -43,13 +43,13 @@ func (c *ChatLogCMD) Execute(ctx context.Context, ui utils.UI) error { if err != nil { return err } - proxy.PacketCB = func(pk packet.Packet, proxy *utils.ProxyContext, toServer bool, _ time.Time) (packet.Packet, error) { + proxy.PacketCB = func(pk packet.Packet, toServer bool, t time.Time) (packet.Packet, error) { if text, ok := pk.(*packet.Text); ok { logLine := text.Message if c.Verbose { logLine += fmt.Sprintf(" (TextType: %d | XUID: %s | PlatformChatID: %s)", text.TextType, text.XUID, text.PlatformChatID) } - f.WriteString(fmt.Sprintf("[%s] ", time.Now().Format(time.RFC3339))) + f.WriteString(fmt.Sprintf("[%s] ", t.Format(time.RFC3339))) logrus.Info(logLine) if toServer { f.WriteString("SENT: ") diff --git a/subcommands/realms-list.go b/subcommands/realms-list.go new file mode 100644 index 0000000..2bd5398 --- /dev/null +++ b/subcommands/realms-list.go @@ -0,0 +1,30 @@ +package subcommands + +import ( + "context" + "flag" + "fmt" + + "github.com/bedrock-tool/bedrocktool/locale" + "github.com/bedrock-tool/bedrocktool/utils" +) + +type RealmListCMD struct{} + +func (*RealmListCMD) Name() string { return "list-realms" } +func (*RealmListCMD) Synopsis() string { return locale.Loc("list_realms_synopsis", nil) } +func (c *RealmListCMD) SetFlags(f *flag.FlagSet) {} +func (c *RealmListCMD) Execute(ctx context.Context, ui utils.UI) error { + realms, err := utils.GetRealmsAPI().Realms(ctx) + if err != nil { + return err + } + for _, realm := range realms { + fmt.Println(locale.Loc("realm_list_line", locale.Strmap{"Name": realm.Name, "Id": realm.ID})) + } + return nil +} + +func init() { + utils.RegisterCommand(&RealmListCMD{}) +} diff --git a/subcommands/resourcepack-d/resourcepack-d.go b/subcommands/resourcepack-d/resourcepack-d.go index f7d3b06..ca60d6d 100644 Binary files a/subcommands/resourcepack-d/resourcepack-d.go and b/subcommands/resourcepack-d/resourcepack-d.go differ diff --git a/subcommands/skins/skins.go b/subcommands/skins/skins.go index 48a2407..cf3832d 100644 --- a/subcommands/skins/skins.go +++ b/subcommands/skins/skins.go @@ -148,10 +148,10 @@ func (c *SkinCMD) Execute(ctx context.Context, ui utils.UI) error { proxy, _ := utils.NewProxy() proxy.WithClient = !c.NoProxy - proxy.OnClientConnect = func(proxy *utils.ProxyContext, hasClient bool) { + proxy.OnClientConnect = func(hasClient bool) { ui.Message(messages.SetUIState, messages.UIStateConnecting) } - proxy.ConnectCB = func(proxy *utils.ProxyContext, err error) bool { + proxy.ConnectCB = func(err error) bool { if err != nil { return false } @@ -165,7 +165,7 @@ func (c *SkinCMD) Execute(ctx context.Context, ui utils.UI) error { s := NewSkinsSession(proxy, hostname, outPathBase) - proxy.PacketCB = func(pk packet.Packet, _ *utils.ProxyContext, toServer bool, _ time.Time) (packet.Packet, error) { + proxy.PacketCB = func(pk packet.Packet, toServer bool, _ time.Time) (packet.Packet, error) { if !toServer { for _, s := range s.ProcessPacket(pk) { ui.Message(messages.NewSkin, messages.NewSkinPayload{ diff --git a/subcommands/world/chunk.go b/subcommands/world/chunk.go index f9bfe68..6b50a4f 100644 --- a/subcommands/world/chunk.go +++ b/subcommands/world/chunk.go @@ -44,29 +44,14 @@ func (w *WorldState) processLevelChunk(pk *packet.LevelChunk) { pk.Position.X(), 0, pk.Position.Z(), }] = blockNBTs } - - // check if chunk is empty - empty := true - for _, sub := range ch.Sub() { - if !sub.Empty() { - empty = false - break - } - } - w.chunks[pk.Position] = ch - if pk.SubChunkRequestMode == protocol.SubChunkRequestModeLegacy { - if !empty { - w.mapUI.SetChunk(pk.Position, ch) - } - } else { - // request all the subchunks - max := w.Dim.Range().Height() / 16 - if pk.SubChunkRequestMode == protocol.SubChunkRequestModeLimited { - max = int(pk.HighestSubChunk) - } - + max := w.Dim.Range().Height() / 16 + switch pk.SubChunkCount { + case protocol.SubChunkRequestModeLimited: + max = int(pk.HighestSubChunk) + fallthrough + case protocol.SubChunkRequestModeLimitless: w.proxy.Server.WritePacket(&packet.SubChunkRequest{ Dimension: int32(w.Dim.EncodeDimension()), Position: protocol.SubChunkPos{ @@ -74,6 +59,18 @@ func (w *WorldState) processLevelChunk(pk *packet.LevelChunk) { }, Offsets: offsetTable[:max], }) + default: + // legacy + empty := true + for _, sub := range ch.Sub() { + if !sub.Empty() { + empty = false + break + } + } + if !empty { + w.mapUI.SetChunk(pk.Position, ch) + } } } diff --git a/subcommands/world/chunk_render.go b/subcommands/world/chunk_render.go index 5e121b7..e0007fd 100644 --- a/subcommands/world/chunk_render.go +++ b/subcommands/world/chunk_render.go @@ -12,39 +12,45 @@ import ( "github.com/df-mc/dragonfly/server/world/chunk" ) +func isBlockLightblocking(b world.Block) bool { + d, isDiffuser := b.(block.LightDiffuser) + _, isSlab := b.(block.Slab) + noDiffuse := isDiffuser && d.LightDiffusionLevel() == 0 + return noDiffuse && !isSlab +} + func blockColorAt(c *chunk.Chunk, x uint8, y int16, z uint8) (blockColor color.RGBA) { - if y < int16(c.Range().Min()) { + if y <= int16(c.Range().Min()) { return color.RGBA{0, 0, 0, 0} } blockColor = color.RGBA{255, 0, 255, 255} rid := c.Block(x, y, z, 0) - if rid == 0 && y == 0 { // void + if rid == 0 && y == int16(c.Range().Min()) { // void blockColor = color.RGBA{0, 0, 0, 255} } else { b, found := world.BlockByRuntimeID(rid) if found { - d, isDiffuser := b.(block.LightDiffuser) - if isDiffuser && d.LightDiffusionLevel() == 0 { - if _, ok := b.(block.Slab); !ok { - return blockColorAt(c, x, y-1, z) - } + if isBlockLightblocking(b) { + return blockColorAt(c, x, y-1, z) + } + _, isWater := b.(block.Water) + if !isWater { + return b.Color() + } + // get the first non water block at the position + heightBlock := c.HeightMap().At(x, z) + depth := y - heightBlock + if depth > 0 { + blockColor = blockColorAt(c, x, heightBlock, z) } - if _, ok := b.(block.Water); ok { - y2 := c.HeightMap().At(x, z) - depth := y - y2 - if depth > 0 { - blockColor = blockColorAt(c, x, y2, z) - } - bw := (&block.Water{}).Color() - bw.A = uint8(utils.Clamp(int(150+depth*7), 255)) - blockColor = utils.BlendColors(blockColor, bw) - blockColor.R -= uint8(depth * 2) - blockColor.G -= uint8(depth * 2) - blockColor.B -= uint8(depth * 2) - } else { - blockColor = b.Color() - } + // blend that blocks color with water depending on depth + waterColor := (&block.Water{}).Color() + waterColor.A = uint8(utils.Clamp(int(150+depth*7), 255)) + blockColor = utils.BlendColors(blockColor, waterColor) + blockColor.R -= uint8(depth * 2) + blockColor.G -= uint8(depth * 2) + blockColor.B -= uint8(depth * 2) } /* if blockColor.R == 0 || blockColor.R == 255 && blockColor.B == 255 { @@ -58,39 +64,37 @@ func blockColorAt(c *chunk.Chunk, x uint8, y int16, z uint8) (blockColor color.R } func chunkGetColorAt(c *chunk.Chunk, x uint8, y int16, z uint8) color.RGBA { - p := cube.Pos{int(x), int(y), int(z)} haveUp := false - p.Side(cube.FaceUp).Neighbours(func(neighbour cube.Pos) { - if neighbour.X() < 0 || neighbour.X() >= 16 || neighbour.Z() < 0 || neighbour.Z() >= 16 || neighbour.Y() > c.Range().Max() { - return - } - if !haveUp { + cube.Pos{int(x), int(y), int(z)}. + Side(cube.FaceUp). + Neighbours(func(neighbour cube.Pos) { + if neighbour.X() < 0 || neighbour.X() >= 16 || neighbour.Z() < 0 || neighbour.Z() >= 16 || neighbour.Y() > c.Range().Max() || haveUp { + return + } blockRid := c.Block(uint8(neighbour[0]), int16(neighbour[1]), uint8(neighbour[2]), 0) if blockRid > 0 { b, found := world.BlockByRuntimeID(blockRid) if found { - if _, ok := b.(block.Air); !ok { + if isBlockLightblocking(b) { haveUp = true } } } - } - }, cube.Range{int(y + 1), int(y + 1)}) - - col := blockColorAt(c, x, y, z) + }, cube.Range{int(y + 1), int(y + 1)}) + blockColor := blockColorAt(c, x, y, z) if haveUp { - if col.R > 10 { - col.R -= 10 + if blockColor.R > 10 { + blockColor.R -= 10 } - if col.G > 10 { - col.G -= 10 + if blockColor.G > 10 { + blockColor.G -= 10 } - if col.B > 10 { - col.B -= 10 + if blockColor.B > 10 { + blockColor.B -= 10 } } - return col + return blockColor } func Chunk2Img(c *chunk.Chunk) *image.RGBA { @@ -99,9 +103,10 @@ func Chunk2Img(c *chunk.Chunk) *image.RGBA { for x := uint8(0); x < 16; x++ { for z := uint8(0); z < 16; z++ { - height := hm.At(x, z) - col := chunkGetColorAt(c, x, height, z) - img.SetRGBA(int(x), int(z), col) + img.SetRGBA( + int(x), int(z), + chunkGetColorAt(c, x, hm.At(x, z), z), + ) } } return img diff --git a/subcommands/world/map_item.go b/subcommands/world/map_item.go index f17bff6..3c7c13a 100644 --- a/subcommands/world/map_item.go +++ b/subcommands/world/map_item.go @@ -100,19 +100,18 @@ func (m *MapUI) Start() { } // init map - if m.w.proxy.Client != nil { - if err := m.w.proxy.Client.WritePacket(&packet.ClientBoundMapItemData{ - MapID: ViewMapID, - Scale: 4, - MapsIncludedIn: []int64{ViewMapID}, - Width: 0, - Height: 0, - Pixels: nil, - UpdateFlags: packet.MapUpdateFlagInitialisation, - }); err != nil { - logrus.Error(err) - return - } + err := m.w.proxy.ClientWritePacket(&packet.ClientBoundMapItemData{ + MapID: ViewMapID, + Scale: 4, + MapsIncludedIn: []int64{ViewMapID}, + Width: 0, + Height: 0, + Pixels: nil, + UpdateFlags: packet.MapUpdateFlagInitialisation, + }) + if err != nil { + logrus.Error(err) + return } m.ticker = time.NewTicker(33 * time.Millisecond) @@ -122,18 +121,16 @@ func (m *MapUI) Start() { m.needRedraw = false m.Redraw() - if m.w.proxy.Client != nil { - if err := m.w.proxy.Client.WritePacket(&packet.ClientBoundMapItemData{ - MapID: ViewMapID, - Scale: 4, - Width: 128, - Height: 128, - Pixels: utils.Img2rgba(m.img), - UpdateFlags: packet.MapUpdateFlagTexture, - }); err != nil { - logrus.Error(err) - return - } + if err := m.w.proxy.ClientWritePacket(&packet.ClientBoundMapItemData{ + MapID: ViewMapID, + Scale: 4, + Width: 128, + Height: 128, + Pixels: utils.Img2rgba(m.img), + UpdateFlags: packet.MapUpdateFlagTexture, + }); err != nil { + logrus.Error(err) + return } } } @@ -144,12 +141,10 @@ func (m *MapUI) Start() { if m.w.ctx.Err() != nil { return } - if m.w.proxy.Client != nil { - err := m.w.proxy.Client.WritePacket(&MapItemPacket) - if err != nil { - logrus.Error(err) - return - } + err := m.w.proxy.ClientWritePacket(&MapItemPacket) + if err != nil { + logrus.Error(err) + return } } }() diff --git a/subcommands/world/world.go b/subcommands/world/world.go index 89c9bb3..7e84932 100644 --- a/subcommands/world/world.go +++ b/subcommands/world/world.go @@ -156,10 +156,10 @@ func (c *WorldCMD) Execute(ctx context.Context, ui utils.UI) error { proxy.AlwaysGetPacks = true proxy.ConnectCB = w.OnConnect - proxy.OnClientConnect = func(proxy *utils.ProxyContext, hasClient bool) { + proxy.OnClientConnect = func(hasClient bool) { w.gui.Message(messages.SetUIState, messages.UIStateConnecting) } - proxy.PacketCB = func(pk packet.Packet, proxy *utils.ProxyContext, toServer bool, _ time.Time) (packet.Packet, error) { + proxy.PacketCB = func(pk packet.Packet, toServer bool, _ time.Time) (packet.Packet, error) { forward := true if toServer { @@ -263,11 +263,12 @@ func (w *WorldState) Reset() { // SaveAndReset writes the world to a folder, resets all the chunks func (w *WorldState) SaveAndReset() { + + // cull empty chunks keys := make([]protocol.ChunkPos, 0, len(w.chunks)) for cp := range w.chunks { keys = append(keys, cp) } - for _, cp := range keys { has_any := false for _, sc := range w.chunks[cp].Sub() { @@ -280,7 +281,6 @@ func (w *WorldState) SaveAndReset() { delete(w.chunks, cp) } } - if len(w.chunks) == 0 { w.Reset() return @@ -316,6 +316,7 @@ func (w *WorldState) SaveAndReset() { } } + // save entities chunkEntities := make(map[world.ChunkPos][]world.Entity) for _, es := range w.entities { cp := world.ChunkPos{int32(es.Position.X()) >> 4, int32(es.Position.Z()) >> 4} @@ -517,13 +518,12 @@ func (w *WorldState) SaveAndReset() { w.Reset() } -func (w *WorldState) OnConnect(proxy *utils.ProxyContext, err error) bool { +func (w *WorldState) OnConnect(err error) bool { w.gui.Message(messages.SetUIState, messages.UIStateMain) if err != nil { return false } - w.proxy = proxy gd := w.proxy.Server.GameData() w.ChunkRadius = int(gd.ChunkRadius) @@ -570,9 +570,7 @@ func (w *WorldState) OnConnect(proxy *utils.ProxyContext, err error) bool { w.proxy.SendMessage(locale.Loc("use_setname", nil)) - w.mapUI.Start() - - proxy.AddCommand(utils.IngameCommand{ + w.proxy.AddCommand(utils.IngameCommand{ Exec: func(cmdline []string) bool { return w.setWorldName(strings.Join(cmdline, " "), false) }, @@ -593,7 +591,7 @@ func (w *WorldState) OnConnect(proxy *utils.ProxyContext, err error) bool { }, }) - proxy.AddCommand(utils.IngameCommand{ + w.proxy.AddCommand(utils.IngameCommand{ Exec: func(cmdline []string) bool { return w.setVoidGen(!w.voidGen, false) }, @@ -603,9 +601,10 @@ func (w *WorldState) OnConnect(proxy *utils.ProxyContext, err error) bool { }, }) - if w.proxy.Client != nil { - w.proxy.Client.WritePacket(&packet.ChunkRadiusUpdated{ChunkRadius: 80}) - } + w.mapUI.Start() + w.proxy.ClientWritePacket(&packet.ChunkRadiusUpdated{ + ChunkRadius: 80, + }) return true } diff --git a/ui/gui/pages/settings/settings.go b/ui/gui/pages/settings/settings.go index d7b182e..1c1c17f 100644 --- a/ui/gui/pages/settings/settings.go +++ b/ui/gui/pages/settings/settings.go @@ -59,7 +59,6 @@ func New(router *pages.Router) *Page { OptionList: layout.List{}, Options: options, } - //p.cmdMenu.selected = "worlds" for _, su := range settings.Settings { su.Init() diff --git a/ui/gui/pages/skins/skins.go b/ui/gui/pages/skins/skins.go index f972808..41e34a4 100644 --- a/ui/gui/pages/skins/skins.go +++ b/ui/gui/pages/skins/skins.go @@ -77,15 +77,13 @@ func (p *Page) Layout(gtx C, th *material.Theme) D { Axis: layout.Vertical, }.Layout(gtx, layout.Rigid(material.Label(th, 20, "Skin Basic UI").Layout), - layout.Flexed(1, func(gtx layout.Context) layout.Dimensions { + layout.Flexed(1, func(gtx C) D { p.l.Lock() defer p.l.Unlock() - return material.List(th, &p.SkinsList).Layout(gtx, len(p.Skins), func(gtx layout.Context, index int) layout.Dimensions { + return material.List(th, &p.SkinsList).Layout(gtx, len(p.Skins), func(gtx C, index int) D { entry := p.Skins[len(p.Skins)-index-1] - return layout.UniformInset(25).Layout(gtx, func(gtx layout.Context) layout.Dimensions { - return layout.Flex{ - Axis: layout.Horizontal, - }.Layout(gtx, + return layout.UniformInset(25).Layout(gtx, func(gtx C) D { + return layout.Flex{Axis: layout.Horizontal}.Layout(gtx, layout.Rigid(material.Label(th, th.TextSize, entry.PlayerName).Layout), ) }) diff --git a/ui/gui/pages/worlds/worlds.go b/ui/gui/pages/worlds/worlds.go index 271563d..9be2e57 100644 --- a/ui/gui/pages/worlds/worlds.go +++ b/ui/gui/pages/worlds/worlds.go @@ -66,16 +66,14 @@ func (p *Page) Layout(gtx C, th *material.Theme) D { return margin.Layout(gtx, material.Label(th, 100, "Connecting").Layout) case messages.UIStateMain: // show the main ui - return margin.Layout(gtx, func(gtx C) D { - return layout.Flex{ - Axis: layout.Vertical, - }.Layout(gtx, - layout.Rigid(material.Label(th, 20, "World Downloader Basic UI").Layout), - layout.Flexed(1, func(gtx C) D { - return layout.Center.Layout(gtx, p.worldMap.Layout) - }), - ) - }) + return layout.Flex{ + Axis: layout.Vertical, + }.Layout(gtx, + layout.Rigid(material.Label(th, 20, "World Downloader Basic UI").Layout), + layout.Flexed(1, func(gtx C) D { + return layout.Center.Layout(gtx, p.worldMap.Layout) + }), + ) } return layout.Flex{}.Layout(gtx) diff --git a/utils/packet_logger.go b/utils/packet_logger.go index b271731..9ce63f0 100644 --- a/utils/packet_logger.go +++ b/utils/packet_logger.go @@ -162,6 +162,8 @@ func DumpStruct(data interface{}) { FLog.Write([]byte("\n\n\n")) } +var ClientAddr net.Addr + func PacketLogger(header packet.Header, payload []byte, src, dst net.Addr) { var pk packet.Packet if pkFunc, ok := pool[header.PacketID]; ok { @@ -176,11 +178,11 @@ func PacketLogger(header packet.Header, payload []byte, src, dst net.Addr) { defer func() { if recoveredErr := recover(); recoveredErr != nil { - logrus.Errorf("%T: %w", pk, recoveredErr) + logrus.Errorf("%T: %s", pk, recoveredErr.(error)) } }() - pk.Unmarshal(protocol.NewReader(bytes.NewBuffer(payload), 0)) + pk.Marshal(protocol.NewReader(bytes.NewBuffer(payload), 0)) if FLog != nil { dmpLock.Lock() diff --git a/utils/proxy.go b/utils/proxy.go index 9d679dc..743bcb6 100644 --- a/utils/proxy.go +++ b/utils/proxy.go @@ -41,9 +41,9 @@ func (p dummyProto) ConvertFromLatest(pk packet.Packet, _ *minecraft.Conn) []pac type ( PacketFunc func(header packet.Header, payload []byte, src, dst net.Addr) - PacketCallback func(pk packet.Packet, proxy *ProxyContext, toServer bool, timeReceived time.Time) (packet.Packet, error) - ClientConnectCallback func(proxy *ProxyContext, hasClient bool) - ConnectCallback func(proxy *ProxyContext, err error) bool + PacketCallback func(pk packet.Packet, toServer bool, timeReceived time.Time) (packet.Packet, error) + ClientConnectCallback func(hasClient bool) + ConnectCallback func(err error) bool IngameCommand struct { Exec func(cmdline []string) bool Cmd protocol.Command @@ -161,25 +161,28 @@ func (p *ProxyContext) LoadCustomUserData(path string) error { return nil } -func (p *ProxyContext) SendMessage(text string) { - if p.Client != nil { - p.Client.WritePacket(&packet.Text{ - TextType: packet.TextTypeSystem, - Message: "§8[§bBedrocktool§8]§r " + text, - }) +func (p *ProxyContext) ClientWritePacket(pk packet.Packet) error { + if p.Client == nil { + return nil } + return p.Client.WritePacket(pk) +} + +func (p *ProxyContext) SendMessage(text string) { + p.ClientWritePacket(&packet.Text{ + TextType: packet.TextTypeSystem, + Message: "§8[§bBedrocktool§8]§r " + text, + }) } func (p *ProxyContext) SendPopup(text string) { - if p.Client != nil { - p.Client.WritePacket(&packet.Text{ - TextType: packet.TextTypePopup, - Message: text, - }) - } + p.ClientWritePacket(&packet.Text{ + TextType: packet.TextTypePopup, + Message: text, + }) } -func (p *ProxyContext) CommandHandlerPacketCB(pk packet.Packet, proxy *ProxyContext, toServer bool, _ time.Time) (packet.Packet, error) { +func (p *ProxyContext) CommandHandlerPacketCB(pk packet.Packet, toServer bool, _ time.Time) (packet.Packet, error) { switch _pk := pk.(type) { case *packet.CommandRequest: cmd := strings.Split(_pk.CommandLine, " ") @@ -223,7 +226,7 @@ func (p *ProxyContext) proxyLoop(ctx context.Context, toServer bool, packetCBs [ } for _, packetCB := range packetCBs { - pk, err = packetCB(pk, p, toServer, time.Now()) + pk, err = packetCB(pk, toServer, time.Now()) if err != nil { return err } @@ -240,11 +243,9 @@ func (p *ProxyContext) proxyLoop(ctx context.Context, toServer bool, packetCBs [ } } -var ClientAddr net.Addr - func (p *ProxyContext) Run(ctx context.Context, serverAddress string) (err error) { if strings.HasPrefix(serverAddress, "PCAP!") { - return createReplayConnection(ctx, serverAddress[5:], p.ConnectCB, p.PacketCB) + return createReplayConnection(ctx, serverAddress[5:], p) } GetTokenSource() // ask for login before listening @@ -298,7 +299,7 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress string) (err error } if p.OnClientConnect != nil { - p.OnClientConnect(p, p.WithClient) + p.OnClientConnect(p.WithClient) } if p.CustomClientData != nil { @@ -308,7 +309,7 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress string) (err error p.Server, err = connectServer(ctx, serverAddress, cdp, p.AlwaysGetPacks, p.PacketFunc) if err != nil { if p.ConnectCB != nil { - if p.ConnectCB(p, err) { + if p.ConnectCB(err) { err = nil } } @@ -324,7 +325,7 @@ func (p *ProxyContext) Run(ctx context.Context, serverAddress string) (err error } if p.ConnectCB != nil { - if !p.ConnectCB(p, nil) { + if !p.ConnectCB(nil) { return errors.New("Cancelled") } } diff --git a/utils/realms.go b/utils/realms.go index 12230ab..d2a7991 100644 --- a/utils/realms.go +++ b/utils/realms.go @@ -2,11 +2,8 @@ package utils import ( "context" - "flag" "fmt" "strings" - - "github.com/bedrock-tool/bedrocktool/locale" ) func getRealm(ctx context.Context, realmName, id string) (name string, address string, err error) { @@ -29,23 +26,3 @@ func getRealm(ctx context.Context, realmName, id string) (name string, address s } return "", "", fmt.Errorf("realm not found") } - -type RealmListCMD struct{} - -func (*RealmListCMD) Name() string { return "list-realms" } -func (*RealmListCMD) Synopsis() string { return locale.Loc("list_realms_synopsis", nil) } -func (c *RealmListCMD) SetFlags(f *flag.FlagSet) {} -func (c *RealmListCMD) Execute(ctx context.Context, ui UI) error { - realms, err := GetRealmsAPI().Realms(ctx) - if err != nil { - return err - } - for _, realm := range realms { - fmt.Println(locale.Loc("realm_list_line", locale.Strmap{"Name": realm.Name, "Id": realm.ID})) - } - return nil -} - -func init() { - RegisterCommand(&RealmListCMD{}) -} diff --git a/utils/replay.go b/utils/replay.go index 525fdd5..1d270b7 100644 --- a/utils/replay.go +++ b/utils/replay.go @@ -34,7 +34,7 @@ func WriteReplayHeader(f io.Writer) { binary.Write(f, binary.LittleEndian, &header) } -func createReplayConnection(ctx context.Context, filename string, onConnect ConnectCallback, packetCB PacketCallback) error { +func createReplayConnection(ctx context.Context, filename string, proxy *ProxyContext) error { logrus.Infof("Reading replay %s", filename) f, err := os.Open(filename) @@ -63,7 +63,6 @@ func createReplayConnection(ctx context.Context, filename string, onConnect Conn f.Seek(-4, io.SeekCurrent) } - proxy, _ := NewProxy() proxy.Server = minecraft.NewConn() gameStarted := false @@ -129,8 +128,8 @@ func createReplayConnection(ctx context.Context, filename string, onConnect Conn } if gameStarted { - if packetCB != nil { - packetCB(pk, proxy, toServer, timeReceived) + if proxy.PacketCB != nil { + proxy.PacketCB(pk, toServer, timeReceived) } } else { switch pk := pk.(type) { @@ -165,8 +164,8 @@ func createReplayConnection(ctx context.Context, filename string, onConnect Conn DisablePlayerInteractions: pk.DisablePlayerInteractions, }) gameStarted = true - if onConnect != nil { - onConnect(proxy, nil) + if proxy.ConnectCB != nil { + proxy.ConnectCB(nil) } } }