Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

IrcClient.kt 3.0KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package com.dmdirc.ktirc
  2. import com.dmdirc.ktirc.events.EventHandler
  3. import com.dmdirc.ktirc.events.IrcEvent
  4. import com.dmdirc.ktirc.events.ServerWelcome
  5. import com.dmdirc.ktirc.events.eventHandlers
  6. import com.dmdirc.ktirc.io.KtorLineBufferedSocket
  7. import com.dmdirc.ktirc.io.LineBufferedSocket
  8. import com.dmdirc.ktirc.io.MessageHandler
  9. import com.dmdirc.ktirc.io.MessageParser
  10. import com.dmdirc.ktirc.messages.*
  11. import com.dmdirc.ktirc.model.Profile
  12. import com.dmdirc.ktirc.model.Server
  13. import com.dmdirc.ktirc.model.ServerState
  14. import kotlinx.coroutines.channels.map
  15. import kotlinx.coroutines.coroutineScope
  16. import kotlinx.coroutines.runBlocking
  17. import java.util.logging.Level
  18. import java.util.logging.LogManager
  19. interface IrcClient {
  20. suspend fun send(message: String)
  21. val serverState: ServerState
  22. }
  23. // TODO: How should alternative nicknames work?
  24. // TODO: Should IRC Client take a pool of servers and rotate through, or make the caller do that?
  25. // TODO: Should there be a default profile?
  26. class IrcClientImpl(private val server: Server, private val profile: Profile) : IrcClient {
  27. var socketFactory: (String, Int) -> LineBufferedSocket = ::KtorLineBufferedSocket
  28. override val serverState = ServerState(profile.initialNick)
  29. private val messageHandler = MessageHandler(messageProcessors, eventHandlers + object : EventHandler {
  30. override suspend fun processEvent(client: IrcClient, event: IrcEvent) {
  31. when (event) {
  32. is ServerWelcome -> client.send(joinMessage("#mdbot"))
  33. }
  34. }
  35. })
  36. private val parser = MessageParser()
  37. private var socket: LineBufferedSocket? = null
  38. override suspend fun send(message: String) {
  39. socket?.sendLine(message)
  40. }
  41. suspend fun connect() {
  42. // TODO: Concurrency!
  43. check(socket == null)
  44. coroutineScope {
  45. with(socketFactory(server.host, server.port)) {
  46. socket = this
  47. connect()
  48. // TODO: CAP LS
  49. server.password?.let { pass -> sendLine(passwordMessage(pass)) }
  50. sendLine(nickMessage(profile.initialNick))
  51. // TODO: Send correct host
  52. sendLine(userMessage(profile.userName, "localhost", server.host, profile.realName))
  53. // TODO: This should be elsewhere
  54. messageHandler.processMessages(this@IrcClientImpl, readLines(this@coroutineScope).map { parser.parse(it) })
  55. }
  56. }
  57. }
  58. companion object {
  59. @JvmStatic
  60. fun main(args: Array<String>) {
  61. val rootLogger = LogManager.getLogManager().getLogger("")
  62. rootLogger.level = Level.FINEST
  63. for (h in rootLogger.handlers) {
  64. h.level = Level.FINEST
  65. }
  66. runBlocking {
  67. val client = IrcClientImpl(Server("irc.quakenet.org", 6667), Profile("KtIrc", "Kotlin!", "kotlin"))
  68. client.connect()
  69. }
  70. }
  71. }
  72. }