From 77f7d4d2d9b0d5ff6275055a4b9f66414534c01a Mon Sep 17 00:00:00 2001 From: olebeck <31539311+olebeck@users.noreply.github.com> Date: Mon, 5 Sep 2022 17:40:03 +0200 Subject: [PATCH] render queue --- subcommands/world/map_item.go | 51 ++++++++++++++++++++++++----------- subcommands/world/world.go | 45 ++++++++++++++++++++----------- utils/packet_logger.go | 2 -- 3 files changed, 65 insertions(+), 33 deletions(-) diff --git a/subcommands/world/map_item.go b/subcommands/world/map_item.go index 6348882..36548f1 100644 --- a/subcommands/world/map_item.go +++ b/subcommands/world/map_item.go @@ -2,6 +2,7 @@ package world import ( "bytes" + "container/list" "image" "image/draw" "math" @@ -41,26 +42,34 @@ var MAP_ITEM_PACKET packet.InventoryContent = packet.InventoryContent{ }, } +type RenderElem struct { + pos protocol.ChunkPos + ch *chunk.Chunk +} + type MapUI struct { - img *image.RGBA // rendered image - zoomLevel int // pixels per chunk + img *image.RGBA // rendered image + zoomLevel int // pixels per chunk + render_queue *list.List + render_lock *sync.Mutex chunks_images map[protocol.ChunkPos]*image.RGBA // prerendered chunks needRedraw bool // when the map has updated this is true - image_lock *sync.Mutex ticker *time.Ticker w *WorldState } -func NewMapUI(w *WorldState) MapUI { - return MapUI{ +func NewMapUI(w *WorldState) *MapUI { + m := &MapUI{ img: image.NewRGBA(image.Rect(0, 0, 128, 128)), zoomLevel: 16, + render_queue: list.New(), + render_lock: &sync.Mutex{}, chunks_images: make(map[protocol.ChunkPos]*image.RGBA), - image_lock: &sync.Mutex{}, needRedraw: true, w: w, } + return m } func (m *MapUI) Start() { @@ -68,12 +77,12 @@ func (m *MapUI) Start() { go func() { for range m.ticker.C { if m.needRedraw { - if !m.image_lock.TryLock() { - continue // dont send if send is in progress + if !m.render_lock.TryLock() { + continue } m.needRedraw = false m.Redraw() - m.image_lock.Unlock() + m.render_lock.Unlock() if m.w.proxy.Client != nil { if err := m.w.proxy.Client.WritePacket(&packet.ClientBoundMapItemData{ @@ -137,6 +146,20 @@ func draw_img_scaled_pos(dst *image.RGBA, src *image.RGBA, bottom_left image.Poi // draw chunk images to the map image func (m *MapUI) Redraw() { + for { + e := m.render_queue.Back() + if e == nil { + break + } + r := e.Value.(RenderElem) + if r.ch != nil { + m.chunks_images[r.pos] = Chunk2Img(r.ch) + } else { + m.chunks_images[r.pos] = black_16x16 + } + m.render_queue.Remove(e) + } + // get the chunk coord bounds min := protocol.ChunkPos{} max := protocol.ChunkPos{} @@ -215,12 +238,8 @@ func (m *MapUI) Redraw() { } func (m *MapUI) SetChunk(pos protocol.ChunkPos, ch *chunk.Chunk) { - var img *image.RGBA = black_16x16 - if ch != nil { - img = Chunk2Img(ch) - } - m.image_lock.Lock() // dont send while adding a chunk - m.chunks_images[pos] = img - m.image_lock.Unlock() + m.render_lock.Lock() + defer m.render_lock.Unlock() + m.render_queue.PushBack(RenderElem{pos, ch}) m.SchedRedraw() } diff --git a/subcommands/world/world.go b/subcommands/world/world.go index 988521b..74d5906 100644 --- a/subcommands/world/world.go +++ b/subcommands/world/world.go @@ -59,7 +59,7 @@ type WorldState struct { proxy *utils.ProxyContext // ui - ui MapUI + ui *MapUI } func NewWorldState() *WorldState { @@ -143,10 +143,14 @@ func (c *WorldCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{ proxy := utils.NewProxy(logrus.StandardLogger()) proxy.ConnectCB = w.OnConnect proxy.PacketCB = func(pk packet.Packet, proxy *utils.ProxyContext, toServer bool) (packet.Packet, error) { + var forward bool if toServer { - pk = w.ProcessPacketClient(pk) + pk, forward = w.ProcessPacketClient(pk) } else { - pk = w.ProcessPacketServer(pk) + pk, forward = w.ProcessPacketServer(pk) + } + if !forward { + return nil, nil } return pk, nil } @@ -320,10 +324,11 @@ func (w *WorldState) SaveAndReset() { // write metadata s := provider.Settings() + player := w.proxy.Client.GameData().PlayerPosition s.Spawn = cube.Pos{ - int(w.PlayerPos.Position[0]), - int(w.PlayerPos.Position[1]), - int(w.PlayerPos.Position[2]), + int(player.X()), + int(player.Y()), + int(player.Z()), } s.Name = w.WorldName @@ -432,6 +437,16 @@ func (w *WorldState) SaveAndReset() { func (w *WorldState) OnConnect(proxy *utils.ProxyContext) { w.proxy = proxy + gd := w.proxy.Server.GameData() + + /* + if len(gd.CustomBlocks) > 0 { + for _, be := range gd.CustomBlocks { + b := block.ServerCustomBlock(be) + world.RegisterBlock(b) + } + } + */ if w.withPacks { fmt.Println("reformatting packs") @@ -441,7 +456,6 @@ func (w *WorldState) OnConnect(proxy *utils.ProxyContext) { } { // check game version - gd := w.proxy.Server.GameData() gv := strings.Split(gd.BaseGameVersion, ".") var err error if len(gv) > 1 { @@ -475,8 +489,8 @@ func (w *WorldState) OnConnect(proxy *utils.ProxyContext) { case <-w.ctx.Done(): return default: - t := time.NewTimer(1 * time.Second) - for range t.C { + for { + time.Sleep(1 * time.Second) if w.proxy.Client != nil { err := w.proxy.Client.WritePacket(&MAP_ITEM_PACKET) if err != nil { @@ -515,7 +529,8 @@ func (w *WorldState) OnConnect(proxy *utils.ProxyContext) { }) } -func (w *WorldState) ProcessPacketClient(pk packet.Packet) packet.Packet { +func (w *WorldState) ProcessPacketClient(pk packet.Packet) (packet.Packet, bool) { + forward := true switch pk := pk.(type) { case *packet.MovePlayer: w.SetPlayerPos(pk.Position, pk.Pitch, pk.Yaw, pk.HeadYaw) @@ -524,19 +539,19 @@ func (w *WorldState) ProcessPacketClient(pk packet.Packet) packet.Packet { case *packet.MapInfoRequest: if pk.MapID == VIEW_MAP_ID { w.ui.SchedRedraw() - pk = nil + forward = false } case *packet.MobEquipment: if pk.NewItem.Stack.NBTData["map_uuid"] == int64(VIEW_MAP_ID) { - pk = nil + forward = false } case *packet.Animate: w.ProcessAnimate(pk) } - return pk + return pk, forward } -func (w *WorldState) ProcessPacketServer(pk packet.Packet) packet.Packet { +func (w *WorldState) ProcessPacketServer(pk packet.Packet) (packet.Packet, bool) { switch pk := pk.(type) { case *packet.ChangeDimension: w.ProcessChangeDimension(pk) @@ -546,5 +561,5 @@ func (w *WorldState) ProcessPacketServer(pk packet.Packet) packet.Packet { case *packet.SubChunk: w.ProcessSubChunk(pk) } - return pk + return pk, true } diff --git a/utils/packet_logger.go b/utils/packet_logger.go index 0c6f976..8dce725 100644 --- a/utils/packet_logger.go +++ b/utils/packet_logger.go @@ -68,8 +68,6 @@ func PacketLogger(header packet.Header, payload []byte, src, dst net.Addr) { switch pk := pk.(type) { case *packet.Disconnect: logrus.Infof("Disconnect: %s", pk.Message) - case *packet.Event: - logrus.Infof("Event %d %+v", pk.EventType, pk.EventData) } dir := color.GreenString("S") + "->" + color.CyanString("C")