您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

MessageBuilders.kt 3.1KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package com.dmdirc.ktirc.messages
  2. import com.dmdirc.ktirc.IrcClient
  3. import com.dmdirc.ktirc.model.MessageTag
  4. /** Sends a message to ask the server to list capabilities. */
  5. internal fun IrcClient.sendCapabilityList() = send("CAP LS 302")
  6. /** Sends a message indicating the end of capability negotiation. */
  7. internal fun IrcClient.sendCapabilityEnd() = send("CAP END")
  8. /** Sends a message requesting the specified caps are enabled. */
  9. internal fun IrcClient.sendCapabilityRequest(capabilities: List<String>) = send("CAP REQ :${capabilities.joinToString(" ")}")
  10. /** Sends a request to join the given channel. */
  11. fun IrcClient.sendJoin(channel: String) = send("JOIN :$channel")
  12. /** Sends a request to change to the given nickname. */
  13. fun IrcClient.sendNickChange(nick: String) = send("NICK :$nick")
  14. /** Sends the connection password to the server. */
  15. internal fun IrcClient.sendPassword(password: String) = send("PASS :$password")
  16. /** Sends a response to a PING event. */
  17. internal fun IrcClient.sendPong(nonce: ByteArray) = send("PONG :${String(nonce)}")
  18. /** Sends a CTCP message of the specified [type] and with optional [data] to [target] (a user or a channel). */
  19. fun IrcClient.sendCtcp(target: String, type: String, data: String? = null) =
  20. sendMessage(target, "\u0001${type.toUpperCase()}${data?.let { " $it" } ?: ""}\u0001")
  21. /** Sends an action to the given [target] (a user or a channel). */
  22. fun IrcClient.sendAction(target: String, action: String) = sendCtcp(target, "ACTION", action)
  23. /** Sends a private message to a user or channel. */
  24. fun IrcClient.sendMessage(target: String, message: String, inReplyTo: String? = null) =
  25. sendWithTags(mapOf(MessageTag.Reply to inReplyTo), "PRIVMSG $target :$message")
  26. /**
  27. * Sends a tag-only message.
  28. *
  29. * If [inReplyTo] is specified then the [MessageTag.Reply] tag will be automatically added.
  30. */
  31. fun IrcClient.sendTagMessage(target: String, tags: Map<MessageTag, String>, inReplyTo: String? = null) {
  32. sendWithTags(inReplyTo?.let { tags + (MessageTag.Reply to inReplyTo) } ?: tags, "TAGMSG $target")
  33. }
  34. /** Sends a message to register a user with the server. */
  35. internal fun IrcClient.sendUser(userName: String, realName: String) = send("USER $userName 0 * :$realName")
  36. /** Starts an authentication request. */
  37. internal fun IrcClient.sendAuthenticationMessage(data: String = "+") = send("AUTHENTICATE $data")
  38. /**
  39. * Sends a message prefixed with some IRCv3 tags.
  40. *
  41. * For convenience, if the value of a tag is `null`, the tag will be omitted. If no tags are present the
  42. * message is sent directly with no prefix.
  43. */
  44. internal fun IrcClient.sendWithTags(tags: Map<MessageTag, String?>, message: String) = tags
  45. .filterValues { it != null }
  46. .map { (key, value) -> "${key.name}=${value?.escapeTagValue()}" }
  47. .joinToString(";")
  48. .let {
  49. if (it.isEmpty()) send(message) else send("@$it $message")
  50. }
  51. internal fun String.escapeTagValue() = replace("\\", "\\\\")
  52. .replace("\n", "\\n")
  53. .replace("\r", "\\r")
  54. .replace(";", "\\:")
  55. .replace(" ", "\\s")