diff --git a/psoserv/src/main/kotlin/world/phantasmal/psoserv/messages/BbMessages.kt b/psoserv/src/main/kotlin/world/phantasmal/psoserv/messages/BbMessages.kt index 803d5513..cc14003e 100644 --- a/psoserv/src/main/kotlin/world/phantasmal/psoserv/messages/BbMessages.kt +++ b/psoserv/src/main/kotlin/world/phantasmal/psoserv/messages/BbMessages.kt @@ -4,6 +4,7 @@ import world.phantasmal.psolib.buffer.Buffer import world.phantasmal.psolib.cursor.Cursor import world.phantasmal.psolib.cursor.WritableCursor import world.phantasmal.psolib.cursor.cursor +import world.phantasmal.psoserv.utils.toHex private const val INIT_MSG_SIZE: Int = 96 private const val KEY_SIZE: Int = 48 @@ -32,6 +33,8 @@ object BbMessageDescriptor : MessageDescriptor { 0x0007 -> BbMessage.BlockList(buffer) 0x0010 -> BbMessage.MenuSelect(buffer) 0x0019 -> BbMessage.Redirect(buffer) + 0x001D -> BbMessage.Ping(buffer) + 0x0060 -> BbMessage.Broadcast(buffer) 0x0061 -> BbMessage.CharData(buffer) 0x0067 -> BbMessage.JoinLobby(buffer) 0x0083 -> BbMessage.LobbyList(buffer) @@ -162,6 +165,31 @@ sealed class BbMessage(override val buffer: Buffer) : AbstractMessage(BB_HEADER_ ) } + // 0x001D + class Ping(buffer: Buffer) : BbMessage(buffer) { + constructor() : this(buf(code = 0x001D)) + } + + // 0x0060 + class Broadcast(buffer: Buffer) : BbMessage(buffer) { + var subType: UByte + get() = uByte(0) + set(value) = setUByte(0, value) + var subSize: UByte + get() = uByte(1) + set(value) = setUByte(1, value) + var clientId: UByte + get() = uByte(2) + set(value) = setUByte(2, value) + + override fun toString(): String = + messageString( + "subType" to subType.toHex(), + "subSize" to subSize, + "clientId" to clientId, + ) + } + // 0x0061 class CharData(buffer: Buffer) : BbMessage(buffer) diff --git a/psoserv/src/main/kotlin/world/phantasmal/psoserv/messages/Messages.kt b/psoserv/src/main/kotlin/world/phantasmal/psoserv/messages/Messages.kt index 25ad770c..0d7a54f1 100644 --- a/psoserv/src/main/kotlin/world/phantasmal/psoserv/messages/Messages.kt +++ b/psoserv/src/main/kotlin/world/phantasmal/psoserv/messages/Messages.kt @@ -1,20 +1,27 @@ package world.phantasmal.psoserv.messages import world.phantasmal.psolib.buffer.Buffer +import world.phantasmal.psoserv.utils.toHex fun messageString( code: Int, size: Int, + flags: Int, name: String? = null, vararg props: Pair, ): String = buildString { append(name ?: "Message") - append("[0x") - append(code.toString(16).uppercase().padStart(4, '0')) + append("[") + append(code.toHex(pad = 4)) append(",size=") append(size) + if (flags != 0) { + append(",flags=") + append(flags.toHex()) + } + if (props.isNotEmpty()) { props.joinTo(this, prefix = ",", separator = ",") { (prop, value) -> "$prop=$value" } } @@ -97,5 +104,5 @@ abstract class AbstractMessage(override val headerSize: Int) : Message { } protected fun messageString(vararg props: Pair): String = - messageString(code, size, this::class.simpleName, *props) + messageString(code, size, flags, this::class.simpleName, *props) } diff --git a/psoserv/src/main/kotlin/world/phantasmal/psoserv/servers/ProxyServer.kt b/psoserv/src/main/kotlin/world/phantasmal/psoserv/servers/ProxyServer.kt index 88d3e339..f5305ed8 100644 --- a/psoserv/src/main/kotlin/world/phantasmal/psoserv/servers/ProxyServer.kt +++ b/psoserv/src/main/kotlin/world/phantasmal/psoserv/servers/ProxyServer.kt @@ -120,9 +120,9 @@ class ProxyServer( override val messageDescriptor = this@ProxyServer.messageDescriptor - override fun logMessageTooLarge(code: Int, size: Int) { + override fun logMessageTooLarge(code: Int, size: Int, flags: Int) { logger.warn { - val message = messageString(code, size) + val message = messageString(code, size, flags) "Sending $message with size ${size}B. Skipping because it's too large." } } diff --git a/psoserv/src/main/kotlin/world/phantasmal/psoserv/servers/SocketHandler.kt b/psoserv/src/main/kotlin/world/phantasmal/psoserv/servers/SocketHandler.kt index ffad93e1..3dd0501e 100644 --- a/psoserv/src/main/kotlin/world/phantasmal/psoserv/servers/SocketHandler.kt +++ b/psoserv/src/main/kotlin/world/phantasmal/psoserv/servers/SocketHandler.kt @@ -73,7 +73,7 @@ abstract class SocketHandler( decryptCipher.decrypt(headerBuffer) } - val (code, size) = messageDescriptor.readHeader(headerBuffer) + val (code, size, flags) = messageDescriptor.readHeader(headerBuffer) val encryptedSize = alignToWidth(size, decryptCipher?.blockSize ?: 1) // Bytes available for the next message. val available = readBuffer.size - offset @@ -81,7 +81,7 @@ abstract class SocketHandler( when { // Don't parse the message when it's too large. encryptedSize > BUFFER_CAPACITY -> { - logMessageTooLarge(code, size) + logMessageTooLarge(code, size, flags) bytesToSkip = encryptedSize - available @@ -273,9 +273,9 @@ abstract class SocketHandler( // Do nothing. } - protected open fun logMessageTooLarge(code: Int, size: Int) { + protected open fun logMessageTooLarge(code: Int, size: Int, flags: Int) { logger.warn { - val message = messageString(code, size) + val message = messageString(code, size, flags) "Receiving $message with size ${size}B. Skipping because it's too large." } } diff --git a/psoserv/src/main/kotlin/world/phantasmal/psoserv/utils/StringUtils.kt b/psoserv/src/main/kotlin/world/phantasmal/psoserv/utils/StringUtils.kt new file mode 100644 index 00000000..2678c073 --- /dev/null +++ b/psoserv/src/main/kotlin/world/phantasmal/psoserv/utils/StringUtils.kt @@ -0,0 +1,7 @@ +package world.phantasmal.psoserv.utils + +fun Int.toHex(pad: Int = 8): String = + "0x" + toString(16).uppercase().padStart(pad, '0') + +fun UByte.toHex(pad: Int = 2): String = + "0x" + toString(16).uppercase().padStart(pad, '0')