package com.shr4pnel.ferretirc.net.messages import com.shr4pnel.ferretirc.irc.IRCChannel /** * IRC Messages sent by the client */ sealed class ClientMessage(val strName: String) { fun toWire() = "${toWireIntermediate()}\r\n".encodeToByteArray() protected open val params = emptyList() protected open val trailing: String? = null fun toWireIntermediate(): String { return buildString { append(strName) params.forEach { append(" $it") } trailing?.let { append(" :$it") } } } override fun toString() = "$strName[params=$params trailing=:$trailing]" 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 val params: kotlin.collections.List get() = listOfNotNull(token) } sealed class Cap : ClientMessage("CAP") { class LS(val version: Int = 302) : Cap() { override val params: kotlin.collections.List get() = listOf("LS", version.toString()) } class LIST : Cap() { override val params: kotlin.collections.List get() = TODO("IMPLEMENT CAP LIST") } class REQ(val version: Int?) : Cap() { override val params: kotlin.collections.List get() = TODO("IMPL CAP REQ") } class END : Cap() { override val params: kotlin.collections.List get() = listOf("END") } } class Nick(val nickname: String) : ClientMessage("NICK") { 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" } } override val params: kotlin.collections.List get() = listOf(nickname) } 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 val params: kotlin.collections.List get() = listOf(username, "0", "*") override val trailing: String get() = realName } class Pass(val password: String) : ClientMessage("PASS") { override val params: kotlin.collections.List get() = listOf(password) } class Oper(val name: String, val password: String) : ClientMessage("OPER") { override val params: kotlin.collections.List get() = listOf(name, password) } class Die : ClientMessage("DIE") class List : ClientMessage("LIST") class Join(val channel: IRCChannel) : ClientMessage("JOIN") { override val params: kotlin.collections.List get() = listOf(channel.chanName) } // TODO RPL_ISUPPORT REQUIREMENTS IN FUN EG LINELEN STATUSMSG - ALSO ADD FUCKING STUPID STATUSMSG & SUPPORT FOR MASKS. FUCK ME class PrivMsg(val target: IRCChannel, val message: String) : ClientMessage("PRIVMSG") { override val params: kotlin.collections.List get() = listOf( target.chanName, ) override val trailing: String get() = message } }