Create MessageParser, use in Reader, add logs
This commit is contained in:
@@ -1,39 +1,58 @@
|
|||||||
package com.shr4pnel.ferretirc
|
package com.shr4pnel.ferretirc
|
||||||
|
|
||||||
import com.shr4pnel.ferretirc.net.ClientMessage
|
import com.shr4pnel.ferretirc.net.messages.ClientMessage
|
||||||
import com.shr4pnel.ferretirc.net.Connection
|
import com.shr4pnel.ferretirc.net.Connection
|
||||||
import com.shr4pnel.ferretirc.net.MessageReader
|
import com.shr4pnel.ferretirc.net.messages.ServerMessage
|
||||||
import com.shr4pnel.ferretirc.net.MessageWriter
|
import io.github.oshai.kotlinlogging.KotlinLoggingConfiguration
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.channels.Channel
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import java.net.URL
|
|
||||||
|
|
||||||
class IrcClient(val nick: String, val sock: URL) {
|
|
||||||
val port: Int = sock.port
|
|
||||||
val hostname: String = sock.host
|
|
||||||
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
|
||||||
private val connection = Connection(hostname, port, scope)
|
|
||||||
lateinit var messages: Channel<String>
|
|
||||||
|
|
||||||
|
class IrcClient(hostname: String, port: Int) {
|
||||||
init {
|
init {
|
||||||
require(port != -1, fun() = "A port must be specified in your argument to IRCClient")
|
KotlinLoggingConfiguration.logStartupMessage = false
|
||||||
require(hostname.isNotEmpty(), fun() = "A port must be specified in your argument to IRCClient")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
||||||
|
|
||||||
|
@PublishedApi
|
||||||
|
internal val connection = Connection(hostname, port, scope)
|
||||||
|
|
||||||
suspend fun connect() {
|
suspend fun connect() {
|
||||||
connection.connect()
|
connection.connect()
|
||||||
messages = connection.reader.incomingMessages
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun queueMessage(message: ClientMessage) = scope.launch {
|
suspend fun queueMessage(message: ClientMessage) {
|
||||||
connection.writer.outgoingMessages.send(message)
|
connection.writer.outgoingMessages.send(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun queueMessages(vararg messages: ClientMessage) {
|
||||||
|
messages.forEach {
|
||||||
|
connection.writer.outgoingMessages.send(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun close() {
|
fun close() {
|
||||||
scope.cancel()
|
scope.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the next Server Message meeting condition
|
||||||
|
* @param predicate A function to filter a message based on its parameters
|
||||||
|
*/
|
||||||
|
suspend inline fun <reified T : ServerMessage> 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())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.shr4pnel.ferretirc.net
|
package com.shr4pnel.ferretirc.net
|
||||||
|
|
||||||
|
import com.shr4pnel.ferretirc.net.messages.ClientMessage
|
||||||
import io.ktor.network.sockets.Socket
|
import io.ktor.network.sockets.Socket
|
||||||
import io.ktor.network.sockets.aSocket
|
import io.ktor.network.sockets.aSocket
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.shr4pnel.ferretirc.net
|
package com.shr4pnel.ferretirc.net
|
||||||
|
|
||||||
|
import com.shr4pnel.ferretirc.net.messages.MessageIO
|
||||||
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
import io.ktor.network.sockets.Socket
|
import io.ktor.network.sockets.Socket
|
||||||
import io.ktor.network.sockets.openWriteChannel
|
import io.ktor.network.sockets.openWriteChannel
|
||||||
import io.ktor.utils.io.ByteWriteChannel
|
import io.ktor.utils.io.ByteWriteChannel
|
||||||
@@ -7,16 +9,17 @@ import io.ktor.utils.io.writeFully
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class MessageWriter(socket: Socket, scope: CoroutineScope): MessageIO(socket, scope) {
|
class MessageWriter(socket: Socket, scope: CoroutineScope) : MessageIO(socket, scope) {
|
||||||
private lateinit var send: ByteWriteChannel
|
private lateinit var send: ByteWriteChannel
|
||||||
|
private val logger = KotlinLogging.logger("MessageWriter")
|
||||||
|
|
||||||
override suspend fun start() {
|
override fun start() = scope.launch {
|
||||||
send = socket.openWriteChannel()
|
send = socket.openWriteChannel()
|
||||||
scope.launch {
|
|
||||||
for (msg in outgoingMessages) {
|
for (msg in outgoingMessages) {
|
||||||
send.writeFully(msg.toWire())
|
logger.debug { msg.toWireIntermediate() }
|
||||||
send.flush()
|
send.writeFully(msg.toWire())
|
||||||
}
|
send.flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user