Increased server stability

Fixed NPE in IoEventHandler
Fixed NPEs in PacketWriteQueue
Reworked PacketWriteQueue slightly so that instead of breaking at first null packet we continue past it and pop the whole queue along the way
This commit is contained in:
Ceikry
2022-06-27 14:09:44 +00:00
committed by Ryan
parent ee5bc78b62
commit 95414bc02b
2 changed files with 20 additions and 17 deletions
@@ -72,7 +72,8 @@ public class IoEventHandler {
} catch (IOException e) { } catch (IOException e) {
if (e.getMessage().contains("reset by peer")) { if (e.getMessage().contains("reset by peer")) {
session.disconnect(); session.disconnect();
session.getPlayer().clear(true); if (session.getPlayer() != null)
session.getPlayer().clear(true);
} else e.printStackTrace(); } else e.printStackTrace();
} }
buffer.flip(); buffer.flip();
@@ -6,6 +6,7 @@ import core.net.packet.out.*
import rs09.game.system.SystemLogger import rs09.game.system.SystemLogger
import java.util.* import java.util.*
import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.locks.ReentrantLock
import kotlin.NoSuchElementException
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
class PacketWriteQueue : TickListener { class PacketWriteQueue : TickListener {
@@ -15,8 +16,8 @@ class PacketWriteQueue : TickListener {
companion object { companion object {
private val queueLock = ReentrantLock() private val queueLock = ReentrantLock()
private val packetsToQueue = ArrayList<QueuedPacket<*>>(1000) private val packetsToQueue = ArrayList<QueuedPacket<*>?>(1000)
private val packetsToWrite = LinkedList<QueuedPacket<*>>() private val packetsToWrite = LinkedList<QueuedPacket<*>?>()
@JvmStatic @JvmStatic
fun <T> handle(packet: OutgoingPacket<T>, context: T) { fun <T> handle(packet: OutgoingPacket<T>, context: T) {
@@ -39,25 +40,24 @@ class PacketWriteQueue : TickListener {
packetsToWrite.add(QueuedPacket(packet, context)) packetsToWrite.add(QueuedPacket(packet, context))
} }
@JvmStatic
fun pop(): QueuedPacket<*>? {
return try {
packetsToWrite.pop()
} catch (e: NoSuchElementException) {
null
}
}
@JvmStatic @JvmStatic
fun flush() { fun flush() {
queueLock.lock() queueLock.lock()
var packet: QueuedPacket<*>?
while (pop().also { packet = it } != null) var hasEnded = false
write(packet?.out ?: break, packet?.context ?: break) while (!hasEnded) {
try {
val packet = packetsToWrite.pop()
write(packet?.out ?: continue, packet.context ?: continue)
} catch (e: NoSuchElementException) {
hasEnded = true
}
}
if (packetsToWrite.isNotEmpty()) { if (packetsToWrite.isNotEmpty()) {
SystemLogger.logWarn("Packet queue was NOT empty! Remaining packets: ${packetsToWrite.size}") SystemLogger.logWarn("Packet queue was NOT empty! Remaining packets: ${packetsToWrite.size}")
try { try {
for (pkt in packetsToWrite) SystemLogger.logWarn("${pkt.out.javaClass.simpleName} <- ${pkt.context}") for (pkt: QueuedPacket<*>? in packetsToWrite) SystemLogger.logWarn("${pkt?.out?.javaClass?.simpleName ?: "NULL"} <- ${pkt?.context ?: "NULL"}")
} catch (e: Exception) } catch (e: Exception)
{ {
e.printStackTrace() e.printStackTrace()
@@ -65,12 +65,14 @@ class PacketWriteQueue : TickListener {
packetsToWrite.clear() packetsToWrite.clear()
} }
} }
queueLock.unlock()
val queueIter = packetsToQueue.iterator() val queueIter = packetsToQueue.iterator()
while (queueIter.hasNext()) { while (queueIter.hasNext()) {
packetsToWrite.add(queueIter.next()) packetsToWrite.add(queueIter.next())
queueIter.remove() queueIter.remove()
} }
queueLock.unlock()
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")