From bd2e3305654549febb0cf8a0a7cc7577b4042771 Mon Sep 17 00:00:00 2001 From: shrapnelnet Date: Fri, 14 Aug 2026 18:39:50 +0100 Subject: [PATCH] Listen for new servermessages in MessageParser Signed-off-by: observer --- .../shr4pnel/ferretirc/net/MessageParser.kt | 35 +++++++++++++++++-- .../shr4pnel/ferretirc/net/MessageWriter.kt | 2 +- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/shr4pnel/ferretirc/net/MessageParser.kt b/src/main/kotlin/com/shr4pnel/ferretirc/net/MessageParser.kt index 2679c69..badb9e3 100644 --- a/src/main/kotlin/com/shr4pnel/ferretirc/net/MessageParser.kt +++ b/src/main/kotlin/com/shr4pnel/ferretirc/net/MessageParser.kt @@ -2,6 +2,8 @@ package com.shr4pnel.ferretirc.net import com.shr4pnel.ferretirc.net.messages.ServerMessage import io.github.oshai.kotlinlogging.KotlinLogging +import io.ktor.http.parameters +import io.ktor.network.selector.SelectInterest import io.ktor.util.toUpperCasePreservingASCIIRules import kotlinx.coroutines.channels.Channel @@ -10,22 +12,49 @@ class MessageParser(val incoming: Channel) { val incomingParsedMessages = Channel() private companion object MessageBuilder { + val logger = KotlinLogging.logger("MessageParser.MessageBuilder") + fun getTrailingParameterIndex(params: List) = params.indexOfLast { it.startsWith(":") } + sealed interface Command { fun toServerMessage(): ServerMessage class NamedCommand(val name: String, val parameters: List) : Command { override fun toServerMessage(): ServerMessage { + logger.debug { "Attempting to parse ${name.toUpperCasePreservingASCIIRules()}, with params $parameters" } + return when (name.toUpperCasePreservingASCIIRules()) { // PONG :PREFIX COMMAND HOSTNAME :TOKEN "PONG" -> { - val tokenIndex = parameters.indexOfLast { it.contains(":") } + val tokenIndex = getTrailingParameterIndex(parameters) if (tokenIndex != -1) ServerMessage.Pong( parameters.subList(tokenIndex, parameters.size).joinToString(" ").removePrefix(":") ) else ServerMessage.Pong() } + // MODE :PREFIX NICK :MODES + "MODE" -> { + ServerMessage.Mode(parameters.first(), parameters.last().removePrefix(":")) // TODO MODE, CHANMODE, LOCALMODE + } - else -> ServerMessage.UNIMPLEMENTED("$name ${parameters.joinToString(" ")}") + "NOTICE", "PRIVMSG" -> { + val cmd = name.toUpperCasePreservingASCIIRules() + val trailingIndex = getTrailingParameterIndex(parameters) + if (trailingIndex < 1) { + logger.warn { "Received malformed $cmd. Returning unimplemented as fallback." } + return ServerMessage.UNIMPLEMENTED("$cmd ${parameters.joinToString(" ")}") + } + val targets = parameters.subList(0, trailingIndex - 1) + if (cmd == "NOTICE") + ServerMessage.Notice(targets, "") + else + ServerMessage.PrivMsg(targets, "") + + } + + else -> { + logger.warn { "$name left unparsed" } + ServerMessage.UNIMPLEMENTED("$name ${parameters.joinToString(" ")}") + } } } } @@ -76,7 +105,7 @@ class MessageParser(val incoming: Channel) { suspend fun start() { for (msg in incoming) { - logger.debug { msg } +// logger.debug { msg } incomingParsedMessages.send(build(msg)) } } diff --git a/src/main/kotlin/com/shr4pnel/ferretirc/net/MessageWriter.kt b/src/main/kotlin/com/shr4pnel/ferretirc/net/MessageWriter.kt index f797815..21d339c 100644 --- a/src/main/kotlin/com/shr4pnel/ferretirc/net/MessageWriter.kt +++ b/src/main/kotlin/com/shr4pnel/ferretirc/net/MessageWriter.kt @@ -17,7 +17,7 @@ class MessageWriter(socket: Socket, scope: CoroutineScope) : MessageIO(socket, s send = socket.openWriteChannel() for (msg in outgoingMessages) { - logger.debug { msg.toWireIntermediate() } + logger.debug { "Sending: ${msg.toWireIntermediate()}" } send.writeFully(msg.toWire()) send.flush() }