Skip to content

Commit 1432f83

Browse files
committed
fix block update hang
1 parent 62babdf commit 1432f83

File tree

4 files changed

+84
-43
lines changed

4 files changed

+84
-43
lines changed

gophertunnel

handlers/worlds/entity/entity.go

+5
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ func (s *Entity) toNBT(nbt map[string]any) {
126126
if name, ok := metadata[protocol.EntityDataKeyName]; ok {
127127
nbt["CustomName"] = name
128128
}
129+
130+
if rawName, ok := metadata[protocol.EntityDataKeyNameRawText].(string); ok {
131+
nbt["CustomName"] = rawName
132+
}
133+
129134
if ShowNameTag, ok := metadata[protocol.EntityDataKeyAlwaysShowNameTag]; ok {
130135
if ShowNameTag != 0 {
131136
nbt["CustomNameVisible"] = true

handlers/worlds/worldstate/world.go

+47-37
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ type World struct {
6666
paused bool
6767
pausedState *worldStateMem
6868
// access to states
69-
l sync.Mutex
69+
stateLock sync.Mutex
70+
71+
entityLock sync.Mutex
7072

7173
ResourcePacks []resource.Pack
7274
resourcePacksDone chan error
@@ -84,10 +86,11 @@ type World struct {
8486
Name string
8587
Folder string
8688

87-
UseHashedRids bool
88-
blockUpdates map[world.ChunkPos][]blockUpdate
89-
onChunkUpdate func(pos world.ChunkPos, chunk *chunk.Chunk, isPaused bool)
90-
IgnoredChunks map[world.ChunkPos]bool
89+
UseHashedRids bool
90+
blockUpdatesLock sync.Mutex
91+
blockUpdates map[world.ChunkPos][]blockUpdate
92+
onChunkUpdate func(pos world.ChunkPos, chunk *chunk.Chunk, isPaused bool)
93+
IgnoredChunks map[world.ChunkPos]bool
9194

9295
log *logrus.Entry
9396
}
@@ -341,9 +344,12 @@ func (w *World) SetTime(real time.Time, ingame int) {
341344
}
342345

343346
func (w *World) StoreChunk(pos world.ChunkPos, ch *chunk.Chunk, blockNBT map[cube.Pos]DummyBlock) (err error) {
344-
w.l.Lock()
345-
defer w.l.Unlock()
347+
w.stateLock.Lock()
348+
defer w.stateLock.Unlock()
349+
return w.storeChunkLocked(pos, ch, blockNBT)
350+
}
346351

352+
func (w *World) storeChunkLocked(pos world.ChunkPos, ch *chunk.Chunk, blockNBT map[cube.Pos]DummyBlock) (err error) {
347353
var empty = true
348354
for _, sub := range ch.Sub() {
349355
if !sub.Empty() {
@@ -362,10 +368,10 @@ func (w *World) StoreChunk(pos world.ChunkPos, ch *chunk.Chunk, blockNBT map[cub
362368
case <-w.finish:
363369
return
364370
case <-t.C:
365-
w.l.Lock()
371+
w.stateLock.Lock()
366372
w.applyBlockUpdates()
367373
w.storeMemToProvider()
368-
w.l.Unlock()
374+
w.stateLock.Unlock()
369375
}
370376
}
371377
}()
@@ -378,9 +384,12 @@ func (w *World) StoreChunk(pos world.ChunkPos, ch *chunk.Chunk, blockNBT map[cub
378384
}
379385

380386
func (w *World) LoadChunk(pos world.ChunkPos) (*chunk.Chunk, bool, error) {
381-
w.l.Lock()
382-
defer w.l.Unlock()
387+
w.stateLock.Lock()
388+
defer w.stateLock.Unlock()
389+
return w.loadChunkLocked(pos)
390+
}
383391

392+
func (w *World) loadChunkLocked(pos world.ChunkPos) (*chunk.Chunk, bool, error) {
384393
if w.paused {
385394
ch, ok := w.pausedState.chunks[pos]
386395
if ok {
@@ -408,28 +417,27 @@ func (w *World) LoadChunk(pos world.ChunkPos) (*chunk.Chunk, bool, error) {
408417
}
409418

410419
func (w *World) QueueBlockUpdate(pos protocol.BlockPos, ridTo uint32, layer uint8) {
411-
w.l.Lock()
412420
cp := world.ChunkPos{pos.X() >> 4, pos.Z() >> 4}
421+
w.blockUpdatesLock.Lock()
422+
defer w.blockUpdatesLock.Unlock()
413423
w.blockUpdates[cp] = append(w.blockUpdates[cp], blockUpdate{rid: ridTo, pos: pos, layer: layer})
414-
w.l.Unlock()
415424
}
416425

417426
func (w *World) SetBlockNBT(pos cube.Pos, nbt map[string]any, merge bool) {
418-
w.l.Lock()
419-
defer w.l.Unlock()
427+
w.entityLock.Lock()
428+
defer w.entityLock.Unlock()
420429
w.currState().SetBlockNBT(pos, nbt, merge)
421430
}
422431

423432
func (w *World) StoreEntity(id entity.RuntimeID, es *entity.Entity) {
424-
w.l.Lock()
425-
defer w.l.Unlock()
426-
state := w.currState()
427-
state.StoreEntity(id, es)
433+
w.entityLock.Lock()
434+
defer w.entityLock.Unlock()
435+
w.currState().StoreEntity(id, es)
428436
}
429437

430438
func (w *World) StoreMap(m *packet.ClientBoundMapItemData) {
431-
w.l.Lock()
432-
defer w.l.Unlock()
439+
w.entityLock.Lock()
440+
defer w.entityLock.Unlock()
433441
w.currState().StoreMap(m)
434442
}
435443

@@ -439,8 +447,8 @@ func (w *World) GetEntityUniqueID(id entity.UniqueID) *entity.Entity {
439447
}
440448

441449
func (w *World) GetEntity(id entity.RuntimeID) *entity.Entity {
442-
w.l.Lock()
443-
defer w.l.Unlock()
450+
w.entityLock.Lock()
451+
defer w.entityLock.Unlock()
444452
if w.paused {
445453
es := w.pausedState.GetEntity(id)
446454
if es != nil {
@@ -455,13 +463,13 @@ func (w *World) EntityCount() int {
455463
}
456464

457465
func (w *World) AddEntityLink(el protocol.EntityLink) {
458-
w.l.Lock()
459-
defer w.l.Unlock()
466+
w.entityLock.Lock()
467+
defer w.entityLock.Unlock()
460468
w.currState().AddEntityLink(el)
461469
}
462470

463471
func (w *World) PauseCapture() {
464-
w.l.Lock()
472+
w.entityLock.Lock()
465473
w.paused = true
466474
w.pausedState = &worldStateMem{
467475
chunks: make(map[world.ChunkPos]*chunk.Chunk),
@@ -471,12 +479,12 @@ func (w *World) PauseCapture() {
471479

472480
uniqueIDsToRuntimeIDs: make(map[int64]uint64),
473481
}
474-
w.l.Unlock()
482+
w.stateLock.Unlock()
475483
}
476484

477485
func (w *World) UnpauseCapture(around cube.Pos, radius int32) {
478-
w.l.Lock()
479-
defer w.l.Unlock()
486+
w.stateLock.Lock()
487+
defer w.stateLock.Unlock()
480488
if !w.paused {
481489
panic("attempt to unpause when not paused")
482490
}
@@ -492,8 +500,8 @@ func (w *World) IsPaused() bool {
492500
}
493501

494502
func (w *World) Open(name string, folder string, deferred bool) {
495-
w.l.Lock()
496-
defer w.l.Unlock()
503+
w.stateLock.Lock()
504+
defer w.stateLock.Unlock()
497505
w.Name = name
498506
w.Folder = folder
499507

@@ -525,9 +533,11 @@ func (w *World) BlockByID(rid uint32) (runtimeID uint32, name string, properties
525533
}
526534

527535
func (w *World) applyBlockUpdates() {
536+
w.blockUpdatesLock.Lock()
537+
defer w.blockUpdatesLock.Unlock()
528538
for pos, updates := range w.blockUpdates {
529539
delete(w.blockUpdates, pos)
530-
chunk, ok, err := w.LoadChunk(world.ChunkPos(pos))
540+
chunk, ok, err := w.loadChunkLocked(world.ChunkPos(pos))
531541
if !ok {
532542
w.log.Warnf("Chunk updates for a chunk we dont have pos = %v", pos)
533543
continue
@@ -541,14 +551,14 @@ func (w *World) applyBlockUpdates() {
541551
x, y, z := blockPosInChunk(update.pos)
542552
chunk.SetBlock(x, y, z, update.layer, update.rid)
543553
}
544-
w.StoreChunk(pos, chunk, nil)
554+
w.storeChunkLocked(pos, chunk, nil)
545555
}
546556
}
547557

548558
// Rename moves the folder and reopens it
549559
func (w *World) Rename(name, folder string) error {
550-
w.l.Lock()
551-
defer w.l.Unlock()
560+
w.stateLock.Lock()
561+
defer w.stateLock.Unlock()
552562

553563
os.RemoveAll(folder)
554564
if w.provider != nil {
@@ -576,8 +586,8 @@ func (w *World) Rename(name, folder string) error {
576586
}
577587

578588
func (w *World) Finish(playerData map[string]any, excludedMobs []string, withPlayers bool, spawn cube.Pos, gd minecraft.GameData, experimental bool) error {
579-
w.l.Lock()
580-
defer w.l.Unlock()
589+
w.stateLock.Lock()
590+
defer w.stateLock.Unlock()
581591
close(w.finish)
582592

583593
if withPlayers {

utils/behaviourpack/item.go

+31-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func (bp *Pack) AddItem(item protocol.ItemEntry) {
2525
}
2626

2727
bp.items[item.Name] = &itemBehaviour{
28-
FormatVersion: bp.formatVersion,
28+
FormatVersion: "1.20.50",
2929
MinecraftItem: minecraftItem{
3030
Description: itemDescription{
3131
Identifier: item.Name,
@@ -43,19 +43,45 @@ func (bp *Pack) ApplyComponentEntries(entries []protocol.ItemComponentEntry) {
4343
continue
4444
}
4545
if components, ok := ice.Data["components"].(map[string]any); ok {
46+
var componentsOut = make(map[string]any)
47+
4648
if _, ok := components["minecraft:icon"]; !ok {
4749
if item_properties, ok := components["item_properties"].(map[string]any); ok {
4850
components["minecraft:icon"] = item_properties["minecraft:icon"]
4951
}
5052
}
5153

52-
if icon, ok := components["minecraft:icon"].(map[string]any); ok {
53-
if textures, ok := icon["textures"].(map[string]any); ok {
54-
icon["textures"] = textures["default"]
54+
for key, component := range components {
55+
switch key {
56+
case "item_properties":
57+
if item_properties, ok := component.(map[string]any); ok {
58+
if icon, ok := item_properties["minecraft:icon"].(map[string]any); ok {
59+
if textures, ok := icon["textures"].(map[string]any); ok {
60+
componentsOut["minecraft:icon"] = map[string]any{
61+
"texture": textures["default"],
62+
}
63+
}
64+
}
65+
}
66+
67+
case "minecraft:icon":
68+
if icon, ok := component.(map[string]any); ok {
69+
if textures, ok := icon["textures"].(map[string]any); ok {
70+
componentsOut[key] = map[string]any{
71+
"texture": textures["default"],
72+
}
73+
}
74+
}
75+
case "minecraft:interact_button":
76+
if interact_button, ok := component.(map[string]any); ok {
77+
componentsOut[key] = interact_button["interact_text"]
78+
}
79+
default:
80+
componentsOut[key] = component
5581
}
5682
}
5783

58-
item.MinecraftItem.Components = components
84+
item.MinecraftItem.Components = componentsOut
5985
}
6086
}
6187
}

0 commit comments

Comments
 (0)