Listen for new servermessages in MessageParser

This commit is contained in:
2026-08-14 18:39:50 +01:00
parent f7a2e9c6b6
commit 0b5a370e6e
2 changed files with 33 additions and 4 deletions
@@ -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<String>) {
val incomingParsedMessages = Channel<ServerMessage>()
private companion object MessageBuilder {
val logger = KotlinLogging.logger("MessageParser.MessageBuilder")
fun getTrailingParameterIndex(params: List<String>) = params.indexOfLast { it.startsWith(":") }
sealed interface Command {
fun toServerMessage(): ServerMessage
class NamedCommand(val name: String, val parameters: List<String>) : 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<String>) {
suspend fun start() {
for (msg in incoming) {
logger.debug { msg }
// logger.debug { msg }
incomingParsedMessages.send(build(msg))
}
}
@@ -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()
}