From 7c53ab861ee8223aebe5a9731ca580b8bf778809 Mon Sep 17 00:00:00 2001 From: Aaron Weiss Date: Tue, 30 Jan 2018 01:27:23 +0100 Subject: [PATCH 01/16] Changed README to reflect a more concrete name. --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3747810..e51a3a9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# irc [![Build Status][ci-badge]][ci] [![Crates.io][cr-badge]][cr] [![Docs][doc-badge]][doc] [![Built with Spacemacs][bws]][sm] +# the irc crate [![Build Status][ci-badge]][ci] [![Crates.io][cr-badge]][cr] [![Docs][doc-badge]][doc] [![Built with Spacemacs][bws]][sm] [ci-badge]: https://travis-ci.org/aatxe/irc.svg?branch=stable [ci]: https://travis-ci.org/aatxe/irc @@ -33,7 +33,7 @@ use irc::client::prelude::*; fn main() { let cfg = Config { - nickname: Some(format!("irc-rs")), + nickname: Some(format!("the-irc-crate")), client: Some(format!("irc.example.com")), channels: Some(vec![format!("#test")]), .. Default::default() @@ -71,7 +71,7 @@ fn main() { ## Configuration ## -Like the rest of the IRC crate, configuration is built with flexibility in mind. You can easily +Like the rest of the irc crate, configuration is built with flexibility in mind. You can easily create `Config` objects programmatically and choose your own methods for handling any saving or loading of configuration required. However, for convenience, we've also included the option of loading files with `serde` to write configurations. The default configuration format is TOML, @@ -97,7 +97,7 @@ cert_path = "cert.der" encoding = "UTF-8" channels = ["#rust", "#haskell", "#fake"] umodes = "+RB-x" -user_info = "I'm a test user for the Rust IRC crate." +user_info = "I'm a test user for the irc crate." version = "irc:git:Rust" source = "https://github.com/aatxe/irc" ping_time = 180 From e28b68abf687cf7d0f724256046a6749b59cad18 Mon Sep 17 00:00:00 2001 From: Aaron Weiss Date: Tue, 30 Jan 2018 03:10:05 +0100 Subject: [PATCH 02/16] Wrote up a new README and added it to the travis tests. --- .travis.yml | 7 +-- README.md | 132 +++++++++++++++++++++++++++++++--------------------- 2 files changed, 82 insertions(+), 57 deletions(-) diff --git a/.travis.yml b/.travis.yml index 598bcf1..d50d01c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,13 @@ -env: - global: - - secure: aGzqk53//ZQmZ/7Eb8XtlUG3bmwmR5p+RCSqUEz0xUazsYAO0/NRYgEkebXpggvjQCaJFsWWNxfSq5+3bVa43boIChKzshkrqIvF6sO5RxMslNQbb4rabo4GadJYMMFmoG/3h1EwFk3pEsAorNC/M6VVuH9XLKD5dWgvefMqclc= language: rust rust: stable sudo: false script: - chmod +x mktestconfig.sh - ./mktestconfig.sh - - cargo build --verbose --features "toml yaml" + - cargo build --verbose + - rustdoc --test README.md -L target/debug/deps - cargo test --verbose --features "toml yaml" - cargo test --doc - - cargo build --verbose --no-default-features - cargo test --verbose --no-default-features notifications: email: false diff --git a/README.md b/README.md index e51a3a9..3f07d2e 100644 --- a/README.md +++ b/README.md @@ -9,78 +9,105 @@ [bws]: https://cdn.rawgit.com/syl20bnr/spacemacs/442d025779da2f62fc86c2082703697714db6514/assets/spacemacs-badge.svg [sm]: http://spacemacs.org -A robust, thread-safe and async-friendly library for IRC clients in Rust. It's compliant with -[RFC 2812](http://tools.ietf.org/html/rfc2812), [IRCv3.1](http://ircv3.net/irc/3.1.html), -[IRCv3.2](http://ircv3.net/irc/3.2.html), and includes some additional, common features. It also -includes a number of useful built-in features to faciliate rapid development of clients. You can -find up-to-date, ready-to-use documentation online [here](https://docs.rs/irc/). The -documentation is generated with the default features. These are, however, strictly optional and -can be disabled accordingly. +[rfc2812]: http://tools.ietf.org/html/rfc2812 +[ircv3.1]: http://ircv3.net/irc/3.1.html +[ircv3.2]: http://ircv3.net/irc/3.2.html + +"the irc crate" is a thread-safe and async-friendly IRC client library written in Rust. It's +compliant with [RFC 2812][rfc2812], [IRCv3.1][ircv3.1], [IRCv3.2][ircv3.2], and includes some +additional, common features from popular IRCds. You can find up-to-date, ready-to-use documentation +online [on docs.rs][doc]. ## Getting Started ## -To start using this library with cargo, you can simply add `irc = "0.13"` to your dependencies in -your Cargo.toml file. You'll likely want to take a look at some of the examples, as well as the -documentation. You'll also be able to find below a small template to get a feel for the library. +To start using the irc crate with cargo, you can simply add `irc = "0.13"` to your dependencies in +your Cargo.toml file. The high-level API can be found `irc::client::prelude` linked to from the +[doc root][doc]. You'll find a number of examples in `examples/`, throughout the documentation, and +below. -## Getting Started by Example ## +## A Tale of Two APIs ## -```rust +### Reactors (The "New" API) ### + +The release of v0.13 brought with it a new API called `IrcReactor` that enables easier multiserver +support and more graceful error handling. The general model is that you use the reactor to create +new `IrcClients`, register message handler functions, and finally block the thread to run the +clients with their respective handlers. Here's an example: + +```rust,no_run +extern crate irc; + +use irc::client::prelude::*; + +fn main() { + // We can also load the Config at runtime via Config::load("path/to/config.toml") + let config = Config { + nickname: Some("the-irc-crate".to_owned()), + server: Some("irc.pdgn.co".to_owned()), + channels: Some(vec!["#test".to_owned()]), + ..Config::default() + }; + + let mut reactor = IrcReactor::new().unwrap(); + let client = reactor.prepare_client_and_connect(&config).unwrap(); + client.identify().unwrap(); + + reactor.register_client_with_handler(client, |client, message| { + print!("{}", message); + // And here we can do whatever we want with the messages. + Ok(()) + }); + + reactor.run().unwrap(); +} +``` + + +### Direct Style (The "Old" API) ### + +The old API for connecting to an IRC server is still supported through the `IrcClient` type. It's +simpler for the most basic use case, but will panic upon encountering any sort of connection issues. +In general, it's recommended that users switch to the new API if possible. Nevertheless, here is an +example: + +```rust,no_run extern crate irc; use std::default::Default; use irc::client::prelude::*; fn main() { + // We can also load the Config at runtime via Config::load("path/to/config.toml") let cfg = Config { nickname: Some(format!("the-irc-crate")), - client: Some(format!("irc.example.com")), + server: Some(format!("irc.example.com")), channels: Some(vec![format!("#test")]), .. Default::default() }; + let client = IrcClient::from_config(cfg).unwrap(); client.identify().unwrap(); + client.for_each_incoming(|message| { - // Do message processing. + print!("{}", message); + // And here we can do whatever we want with the messages. }).unwrap() } ``` -It may not seem like much, but all it takes to get started with an IRC connection is the stub -above. In just a few lines, you can be connected to a server and processing IRC messages as you -wish. The library is built with flexibility in mind. If you need to work on multiple threads, -simply clone the server and have at it. We'll take care of the rest. +## Configuring IRC Clients ## -You'll probably find that programmatic configuration is a bit of a chore, and you'll often want to -be able to change the configuration between runs of the program (for example, to change the server -that you're connecting to). Fortunately, runtime configuration loading is straightforward. +As seen above, there are two techniques for configuring the irc crate: runtime loading and +programmatic configuration. Runtime loading is done via the function `Config::load`, and is likely +sufficient for most IRC bots. Programmatic configuration is convenient for writing tests, but can +also be useful when defining your own custom configuration format that can be converted to `Config`. +The primary configuration format is TOML, but if you are so inclined, you can use JSON and/or YAML +via the optional `json` and `yaml` features respectively. At the minimum, a configuration requires +`nickname` and `server` to be defined, and all other fields are optional. You can find detailed +explanations of the various fields on +[docs.rs](https://docs.rs/irc/0.13.2/irc/client/data/config/struct.Config.html#fields). -```rust -extern crate irc; - -use irc::client::prelude::*; - -fn main() { - let client = IrcClient::new("config.toml").unwrap(); - client.identify().unwrap(); - client.for_each_incoming(|message| { - // Do message processing. - }).unwrap() -} -``` - -## Configuration ## - -Like the rest of the irc crate, configuration is built with flexibility in mind. You can easily -create `Config` objects programmatically and choose your own methods for handling any saving or -loading of configuration required. However, for convenience, we've also included the option of -loading files with `serde` to write configurations. The default configuration format is TOML, -though there is optional support for JSON and YAML via the optional `json` and `yaml` features. All -the configuration fields are optional, and can thus be omitted, but a working configuration requires -at least a `server` and `nickname`. You can find detailed explanations of the configuration format -[here](https://docs.rs/irc/0.12.8/irc/client/data/config/struct.Config.html#fields). - -Here's an example of a complete configuration in TOML: +Alternatively, you can look at the example below of a TOML configuration with all the fields: ```toml owners = [] @@ -118,7 +145,7 @@ key = "value" You can convert between different configuration formats with `convertconf` like so: -``` +```shell cargo run --example convertconf -- -i client_config.json -o client_config.toml ``` @@ -126,7 +153,8 @@ Note that the formats are automatically determined based on the selected file ex tool should make it easy for users to migrate their old configurations to TOML. ## Contributing ## -Contributions to this library would be immensely appreciated. Prior to version 0.12.0, this -library was public domain. As of 0.12.0, this library is offered under the Mozilla Public License -2.0 whose text can be found in `LICENSE.md`. Fostering an inclusive community around `irc` is -important, and to that end, we've adopted an explicit Code of Conduct found in `CODE_OF_CONDUCT.md`. +the irc crate is an free, open source library that relies on contributions from its maintainers, +Aaron Weiss (@aatxe) and Peter Atashian (@retep998), as well as the broader Rust community. It's +licensed under the Mozilla Public License 2.0 whose text can be found in `LICENSE.md`. To foster an +inclusive community around the irc crate, we have adopted a Code of Conduct whose text can be found +in `CODE_OF_CONDUCT.md`. From 9f684161be34189a1d8c3ed51d1ddde30391119f Mon Sep 17 00:00:00 2001 From: Aaron Weiss Date: Tue, 30 Jan 2018 03:12:19 +0100 Subject: [PATCH 03/16] Added links to @aatxe and @retep998 GitHub profiles. --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3f07d2e..ab31cf6 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,10 @@ tool should make it easy for users to migrate their old configurations to TOML. ## Contributing ## the irc crate is an free, open source library that relies on contributions from its maintainers, -Aaron Weiss (@aatxe) and Peter Atashian (@retep998), as well as the broader Rust community. It's -licensed under the Mozilla Public License 2.0 whose text can be found in `LICENSE.md`. To foster an -inclusive community around the irc crate, we have adopted a Code of Conduct whose text can be found -in `CODE_OF_CONDUCT.md`. +Aaron Weiss ([@aatxe][awe]) and Peter Atashian ([@retep998][bun]), as well as the broader Rust +community. It's licensed under the Mozilla Public License 2.0 whose text can be found in +`LICENSE.md`. To foster an inclusive community around the irc crate, we have adopted a Code of +Conduct whose text can be found in `CODE_OF_CONDUCT.md`. + +[awe]: https://github.com/aatxe/ +[bun]: https://github.com/retep998/ From dfae4b4f4522da8b5f774fc410fc7444fa62578a Mon Sep 17 00:00:00 2001 From: Aaron Weiss Date: Tue, 30 Jan 2018 03:16:55 +0100 Subject: [PATCH 04/16] Added a cargo clean before the first cargo build (to ensure only one copy of irc for doc tests). --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d50d01c..1621827 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ sudo: false script: - chmod +x mktestconfig.sh - ./mktestconfig.sh + - cargo clean - cargo build --verbose - rustdoc --test README.md -L target/debug/deps - cargo test --verbose --features "toml yaml" From 8609815f9986bcd8697a56b8df6e505cd5fb01cf Mon Sep 17 00:00:00 2001 From: Aaron Weiss Date: Tue, 30 Jan 2018 03:21:47 +0100 Subject: [PATCH 05/16] Changed rustdoc --test to specify explicit libirc to use. --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1621827..be06bf3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,8 @@ sudo: false script: - chmod +x mktestconfig.sh - ./mktestconfig.sh - - cargo clean - cargo build --verbose - - rustdoc --test README.md -L target/debug/deps + - rustdoc --test README.md --extern irc=target/debug/libirc.rlib -L target/debug/deps - cargo test --verbose --features "toml yaml" - cargo test --doc - cargo test --verbose --no-default-features From b29147623b1e68a6e772e3a4f867c9fa2220e2d2 Mon Sep 17 00:00:00 2001 From: Aaron Weiss Date: Tue, 30 Jan 2018 03:41:36 +0100 Subject: [PATCH 06/16] Added some examples of software written with the irc crate to the README. --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index ab31cf6..e491a59 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,24 @@ compliant with [RFC 2812][rfc2812], [IRCv3.1][ircv3.1], [IRCv3.2][ircv3.2], and additional, common features from popular IRCds. You can find up-to-date, ready-to-use documentation online [on docs.rs][doc]. +## Built with the irc crate ## + +the irc crate is being used to build new IRC software in Rust. Here are some of our favorite +projects: + +- [alectro][alectro] — a terminal IRC client +- [spilo][spilo] — a minimalistic IRC bouncer +- [irc-bot.rs][ircbot] — a library for writing IRC bots +- [bunnybutt-rs][bunnybutt] — an IRC bot for the [Feed The Beast Wiki][ftb-wiki] + +[alectro]: https://github.com/aatxe/alectro +[spilo]: https://github.com/aatxe/spilo +[ircbot]: https://github.com/8573/irc-bot.rs +[bunnybutt]: https://github.com/FTB-Gamepedia/bunnybutt-rs +[ftb-wiki]: https://ftb.gamepedia.com/FTB_Wiki + +Making your own project? [Submit a pull request](https://github.com/aatxe/irc/pulls) to add it! + ## Getting Started ## To start using the irc crate with cargo, you can simply add `irc = "0.13"` to your dependencies in From 31f8c692b6ee89839cd6b41e01298fbbafd5cefd Mon Sep 17 00:00:00 2001 From: Aaron Weiss Date: Wed, 7 Feb 2018 12:08:59 +0100 Subject: [PATCH 07/16] Added some more information to the response docs, and some extra common response codes. --- src/proto/response.rs | 382 ++++++++++++++++++++++++------------------ 1 file changed, 215 insertions(+), 167 deletions(-) diff --git a/src/proto/response.rs b/src/proto/response.rs index c729361..8fc7019 100644 --- a/src/proto/response.rs +++ b/src/proto/response.rs @@ -3,14 +3,16 @@ use std::str::FromStr; macro_rules! make_response { - ($(#[$attr:meta] $variant:ident = $value:expr),+) => { + ($($(#[$attr:meta])+ $variant:ident = $value:expr),+) => { /// List of all server responses as defined in - /// [RFC 2812](http://tools.ietf.org/html/rfc2812). - /// All commands are documented with their expected form from the RFC. + /// [RFC 2812](http://tools.ietf.org/html/rfc2812) and + /// [Modern docs](https://modern.ircdocs.horse/#numerics) (henceforth referred to as + /// Modern). All commands are documented with their expected form from the RFC, and any + /// useful, additional information about the response code. #[derive(Clone, Copy, Debug, PartialEq)] #[repr(u16)] pub enum Response { - $(#[$attr] $variant = $value),+ + $($(#[$attr])+ $variant = $value),+ } impl Response { @@ -27,334 +29,380 @@ macro_rules! make_response { make_response! { // Expected replies - /// `001 Welcome to the Internet Relay Network !@` + /// `001 Welcome to the Internet Relay Network !@` (Source: RFC2812) RPL_WELCOME = 1, - /// `002 Your host is , running version ` + /// `002 Your host is , running version ` (Source: RFC2812) RPL_YOURHOST = 2, - /// `003 This server was created ` + /// `003 This server was created ` (Source: RFC2812) RPL_CREATED = 3, - /// `004 available channel modes>` + /// `004 ` (Source: + /// RFC2812) + /// + /// Various IRCds may choose to include additional arguments to `RPL_MYINFO`, and it's best to + /// check for certain what the servers you're targeting do. Typically, there are additional + /// parameters at the end for modes that have parameters, and server modes. RPL_MYINFO = 4, - /// `005 *((=)) :are supported by this server` + /// `005 *((=)) :are supported by this server` (Source: Modern) + /// + /// [RPL_ISUPPORT](https://modern.ircdocs.horse/#rplisupport-005) replaces RPL_BOUNCE from + /// RFC2812, but does so consistently in modern IRCd implementations. RPL_BOUNCE has been moved + /// to `010`. RPL_ISUPPORT = 5, - /// `010 Try server , port ` + /// `010 Try server , port ` (Source: Modern) RPL_BOUNCE = 10, - /// `302 :*1 *( " " )` + /// Undefined format. (Source: Modern) + /// + /// RPL_NONE is a dummy numeric. It does not have a defined use nor format. + RPL_NONE = 300, + /// `302 :*1 *( " " )` (Source: RFC2812) RPL_USERHOST = 302, - /// `303 :*1 *( " " )` + /// `303 :*1 *( " " )` (Source: RFC2812) RPL_ISON = 303, - /// `301 :` + /// `301 :` (Source: RFC2812) RPL_AWAY = 301, - /// `305 :You are no longer marked as being away` + /// `305 :You are no longer marked as being away` (Source: RFC2812) RPL_UNAWAY = 305, - /// `306 :You have been marked as being away` + /// `306 :You have been marked as being away` (Source: RFC2812) RPL_NOWAWAY = 306, - /// `311 * :` + /// `311 * :` (Source: RFC2812) RPL_WHOISUSER = 311, - /// `312 :` + /// `312 :` (Source: RFC2812) RPL_WHOISSERVER = 312, - /// `313 :is an IRC operator` + /// `313 :is an IRC operator` (Source: RFC2812) RPL_WHOISOPERATOR = 313, - /// `317 :seconds idle` + /// `317 :seconds idle` (Source: RFC2812) RPL_WHOISIDLE = 317, - /// `318 :End of WHOIS list` + /// `318 :End of WHOIS list` (Source: RFC2812) RPL_ENDOFWHOIS = 318, - /// `319 :*( ( "@" / "+" ) " " )` + /// `319 :*( ( "@" / "+" ) " " )` (Source: RFC2812) RPL_WHOISCHANNELS = 319, - /// `314 * :` + /// `314 * :` (Source: RFC2812) RPL_WHOWASUSER = 314, - /// `369 :End of WHOWAS` + /// `369 :End of WHOWAS` (Source: RFC2812) RPL_ENDOFWHOWAS = 369, - /// Obsolete. Not used. + /// Obsolete. Not used. (Source: RFC2812) RPL_LISTSTART = 321, - /// `322 <# visible> :` + /// `322 <# visible> :` (Source: RFC2812) RPL_LIST = 322, - /// `323 :End of LIST + /// `323 :End of LIST (Source: RFC2812) RPL_LISTEND = 323, - /// `325 ` + /// `325 ` (Source: RFC2812) RPL_UNIQOPIS = 325, - /// `324 ` + /// `324 ` (Source: RFC2812) RPL_CHANNELMODEIS = 324, - /// `331 :No topic is set` + /// `331 :No topic is set` (Source: RFC2812) RPL_NOTOPIC = 331, - /// `332 :` + /// `332 :` (Source: RFC2812) RPL_TOPIC = 332, - /// `333 !@ ` + /// `333 !@ ` (Source: RFC2812) RPL_TOPICWHOTIME = 333, - /// `341 ` + /// `341 ` (Source: RFC2812) RPL_INVITING = 341, - /// `342 :Summoning user to IRC` + /// `342 :Summoning user to IRC` (Source: RFC2812) + /// + /// According to Modern, this response is rarely implemented. In practice, people simply message + /// one another in a channel with their specified username in the message, rather than use the + /// `SUMMON` command. RPL_SUMMONING = 342, - /// `346 ` + /// `346 ` (Source: RFC2812) RPL_INVITELIST = 346, - /// `347 :End of channel invite list` + /// `347 :End of channel invite list` (Source: RFC2812) + /// + /// According to Modern, `RPL_ENDOFEXCEPTLIST` (349) is frequently deployed for this same + /// purpose and the difference will be noted in channel mode and the statement in the suffix. RPL_ENDOFINVITELIST = 347, - /// `348 ` + /// `348 ` (Source: RFC2812) RPL_EXCEPTLIST = 348, - /// `349 :End of channel exception list` + /// `349 :End of channel exception list` (Source: RFC2812) RPL_ENDOFEXCEPTLIST = 349, - /// `351 . :` + /// `351 :` (Source: RFC2812/Modern) RPL_VERSION = 351, - /** `352 ( "H" / "G" > ["*"] [ ( "@" / "+" ) ] - : ` **/ + /// `352 ( "H" / "G" > ["*"] [ ( "@" / "+" ) ] + /// : ` (Source: RFC2812) RPL_WHOREPLY = 352, - /// `315 :End of WHO list` + /// `315 :End of WHO list` (Source: RFC2812) RPL_ENDOFWHO = 315, /// `353 ( "=" / "*" / "@" ) :[ "@" / "+" ] *( " " [ "@" / "+" ] )` + /// (Source: RFC2812) RPL_NAMREPLY = 353, - /// `366 :End of NAMES list` + /// `366 :End of NAMES list` (Source: RFC2812) RPL_ENDOFNAMES = 366, - /// `364 : ` + /// `364 : ` (Source: RFC2812) RPL_LINKS = 364, - /// `365 :End of LINKS list` + /// `365 :End of LINKS list` (Source: RFC2812) RPL_ENDOFLINKS = 365, - /// `367 ` + /// `367 ` (Source: RFC2812) RPL_BANLIST = 367, - /// `368 :End of channel ban list` + /// `368 :End of channel ban list` (Source: RFC2812) RPL_ENDOFBANLIST = 368, - /// `371 :` + /// `371 :` (Source: RFC2812) RPL_INFO = 371, - /// `374 :End of INFO list` + /// `374 :End of INFO list` (Source: RFC2812) RPL_ENDOFINFO = 374, - /// `375 :- Message of the day -` + /// `375 :- Message of the day -` (Source: RFC2812) RPL_MOTDSTART = 375, - /// `372 :- ` + /// `372 :- ` (Source: RFC2812) RPL_MOTD = 372, - /// `376 :End of MOTD command` + /// `376 :End of MOTD command` (Source: RFC2812) RPL_ENDOFMOTD = 376, - /// `381 :You are now an IRC operator` + /// `381 :You are now an IRC operator` (Source: RFC2812) RPL_YOUREOPER = 381, - /// `382 :Rehashing` + /// `382 :Rehashing` (Source: RFC2812) RPL_REHASHING = 382, - /// `383 You are service ` + /// `383 You are service ` (Source: RFC2812) RPL_YOURESERVICE = 383, - /// `391 :` + /// `391 :` (Source: RFC2812) RPL_TIME = 391, - /// `392 :UserID Terminal Host` + /// `392 :UserID Terminal Host` (Source: RFC2812) RPL_USERSSTART = 392, - /// `393 : ` + /// `393 : ` (Source: RFC2812) RPL_USERS = 393, - /// `394 :End of users` + /// `394 :End of users` (Source: RFC2812) RPL_ENDOFUSERS = 394, - /// `395 :Nobody logged in` + /// `395 :Nobody logged in` (Source: RFC2812) RPL_NOUSERS = 395, - /** `200 Link V - ` **/ + /// `396 :is now your displayed host` (Source: InspIRCd) + /// + /// This response code is sent after a user enables the user mode +x (host masking), and it is + /// successfully enabled. The particular format described above is from InspIRCd, but the + /// response code should be common amongst servers that support host masks. + RPL_HOSTHIDDEN = 396, + /// `200 Link V + /// ` (Source: RFC2812) RPL_TRACELINK = 200, - /// `201 Try. ` + /// `201 Try. ` (Source: RFC2812) RPL_TRACECONNECTING = 201, - /// `202 H.S. ` + /// `202 H.S. ` (Source: RFC2812) RPL_TRACEHANDSHAKE = 202, - /// `203 ???? []` + /// `203 ???? []` (Source: RFC2812) RPL_TRACEUKNOWN = 203, - /// `204 Oper ` + /// `204 Oper ` (Source: RFC2812) RPL_TRACEOPERATOR = 204, - /// `205 User ` + /// `205 User ` (Source: RFC2812) RPL_TRACEUSER = 205, /// `206 Serv S C @ V` + /// (Source: RFC2812) RPL_TRACESERVER = 206, - /// `207 Service ` + /// `207 Service ` (Source: RFC2812) RPL_TRACESERVICE = 207, - /// `208 0 ` + /// `208 0 ` (Source: RFC2812) RPL_TRACENEWTYPE = 208, - /// `209 Class ` + /// `209 Class ` (Source: RFC2812) RPL_TRACECLASS = 209, - /// Unused. + /// Unused. (Source: RFC2812) RPL_TRACERECONNECT = 210, - /// `261 File ` + /// `261 File ` (Source: RFC2812) RPL_TRACELOG = 261, - /// `262 :End of TRACE` + /// `262 :End of TRACE` (Source: RFC2812) RPL_TRACEEND = 262, - /** `211 -