diff --git a/Server/src/main/core/net/packet/PacketWriteQueue.kt b/Server/src/main/core/net/packet/PacketWriteQueue.kt index 294a54452..1bc60a382 100644 --- a/Server/src/main/core/net/packet/PacketWriteQueue.kt +++ b/Server/src/main/core/net/packet/PacketWriteQueue.kt @@ -1,21 +1,15 @@ package core.net.packet -import core.api.TickListener +import core.api.tryPop import core.net.packet.out.* import core.tools.SystemLogger -import java.lang.IndexOutOfBoundsException +import java.io.PrintWriter +import java.io.StringWriter import java.util.* import java.util.concurrent.locks.ReentrantLock -import kotlin.NoSuchElementException - -class PacketWriteQueue : TickListener { - override fun tick() { - flush() - } +class PacketWriteQueue { companion object { - private val queueLock = ReentrantLock() - private val packetsToQueue = LinkedList?>() private val packetsToWrite = LinkedList?>() @JvmStatic @@ -33,46 +27,24 @@ class PacketWriteQueue : TickListener { @JvmStatic fun push(packet: OutgoingPacket, context: T) { - if (queueLock.isHeldByCurrentThread) - packetsToQueue.add(QueuedPacket(packet, context)) - else - packetsToWrite.add(QueuedPacket(packet, context)) + packetsToWrite.add(QueuedPacket(packet, context)) } @JvmStatic fun flush() { - queueLock.lock() - - var hasEnded = false - while (!hasEnded) { + var countThisCycle = packetsToWrite.size + val sw = StringWriter() + val pw = PrintWriter(sw) + while (countThisCycle-- > 0) { + val pkt = packetsToWrite.tryPop(null) ?: continue try { - val packet = packetsToWrite.pop() - write(packet?.out ?: continue, packet.context ?: continue) - } catch (e: NoSuchElementException) { - hasEnded = true - } - } - - if (packetsToWrite.isNotEmpty()) { - SystemLogger.logWarn(this::class.java, "Packet queue was NOT empty! Remaining packets: ${packetsToWrite.size}") - try { - for (pkt: QueuedPacket<*>? in packetsToWrite) SystemLogger.logWarn(this::class.java, "${pkt?.out?.javaClass?.simpleName ?: "NULL"} <- ${pkt?.context ?: "NULL"}") - } catch (ignored: NullPointerException) { - //do nothing, we don't care, this can happen when everything is working as intended. - } catch (ignored: IndexOutOfBoundsException) { - //do nothing, we don't care, this can happen when everything is working as intended. + write(pkt.out, pkt.context) } catch (e: Exception) { - e.printStackTrace() - } finally { - packetsToWrite.clear() + e.printStackTrace(pw) + SystemLogger.logErr(this::class.java, "Error flushing packet ${pkt.out::class.java}: $sw") + continue } } - - queueLock.unlock() - - while (packetsToQueue.isNotEmpty()) { - packetsToWrite.add(packetsToQueue.pop()) - } } @Suppress("UNCHECKED_CAST") @@ -80,8 +52,7 @@ class PacketWriteQueue : TickListener { val pack = out as? OutgoingPacket val ctx = context as? T if (pack == null || ctx == null) { - SystemLogger.logWarn(this::class.java, "Failed packet casting") - return + throw IllegalStateException("Failed packet casting") } pack.send(ctx) } diff --git a/Server/src/main/core/worker/MajorUpdateWorker.kt b/Server/src/main/core/worker/MajorUpdateWorker.kt index 104ab5a50..88c4c8261 100644 --- a/Server/src/main/core/worker/MajorUpdateWorker.kt +++ b/Server/src/main/core/worker/MajorUpdateWorker.kt @@ -11,6 +11,7 @@ import core.game.world.GameWorld import core.game.world.repository.Repository import core.game.world.update.UpdateSequence import core.net.packet.PacketProcessor +import core.net.packet.PacketWriteQueue import core.tools.colorize import java.lang.Long.max import java.text.SimpleDateFormat @@ -84,6 +85,7 @@ class MajorUpdateWorker { if (!skipPulseUpdate) { GameWorld.Pulser.updateAll() } + GameWorld.tickListeners.forEach { it.tick() } try { sequence.start() @@ -96,9 +98,10 @@ class MajorUpdateWorker { GameWorld.pulse() //disconnect all players waiting to be disconnected Repository.disconnectionQueue.update() - GameWorld.tickListeners.forEach { it.tick() } //tick all manager plugins Managers.tick() + + PacketWriteQueue.flush() } fun start() {