Also avoid potential loops

This commit is contained in:
DBotThePony 2022-10-12 10:03:46 +07:00
parent d1d35f0730
commit 6b1b90a795
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -24,7 +24,12 @@ import java.lang.ref.WeakReference
import java.util.WeakHashMap import java.util.WeakHashMap
abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_) { 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 { val synchronizer = FieldSynchronizer {
if (isSynchronizing)
return@FieldSynchronizer
if (!isRemoved && level?.isClientSide == false && (_subCache == null || (_subCache ?: throw ConcurrentModificationException()).players.isNotEmpty())) { if (!isRemoved && level?.isClientSide == false && (_subCache == null || (_subCache ?: throw ConcurrentModificationException()).players.isNotEmpty())) {
onceServer { onceServer {
synchronizeToPlayers(true) synchronizeToPlayers(true)
@ -103,33 +108,39 @@ abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_:
} }
protected fun synchronizeToPlayers(callbedBySynchronizer: Boolean) { protected fun synchronizeToPlayers(callbedBySynchronizer: Boolean) {
if (synchronizer.isEmpty || isRemoved) { isSynchronizing = true
if (callbedBySynchronizer) synchronizer.markClean()
return
}
check(level is ServerLevel) { "Invalid realm or Level is null" } try {
if (synchronizer.isEmpty || isRemoved) {
synchronizer.observe() if (callbedBySynchronizer) synchronizer.markClean()
return
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() 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( private data class ChunkSubscribers(