Listen for new servermessages in MessageParser

Signed-off-by: observer <admin@shr4pnel.com>
This commit is contained in:
2026-08-14 23:46:25 +01:00
committed by observer
parent 6dab22a04c
commit bd2e330565
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))
}
}