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.

IrcMessage.kt 2.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package com.dmdirc.ktirc.model
  2. import com.dmdirc.ktirc.events.EventMetadata
  3. import com.dmdirc.ktirc.util.currentTimeProvider
  4. import com.dmdirc.ktirc.util.currentTimeZoneProvider
  5. import java.time.Instant
  6. import java.time.LocalDateTime
  7. /**
  8. * Represents an IRC protocol message.
  9. */
  10. internal class IrcMessage(val tags: Map<MessageTag, String>, val prefix: ByteArray?, val command: String, val params: List<ByteArray>) {
  11. /** The time at which the message was sent, or our best guess at it. */
  12. val metadata = EventMetadata(time, batchId, messageId)
  13. /** The user that generated the message, if any. */
  14. val sourceUser by lazy {
  15. prefix?.asUser()?.apply {
  16. tags[MessageTag.AccountName]?.let { account = it }
  17. }
  18. }
  19. private val time
  20. get() = when (MessageTag.ServerTime in tags) {
  21. true -> LocalDateTime.ofInstant(Instant.parse(tags[MessageTag.ServerTime]), currentTimeZoneProvider())
  22. false -> currentTimeProvider()
  23. }
  24. private val batchId
  25. get() = tags[MessageTag.Batch]
  26. private val messageId
  27. get() = tags[MessageTag.MessageId]
  28. }
  29. /**
  30. * Supported tags that may be applied to messages.
  31. */
  32. @Suppress("unused")
  33. sealed class MessageTag(val name: String) {
  34. /** Specifies the account name of the user, if the `account-tag` capability is negotiated. */
  35. object AccountName : MessageTag("account")
  36. /** Specifies the ID that a batch message belongs to. */
  37. object Batch : MessageTag("batch")
  38. /** Specifies the time the server received the message, if the `server-time` capability is negotiated. */
  39. object ServerTime : MessageTag("time")
  40. /** A unique ID for the message, used to reply, react, edit, delete, etc. */
  41. object MessageId : MessageTag("draft/msgid")
  42. /** Used to identify a message ID that was replied to, to enable threaded conversations. */
  43. object Reply : MessageTag("+draft/reply")
  44. /** Used to specify a slack-like reaction to another message. */
  45. object React : MessageTag("+draft/react")
  46. }
  47. internal val messageTags: Map<String, MessageTag> by lazy {
  48. MessageTag::class.nestedClasses.map { it.objectInstance as MessageTag }.associateBy { it.name }
  49. }