123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470 |
- = KtIrc {version}
- Chris Smith
- :version: 1.1.1
- :toc: left
- :toc-position: left
- :toclevels: 5
-
- == About KtIrc
-
- KtIrc is a Kotlin JVM library for connecting to and interacting with IRC servers.
- It is still in an early stage of development. Its main features:
-
- .Built for Kotlin
- KtIrc is written in and designed for use in Kotlin; it uses extension methods,
- DSLs, sealed classes, and so on, to make it much easier to use than an
- equivalent Java library.
-
- .Coroutine-powered
- KtIrc uses co-routines for all of its input/output which lets it deal with
- IRC messages in the background while your app does other things, without
- the overhead of creating a new thread per IRC client.
-
- .Modern IRC standards
- KtIrc supports many IRCv3 features such as SASL authentication, message IDs,
- server timestamps, replies, reactions, account tags, and more. These features
- (where server support is available) make it easier to develop bots and
- clients, and enhance IRC with new user-facing functionality.
-
- == Getting started
-
- === Installing
-
- All you need to do to start using KtIrc is add a single dependency.
- KtIrc is published to JCenter, making it quick and easy to pull in
- to almost any project. The examples below show how to add the JCenter
- repository and then the KtIrc dependency; you may already be using
- JCenter for other dependencies -- in that case just skip the
- repository configuration!
-
- .Gradle (using Kotlin DSL)
- [source,kotlin,subs="attributes"]
- ----
- repositories {
- jcenter()
- }
-
- dependencies {
- implementation("com.dmdirc:ktirc:{version}")
- }
- ----
-
- .Gradle (using Groovy DSL)
- [source,groovy,subs="attributes"]
- ----
- buildscript {
- repositories {
- jcenter()
- }
- }
-
- implementation 'com.dmdirc:ktirc:{version}'
- ----
-
- .Maven
- [source,xml,subs="attributes"]
- ----
- <repositories>
- <repository>
- <id>jcenter</id>
- <url>https://jcenter.bintray.com</url>
- </repository>
- </repositories>
-
- <dependencies>
- <dependency>
- <groupId>com.dmdirc</groupId>
- <artifactId>ktirc</artifactId>
- <version>{version}</version>
- </dependency>
- </dependencies>
- ----
-
- === Creating your first client
-
- KtIrc provides a DSL ("domain specific language") for configuring a
- client that allows you to set the connection details, the user's
- details, and configure the behaviour of KtIrc itself. The DSL is
- accessed through the `IrcClient` function. For full details of all
- supported options, see the <<IrcClient DSL>> reference.
-
- A basic client will look like this:
-
- [source,kotlin]
- ----
- val client = IrcClient {
- server {
- host = "my.server.com"
- }
- profile {
- nickname = "nick"
- username = "username"
- realName = "Hi there"
- }
- }
- ----
-
- === Connecting and handling events
-
- Getting KtIrc to start connecting is as simple as calling the `connect()`
- method, but before that we probably want to add an event listener to deal
- with incoming messages:
-
- [source,kotlin]
- ----
- client.onEvent { event -> <1>
- when (event) { <2>
- is ServerReady ->
- client.sendJoin("#ktirc") <3>
- is ServerDisconnected ->
- client.connect()
- is MessageReceived ->
- if (event.message == "!test") <4>
- client.reply(event, "Test successful!") <5>
- }
- }
-
- client.connect() <6>
- ----
- <1> An event listener is registered using the `onEvent` method. It receives
- a single IrcEvent.
- <2> A Kotlin `when` statement provides a convenient way to switch on the
- type of event received.
- <3> Most common IRC commands have `send` methods defined to quickly and
- safely send the message with the right formatting.
- <4> Kotlin smart-casts the event, so you can access the properties specific
- to the matched event class, such as `message`.
- <5> The IrcClient class provides useful methods to react and respond to
- events.
- <6> The connect() method starts connecting and returns immediately. You'll
- receive events updating you on the progress.
-
- In this example, we're waiting for three events: `ServerReady`, which occurs
- after we have connected and the server has sent us all of the pre-amble
- such as its configuration and capabilities; `ServerDisconnected` which
- is raised whenever KtIrc gets disconnected from (or fails to connect to) the
- IRC server; and `MessageReceived` which occurs, unsuprisingly, whenever a
- message is received. KtIrc has many events: for more information, see the
- <<Events>> reference.
-
- [CAUTION]
- ====
- With this code, KtIrc will immediately try to reconnect as soon as it is
- disconnected. If the server closes the connection early (due to, for
- example, a bad password or the user being banned) this will result in a
- huge number of connection attempts in a short time. In real code you should
- always delay reconnections -- preferably with a backoff -- to avoid
- excessive connection attempts.
- ====
-
- You can see that KtIrc provides a number of useful methods for sending
- requests to the server, and reacting and responding to events. IRC
- commands that KtIrc supports can be invoked using the `send*` methods,
- which are documented in the <<Messages>> reference. Other useful methods
- such as `reply` can be found in the <<Utility methods>> reference.
-
- === Mandatory event handling
-
- In order to properly connect to IRC, stay connected, and handle
- incoming messages properly, the following events MUST be handled:
-
- .<<NicknameChangeRequired>>
- The nickname change required event occurs when connecting to a server
- if our initial nickname is taken. A new nickname must be supplied
- to continue connecting.
-
- .<<ServerDisconnected>>
- When KtIrc becomes disconnected from a server, or fails a connection
- attempt, it will raise this event. If you wish to stay connected
- to IRC you must call the `connect()` method to start a reconnection
- attempt after an appropriate delay.
-
- .<<BatchReceived>>
- On servers that support the IRCv3 batch capability, some incoming
- messages may be sent inside a batch. These could include join or
- quit messages during a netsplit, or other important messages you
- may need to process. At minimum, when receiving a BatchReceived
- event you should apply your normal processing to all the events
- contained within.
-
- === Versioning and deprecation
-
- As of version 1.0.0, KtIrc adheres to semantic versioning: you can
- expect to upgrade between minor versions without problems (e.g. from `1.1.2`
- to `1.13.7`); major version changes include breaking changes such as the
- removal of methods. You should check the changelog before updating to
- a new major version.
-
- Where at all possible, methods will be deprecated for a full major version
- cycle before being removed. e.g., a method deprecated in `0.5.0` will be
- present in all `1.x.x` releases and will likely be removed fully in `2.0.0`.
- This gives users of the library opportunity to migrate away from deprecated
- methods in advance of their removal.
-
- In KtIrc, we define a breaking change as one that either:
-
- * removes public methods, classes, or fields; or
- * adds required parameters to an existing public method; or
- * significantly alters the default behaviour without any API changes
-
- Note that changes that don't meet this threshold to be classed as "breaking"
- may still cause errors in downstream projects. In particular, new enum
- values may be added which could cause compilation errors if they are
- used exhaustively (e.g. in a `return when` construct with no `else` clause).
-
- == IrcClient DSL
-
- The DSL for creating a new `IrcClient` allows you to set a number of
- options relating to how KtIrc connects, what user details it provides,
- and how it behaves. The full range of options available in the DSL is
- shown below:
-
- [source,kotlin]
- ----
- server {
- host = "irc.example.com"
- port = 6667
- useTls = true
- password = "H4ckTh3Pl4n3t"
- }
-
- profile {
- nickname = "MyBot"
- username = "bot"
- realName = "Botomatic v1.2"
- }
-
- behaviour {
- requestModesOnJoin = true
- alwaysEchoMessages = true
- }
-
- sasl {
- mechanisms += "PLAIN"
- username = "botaccount"
- password = "s3cur3"
- }
- ----
-
- === Server settings
-
- The server block allows you to specify the details of the IRC server you
- wish to connect to:
-
- * `host` - the hostname or IP address of the server *(required)*
- * `port` - the port to connect on _(default: 6697)_
- * `useTls` - whether to use a secure connection or not _(default: true)_
- * `password` - the password to provide to the server _(default: null)_
-
- An alternative more compact syntax is available for configuring server details:
-
- [source,kotlin]
- ----
- server("irc.example.com", 6667, true, "H4ckTh3Pl4n3t")
- ----
-
- You can, if you wish, combine the two or use named parameters:
-
- [source,kotlin]
- ----
- server(useTls = true, port = 6697) {
- host = "irc.example.com"
- password = "H4ckTh3Pl4n3t"
- }
- ----
-
- === User profile
-
- The user profile controls how KtIrc will present itself to the IRC server, and
- how other users on that server will see the KtIrc user:
-
- * `nickname` - the initial nickname you wish to use *(required)*
- * `username` - the "username" to provide to the server _(default: KtIrc)_
- * `realName` - the "real name" that will be seen by other clients
- _(default: KtIrc User)_
-
- [TIP]
- ====
- The "username" is sometimes called the "ident" or "gecos". Some IRC servers
- will check for an ident reply from your host and use that in place of the
- username provided if it gets a response. The username (or ident reply)
- becomes part of your client's hostmask, and is visible to other users. It
- is unrelated to nickserv or other account usernames.
- ====
-
- As with the <<Server settings>> you can use a more compact syntax:
-
- [source,kotlin]
- ----
- profile("nickname", "username", "real name")
- ----
-
- === Behaviour
-
- The behaviour block allows you to tweak how KtIrc itself operates. These
- options allow you perform common operations automatically, or enjoy more
- advanced IRC features even if the server doesn't support them:
-
- * `requestModesOnJoin` - if enabled, automatically requests channel modes
- when the client joins a new channel _(default: false)_
- * `alwaysEchoMessages` - if enabled, every message you send will result
- in a `MessageReceived` event being returned. Servers that support the
- IRCv3 `echo-message` capability will do this automatically; enabling the
- behaviour will make all servers act the same way _(default: false)_
- * `preferIPv6` - if enabled, KtIrc will prefer to connect over IPv6 if the
- server publishes AAAA DNS records. If disabled, KtIrc will prefer IPv4.
- If the server is available exclusively on IPv4 or IPv6 then this option
- has no effect. _(default: true)_
-
- The behaviour block is optional in its entirety.
-
- === SASL configuration
-
- SASL ("Simple Authentication and Security Layer") is a standard mechanism
- for securely authenticating to a service that has recently been adopted
- for use in IRC. SASL supports a number of 'mechanisms' that describe how
- the data will be exchanged between the client and server. KtIrc supports
- the following mechanisms:
-
- * `EXTERNAL` - the server uses some external means to authenticate the
- client, instead of a username and password. On most servers this
- means checking the client certificate against one registered with
- the user's account. _(disabled by default)_
- * `PLAIN` - the client sends the username and password in plain text
- during the connection phase. This offers slightly more security
- than calling `nickserv identify` (for example) after connecting.
- * `SCRAM-SHA-1` - this mechanism involves a "salted challenge" being
- completed which results in both the server and the client proving that
- they know the user's password, but without it every being transmitted.
- This is based on the `SHA-1` algorithm which has known issues, but is
- more than sufficient when used in this manner.
- * `SCRAM-SHA-256` - the same as `SCRAM-SHA-1` but using the `SHA-256`
- algorithm instead, which is more modern and secure.
-
- To use `PLAIN`, `SCRAM-SHA-1` or `SCRAM-SHA-256`, you must supply a username
- and password in the configuration:
-
- [source,kotlin]
- ----
- sasl {
- username = "botaccount"
- password = "s3cur3"
- }
- ----
-
- KtIrc enables `SCRAM-SHA-256`, `SCRAM-SHA-1` and `PLAIN` by default, and will
- use them in that order of preference if the server supports more than one.
- You can modify the `mechanisms` parameter if you wish to disable one:
-
-
- [source,kotlin]
- ----
- sasl {
- mechanisms -= "PLAIN"
- username = "botaccount"
- password = "s3cur3"
- }
- ----
-
- You can also clear all the default mechanisms and provide your own list:
-
- [source,kotlin]
- ----
- sasl {
- mechanisms("SCRAM-SHA-256", "PLAIN")
- username = "botaccount"
- password = "s3cur3"
- }
- ----
-
-
- If you wish to enable the `EXTERNAL` mechanism, you do not need to provide
- a username or password:
-
- [source,kotlin]
- ----
- sasl {
- mechanisms("EXTERNAL")
- }
- ----
-
- Alternatively, if you wish to enable `EXTERNAL` but fall back to other
- mechanisms if it doesn't work:
-
- [source,kotlin]
- ----
- sasl {
- mechanisms += "EXTERNAL"
- username = "botaccount"
- password = "s3cur3"
- }
- ----
-
- The SASL block is optional in its entirety.
-
- == State
-
- KtIrc attempts to track all reasonable state of the IRC network. This includes
- details about the server, channels the client is joined to, and users that are
- also in those channels. The state is exposed in a several fields accessible
- from the `IrcClient`:
-
- === ServerState
-
- The server state provides information about the server, and our connection to
- it.
-
- [IMPORTANT]
- ====
- The server state will be updated frequently while KtIrc is connecting to a
- server. The values within it should not be relied upon until a `ServerReady`
- event is received, as they may be incomplete or estimates before then.
- ====
-
- .serverState.status (ServerStatus)
- Provides an enum containing the current server state. One of:
-
- * `Disconnected` - the server is not connected
- * `Connecting` - we are attempting to establish a connection
- * `Negotiating` - we are logging in, negotiating capabilities, etc
- * `Ready` - we are connected and commands may be sent
-
- .serverState.localNickname (String) [DEPRECATED]
- The current nickname we are using on the IRC server. While connecting this
- will default to the nickname from the <<User profile>>, but it may be updated
- if e.g. the nick is in use or not allowed.
-
- [WARNING]
- ====
- This property is deprecated in favour of the <<LocalUser>> property of `IrcClient`.
- You should migrate to using `localUser.nickname` in place of `serverSate.localNickname`.
- ====
-
- .serverState.serverName (String)
- The name the server uses for itself. While connecting this defaults to the
- hostname given in the <<Server settings>>, but it will be updated to the
- value provided by the server. For example, you may connect to
- `irc.example.com` and during the negotiation phase KtIrc will see that it
- is actually talking to `server3.uk.irc.example.com` and update the
- serverName to reflect that.
-
- [TIP]
- ====
- For a user-friendly identifier most servers provide a `NETWORK` token in
- the ISUPPORT reply, which is available via the <<Features>> property.
- ====
-
- .serverState.channelModePrefix (ModePrefixMapping)
- Provides a mapping from channel user modes (such as "o" for op, "v" for
- voice) to the prefixes used before nicknames (such as "@" and "+").
-
- To map prefixes to modes, you can use the `getMode()` or `getModes()`
- functions:
-
- [source,kotlin]
- ----
- getMode('@') == 'o'
- getModes("@+") == "ov"
- ----
-
- .serverState.channelTypes (String)
- Contains the types of channels that are allowed by the server, such as
- `\#&` for normal channels ("#") and local channels ("&").
-
- ==== Capabilities
-
- The IRCv3 specifications introduce the concept of 'capability negotiation'.
- This allows the client and server to negotiate and enable new capabilities
- that are mutually supported.
-
- The capabilities state contains the following properties:
-
- .serverState.capabilities.negotiationState (CapabilitiesNegotiationState)
- The current state of negotiating with the server. One of:
-
- * `AWAITING_LIST` - we have requested a list of capabitilies and are awaiting
- a reply
- * `AWAITING_ACK` - we have sent the capabilities we want to enable, and are
- waitin for the server to acknowledge them
- * `AUTHENTICATING` - we are attempting to authenticate with SASL
- * `FINISHED` - we have completed negotiation
-
- Where a server does not support IRCv3 capability negotiation, the state will
- remain at `AWAITING_LIST`.
-
- .serverState.capabilities.advertisedCapabilities (Map<String, String>)
- Contains a map of capability names to values that the server offered. This
- should only be required for advance use cases, such as looking up the
- languages offered by a server when providing the user with a choice of
- translations.
-
- .serverState.capabilities.enabledCapabilities (Map<Capability, String>)
- Contains a map of capabilities that KtIrc has successfully negotiated with
- the server.
-
- ===== Supported capabilities
-
- * `sasl` - used to perform SASL authentication during connection
- * `message-tags` - allows arbitrary tags on messages
- * `server-time` - the server adds a timestamp tag to each incoming message
- * `account-tag` - the server adds an account tag to incoming user messages
- * `userhost-in-names` - the NAMES reply includes users hosts not just nicknames
- * `multi-prefix` - all modes are included in nick prefixes (e.g. `@+nick`)
- * `extended-join` - more information is sent when a user joins a channel
- * `batch` - allows multi-line responses to be batched together
- * `echo-message` - echos the client's own messages back to it
- * `draft/labeled-responses` - responses are labeled so the client knows which
- incoming message corresponds to which command it sent
- * `account-notify` - the server sends a message when a user's account changes
- * `away-notify` - the server sends a message when a user's away state changes
- * `chghost` - the server sends a message when a user's host changes
-
- ==== Features
-
- Features are KtIrc's way of exposing the information the server declares in
- its ISUPPORT messages. These describe how the server is configured, and what
- limits are placed on clients. You access features using the `features` map
- in the server state:
-
- [source,kotlin]
- ----
- ircClient.serverState.features[ServerFeature.Network]
- ----
-
- The following features are available:
-
- * `Network` - the name of the network the server belongs to __(String?)__
- * `ServerCaseMapping` - the current case mapping of the server __(CaseMapping!)__
- * `Modeprefixes` - the user mode prefix mapping (e.g. ov to @+) __(ModePrefixMapping!)__
- * `MaximumChannels` - the maximum number of channels a user can join __(Int?)__
- * `ChannelModes` - the modes supported in channels __(Array<String>?)__
- * `ChannelTypes` - the types of channel supported (e.g. "#&") __(String!)__
- * `MaximumChannelNameLength` - how long channel names may be __(Int!)__
- * `WhoxSupport` - whether the server supports extended whos ("WHOX") __(Boolean!)__
-
- [NOTE]
- ====
- If the server does not define a feature, KtIrc will either fall back to a
- default value based on the IRC RFCs or common practice (for those features
- identified with a non-null type such as `Int!` or `String!`); otherwise
- the value of the feature will be `null` (such as for those identified as
- `Int?` or `String?` types).
- ====
-
- === UserState
-
- The client's UserState object tracks the details of all users in common
- channels. It can be used to find the most up-to-date and comprehensive
- information for those users, as well as the set of channels that we share
- with them.
-
- The UserState is accessed via the `userState` property of IrcClient and
- acts as a map, accessible using either a nickname or a `User` object:
-
- [source,kotlin]
- ----
- ircClient.userState["acidBurn"]
-
- val user: User = myIrcEvent.user
- ircClient.userState[user]
- ----
-
- The UserState returns a `KnownUser` object which exposes a `details`
- property containing the <<User>> details, and a `channels` property
- containing the common channel names. You can also use the `in`
- operator to check if the user is in a channel:
-
- [source,kotlin]
- ----
- ircClient.userState["acidBurn"]?.let { knownUser -> <1>
- val accountName = knownUser.account
- val inChannel = "#channel" in knownUser <2>
- val allChannels = knownUser.channels <3>
- }
- ----
- <1> If the user isn't known, the call to `get` (using the `[]` operator)
- returns null, so we use a `let` statement to deal only with the case
- that the user is found.
- <2> Check if the user is present on the common channel `#channel`. If
- the KtIrc client is not joined to that channel, it will always return
- false. You can also use the `contains("#channel")` method instead of
- the `in` operator.
- <3> Returns all common channels we share with the user; will never
- include channels that the KtIrc client is not joined to.
-
- ==== User
-
- User objects have the following properties:
-
- * `nickname` - the current nickname of the user, always set
- * `ident` - the ident (username/"gecos") of the user, if known (null otherwise)
- * `hostname` - the hostname of the user, if known (null otherwise)
- * `account` - the account of the user, if known (null if account unknown, or user not registered)
- * `realName` - the real name of the user, if known (null otherwise)
- * `awayMessage` - the away message of the user, if known (null if away state unknown, or user not away)
-
- === LocalUser
-
- Contains a <<User>> instance corresponding to our own details on the IRC
- network. This is the same instance that would be returned from
- `ircClient.userState[nickname]` for the current nickname.
-
- While connecting this will default to a User with only a nickname, which will
- be taken from the <<User profile>>. It will be updated as more information
- is received from the IRC server.
-
- === ChannelState
-
- The ChannelState keeps track of the state for all channels that the client
- is joined to. It is indexed by channel name:
-
- [source,kotlin]
- ----
- ircClient.channelState["#ktirc"]
- ----
-
- Each channel's state contains the following properties:
-
- * `receivingUserList` - boolean value indicating whether we are in the process
- of receiving the list of users for the channel. If we are, the `users`
- property will be incomplete.
- * `modesDiscovered` - boolean value indicating whether we have received the
- full set of modes set on the channel. The `requestModesOnJoin` <<Behaviour>>
- allows you to make KtIrc request these automatically.
- * `topic` - a ChannelTopic object representing the current channel topic.
- If no topic is set, then a ChannelTopic with `null` properties will be
- provided.
- * `users` - a map of all known users in the channel, see <<Channel users>>
- for more information
- * `modes` - A map of the current channel modes and their values. Only
- complete if `modesDiscovered` is true.
-
- ==== Channel users
-
- Channel users are accessed using the `users` property, which provides an
- iterable map of nickname to `ChannelUser`. Each `ChannelUser` contains
- the nickname and current modes for that user. To get further details about
- a user, such as their hostmask or real name, you should query the <<UserState>>
- with the given nickname.
-
- [source,kotlin]
- ----
- ircClient.channelState["#ktirc"]?.users?.forEach { user ->
- println("${user.nickname} has modes ${user.modes}")
- }
- ----
-
- == Events
-
- Incoming lines from the IRC server are converted by KtIrc to subclasses of
- `IrcEvent`. These, along with other more advance events, are then published
- to users of the client using the `onEvent` method in `IrcClient`.
-
- All events extend `IrcEvent`, which offers a single `metadata` property.
- This contains details related to the event:
-
- * `time` - the time at which the message occurred (if the server supports
- the `server-time` capability), or the time at which we received it.
- Always present.
- * `batchId` - an opaque string identifier for the batch the message is
- part of (if the server supports the `batch` capability). Null for
- messages not in a batch.
- * `messageId` - a unique, opaque string identifier for the message if
- the server supports the `msgid` tag. Null otherwise.
- * `label` - a unique, opaque string identifier that ties a message to
- a labelled command that was sent by KtIrc, if the server supports
- the `labelled-replies` capability. Null otherwise.
-
- Several specialised versions of `IrcEvent` are used which allow for easier
- processing:
-
- .TargetedEvent
-
- A `TargetedEvent` is one that is targeted at either a user or a channel.
- `TargetedEvent` exposes a string `target` property that identifies the
- target of the message. This allows you to direct messages to the right
- handler or UI component more easily:
-
- [source,kotlin]
- ----
- ircClient.onEvent { event ->
- when (event) {
- is TargetedEvent -> dispatchEvent(event.target, event)
- }
- }
- ----
-
- .SourcedEvent
-
- A large number of events come from a remote IRC user, and it can be
- useful to handle these in the same way. KtIrc offers a `SourcedEvent`
- interface for all events that originate from a user, and it exposes
- a single `user` property:
-
- [source,kotlin]
- ----
- ircClient.onEvent { event ->
- when (event) {
- is SourcedEvent -> notifyAboutUserActivity(event.user)
- }
- }
- ----
-
- .ChannelMembershipAdjustment
-
- A number of events describe how the membership of a channel changes --
- namely, joins, parts, quits, kicks, names replies, and nick changes.
- All of these events implement the `ChannelMembershipAdjustment` interface
- which reduces the amount of logic you need to do if you wish to maintain
- a membership list (for example in a UI). The interface exposes three
- properties:
-
- * `addedUser` - a single nickname to be added _(String)_
- * `removedUser` - a single nickname to be removed _(String)_
- * `replacedUsers` - a list of nicknames to replace any existing ones with
- _(Array<String>)_
-
- All the properties are nullable, and most events will only populate
- one of the three.
-
- === Server events
-
- ==== ServerConnecting
- * Type: IrcEvent
- * Properties: _(none)_
-
- This event is raised by KtIrc as soon as it starts attempting to connect to
- a server. It will be followed by either a <<ServerConnected>> or a
- <<ServerConnectionError>> event at some point.
-
- ==== ServerConnected
- * Type: IrcEvent
- * Properties: _(none)_
-
- This event is raised by KtIrc when it has connected to the server, and is
- starting the process of registering, negotiating capabilities, etc.
- The server will *not* yet be ready for use - a <<ServerReady>> event will
- follow once all of the initial setup has completed.
-
- ==== ServerConnectionError
- * Type: IrcEvent
- * Properties:
- ** `error`: `ConnectionError` - the type of error that occurred
- ** `details`: `String?` - information about the error, if available
-
- This event is raised by KtIrc when a problem occurred while connecting
- to the server. The `ConnectionError` enum will provide the cause of
- the error, if known:
-
- * `UnresolvableAddress` - the hostname provided could not be resolved
- to an IP address
- * `ConnectionRefused` - the server did not answer a connection request
- on the given port
- * `BadTlsCertificate` - there was an issue with the TLS certificate the
- server presented (e.g. it was out of date, for the wrong domain, etc)
- * `Unknown` - the exact cause of the error isn't known
-
- This event will be followed by a <<ServerDisconnected>> event.
-
- ==== ServerWelcome
- * Type: IrcEvent
- * Properties:
- ** `server`: `String` - the name the server supplied for itself
- ** `localNick`: `String` - the nickname the server says we are using
-
- This event is raised in response to the server sending a 001 WELCOME
- message. It contains the name that the server supplied for itself
- (for example, KtIrc may connect to a round-robin address like
- `irc.example.com` and the server it actually connects to then
- identifies itself as `node3.uk.irc.example.com`), and the nickname
- that the server says we are using.
-
- ==== ServerReady
- * Type: IrcEvent
- * Properties: _(none)_
-
- This event is raised by KtIrc when it has connected to a server,
- registered with the IRC network, and received all of the server's
- initial data describing its configurations and its features.
-
- At this point it is safe to start issuing commands, checking
- state, joining channels, etc.
-
- ==== ServerDisconnected
- * Type: IrcEvent
- * Properties: _(none)_
-
- Raised in all cases where KtIrc has attempted to connect to an IRC server and
- has now been disconnected. KtIrc will not automatically attempt to reconnect;
- the `connect()` method should be called again after an appropriate delay.
-
- NOTE: All of KtIrc's internal state, such as details about users and
- channels, will be reset when disconnected from the server. State should not
- be queried until a new <<ServerReady>> event has been received, at which
- point it will have been recreated.
-
- ==== MotdLineReceived
- * Type: IrcEvent
- * Properties:
- ** `line`: `String` - the line of the message of the day that was received
- ** `first`: `Boolean` - true if the line is the first one received
-
- The MotdLineReceived event is raised whenever the server sends a single
- line of its Message of the Day. The `first` parameter is set on the
- first line of the MOTD so that special formatting or UI handling can
- be applied. When the MOTD is finished, a <<MotdFinished>> event is raised.
-
- ==== MotdFinished
- * Type: IrcEvent
- * Properties:
- ** `missing`: `Boolean` - indicates the MOTD was missing
-
- This event occurs in two circumstances: when the server has sent a
- series of <<MotdLineReceived>> events and has reached the end of the
- Message of the Day; or when the server has no MOTD to send and
- informs the client that the MOTD is missing.
-
- === Channel events
-
- NOTE: Many events such as <<MessageReceived>> apply to both channels and
- users. These are documented in the <<Channel/User events>> category.
-
- ==== ChannelJoined
- * Type: IrcEvent, TargetedEvent, SourcedEvent, ChannelMembershipAdjustment
- * Properties:
- ** `user`: `User` - the user that joined the channel
- ** `target`: `String` - the channel that was joined
-
- Raised whenever a user joins a channel, including the KtIrc client. You
- can determine whether the join applies to another user or the local client
- using the <<IsLocalClient>> utility method.
-
- When the local client joins a new channel, this event will typically be
- followed by one or more <<ChannelNamesReceived>> events, then
- <<ChannelNamesFinished>>, <<ChannelTopicDiscovered>> and if the
- `requestModesOnJoin` <<Behaviour>> is enabled a <<ModeChanged>> event.
-
- ==== ChannelJoinFailed
- * Type: IrcEvent, TargetedEvent
- * Properties:
- ** `target`: `String` - the channel that we tried to join
- ** `reason`: `JoinError` - the error that prevented us from joining
-
- The ChannelJoinFailed event is raised when we attempt to join a channel
- but the server doesn't allow us to do so. The reason parameter enumerates
- the possible problems:
-
- * `TooManyChannels` - we are already in the maximum number of channels allowed
- by the server.
- * `NoHiding` - the channel is no-hiding (+H), but we have invisible join/parts
- enabled.
- * `NeedKey` - the channel is keyed (+k) and a valid key was not provided
- * `NeedInvite` - the channel is invite only (+i) and no invite was received.
- * `NeedRegisteredNick` - the channel is limited to registered users only, and we
- are not registered.
- * `NeedTls` - the channel is secure-only, and we're not using TLS.
- * `NeedAdmin` - the channel is limited to server admins and we are not one.
- * `NeedOper` - the channel is limited to ircops and we are not one.
- * `Banned` - we are banned from the channel.
- * `ChannelFull` - the channel is limited (+l) and currently full.
- * `BadChannelName` - the channel name is disallowed by the server.
- * `Throttled` - we're trying to joiin too many channels and have been throttled.
- * `Unknown` - we don't know why.
-
- [WARNING]
- ====
- ChannelJoinFailed events are generated on a _best-effort_ basis by KtIrc. Error
- handling on IRC is very poorly standardised, and varies wildly between server
- implementations. For example, trying to join a secure-only channel on an
- ircd-seven server will send a NOTICE to the user instead of an error response,
- so no `ChannelJoinFailed` event will be raised.
-
- When tracking whether a join suceeded or failed you should combine monitoring
- for the response with a reasonable timeout, and assume failure if the timeout
- lapses without a <<ChannelJoined>> or <<ChannelJoinFailed>> event occurring.
- ====
-
- ==== ChannelParted
- * Type: IrcEvent, TargetedEvent, SourcedEvent, ChannelMembershipAdjustment
- * Properties:
- ** `user`: `User` - the user that parted the channel
- ** `target`: `String` - the channel that was parted
- ** `reason`: `String` - the user-supplied reason for parting
-
- Raised when any user parts a channel that we are on. Users can supply a reason
- when parting a channel; if they have done so the `reason` property will be
- non-empty.
-
- ==== ChannelUserKicked
- * Type: IrcEvent, TargetedEvent, SourcedEvent, ChannelMembershipAdjustment
- * Properties:
- ** `user`: `User` - the user that performed the kick
- ** `victim`: `String` - the nickname of the user that was kicked
- ** `target`: `String` - the channel that the victim was kicked from
- ** `reason`: `String` - the user-supplied reason for kicking
-
- This event occurs when a user is kicked (forcibly removed) from a channel.
-
- NOTE: The `user` is the one performing the kick, and will remain in the
- channel. The `victim` is the one being forcibly ejected.
-
- ==== ChannelQuit
- * Type: IrcEvent, TargetedEvent, SourcedEvent, ChannelMembershipAdjustment
- * Properties:
- ** `user`: `User` - the user that quit
- ** `target`: `String` - the channel that the user was in
- ** `reason`: `String` - the user-supplied reason for quitting
-
- After a <<UserQuit>> event, KtIrc will "fan out" the event to all of the
- channels that we share with the user and raise a `ChannelQuit` event for
- each channel. This is designed to make implementing certain features easier;
- if you fully handle a UserQuit event there is no need to also handle the
- ChannelQuit events, and vice-versa.
-
- Users and servers can supply a reason when a user quits; if supplied then
- the `reason` parameter will be non-empty.
-
- ==== ChannelNickChanged
- * Type: IrcEvent, TargetedEvent, SourcedEvent, ChannelMembershipAdjustment
- * Properties:
- ** `user`: `User` - the user who has changed their nickname
- ** `target`: `String` - the channel that the user is in
- ** `newNick`: `String` - the user's new nickname
-
- After a <<UserNickChanged>> event, KtIrc will "fan out" the event to
- all of the channels that we share with the user and raise a `ChannelNickChanged`
- event for each channel. This is designed to make implementing certain features
- easier; if you fully handle a UserNickChanged event there is no need to also
- handle the ChannelNickChanged events, and vice-versa.
-
- TIP: The user property will contain the user's old details, but you will
- not be able to access additional information from the <<UserState>> using
- these details as KtIrc will have internally renamed the user to use the
- new nickname.
-
- ==== ChannelNamesReceived
- * Type: IrcEvent, TargetedEvent
- * Properties:
- ** `target`: `String` - the channel that the user is in
- ** `names`: `List<String>` - the partial list of names that are in the channel
-
- When we join a channel (or manually request it) the IRC server sends the
- list of channel members in a sequence of NAMES messages. KtIrc raises a
- `ChannelNamesReceived` event for each of these messages.
-
- WARNING: The given names may not be a complete list of members of the channel,
- as more names could follow. The format of the names varies between IRC servers
- and depending on the IRCv3 <<Capabilities>> that KtIrc negotiated. Most
- implementations should simply wait for <<ChannelNamesFinished>> and then request
- the complete list of names from KtIrc's <<ChannelState>>.
-
- ==== ChannelNamesFinished
- * Type: IrcEvent, TargetedEvent, ChannelMembershipAdjustment
- * Properties:
- ** `target`: `String` - the channel whose names response has finished
-
- Raised when the IRC server has finished receiving all of the names of users
- that are currently in a channel. At this point you can query the channel's
- <<ChannelState>> to get a detailed list of members.
-
- ==== ChannelTopicDiscovered
- * Type: IrcEvent, TargetedEvent
- * Properties:
- ** `target`: `String` - the channel whose topic was discovered
- ** `topic`: `String?` - the topic in the channel, if any
-
- `ChannelTopicDiscovered` occurs when we join a channel (or manually request
- that the server repeats the current topic) and contains the current channel
- topic. If there is no topic set, the `topic` parameter will be `null`.
-
- Metadata about the topic, such as who set it and when, is contained in the
- <<ChannelTopicMetadataDiscovered>> event which should follow this one, if
- the topic was set.
-
- ==== ChannelTopicMetadataDiscovered
- * Type: IrcEvent, TargetedEvent
- * Properties:
- ** `target`: `String` - the channel whose topic metadata was discovered
- ** `user`: `User` - the user who set the topic
- ** `setTime`: `LocalDateTime` - the time at which the topic was set
-
- Provides meta-data relating to a topic that was previously set on the
- channel.
-
- NOTE: The given user may not exist on the network any more, or may have
- changed details since the topic was set. You should not expect to be able
- to look up the user's details in the <<UserState>>, or interact with them
- directly on IRC.
-
- ==== ChannelTopicChanged
- * Type: IrcEvent, TargetedEvent, SourcedEvent
- * Properties:
- ** `user`: `User` - the user who has changed the topic
- ** `target`: `String` - the channel that the topic was changed in
- ** `topic`: `String?` - the channel's new topic
-
- Raised when a user changes the topic of a channel we are joined to. If
- the topic was cleared/removed, the `topic` parameter will be `null`.
-
- ==== ChannelAway
- * Type: IrcEvent, TargetedEvent, SourcedEvent
- * Properties:
- ** `user`: `User` - the user whose away state has changed
- ** `target`: `String` - the channel that the user is in
- ** `message`: `String?` - the away message, or `null` if the user is back
-
- After a <<UserAway>> event, KtIrc will "fan out" the event to all of the
- channels that we share with the user and raise a `ChannelAway`
- event for each channel. This is designed to make implementing certain features
- easier; if you fully handle a UserAway event there is no need to also
- handle the ChannelAway events, and vice-versa.
-
- === Channel/User events
-
- These are events that may be targeted to either a channel or a user. You
- can use the <<IsChannel>> method to determine whether the target of one
- of these events is a channel or not.
-
- ==== MessageReceived
- * Type: IrcEvent, TargetedEvent, SourcedEvent
- * Properties:
- ** `user`: `User` - the user who sent the message
- ** `target`: `String` - the channel or user the message was sent to
- ** `message`: `String` - the text of the message
-
- Raised whenever we receive a message on a channel or directly to our
- local user. CTCPs and Actions, which are client-side extensions to
- messages will not raise this event; instead they will raise
- <<CtcpReceived>> and <<ActionReceived>> respectively.
-
- The <<Reply>> function can be used to reply to a message,
- automatically selecting the appropriate target and including the
- message ID in the reply where supported by the IRC server.
-
- ==== NoticeReceived
- * Type: IrcEvent, TargetedEvent, SourcedEvent
- * Properties:
- ** `user`: `User` - the user who sent the notice
- ** `target`: `String` - the channel or user the notice was sent to
- ** `message`: `String` - the text of the notice
-
- Raised whenever we receive a notice on a channel or directly to our
- local user. CTCP replies, which are client-side extensions to
- notices will not raise this event; instead they will raise
- <<CtcpReplyReceived>>.
-
- During connection, notices may be received which target either the
- magic string `AUTH` or `*`, as the client's nickname is not yet
- known.
-
- ==== ActionReceived
- * Type: IrcEvent, TargetedEvent, SourcedEvent
- * Properties:
- ** `user`: `User` - the user who sent the action
- ** `target`: `String` - the channel or user the action was sent to
- ** `action`: `String` - the text of the action
-
- Raised whenever we receive an 'action' message on a channel or
- directly to our local user. Actions are a client-side extension
- to the IRC protocol that allow users to describe something they
- are doing.
-
- ==== CtcpReceived
- * Type: IrcEvent, TargetedEvent, SourcedEvent
- * Properties:
- ** `user`: `User` - the user who sent the CTCP
- ** `target`: `String` - the channel or user the CTCP was sent to
- ** `type`: `String` - the type of the CTCP
- ** `content`: `String` - the (possibly empty) content of the CTCP
-
- Raised in response to a message that contains a CTCP
- (client-to-client protocol) message other than an action.
- CTCPs have a type, such as `PING`, `VERSION`, and optionally
- some content such as a timestamp or nonce when requesting a PING.
-
- KtIrc does not reply to any CTCPs by itself. Replies to CTCPs are
- by convention sent to the originating user, even if the CTCP is
- sent to a channel.
-
- ==== CtcpReplyReceived
- * Type: IrcEvent, TargetedEvent, SourcedEvent
- * Properties:
- ** `user`: `User` - the user who sent the CTCP reply
- ** `target`: `String` - the channel or user the reply was sent to
- ** `type`: `String` - the type of the CTCP reply
- ** `content`: `String` - the (possibly empty) content of the CTCP reply
-
- Raised in response to a notice that contains a CTCP
- (client-to-client protocol) reply. This usually occurs after we
- have issued a CTCP request to a user or channel, and the `content`
- argument will contain the remote client's response.
-
- Replies to CTCPs are by convention sent to the originating user,
- even if the CTCP is sent to a channel. The `target` parameter
- should therefore be the local user in most cases.
-
- ==== ModeChanged
-
- TODO
-
- === User events
-
- TODO
-
- ==== UserAway
- * Type: IrcEvent, SourcedEvent
- * Properties:
- ** `user`: `User` - the user who has changed their away state
- ** `message`: `String?` - the away message, or `null` if the user is back
-
- Raised when we are informed that a user has changed away states. If the server
- supports the `away-notify` capability we will receive notifications for all
- users in our common channels; otherwise, we will only receive notifications
- for our own user.
-
- If the user is away but we don't know the reason for it, the `message`
- property will be empty.
-
- For each channel the user is on, a <<ChannelAway>> event will be generated.
-
- ==== UserQuit
-
- TODO
-
- ==== UserNickChanged
- * Type: IrcEvent, SourcedEvent
- * Properties:
- ** `user`: `User` - the user who has changed their nickname
- ** `newNick`: `String` - the new nickname of the user
-
- Raised when we are informed that a user has changed nicknames.
- For each channel the user is on, a <<ChannelNickChanged>> event will be
- generated
-
- TIP: The user property will contain the user's old details, but you will
- not be able to access additional information from the <<UserState>> using
- these details as KtIrc will have internally renamed the user to use the
- new nickname.
-
- ==== UserHostChanged
- * Type: IrcEvent, SourcedEvent
- * Properties:
- ** `user`: `User` - the user who has changed their ident/hostname
- ** `newIdent`: `String` - the new ident of the user
- ** `newHost`: `String` - the new hostname of the user
-
- Raised when we are informed that a user has changed their ident and/or
- hostname. This is only supported by servers with the `chghost` capability.
-
- ==== UserAccountChanged
- * Type: IrcEvent, SourcedEvent
- * Properties:
- ** `user`: `User` - the user who has changed their account
- ** `newAccount`: `String?` - the new account of the user
-
- Raised when we are informed that a user has changed their account name.
- This is only supported by servers with the `account-notify` capability,
- and may occur when the user logs in or out of their account.
-
- If the user is no longer logged in to an account, `newAccount` will be
- `null`.
-
- === Other events
-
- ==== PingReceived
- * Type: IrcEvent
- * Properties:
- ** `nonce`: `ByteArray` - the unique data that must be included in the reply
-
- Raised when the IRC server sends a PING message to the client. KtIrc will
- automatically reply with an appropriate PONG.
-
- ==== ServerFeaturesUpdated
- * Type: IrcEvent
- * Properties:
- ** `serverFeatures`: `ServerFeatureMap` - the features supplied by the server
-
- Corresponds to the server sending a single 005 ISUPPORT line. Multiple
- events of this type may be raised in quick succession when features are
- split over multiple lines.
-
- In general, you should wait for a <<ServerReady>> event and then query the
- <<Features>> instead of relying on this event.
-
- ==== ServerCapabilitiesReceived
-
- TODO
-
- ==== ServerCapabilitiesAcknowledged
-
- TODO
-
- ==== ServerCapabilitiesFinished
-
- TODO
-
- ==== AuthenticationMessage
-
- TODO
-
- ==== SaslFinished
-
- TODO
-
- ==== SaslMechanismNotAvailableError
-
- TODO
-
- ==== BatchStarted
-
- TODO
-
- ==== BatchFinished
-
- TODO
-
- ==== BatchReceived
-
- TODO
-
- ==== NicknameChangeFailed
- * Type: IrcEvent
- * Properties:
- ** `cause`: `NicknameChangeError` - the reason the nickname must be changed
-
- Raised when the server informs us that our desired nickname is not available
- for some reason. The `cause` parameter will contain a specific reason given
- by the server:
-
- * `ErroneousNickname` - the nickname is not allowed by the server (e.g. it used
- restricted characters)
- * `AlreadyInUse` - the nickname is already in use
- * `Collision` - the nickname has collided with another somehow
- * `NoNicknameGiven` - no nickname was provided
-
- ==== NicknameChangeRequired
- * Type: IrcEvent, NicknameChangeFailed
- * Properties:
- ** `cause`: `NicknameChangeError` - the reason the nickname must be changed
-
- Raised during a connection attempt when there is a problem with the nickname
- that KtIrc was told to use. The exact problem will be detailed in the `cause`
- parameter, and has the same options as the <<NicknameChangeFailed>> event.
-
- Upon receiving this event, a new nickname MUST be chosen and sent to the
- server with the <<sendNickChange>> method. Failure to do so will result
- in the IRC server terminating the connection.
-
- WARNING: `NicknameChangeRequired` currently extends `NicknameChangeFailed`
- for backwards compatibility. This will be removed in KtIrc 2.0.0, and
- both events will need to be handled separately.
-
- == Messages
-
- TODO
-
- === sendNickChange
-
- TODO
-
- == Utility methods
-
- TODO
-
- === IsChannel
-
- TODO
-
- === IsLocalClient
-
- TODO
-
- === React
-
- TODO
-
- === Reply
-
- TODO
-
- == IRCv3 support
-
- The following table shows KtIrc's IRCv3 support as of this release:
-
- [cols=3,options="header,autowidth"]
- |===
- | Feature
- | Status
- | Notes
-
- 3+h| Capability negotiation
-
- | https://ircv3.net/specs/core/capability-negotiation.html[CAP]
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- See <<Supported capabilities>> for the caps KtIrc will negotiate
-
- | https://ircv3.net/specs/core/capability-negotiation.html#cap-ls-version[CAP 302]
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- See <<Supported capabilities>> for the caps KtIrc will negotiate
-
- | https://ircv3.net/specs/core/capability-negotiation.html#cap-notify[cap-notify]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- 3+h| Published specifications
-
- | https://ircv3.net/specs/extensions/account-notify-3.1.html[account-notify] v3.1
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- See <<UserAccountChanged>>
-
- | https://ircv3.net/specs/extensions/account-tag-3.2.html[account-tag] v3.2
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- Accounts are automatically added to `User` properties in events
-
- | https://ircv3.net/specs/extensions/away-notify-3.1.html[away-notify] v3.1
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- See <<UserAway>>.
-
- | https://ircv3.net/specs/extensions/batch-3.2.html[batch] v3.2
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- See <<BatchReceived>>
-
- | https://ircv3.net/specs/extensions/chghost-3.2.html[chghost] v3.2
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- See <<UserHostChanged>>
-
- | https://ircv3.net/specs/extensions/echo-message-3.2.html[echo-message] v3.2
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- See also the `alwaysEchoMessages` <<Behaviour>>
-
- | https://ircv3.net/specs/extensions/extended-join-3.1.html[extended-join] v3.1
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- Additional details are automatically added to `User` properties in events
-
- | https://ircv3.net/specs/extensions/invite-notify-3.2.html[invite-notify] v3.2
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://ircv3.net/specs/extensions/message-tags.html[message-tags]
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- Exposed in the metadata property of <<Events>>
-
- | https://ircv3.net/specs/core/monitor-3.2.html[monitor]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://ircv3.net/specs/extensions/multi-prefix-3.1.html[multi-prefix] v3.1
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- Automatically included in <<ChannelState>>
-
- | https://ircv3.net/specs/extensions/sasl-3.1.html[SASL] v3.1
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- See <<SASL configuration>>
-
- | https://ircv3.net/specs/extensions/sasl-3.2.html[SASL] v3.2
- | {set:cellbgcolor:#eeeeaa} Partial support
- | {set:cellbgcolor!}
- Notifications via `cap-notify` not yet supported. See <<SASL configuration>>
-
- | https://ircv3.net/specs/extensions/server-time-3.2.html[server-time] v3.2
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- Exposed in the metadata property of <<Events>>
-
- | https://ircv3.net/specs/extensions/sts.html[sts]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://ircv3.net/specs/extensions/userhost-in-names-3.2.html[userhost-in-names] v3.2
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- Automatically included in <<UserState>>
-
- | https://ircv3.net/specs/extensions/webirc.html[webirc]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- 3+h| Draft specifications
-
- | https://github.com/ircv3/ircv3-specifications/pull/363[brb]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://github.com/ircv3/ircv3-specifications/pull/308[channel renaming]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://github.com/ircv3/ircv3-specifications/pull/349[chathistory]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://github.com/ircv3/ircv3-specifications/pull/346[delivered]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://github.com/ircv3/ircv3-specifications/pull/304[editmsg]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://ircv3.net/specs/extensions/labeled-response.html[labeled-response]
- | {set:cellbgcolor:#a7eeaa} Supported
- | {set:cellbgcolor!}
- Exposed in the metadata property of <<Events>>
-
- | https://ircv3.net/specs/extensions/message-ids.html[message-ids]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://github.com/ircv3/ircv3-specifications/pull/330[migrate]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://ircv3.net/specs/client-tags/react.html[react]
- | {set:cellbgcolor:#eeeeaa} Partial support
- | {set:cellbgcolor!}
- Sending via <<React>> method, no events generated
-
- | https://github.com/ircv3/ircv3-specifications/pull/347[read]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://github.com/ircv3/ircv3-specifications/pull/276[register]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://ircv3.net/specs/client-tags/reply.html[reply]
- | {set:cellbgcolor:#eeeeaa} Partial support
- | {set:cellbgcolor!}
- Sending via <<Reply>> method, not processed on incoming messages
-
- | https://github.com/ircv3/ircv3-specifications/pull/306[resume]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://github.com/ircv3/ircv3-specifications/pull/361[setname]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://github.com/ircv3/ircv3-specifications/pull/357[standard replies]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- | https://github.com/ircv3/ircv3-specifications/pull/348[typing]
- | {set:cellbgcolor:#f7d5d3} No support
- | {set:cellbgcolor!}
-
- 3+h|Vendor specifications
-
- |===
|