From 6b1b90a7957ca52b080eb4340d425400fbea33eb Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Wed, 12 Oct 2022 10:03:46 +0700 Subject: [PATCH] Also avoid potential loops --- .../block/entity/SynchronizedBlockEntity.kt | 59 +++++++++++-------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/SynchronizedBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/SynchronizedBlockEntity.kt index 89887290f..9c9b7245a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/SynchronizedBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/SynchronizedBlockEntity.kt @@ -24,7 +24,12 @@ import java.lang.ref.WeakReference import java.util.WeakHashMap abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_) { + private var isSynchronizing = false + val synchronizer = FieldSynchronizer { + if (isSynchronizing) + return@FieldSynchronizer + if (!isRemoved && level?.isClientSide == false && (_subCache == null || (_subCache ?: throw ConcurrentModificationException()).players.isNotEmpty())) { onceServer { synchronizeToPlayers(true) @@ -103,33 +108,39 @@ abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: } protected fun synchronizeToPlayers(callbedBySynchronizer: Boolean) { - if (synchronizer.isEmpty || isRemoved) { - if (callbedBySynchronizer) synchronizer.markClean() - return - } + isSynchronizing = true - check(level is ServerLevel) { "Invalid realm or Level is null" } - - synchronizer.observe() - - val subscription = subscription - - if (subscription.players.isEmpty() || lastSubscriptionChangeset == subscription.changeset && !synchronizer.hasChanges) { - if (callbedBySynchronizer) synchronizer.markClean() - return - } - - lastSubscriptionChangeset = subscription.changeset - - for (player in subscription.players) { - val payload = synchronizer.computeEndpointFor(player).collectNetworkPayload() - - if (payload != null) { - WorldNetworkChannel.send(player, BlockEntitySyncPacket(blockPos, payload.array, payload.length)) + try { + if (synchronizer.isEmpty || isRemoved) { + if (callbedBySynchronizer) synchronizer.markClean() + return } - } - synchronizer.markClean() + check(level is ServerLevel) { "Invalid realm or Level is null" } + + synchronizer.observe() + + val subscription = subscription + + if (subscription.players.isEmpty() || lastSubscriptionChangeset == subscription.changeset && !synchronizer.hasChanges) { + if (callbedBySynchronizer) synchronizer.markClean() + return + } + + lastSubscriptionChangeset = subscription.changeset + + for (player in subscription.players) { + val payload = synchronizer.computeEndpointFor(player).collectNetworkPayload() + + if (payload != null) { + WorldNetworkChannel.send(player, BlockEntitySyncPacket(blockPos, payload.array, payload.length)) + } + } + + synchronizer.markClean() + } finally { + isSynchronizing = false + } } private data class ChunkSubscribers(