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.

Events.kt 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. package com.dmdirc.ktirc.events
  2. import com.dmdirc.ktirc.model.ConnectionError
  3. import com.dmdirc.ktirc.model.ServerFeatureMap
  4. import com.dmdirc.ktirc.model.User
  5. import com.dmdirc.ktirc.util.RemoveIn
  6. import java.time.LocalDateTime
  7. /**
  8. * Metadata associated with an event.
  9. *
  10. * @property time The best-guess time at which the event occurred.
  11. * @property batchId The ID of the batch this event is part of, if any.
  12. * @property messageId The unique ID of this message, if any.
  13. * @property label The label of the command that this event was sent in response to, if any.
  14. */
  15. data class EventMetadata internal constructor(
  16. val time: LocalDateTime,
  17. val batchId: String? = null,
  18. val messageId: String? = null,
  19. val label: String? = null)
  20. /**
  21. * Base class for all events raised by KtIrc.
  22. *
  23. * An event occurs in response to some action by the IRC server. Most events correspond to a single
  24. * line received from the server (such as [NoticeReceived]), but some happen when a combination
  25. * of lines lead to a certain state (e.g. [ServerReady]), and the [BatchReceived] event in particular
  26. * can contain *many* lines received from the server.
  27. *
  28. * @property metadata Meta-data about the received event
  29. */
  30. sealed class IrcEvent(val metadata: EventMetadata) {
  31. /** The time at which the event occurred. */
  32. @Deprecated("Moved to metadata", replaceWith = ReplaceWith("metadata.time"))
  33. @RemoveIn("2.0.0")
  34. val time: LocalDateTime
  35. get() = metadata.time
  36. }
  37. /**
  38. * Base class for events that are targeted to a channel or user.
  39. *
  40. * @param target The target of the event - either a channel name, or nick name
  41. */
  42. sealed class TargetedEvent(metadata: EventMetadata, val target: String) : IrcEvent(metadata) {
  43. /** The channel (or user!) this event was targeted at. */
  44. @Deprecated("Use target instead", replaceWith = ReplaceWith("target"))
  45. @RemoveIn("2.0.0")
  46. val channel: String
  47. get() = target
  48. }
  49. /**
  50. * Interface implemented by events that describe a change to a channel's membership.
  51. */
  52. interface ChannelMembershipAdjustment {
  53. /** The nickname of a user that has joined the channel. */
  54. val addedUser: String?
  55. /** The nickname of a user who has left the channel. */
  56. val removedUser: String?
  57. /** The nicknames of all users in the channel, to replace any existing values. */
  58. val replacedUsers: Array<String>?
  59. }
  60. /**
  61. * Interface implemented by events that come from a particular user.
  62. */
  63. interface SourcedEvent {
  64. /** The user that caused the event. */
  65. val user: User
  66. }
  67. /** Raised when a connection to the server is being established. */
  68. class ServerConnecting(metadata: EventMetadata) : IrcEvent(metadata)
  69. /** Raised when the connection to the server has been established. The server will not be ready for use yet. */
  70. class ServerConnected(metadata: EventMetadata) : IrcEvent(metadata)
  71. /** Raised when the connection to the server has ended. */
  72. class ServerDisconnected(metadata: EventMetadata) : IrcEvent(metadata)
  73. /** Raised when an error occurred trying to connect. */
  74. class ServerConnectionError(metadata: EventMetadata, val error: ConnectionError, val details: String?) : IrcEvent(metadata)
  75. /**
  76. * Raised when the server is ready for use.
  77. *
  78. * At this point, you should be able to freely send messages to the IRC server and can start joining channels etc, and
  79. * the server state will contain relevant information about the server, its features, etc.
  80. */
  81. class ServerReady(metadata: EventMetadata) : IrcEvent(metadata)
  82. /** Raised when the server initially welcomes us to the IRC network. */
  83. class ServerWelcome(metadata: EventMetadata, val server: String, val localNick: String) : IrcEvent(metadata)
  84. /** Raised when the features supported by the server have changed. This may occur numerous times. */
  85. class ServerFeaturesUpdated(metadata: EventMetadata, val serverFeatures: ServerFeatureMap) : IrcEvent(metadata)
  86. /** Raised whenever a PING is received from the server. */
  87. class PingReceived(metadata: EventMetadata, val nonce: ByteArray) : IrcEvent(metadata)
  88. /** Raised whenever a PONG is received from the server. */
  89. class PongReceived(metadata: EventMetadata, val nonce: ByteArray) : IrcEvent(metadata)
  90. /** Raised when a user joins a channel. */
  91. class ChannelJoined(metadata: EventMetadata, override val user: User, channel: String)
  92. : TargetedEvent(metadata, channel), SourcedEvent, ChannelMembershipAdjustment {
  93. override val addedUser = user.nickname
  94. override val removedUser: String? = null
  95. override val replacedUsers: Array<String>? = null
  96. }
  97. /** Raised when an attempt to join a channel fails. */
  98. class ChannelJoinFailed(metadata: EventMetadata, channel: String, val reason: JoinError) : TargetedEvent(metadata, channel) {
  99. /** Reasons a join may fail. */
  100. enum class JoinError {
  101. /** We are already in the maximum number of channels allowed by the server. */
  102. TooManyChannels,
  103. /** The channel is no-hiding (+H), but we have invisible join/parts enabled. */
  104. NoHiding,
  105. /** The channel is keyed (+k) and a valid key was not provided. */
  106. NeedKey,
  107. /** The channel is invite only (+i) and no invite was received. */
  108. NeedInvite,
  109. /** The channel is limited to registered users only, and we are not registered. */
  110. NeedRegisteredNick,
  111. /** The channel is secure-only, and we're not using TLS. */
  112. NeedTls,
  113. /** The channel is limited to server admins and we are not one. */
  114. NeedAdmin,
  115. /** The channel is limited to ircops and we are not one. */
  116. NeedOper,
  117. /** We are banned from the channel. */
  118. Banned,
  119. /** The channel is limited (+l) and currently full. */
  120. ChannelFull,
  121. /** The channel name is disallowed by the server. */
  122. BadChannelName,
  123. /** We're trying to joiin too many channels and have been throttled. */
  124. Throttled,
  125. /** We don't know why. */
  126. Unknown
  127. }
  128. }
  129. /** Raised when a user leaves a channel. */
  130. class ChannelParted(metadata: EventMetadata, override val user: User, channel: String, val reason: String = "")
  131. : TargetedEvent(metadata, channel), SourcedEvent, ChannelMembershipAdjustment {
  132. override val addedUser: String? = null
  133. override val removedUser = user.nickname
  134. override val replacedUsers: Array<String>? = null
  135. }
  136. /** Raised when a [victim] is kicked from a channel. */
  137. class ChannelUserKicked(metadata: EventMetadata, override val user: User, channel: String, val victim: String, val reason: String = "")
  138. : TargetedEvent(metadata, channel), SourcedEvent, ChannelMembershipAdjustment {
  139. override val addedUser: String? = null
  140. override val removedUser = victim
  141. override val replacedUsers: Array<String>? = null
  142. }
  143. /** Raised when a user quits, and is in a channel. */
  144. class ChannelQuit(metadata: EventMetadata, override val user: User, channel: String, val reason: String = "")
  145. : TargetedEvent(metadata, channel), SourcedEvent, ChannelMembershipAdjustment {
  146. override val addedUser: String? = null
  147. override val removedUser = user.nickname
  148. override val replacedUsers: Array<String>? = null
  149. }
  150. /** Raised when a user changes nickname, and is in a channel. */
  151. class ChannelNickChanged(metadata: EventMetadata, override val user: User, channel: String, val newNick: String)
  152. : TargetedEvent(metadata, channel), SourcedEvent, ChannelMembershipAdjustment {
  153. override val addedUser = newNick
  154. override val removedUser = user.nickname
  155. override val replacedUsers: Array<String>? = null
  156. }
  157. /**
  158. * Raised when a user's away state changes, and they are in a common channel. If [message] is null then the user is
  159. * now back.
  160. *
  161. * This event is only raised for other users if the server supports the 'away-notify' capability.
  162. */
  163. class ChannelAway(metadata: EventMetadata, override val user: User, channel: String, val message: String?)
  164. : TargetedEvent(metadata, channel), SourcedEvent
  165. /** Raised when a batch of the channel's member list has been received. More batches may follow. */
  166. class ChannelNamesReceived(metadata: EventMetadata, channel: String, val names: List<String>) : TargetedEvent(metadata, channel)
  167. /** Raised when the entirety of the channel's member list has been received. */
  168. class ChannelNamesFinished(metadata: EventMetadata, channel: String) : TargetedEvent(metadata, channel), ChannelMembershipAdjustment {
  169. override val addedUser: String? = null
  170. override val removedUser: String? = null
  171. override var replacedUsers: Array<String>? = null
  172. internal set
  173. }
  174. /** Raised when a channel topic is discovered (not changed). Usually followed by [ChannelTopicMetadataDiscovered] if the [topic] is non-null. */
  175. class ChannelTopicDiscovered(metadata: EventMetadata, channel: String, val topic: String?) : TargetedEvent(metadata, channel)
  176. /** Raised when a channel topic's metadata is discovered. */
  177. class ChannelTopicMetadataDiscovered(metadata: EventMetadata, channel: String, val user: User, val setTime: LocalDateTime) : TargetedEvent(metadata, channel)
  178. /**
  179. * Raised when a channel's topic is changed.
  180. *
  181. * @property topic The new topic of the channel, or `null` if the topic has been unset (cleared)
  182. */
  183. class ChannelTopicChanged(metadata: EventMetadata, override val user: User, channel: String, val topic: String?) : TargetedEvent(metadata, channel), SourcedEvent
  184. /** Raised when a message is received. */
  185. class MessageReceived(metadata: EventMetadata, override val user: User, target: String, val message: String) : TargetedEvent(metadata, target), SourcedEvent {
  186. /** The message ID of this message. */
  187. @Deprecated("Moved to metadata", replaceWith = ReplaceWith("metadata.messageId"))
  188. @RemoveIn("2.0.0")
  189. val messageId: String?
  190. get() = metadata.messageId
  191. }
  192. /**
  193. * Raised when a notice is received.
  194. *
  195. * The [user] may in fact be a server, or have a nickname of `*` while connecting.
  196. */
  197. class NoticeReceived(metadata: EventMetadata, override val user: User, target: String, val message: String) : TargetedEvent(metadata, target), SourcedEvent
  198. /** Raised when an action is received. */
  199. class ActionReceived(metadata: EventMetadata, override val user: User, target: String, val action: String) : TargetedEvent(metadata, target), SourcedEvent {
  200. /** The message ID of this action. */
  201. @Deprecated("Moved to metadata", replaceWith = ReplaceWith("metadata.messageId"))
  202. @RemoveIn("2.0.0")
  203. val messageId: String?
  204. get() = metadata.messageId
  205. }
  206. /** Raised when a CTCP is received. */
  207. class CtcpReceived(metadata: EventMetadata, override val user: User, target: String, val type: String, val content: String) : TargetedEvent(metadata, target), SourcedEvent
  208. /** Raised when a CTCP reply is received. */
  209. class CtcpReplyReceived(metadata: EventMetadata, override val user: User, target: String, val type: String, val content: String) : TargetedEvent(metadata, target), SourcedEvent
  210. /** Raised when a user quits. */
  211. class UserQuit(metadata: EventMetadata, override val user: User, val reason: String = "") : IrcEvent(metadata), SourcedEvent
  212. /** Raised when a user changes nickname. */
  213. class UserNickChanged(metadata: EventMetadata, override val user: User, val newNick: String) : IrcEvent(metadata), SourcedEvent
  214. /** Raised when a user changes hostname. */
  215. class UserHostChanged(metadata: EventMetadata, override val user: User, val newIdent: String, val newHost: String) : IrcEvent(metadata), SourcedEvent
  216. /**
  217. * Raised when a user's account changes (i.e., they auth'd or deauth'd with services).
  218. *
  219. * This event is only raised if the server supports the `account-notify` capability.
  220. */
  221. class UserAccountChanged(metadata: EventMetadata, override val user: User, val newAccount: String?) : IrcEvent(metadata), SourcedEvent
  222. /**
  223. * Raised when a user's away state changes. If [message] is null then the user is now back.
  224. *
  225. * This event is only raised for other users if the server supports the 'away-notify' capability.
  226. */
  227. class UserAway(metadata: EventMetadata, override val user: User, val message: String?) : IrcEvent(metadata), SourcedEvent
  228. /** Raised when available server capabilities are received. More batches may follow. */
  229. class ServerCapabilitiesReceived(metadata: EventMetadata, val capabilities: Map<String, String>) : IrcEvent(metadata)
  230. /** Raised when our requested capabilities are acknowledged. More batches may follow. */
  231. class ServerCapabilitiesAcknowledged(metadata: EventMetadata, val capabilities: Map<String, String>) : IrcEvent(metadata)
  232. /** Raised when the server has finished sending us capabilities. */
  233. class ServerCapabilitiesFinished(metadata: EventMetadata) : IrcEvent(metadata)
  234. /** Raised when a line of the Message Of the Day has been received. */
  235. class MotdLineReceived(metadata: EventMetadata, val line: String, val first: Boolean = false) : IrcEvent(metadata)
  236. /** Raised when a Message Of the Day has completed. */
  237. class MotdFinished(metadata: EventMetadata, val missing: Boolean = false) : IrcEvent(metadata)
  238. /**
  239. * Raised when a mode change occurs.
  240. *
  241. * If [discovered] is true then the event is in response to the server providing the full set of modes on the target,
  242. * and the given modes are thus exhaustive. Otherwise, the modes are a sequence of changes to apply to the existing
  243. * state.
  244. */
  245. class ModeChanged(metadata: EventMetadata, override val user: User, target: String, val modes: String, val arguments: Array<String>, val discovered: Boolean = false)
  246. : TargetedEvent(metadata, target), SourcedEvent
  247. /** Raised when an AUTHENTICATION message is received. [argument] is `null` if the server sent an empty reply ("+") */
  248. class AuthenticationMessage(metadata: EventMetadata, val argument: String?) : IrcEvent(metadata)
  249. /** Raised when a SASL attempt finishes, successfully or otherwise. */
  250. class SaslFinished(metadata: EventMetadata, var success: Boolean) : IrcEvent(metadata)
  251. /** Raised when the server says our SASL mechanism isn't available, but gives us a list of others. */
  252. class SaslMechanismNotAvailableError(metadata: EventMetadata, var mechanisms: Collection<String>) : IrcEvent(metadata)
  253. /** Indicates a batch of messages has begun. */
  254. class BatchStarted(metadata: EventMetadata, val referenceId: String, val batchType: String, val params: Array<String>) : IrcEvent(metadata)
  255. /** Indicates a batch of messages has finished. */
  256. class BatchFinished(metadata: EventMetadata, val referenceId: String) : IrcEvent(metadata)
  257. /** A batch of events that should be handled together. */
  258. class BatchReceived(metadata: EventMetadata, val type: String, val params: Array<String>, val events: List<IrcEvent>) : IrcEvent(metadata)
  259. /**
  260. * Raised when attempting to set or change our nickname fails.
  261. */
  262. open class NicknameChangeFailed(metadata: EventMetadata, val cause: NicknameChangeError) : IrcEvent(metadata)
  263. /**
  264. * Raised during a connection attempt if the nickname we wanted is not available.
  265. *
  266. * The nickname must be changed to continue connecting.
  267. *
  268. * In 2.0.0 this will no longer extend [NicknameChangeFailed] and will have to be handled separately.
  269. */
  270. @RemoveIn("2.0.0")
  271. class NicknameChangeRequired(metadata: EventMetadata, cause: NicknameChangeError) : NicknameChangeFailed(metadata, cause)
  272. /** Reasons a nick change may fail. */
  273. enum class NicknameChangeError {
  274. /** The nickname is not allowed by the server. */
  275. ErroneousNickname,
  276. /** The nickname is already in use. */
  277. AlreadyInUse,
  278. /** The nickname has collided with another somehow. */
  279. Collision,
  280. /** No nickname was provided. */
  281. NoNicknameGiven
  282. }