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.

CapabilityProcessor.kt 2.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package com.dmdirc.ktirc.messages.processors
  2. import com.dmdirc.ktirc.events.EventMetadata
  3. import com.dmdirc.ktirc.events.ServerCapabilitiesAcknowledged
  4. import com.dmdirc.ktirc.events.ServerCapabilitiesFinished
  5. import com.dmdirc.ktirc.events.ServerCapabilitiesReceived
  6. import com.dmdirc.ktirc.model.IrcMessage
  7. import com.dmdirc.ktirc.model.capabilities
  8. import com.dmdirc.ktirc.util.logger
  9. internal class CapabilityProcessor : MessageProcessor {
  10. private val log by logger()
  11. override val commands = arrayOf("CAP")
  12. override fun process(message: IrcMessage) = when {
  13. message.params.size < 2 -> {
  14. log.warning { "Discarding CAP with insufficient args: $message" }
  15. emptyList()
  16. }
  17. message.subCommand == "LS" -> handleList(message.metadata, message.subCommandArguments)
  18. message.subCommand == "ACK" -> listOf(ServerCapabilitiesAcknowledged(message.metadata, message.params.capabilities))
  19. else -> {
  20. log.warning { "Discarding CAP with unknown subcommand: $message" }
  21. emptyList()
  22. }
  23. }
  24. private fun handleList(metadata: EventMetadata, lsParams: List<ByteArray>) = sequence {
  25. yield(ServerCapabilitiesReceived(metadata, lsParams.capabilities))
  26. if (lsParams.size < 2 || String(lsParams[0]) != "*") {
  27. yield(ServerCapabilitiesFinished(metadata))
  28. }
  29. }.toList()
  30. private val IrcMessage.subCommand
  31. get() = String(params[1])
  32. private val IrcMessage.subCommandArguments
  33. get() = params.slice(1 until params.size)
  34. private val List<ByteArray>.capabilities
  35. get() = with (String(last())) { if (isEmpty()) emptyMap() else split(' ').toCapabilities() }
  36. private fun List<String>.toCapabilities() = sequence {
  37. forEach { cap ->
  38. val index = cap.indexOf('=')
  39. val name = if (index == -1) cap else cap.substring(0 until index)
  40. val value = if (index == -1) "" else cap.substring(index + 1)
  41. capabilities[name]?.let { yield(name to value) } ?: log.info { "Unknown capability: $name (value: $value)" }
  42. }
  43. }.toMap()
  44. }