Listen for new servermessages in MessageParser
This commit is contained in:
@@ -2,6 +2,8 @@ package com.shr4pnel.ferretirc.net
|
|||||||
|
|
||||||
import com.shr4pnel.ferretirc.net.messages.ServerMessage
|
import com.shr4pnel.ferretirc.net.messages.ServerMessage
|
||||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import io.ktor.http.parameters
|
||||||
|
import io.ktor.network.selector.SelectInterest
|
||||||
import io.ktor.util.toUpperCasePreservingASCIIRules
|
import io.ktor.util.toUpperCasePreservingASCIIRules
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
|
|
||||||
@@ -10,22 +12,49 @@ class MessageParser(val incoming: Channel<String>) {
|
|||||||
val incomingParsedMessages = Channel<ServerMessage>()
|
val incomingParsedMessages = Channel<ServerMessage>()
|
||||||
|
|
||||||
private companion object MessageBuilder {
|
private companion object MessageBuilder {
|
||||||
|
val logger = KotlinLogging.logger("MessageParser.MessageBuilder")
|
||||||
|
fun getTrailingParameterIndex(params: List<String>) = params.indexOfLast { it.startsWith(":") }
|
||||||
|
|
||||||
sealed interface Command {
|
sealed interface Command {
|
||||||
fun toServerMessage(): ServerMessage
|
fun toServerMessage(): ServerMessage
|
||||||
|
|
||||||
class NamedCommand(val name: String, val parameters: List<String>) : Command {
|
class NamedCommand(val name: String, val parameters: List<String>) : Command {
|
||||||
override fun toServerMessage(): ServerMessage {
|
override fun toServerMessage(): ServerMessage {
|
||||||
|
logger.debug { "Attempting to parse ${name.toUpperCasePreservingASCIIRules()}, with params $parameters" }
|
||||||
|
|
||||||
return when (name.toUpperCasePreservingASCIIRules()) {
|
return when (name.toUpperCasePreservingASCIIRules()) {
|
||||||
// PONG :PREFIX COMMAND HOSTNAME :TOKEN
|
// PONG :PREFIX COMMAND HOSTNAME :TOKEN
|
||||||
"PONG" -> {
|
"PONG" -> {
|
||||||
val tokenIndex = parameters.indexOfLast { it.contains(":") }
|
val tokenIndex = getTrailingParameterIndex(parameters)
|
||||||
if (tokenIndex != -1) ServerMessage.Pong(
|
if (tokenIndex != -1) ServerMessage.Pong(
|
||||||
parameters.subList(tokenIndex, parameters.size).joinToString(" ").removePrefix(":")
|
parameters.subList(tokenIndex, parameters.size).joinToString(" ").removePrefix(":")
|
||||||
)
|
)
|
||||||
else ServerMessage.Pong()
|
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() {
|
suspend fun start() {
|
||||||
for (msg in incoming) {
|
for (msg in incoming) {
|
||||||
logger.debug { msg }
|
// logger.debug { msg }
|
||||||
incomingParsedMessages.send(build(msg))
|
incomingParsedMessages.send(build(msg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class MessageWriter(socket: Socket, scope: CoroutineScope) : MessageIO(socket, s
|
|||||||
send = socket.openWriteChannel()
|
send = socket.openWriteChannel()
|
||||||
|
|
||||||
for (msg in outgoingMessages) {
|
for (msg in outgoingMessages) {
|
||||||
logger.debug { msg.toWireIntermediate() }
|
logger.debug { "Sending: ${msg.toWireIntermediate()}" }
|
||||||
send.writeFully(msg.toWire())
|
send.writeFully(msg.toWire())
|
||||||
send.flush()
|
send.flush()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user