package com.shr4pnel.ferretirc.net.messages import io.ktor.network.selector.SelectorManager import kotlinx.coroutines.Dispatchers /** * IRC Messages sent by the client */ sealed class ClientMessage(val strName: String) { abstract fun toWireIntermediate(): String fun toWire() = "${toWireIntermediate()}\r\n".encodeToByteArray() companion object Util { val selectorManager = SelectorManager(Dispatchers.IO) } class Ping(val token: String? = null) : ClientMessage("PING") { init { require(token?.isNotEmpty() ?: true) { "Token to PING should be null or a non-empty string" } } override fun toWireIntermediate() = "$strName ${token.orEmpty()}" } sealed class Cap : ClientMessage("CAP") { val validSubcommands = listOf("LS", "LIST", "REQ", "END") override fun toWireIntermediate() = when (this) { is LS -> "CAP LS $version" is REQ -> TODO() is END -> "CAP END" is LIST -> TODO() } class LS(val version: Int = 302) : Cap() class LIST : Cap() class REQ(val version: Int?) : Cap() class END : Cap() } class Nick(val nickname: String) : ClientMessage("NICK") { override fun toWireIntermediate() = "NICK $nickname" init { require(nickname.length < 10) { "\"$nickname\" exceeds IRCs maximum nickname length of 9" } require(!nickname.startsWith(":") && !nickname.startsWith("#")) { "\"$nickname\" may not begin with : or #" } // TODO THIS SHOULD BLACKLIST ALL PREFIXES NAMED IN CHANTYPES PARAMETER require(!nickname.contains(" ")) { "$nickname may not contain a space" } } } class User(val username: String, val realName: String) : ClientMessage("USER") { // TODO GET USERNAME INITIALISATION CHECK PARAMETERS FROM USERLEN RPL_ISUPPORT init { require(username.isNotEmpty()) { "Username may not be blank" } } override fun toWireIntermediate() = "USER $username 0 * :$realName" } class Pass(val password: String) : ClientMessage("PASS") { override fun toWireIntermediate() = "PASS $password" } class UNIMPLEMENTED() : ClientMessage("") { override fun toWireIntermediate() = "" } }