You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IrcClient.kt 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package com.dmdirc.ktirc
  2. import com.dmdirc.ktirc.events.IrcEvent
  3. import com.dmdirc.ktirc.io.CaseMapping
  4. import com.dmdirc.ktirc.messages.sendJoin
  5. import com.dmdirc.ktirc.model.*
  6. import com.dmdirc.ktirc.util.RemoveIn
  7. /**
  8. * Primary interface for interacting with KtIrc.
  9. */
  10. interface IrcClient {
  11. /**
  12. * Holds state relating to the current server, its features, and capabilities.
  13. */
  14. val serverState: ServerState
  15. /**
  16. * Holds the state for each channel we are currently joined to.
  17. */
  18. val channelState: ChannelStateMap
  19. /**
  20. * Holds the state for all known users (those in common channels).
  21. */
  22. val userState: UserState
  23. /**
  24. * The configured behaviour of the client.
  25. */
  26. val behaviour: ClientBehaviour
  27. val caseMapping: CaseMapping
  28. get() = serverState.features[ServerFeature.ServerCaseMapping] ?: CaseMapping.Rfc
  29. /**
  30. * Begins a connection attempt to the IRC server.
  31. *
  32. * This method will return immediately, and the attempt to connect will be executed in a coroutine on the
  33. * IO scheduler. To check the status of the connection, monitor events using [onEvent].
  34. */
  35. fun connect()
  36. /**
  37. * Disconnect immediately from the IRC server, without sending a QUIT.
  38. */
  39. fun disconnect()
  40. /**
  41. * Sends the given raw line to the IRC server, followed by a carriage return and line feed.
  42. *
  43. * Standard IRC messages can be constructed using the methods in [com.dmdirc.ktirc.messages]
  44. * such as [sendJoin].
  45. *
  46. * @param message The line to be sent to the IRC server.
  47. */
  48. @Deprecated("Use structured send instead", ReplaceWith("send(command, arguments)"))
  49. @RemoveIn("2.0.0")
  50. fun send(message: String)
  51. /**
  52. * Sends the given command to the IRC server.
  53. *
  54. * This should only be needed to send raw/custom commands; standard messages can be sent using the
  55. * extension methods in [com.dmdirc.ktirc.messages] such as [sendJoin].
  56. *
  57. * @param tags The IRCv3 tags to prefix the message with, if any.
  58. * @param command The command to be sent
  59. * @param arguments The arguments to the command.
  60. */
  61. fun send(tags: Map<MessageTag, String>, command: String, vararg arguments: String)
  62. /**
  63. * Sends the given command to the IRC server.
  64. *
  65. * This should only be needed to send raw/custom commands; standard messages can be sent using the
  66. * extension methods in [com.dmdirc.ktirc.messages] such as [sendJoin].
  67. *
  68. * @param command The command to be sent
  69. * @param arguments The arguments to the command.
  70. */
  71. fun send(command: String, vararg arguments: String) = send(emptyMap(), command, *arguments)
  72. /**
  73. * Registers a new handler for all events on this connection.
  74. *
  75. * All events are subclasses of [IrcEvent]; the idiomatic way to handle them is using a `when` statement:
  76. *
  77. * ```
  78. * client.onEvent {
  79. * when(it) {
  80. * is MessageReceived -> println(it.message)
  81. * }
  82. * }
  83. * ```
  84. *
  85. * *Note*: at present handlers cannot be removed; they last the lifetime of the [IrcClient].
  86. *
  87. * @param handler The method to call when a new event occurs.
  88. */
  89. fun onEvent(handler: (IrcEvent) -> Unit)
  90. /**
  91. * Utility method to determine if the given user is the one we are connected to IRC as. Should only be used after a
  92. * [com.dmdirc.ktirc.events.ServerReady] event has been received.
  93. */
  94. fun isLocalUser(user: User) = isLocalUser(user.nickname)
  95. /**
  96. * Utility method to determine if the given user is the one we are connected to IRC as. Should only be used after a
  97. * [com.dmdirc.ktirc.events.ServerReady] event has been received.
  98. */
  99. fun isLocalUser(nickname: String) = caseMapping.areEquivalent(nickname, serverState.localNickname)
  100. /**
  101. * Determines if the given [target] appears to be a channel or not. Should only be used after a
  102. * [com.dmdirc.ktirc.events.ServerReady] event has been received.
  103. */
  104. fun isChannel(target: String) = target.isNotEmpty() && serverState.channelTypes.contains(target[0])
  105. }
  106. /**
  107. * Defines the behaviour of an [IrcClient].
  108. */
  109. interface ClientBehaviour {
  110. /** Whether or not to request channel modes when we join a channel. */
  111. val requestModesOnJoin: Boolean
  112. /**
  113. * If enabled, all messages (`PRIVMSG`s) sent by the client will always be "echoed" back as a MessageReceived
  114. * event.
  115. *
  116. * This makes the behaviour consistent across ircds that support the echo-message capability and those that
  117. * don't. If disabled, messages will only be echoed back when the server supports the capability.
  118. */
  119. val alwaysEchoMessages: Boolean
  120. }
  121. /**
  122. * Constructs a new [IrcClient] using a configuration DSL.
  123. *
  124. * See [IrcClientConfigBuilder] for details of all options
  125. */
  126. @IrcClientDsl
  127. @Suppress("FunctionName")
  128. fun IrcClient(block: IrcClientConfigBuilder.() -> Unit): IrcClient =
  129. IrcClientImpl(IrcClientConfigBuilder().apply(block).build())