add multiple zoom levels
This commit is contained in:
parent
1415bdc9c6
commit
081a89a8f6
|
@ -36,21 +36,12 @@ jobs:
|
|||
- uses: actions-ecosystem/action-get-latest-tag@v1
|
||||
id: get-latest-tag
|
||||
|
||||
- name: Create Release
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
uses: ncipollo/release-action@v1.10.0
|
||||
with:
|
||||
allowUpdates: true
|
||||
artifacts: dist/*
|
||||
tag: ${{ steps.get-latest-tag.outputs.tag }}
|
||||
|
||||
- name: update latest Release
|
||||
if: "!(startsWith(github.ref, 'refs/tags/v'))"
|
||||
uses: ncipollo/release-action@v1.10.0
|
||||
with:
|
||||
allowUpdates: true
|
||||
artifacts: dist/*
|
||||
tag: latest
|
||||
tag: ${{ steps.get-latest-tag.outputs.tag }}
|
||||
prerelease: true
|
||||
removeArtifacts: true
|
||||
|
||||
|
|
99
map_item.go
99
map_item.go
|
@ -7,10 +7,12 @@ import (
|
|||
"math"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/df-mc/dragonfly/server/world/chunk"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/image/bmp"
|
||||
)
|
||||
|
||||
|
@ -39,19 +41,58 @@ var MAP_ITEM_PACKET packet.InventoryContent = packet.InventoryContent{
|
|||
|
||||
type MapUI struct {
|
||||
img *image.RGBA // rendered image
|
||||
minZoom bool // 1 pixel per block
|
||||
zoomLevel int // pixels per chunk
|
||||
chunks_images map[protocol.ChunkPos]*image.RGBA // prerendered chunks
|
||||
needRedraw bool // when the map has updated this is true
|
||||
send_lock *sync.Mutex
|
||||
image_lock *sync.Mutex
|
||||
|
||||
ticker *time.Ticker
|
||||
w *WorldState
|
||||
}
|
||||
|
||||
func NewMapUI() MapUI {
|
||||
func NewMapUI(w *WorldState) MapUI {
|
||||
return MapUI{
|
||||
img: image.NewRGBA(image.Rect(0, 0, 128, 128)),
|
||||
minZoom: true,
|
||||
zoomLevel: 16,
|
||||
chunks_images: make(map[protocol.ChunkPos]*image.RGBA),
|
||||
image_lock: &sync.Mutex{},
|
||||
needRedraw: true,
|
||||
send_lock: &sync.Mutex{},
|
||||
w: w,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MapUI) Start() {
|
||||
m.ticker = time.NewTicker(66 * time.Millisecond)
|
||||
go func() {
|
||||
for range m.ticker.C {
|
||||
if m.needRedraw {
|
||||
if !m.image_lock.TryLock() {
|
||||
continue // dont send if send is in progress
|
||||
}
|
||||
m.needRedraw = false
|
||||
m.Redraw()
|
||||
m.image_lock.Unlock()
|
||||
|
||||
if m.w.proxy.client != nil {
|
||||
if err := m.w.proxy.client.WritePacket(&packet.ClientBoundMapItemData{
|
||||
MapID: VIEW_MAP_ID,
|
||||
Width: 128,
|
||||
Height: 128,
|
||||
Pixels: img2rgba(m.img),
|
||||
UpdateFlags: 2,
|
||||
}); err != nil {
|
||||
logrus.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (m *MapUI) Stop() {
|
||||
if m.ticker != nil {
|
||||
m.ticker.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +104,10 @@ func (m *MapUI) Reset() {
|
|||
|
||||
// ChangeZoom adds to the zoom value and goes around to 32 once it hits 128
|
||||
func (m *MapUI) ChangeZoom() {
|
||||
m.minZoom = !m.minZoom
|
||||
m.zoomLevel /= 2
|
||||
if m.zoomLevel == 0 {
|
||||
m.zoomLevel = 16
|
||||
}
|
||||
m.SchedRedraw()
|
||||
}
|
||||
|
||||
|
@ -90,7 +134,7 @@ 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(w *WorldState) {
|
||||
func (m *MapUI) Redraw() {
|
||||
// get the chunk coord bounds
|
||||
min := protocol.ChunkPos{}
|
||||
max := protocol.ChunkPos{}
|
||||
|
@ -110,16 +154,16 @@ func (m *MapUI) Redraw(w *WorldState) {
|
|||
}
|
||||
|
||||
middle := protocol.ChunkPos{
|
||||
int32(w.PlayerPos.Position.X()),
|
||||
int32(w.PlayerPos.Position.Z()),
|
||||
int32(m.w.PlayerPos.Position.X()),
|
||||
int32(m.w.PlayerPos.Position.Z()),
|
||||
}
|
||||
|
||||
chunks_x := int(max[0] - min[0] + 1) // how many chunk lengths is x coordinate
|
||||
chunks_y := int(max[1] - min[1] + 1)
|
||||
chunks_per_line := 16 * math.Ceil(math.Min(float64(chunks_x), 32)/16)
|
||||
if m.minZoom {
|
||||
chunks_per_line = 8
|
||||
}
|
||||
|
||||
total_width := 16 * math.Ceil(float64(chunks_x)/16)
|
||||
chunks_per_line := math.Min(total_width, float64(128/m.zoomLevel))
|
||||
|
||||
px_per_block := float64(128 / chunks_per_line / 16) // how many pixels per block
|
||||
sz_chunk := int(math.Ceil(px_per_block * 16))
|
||||
|
||||
|
@ -168,31 +212,6 @@ func (m *MapUI) Redraw(w *WorldState) {
|
|||
}
|
||||
}
|
||||
|
||||
// send
|
||||
func (m *MapUI) Send(w *WorldState) error {
|
||||
if !m.send_lock.TryLock() {
|
||||
return nil // dont send if send is in progress
|
||||
}
|
||||
|
||||
// redraw if needed
|
||||
if m.needRedraw {
|
||||
m.needRedraw = false
|
||||
m.Redraw(w)
|
||||
}
|
||||
|
||||
m.send_lock.Unlock()
|
||||
if w.proxy.client != nil {
|
||||
return w.proxy.client.WritePacket(&packet.ClientBoundMapItemData{
|
||||
MapID: VIEW_MAP_ID,
|
||||
Width: 128,
|
||||
Height: 128,
|
||||
Pixels: img2rgba(m.img),
|
||||
UpdateFlags: 2,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MapUI) SetChunk(pos protocol.ChunkPos, ch *chunk.Chunk) {
|
||||
var img *image.RGBA
|
||||
if ch != nil {
|
||||
|
@ -200,8 +219,8 @@ func (m *MapUI) SetChunk(pos protocol.ChunkPos, ch *chunk.Chunk) {
|
|||
} else {
|
||||
img = black_16x16
|
||||
}
|
||||
m.send_lock.Lock() // dont send while adding a chunk
|
||||
m.image_lock.Lock() // dont send while adding a chunk
|
||||
m.chunks_images[pos] = img
|
||||
m.send_lock.Unlock()
|
||||
m.image_lock.Unlock()
|
||||
m.SchedRedraw()
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/pcapgo"
|
||||
"github.com/sandertv/gophertunnel/minecraft"
|
||||
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
|
||||
|
@ -21,14 +20,6 @@ func SetUnexportedField(field reflect.Value, value interface{}) {
|
|||
Set(reflect.ValueOf(value))
|
||||
}
|
||||
|
||||
type PayloadDecoder struct {
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
func (d PayloadDecoder) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func create_replay_connection(ctx context.Context, log *logrus.Logger, filename string, onConnect ConnectCallback, packetCB PacketCallback) error {
|
||||
log.Infof("Reading replay %s", filename)
|
||||
|
||||
|
|
Binary file not shown.
12
world.go
12
world.go
|
@ -61,15 +61,16 @@ type WorldState struct {
|
|||
}
|
||||
|
||||
func NewWorldState() *WorldState {
|
||||
return &WorldState{
|
||||
w := &WorldState{
|
||||
chunks: make(map[protocol.ChunkPos]*chunk.Chunk),
|
||||
blockNBT: make(map[protocol.SubChunkPos][]map[string]any),
|
||||
entities: make(map[int64]world.SaveableEntity),
|
||||
Dim: nil,
|
||||
WorldName: "world",
|
||||
PlayerPos: TPlayerPos{},
|
||||
ui: NewMapUI(),
|
||||
}
|
||||
w.ui = NewMapUI(w)
|
||||
return w
|
||||
}
|
||||
|
||||
var dimension_ids = map[uint8]world.Dimension{
|
||||
|
@ -233,7 +234,7 @@ func (w *WorldState) ProcessSubChunk(pk *packet.SubChunk) {
|
|||
func (w *WorldState) ProcessAnimate(pk *packet.Animate) {
|
||||
if pk.ActionType == packet.AnimateActionSwingArm {
|
||||
w.ui.ChangeZoom()
|
||||
w.ui.Send(w)
|
||||
w.proxy.sendPopup(fmt.Sprintf("Zoom: %d", w.ui.zoomLevel))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +263,6 @@ func (w *WorldState) SetPlayerPos(Position mgl32.Vec3, Pitch, Yaw, HeadYaw float
|
|||
|
||||
if int(last.Position.X()) != int(w.PlayerPos.Position.X()) || int(last.Position.Z()) != int(w.PlayerPos.Position.Z()) {
|
||||
w.ui.SchedRedraw()
|
||||
w.ui.Send(w)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -455,6 +455,7 @@ func (w *WorldState) OnConnect(proxy *ProxyContext) {
|
|||
w.SaveAndReset()
|
||||
})
|
||||
|
||||
w.ui.Start()
|
||||
go func() { // send map item
|
||||
select {
|
||||
case <-w.ctx.Done():
|
||||
|
@ -508,7 +509,7 @@ func (w *WorldState) ProcessPacketClient(pk packet.Packet) packet.Packet {
|
|||
w.SetPlayerPos(pk.Position, pk.Pitch, pk.Yaw, pk.HeadYaw)
|
||||
case *packet.MapInfoRequest:
|
||||
if pk.MapID == VIEW_MAP_ID {
|
||||
w.ui.Send(w)
|
||||
w.ui.SchedRedraw()
|
||||
pk = nil
|
||||
}
|
||||
case *packet.MobEquipment:
|
||||
|
@ -527,7 +528,6 @@ func (w *WorldState) ProcessPacketServer(pk packet.Packet) packet.Packet {
|
|||
w.ProcessChangeDimension(pk)
|
||||
case *packet.LevelChunk:
|
||||
w.ProcessLevelChunk(pk)
|
||||
w.ui.Send(w)
|
||||
w.proxy.sendPopup(fmt.Sprintf("%d chunks loaded\nname: %s", len(w.chunks), w.WorldName))
|
||||
case *packet.SubChunk:
|
||||
w.ProcessSubChunk(pk)
|
||||
|
|
Loading…
Reference in New Issue