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.

ISupportProcessor.kt 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package com.dmdirc.ktirc.messages
  2. import com.dmdirc.ktirc.events.ServerFeaturesUpdated
  3. import com.dmdirc.ktirc.io.CaseMapping
  4. import com.dmdirc.ktirc.io.IrcMessage
  5. import com.dmdirc.ktirc.model.ServerFeatureMap
  6. import com.dmdirc.ktirc.model.serverFeatures
  7. import com.dmdirc.ktirc.util.logger
  8. import kotlin.reflect.KClass
  9. class ISupportProcessor : MessageProcessor {
  10. private val log by logger()
  11. override val commands = arrayOf("005")
  12. override fun process(message: IrcMessage) = listOf(ServerFeaturesUpdated(ServerFeatureMap().apply {
  13. // Ignore the first (nickname) and last ("are supported by this server") params
  14. for (i in 1 until message.params.size - 1) {
  15. parseParam(message.params[i])
  16. }
  17. }))
  18. private fun ServerFeatureMap.parseParam(param: ByteArray) = when (param[0]) {
  19. '-'.toByte() -> resetFeature(param.sliceArray(1 until param.size))
  20. else -> when (val equals = param.indexOf('='.toByte())) {
  21. -1 -> enableFeatureWithDefault(param)
  22. else -> enableFeature(param.sliceArray(0 until equals), param.sliceArray(equals + 1 until param.size))
  23. }
  24. }
  25. private fun ServerFeatureMap.resetFeature(name: ByteArray) = name.asFeature()?.let {
  26. reset(it)
  27. log.finer { "Reset feature ${it::class}" }
  28. }
  29. @Suppress("UNCHECKED_CAST")
  30. private fun ServerFeatureMap.enableFeature(name: ByteArray, value: ByteArray) {
  31. name.asFeature()?.let { feature ->
  32. set(feature, value.cast(feature.type))
  33. log.finer { "Set feature ${feature::class} to ${String(value)}" }
  34. }
  35. }
  36. private fun ServerFeatureMap.enableFeatureWithDefault(name: ByteArray) {
  37. name.asFeature()?.let { feature ->
  38. when (feature.type) {
  39. Boolean::class -> set(feature, true)
  40. else -> TODO("not implemented")
  41. }
  42. }
  43. }
  44. private fun ByteArray.asFeature() = serverFeatures[String(this)]
  45. ?: run {
  46. log.warning { "Unknown feature in 005: ${String(this)}" }
  47. null
  48. }
  49. private fun ByteArray.cast(to: KClass<out Any>): Any = when (to) {
  50. Int::class -> String(this).toInt()
  51. String::class -> String(this)
  52. CaseMapping::class -> CaseMapping.fromName(String(this))
  53. else -> TODO("not implemented")
  54. }
  55. }