diff --git a/src/main/java/com/anatawa12/fixRtm/ThreadUtil.kt b/src/main/java/com/anatawa12/fixRtm/ThreadUtil.kt new file mode 100644 index 00000000..febbaa4a --- /dev/null +++ b/src/main/java/com/anatawa12/fixRtm/ThreadUtil.kt @@ -0,0 +1,28 @@ +package com.anatawa12.fixRtm + +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import java.util.concurrent.ConcurrentLinkedQueue + +object ThreadUtil { + fun runOnClientThread(block: () -> Unit) { + client.add(block) + } + + fun runOnServerThread(block: () -> Unit) { + server.add(block) + } + + @SubscribeEvent + fun onClientTick(e: TickEvent.ClientTickEvent) { + while (true) (client.poll() ?: return)() + } + + @SubscribeEvent + fun onServerTick(e: TickEvent.ServerTickEvent) { + while (true) (server.poll() ?: return)() + } + + private val client = ConcurrentLinkedQueue<() -> Unit>() + private val server = ConcurrentLinkedQueue<() -> Unit>() +} diff --git a/src/main/java/com/anatawa12/fixRtm/network/NotifyUntracked.kt b/src/main/java/com/anatawa12/fixRtm/network/NotifyUntracked.kt index 21967f9e..fe018700 100644 --- a/src/main/java/com/anatawa12/fixRtm/network/NotifyUntracked.kt +++ b/src/main/java/com/anatawa12/fixRtm/network/NotifyUntracked.kt @@ -1,6 +1,7 @@ package com.anatawa12.fixRtm.network import com.anatawa12.fixRtm.Loggers +import com.anatawa12.fixRtm.ThreadUtil import io.netty.buffer.ByteBuf import net.minecraft.world.WorldServer import net.minecraftforge.fml.common.network.simpleimpl.IMessage @@ -30,14 +31,16 @@ class NotifyUntracked : IMessage { companion object : IMessageHandler { override fun onMessage(message: NotifyUntracked, ctx: MessageContext): Nothing? { - val entry = ctx.serverHandler.player.world - .let { it as WorldServer } - .entityTracker - .trackedEntityHashTable - .lookup(message.entityId) - ?: return null.also { logger.error("entry for #${message.entityId} not found") } - - entry.trackingPlayers.remove(ctx.serverHandler.player) + val world = ctx.serverHandler.player.world as WorldServer + ThreadUtil.runOnServerThread { + val entry = world + .entityTracker + .trackedEntityHashTable + .lookup(message.entityId) + ?: return@runOnServerThread logger.error("entry for #${message.entityId} not found") + + entry.trackingPlayers.remove(ctx.serverHandler.player) + } return null }