package com.shr4pnel.ferretirc import com.shr4pnel.ferretirc.net.messages.ClientMessage import com.shr4pnel.ferretirc.net.Connection import com.shr4pnel.ferretirc.net.messages.ServerMessage import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel class IrcClient(hostname: String, port: Int) { init { KotlinLoggingConfiguration.logStartupMessage = false } val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) @PublishedApi internal val connection = Connection(hostname, port, scope) suspend fun connect() { connection.connect() } suspend fun queueMessage(message: ClientMessage) { connection.writer.outgoingMessages.send(message) } suspend fun queueMessages(vararg messages: ClientMessage) { messages.forEach { connection.writer.outgoingMessages.send(it) } } fun close() { scope.cancel() } /** * Return the next Server Message meeting condition * @param predicate A function to filter a message based on its parameters */ suspend inline fun waitForNext(noinline predicate: (T) -> Boolean = { true }): T = connection.reader.waitForNext(T::class, predicate) suspend fun register(nick: String, realName: String? = null, password: String? = null) { val messages = buildList { if (!password.isNullOrEmpty()) add(ClientMessage.Pass(password)) add(ClientMessage.Cap.LS()) add(ClientMessage.Nick(nick)) if (!realName.isNullOrEmpty()) add(ClientMessage.User(nick, realName)) else add(ClientMessage.User(nick, nick)) add(ClientMessage.Cap.END()) } queueMessages(*messages.toTypedArray()) } }