@@ -66,7 +66,9 @@ type World struct {
66
66
paused bool
67
67
pausedState * worldStateMem
68
68
// access to states
69
- l sync.Mutex
69
+ stateLock sync.Mutex
70
+
71
+ entityLock sync.Mutex
70
72
71
73
ResourcePacks []resource.Pack
72
74
resourcePacksDone chan error
@@ -84,10 +86,11 @@ type World struct {
84
86
Name string
85
87
Folder string
86
88
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
91
94
92
95
log * logrus.Entry
93
96
}
@@ -341,9 +344,12 @@ func (w *World) SetTime(real time.Time, ingame int) {
341
344
}
342
345
343
346
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
+ }
346
351
352
+ func (w * World ) storeChunkLocked (pos world.ChunkPos , ch * chunk.Chunk , blockNBT map [cube.Pos ]DummyBlock ) (err error ) {
347
353
var empty = true
348
354
for _ , sub := range ch .Sub () {
349
355
if ! sub .Empty () {
@@ -362,10 +368,10 @@ func (w *World) StoreChunk(pos world.ChunkPos, ch *chunk.Chunk, blockNBT map[cub
362
368
case <- w .finish :
363
369
return
364
370
case <- t .C :
365
- w .l .Lock ()
371
+ w .stateLock .Lock ()
366
372
w .applyBlockUpdates ()
367
373
w .storeMemToProvider ()
368
- w .l .Unlock ()
374
+ w .stateLock .Unlock ()
369
375
}
370
376
}
371
377
}()
@@ -378,9 +384,12 @@ func (w *World) StoreChunk(pos world.ChunkPos, ch *chunk.Chunk, blockNBT map[cub
378
384
}
379
385
380
386
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
+ }
383
391
392
+ func (w * World ) loadChunkLocked (pos world.ChunkPos ) (* chunk.Chunk , bool , error ) {
384
393
if w .paused {
385
394
ch , ok := w .pausedState .chunks [pos ]
386
395
if ok {
@@ -408,28 +417,27 @@ func (w *World) LoadChunk(pos world.ChunkPos) (*chunk.Chunk, bool, error) {
408
417
}
409
418
410
419
func (w * World ) QueueBlockUpdate (pos protocol.BlockPos , ridTo uint32 , layer uint8 ) {
411
- w .l .Lock ()
412
420
cp := world.ChunkPos {pos .X () >> 4 , pos .Z () >> 4 }
421
+ w .blockUpdatesLock .Lock ()
422
+ defer w .blockUpdatesLock .Unlock ()
413
423
w .blockUpdates [cp ] = append (w .blockUpdates [cp ], blockUpdate {rid : ridTo , pos : pos , layer : layer })
414
- w .l .Unlock ()
415
424
}
416
425
417
426
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 ()
420
429
w .currState ().SetBlockNBT (pos , nbt , merge )
421
430
}
422
431
423
432
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 )
428
436
}
429
437
430
438
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 ()
433
441
w .currState ().StoreMap (m )
434
442
}
435
443
@@ -439,8 +447,8 @@ func (w *World) GetEntityUniqueID(id entity.UniqueID) *entity.Entity {
439
447
}
440
448
441
449
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 ()
444
452
if w .paused {
445
453
es := w .pausedState .GetEntity (id )
446
454
if es != nil {
@@ -455,13 +463,13 @@ func (w *World) EntityCount() int {
455
463
}
456
464
457
465
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 ()
460
468
w .currState ().AddEntityLink (el )
461
469
}
462
470
463
471
func (w * World ) PauseCapture () {
464
- w .l .Lock ()
472
+ w .entityLock .Lock ()
465
473
w .paused = true
466
474
w .pausedState = & worldStateMem {
467
475
chunks : make (map [world.ChunkPos ]* chunk.Chunk ),
@@ -471,12 +479,12 @@ func (w *World) PauseCapture() {
471
479
472
480
uniqueIDsToRuntimeIDs : make (map [int64 ]uint64 ),
473
481
}
474
- w .l .Unlock ()
482
+ w .stateLock .Unlock ()
475
483
}
476
484
477
485
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 ()
480
488
if ! w .paused {
481
489
panic ("attempt to unpause when not paused" )
482
490
}
@@ -492,8 +500,8 @@ func (w *World) IsPaused() bool {
492
500
}
493
501
494
502
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 ()
497
505
w .Name = name
498
506
w .Folder = folder
499
507
@@ -525,9 +533,11 @@ func (w *World) BlockByID(rid uint32) (runtimeID uint32, name string, properties
525
533
}
526
534
527
535
func (w * World ) applyBlockUpdates () {
536
+ w .blockUpdatesLock .Lock ()
537
+ defer w .blockUpdatesLock .Unlock ()
528
538
for pos , updates := range w .blockUpdates {
529
539
delete (w .blockUpdates , pos )
530
- chunk , ok , err := w .LoadChunk (world .ChunkPos (pos ))
540
+ chunk , ok , err := w .loadChunkLocked (world .ChunkPos (pos ))
531
541
if ! ok {
532
542
w .log .Warnf ("Chunk updates for a chunk we dont have pos = %v" , pos )
533
543
continue
@@ -541,14 +551,14 @@ func (w *World) applyBlockUpdates() {
541
551
x , y , z := blockPosInChunk (update .pos )
542
552
chunk .SetBlock (x , y , z , update .layer , update .rid )
543
553
}
544
- w .StoreChunk (pos , chunk , nil )
554
+ w .storeChunkLocked (pos , chunk , nil )
545
555
}
546
556
}
547
557
548
558
// Rename moves the folder and reopens it
549
559
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 ()
552
562
553
563
os .RemoveAll (folder )
554
564
if w .provider != nil {
@@ -576,8 +586,8 @@ func (w *World) Rename(name, folder string) error {
576
586
}
577
587
578
588
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 ()
581
591
close (w .finish )
582
592
583
593
if withPlayers {
0 commit comments