Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

ServerState.kt 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package com.dmdirc.ktirc.model
  2. import com.dmdirc.ktirc.io.CaseMapping
  3. import kotlin.reflect.KClass
  4. /**
  5. * Contains the current state of a single IRC server.
  6. */
  7. class ServerState internal constructor(initialNickname: String) {
  8. /** Whether we've received the 'Welcome to IRC' (001) message. */
  9. internal var receivedWelcome = false
  10. /** The current status of the server. */
  11. var status = ServerStatus.Connecting
  12. internal set
  13. /** Our present nickname on the server. */
  14. var localNickname: String = initialNickname
  15. internal set
  16. /** The features that the server has declared it supports (from the 005 header). */
  17. val features = ServerFeatureMap()
  18. /** The capabilities we have negotiated with the server (from IRCv3). */
  19. val capabilities = CapabilitiesState()
  20. }
  21. class ServerFeatureMap {
  22. private val features = HashMap<ServerFeature<*>, Any?>()
  23. @Suppress("UNCHECKED_CAST")
  24. operator fun <T : Any> get(feature: ServerFeature<T>) = features.getOrDefault(feature, feature.default) as? T? ?: feature.default
  25. internal operator fun set(feature: ServerFeature<*>, value: Any) {
  26. require(feature.type.isInstance(value))
  27. features[feature] = value
  28. }
  29. internal fun setAll(featureMap: ServerFeatureMap) = featureMap.features.forEach { feature, value -> features[feature] = value }
  30. internal fun reset(feature: ServerFeature<*>) = features.put(feature, null)
  31. }
  32. data class ModePrefixMapping(val modes: String, val prefixes: String) {
  33. fun isPrefix(char: Char) = prefixes.contains(char)
  34. fun getMode(prefix: Char) = modes[prefixes.indexOf(prefix)]
  35. fun getModes(prefixes: String) = String(prefixes.map(this::getMode).toCharArray())
  36. }
  37. sealed class ServerFeature<T : Any>(val name: String, val type: KClass<T>, val default: T? = null) {
  38. object ServerCaseMapping : ServerFeature<CaseMapping>("CASEMAPPING", CaseMapping::class, CaseMapping.Rfc)
  39. object ModePrefixes : ServerFeature<ModePrefixMapping>("PREFIX", ModePrefixMapping::class, ModePrefixMapping("ov", "@+"))
  40. object MaximumChannels : ServerFeature<Int>("MAXCHANNELS", Int::class) // TODO: CHANLIMIT also exists
  41. object ChannelModes : ServerFeature<String>("CHANMODES", String::class)
  42. object MaximumChannelNameLength : ServerFeature<Int>("CHANNELLEN", Int::class, 200)
  43. object WhoxSupport : ServerFeature<Boolean>("WHOX", Boolean::class, false)
  44. }
  45. internal val serverFeatures: Map<String, ServerFeature<*>> by lazy {
  46. ServerFeature::class.nestedClasses.map { it.objectInstance as ServerFeature<*> }.associateBy { it.name }
  47. }
  48. /**
  49. * Enumeration of the possible states of a server.
  50. */
  51. enum class ServerStatus {
  52. /** We are attempting to connect to the server. It is not yet ready for use. */
  53. Connecting,
  54. /** We are logging in, dealing with capabilities, etc. The server is not yet ready for use. */
  55. Negotiating,
  56. /** We are connected and commands can be sent. */
  57. Ready,
  58. }