1 /++ 2 Definitions of struct aggregates used throughout the library, representing 3 [IRCEvent]s and thereto related objects like [IRCServer] and [IRCUser]. 4 5 Things related to actually parsing IRC do not belong here; what's here 6 should only be applicable to be used as a header. 7 8 The only lu dependency should be [lu.uda]. 9 +/ 10 module dialect.defs; 11 12 private: 13 14 import lu.uda; 15 16 public: 17 18 final: 19 pure: 20 nothrow: 21 @nogc: 22 23 24 // IRCEvent 25 /++ 26 A single IRC event, parsed from server input. 27 28 The [IRCEvent] struct is a construct with fields extracted from raw server 29 strings. Since structs are not polymorphic the [IRCEvent.Type|Type] enum 30 dictates what kind of event it is. 31 +/ 32 struct IRCEvent 33 { 34 private: 35 import std.typecons : Nullable; 36 37 /++ 38 How many elements should be allocated for auxiliary strings. 39 40 `RPL_ISUPPORT` can contain a lot of strings and should be considered the 41 worst case. 42 +/ 43 enum numAuxStrings = 16; 44 45 /++ 46 How many elements should be allocated for counts. 47 +/ 48 enum numCounts = 16; 49 50 public: 51 /++ 52 [Type]s of [IRCEvent]s. 53 54 Taken from https://tools.ietf.org/html/rfc1459 with many additions. 55 56 Some are outright fabrications of ours, like [Type.CHAN|CHAN] and 57 [Type.QUERY|QUERY]. These are not prefixed with `RPL_` and `ERR_` 58 (but not all such are made up, like [Type.AWAY|AWAY] and 59 [Type.CHGHOST|CHGHOST] that are properly [Type.AWAY|AWAY] and 60 [Type.CHGHOST|CHGHOST]). 61 62 See_Also: 63 https://tools.ietf.org/html/rfc1459 64 https://www.alien.net.au/irc/irc2numerics.html 65 https://defs.ircdocs.horse 66 +/ 67 enum Type 68 { 69 UNSET, /// Invalid [IRCEvent] with no [Type]. 70 ANY, /// Meta-[Type] for *any* kind of [IRCEvent]. 71 ERROR, /// Generic error [Type]. 72 NUMERIC, /// *Numeric* event of an unknown [Type]. 73 PRIVMSG, /// Private message or channel message. 74 CHAN, /// Channel message. 75 QUERY, /// Private query message. 76 EMOTE, /// CTCP **ACTION**; `/me slaps Foo with a large trout`. 77 SELFQUERY, /// A message from you in a query (CAP `znc.in/self-message`). 78 SELFCHAN, /// A message from you in a channel (CAP `znc.in/self-message`). 79 SELFEMOTE, /// A CTCP ACTION from you. (Twitch etc) 80 AWAY, /// Someone flagged themselves as away (from keyboard). 81 BACK, /// Someone returned from `AWAY`. 82 JOIN, /// Someone joined a channel. 83 PART, /// Someone left a channel. 84 QUIT, /// Someone quit the server. 85 KICK, /// Someone was kicked from a channel. 86 INVITE, /// You were invited to a channel. 87 NOTICE, /// A server `NOTICE` event. 88 PING, /// The server periodically `PING`ed you. 89 PONG, /// The server actually `PONG`ed you. 90 NICK, /// Someone changed nickname. 91 MODE, /// Someone changed the modes of a channel. 92 SELFQUIT, /// You quit the server. 93 SELFJOIN, /// You joined a channel. 94 SELFPART, /// You left a channel. 95 SELFMODE, /// You changed your modes. 96 SELFNICK, /// You changed your nickname. 97 SELFKICK, /// You were kicked. 98 TOPIC, /// Someone changed channel topic. 99 CAP, /// CAPability exchange during connect. 100 CTCP_VERSION,/// Something requested your version info. 101 CTCP_TIME, /// Something requested your time. 102 CTCP_PING, /// Something pinged you. 103 CTCP_CLIENTINFO,/// Something asked what CTCP events the client can handle. 104 CTCP_DCC, /// Something requested a DCC connection (chat, file transfer). 105 CTCP_SOURCE,/// Something requested an URL to the client source code. 106 CTCP_USERINFO,/// Something requested the nickname and user of the client. 107 CTCP_FINGER,/// Someone requested miscellaneous info about the client. 108 CTCP_LAG, /// Something requested LAG info? 109 CTCP_AVATAR,/// Someone requested an avatar image. 110 CTCP_SLOTS, /// Someone broadcast their file transfer slots. 111 ACCOUNT, /// Someone logged in on nickname services. 112 WALLOPS, /// "WALLOPS messages are for broadcasting network information and its status to following users." 113 SASL_AUTHENTICATE,/// SASL authentication negotiation. 114 AUTH_CHALLENGE, /// Authentication challenge. 115 AUTH_FAILURE, /// Authentication failure. 116 AUTH_SUCCESS, /// Authentication success. 117 CHGHOST, /// User "changes host", which is a thing on some networks. 118 CHANNELFORBIDDEN, // = 926, // <nickname> <channel> :Channel <channel> is forbidden: This channel is closed by request of the channel operators. 119 BOTSNOTWELCOME, // = 931, // <nickname> :Malicious bot, spammers, and other automated systems of dubious origins are NOT welcome here. 120 ENDOFSPAMFILTERLIST,// = 940, // <nickname> <channel> :End of channel spamfilter list 121 SPAMFILTERLIST, // = 941, 122 NICKUNLOCKED, // = 945, 123 NICKNOTLOCKED, // = 946, 124 ENDOFEXEMPTOPSLIST,// = 953 // End of exempt channel ops list. 125 MODELIST, // = 961 /// +noctcp +nickflood 5:60 +nonotice +flood 30:5 +joinflood 5:1 +noextmsg +topiclock +globalflood 10:5 126 ENDOFMODELIST, // = 960 // End of mode list. 127 ENDOFCHANNELACCLIST, // = 911 // End of Channel Access List 128 THISSERVERINSTEAD,// = 010 // <nickname> <new server> +<port> :Please use this Server/Port instead$ 129 130 // Twitch specifics 131 USERSTATE, /// Twitch user information. 132 ROOMSTATE, /// Twitch channel information. 133 GLOBALUSERSTATE, /// Twitch information about self upon login. 134 CLEARCHAT, /// Twitch `CLEARCHAT` event, clearing the chat or banning a user. 135 CLEARMSG, /// Twitch `CLEARMSG` event, deletes a sent message. 136 USERNOTICE, /// Twitch subscription or resubscription event. 137 RECONNECT, /// Twitch `RECONNECT` event; Twitch IRC processes restarting. 138 WHISPER, /// Twitch private query message. 139 TWITCH_NOTICE, /// Twitch generic server notice, see `event.aux`. 140 TWITCH_ERROR, /// Twitch generic error, see `event.aux`. 141 TWITCH_TIMEOUT, /// Twitch temporary ban (seconds in `count`). 142 TWITCH_BAN, /// Twitch permanent ban. 143 TWITCH_SUB, /// Twitch subscription event, including resubs. 144 TWITCH_CHEER, /// Twitch "bits" donation. 145 TWITCH_SUBGIFT, /// Twitch subscription gift event. 146 TWITCH_BITSBADGETIER, /// Twitch event, unsure of its meaning. 147 TWITCH_RAID, /// Twitch raid. 148 TWITCH_UNRAID, /// End of a Twitch raid. 149 TWITCH_RITUAL, /// Twitch Ritual event. 150 TWITCH_REWARDGIFT,/// Twitch "reward gift". 151 TWITCH_GIFTCHAIN, /// Twitch "continuing the gift sub" 152 TWITCH_SUBUPGRADE,/// Twitch, someone paying to upgrade their subscription. 153 TWITCH_CHARITY, /// Twitch charity donation. 154 TWITCH_BULKGIFT, /// Twitch no-target multiple gift event. 155 TWITCH_EXTENDSUB, /// Twitch sub extension. 156 TWITCH_GIFTRECEIVED , /// Twitch Prime community gift received. 157 TWITCH_PAYFORWARD,/// Twitch paying forward of gifts. 158 TWITCH_CROWDCHANT,/// Twitch message with some emotes. 159 TWITCH_ANNOUNCEMENT, /// Twitch channel announcement. 160 TWITCH_DIRECTCHEER, /// Twitch direct cheer with real currency. 161 TWITCH_INTRO, /// Twitch, someone introducing themselves in a channel. 162 163 RPL_WELCOME, // = 001, // ":Welcome to <server name> <user>" 164 RPL_YOURHOST, // = 002, // ":Your host is <servername>, running version <version>" 165 RPL_CREATED, // = 003, // ":This server was created <date>" 166 RPL_MYINFO, // = 004, // "<server_name> <version> <user_modes> <chan_modes>" 167 RPL_BOUNCE, // = 005, // CONFLICT ":Try server <server_name>, port <port_number>" 168 RPL_ISUPPORT, // = 005, // (server information, different syntax) 169 RPL_MAP, // = 006, 170 RPL_MAPEND, // = 007, 171 RPL_SNOMASK, // = 008, // Server notice mask (hex) 172 RPL_STATMEMTOT, // = 009, 173 //RPL_BOUNCE, // = 010, // CONFLICT "<hostname> <port> :<info>", 174 //RPL_STATMEM, // = 010, // deprecated, prefer THISSERVERINSTEAD 175 RPL_YOURCOOKIE, // = 014, 176 //RPL_MAP, // = 015, 177 RPL_MAPMORE, // = 016, 178 //RPL_MAPEND, // = 017, 179 RPL_HELLO, // = 020, 180 RPL_APASSWARN_SET, // = 030, 181 RPL_APASSWARN_SECRET, // = 031, 182 RPL_APASSWARN_CLEAR, // = 032, 183 RPL_YOURID, // = 042, // <nickname> <id> :your unique ID 184 RPL_SAVENICK, // = 043, // Sent to the client when their nickname was forced to change due to a collision 185 RPL_ATTEMPTINGJUNC, // = 050, 186 RPL_ATTEMPTINGREROUTE, // = 051, 187 188 RPL_REMOTEISUPPORT, // 105, 189 190 RPL_TRACELINK, // = 200, // "Link <version & debug level> <destination> <next server>" 191 RPL_TRACECONNECTING, // = 201, // "Try. <class> <server>" 192 RPL_TRACEHANDSHAKE, // = 202, // "H.S. <class> <server>" 193 RPL_TRACEUNKNOWN, // = 203, // "???? <class> [<client IP address in dot form>]" 194 RPL_TRACEOPERATOR, // = 204, // "Oper <class> <nick>" 195 RPL_TRACEUSER, // = 205, // "User <class> <nick>" 196 RPL_TRACESERVER, // = 206, // "Serv <class> <int>S <int>C <server> <nick!user|*!*>@<host|server>" 197 RPL_TRACESERVICE, // = 207, // "Service <class> <name> <type> <active_type> 198 RPL_TRACENEWTYPE, // = 208, // "<newtype> 0 <client name>" 199 RPL_TRACECLASS, // = 209, // "Class <class> <count>" 200 RPL_TRACERECONNECT, // = 210, // CONFLICT 201 RPL_STATSHELP, // = 210, // CONFLICT 202 RPL_STATS, // = 210, // Used instead of having multiple stats numerics 203 RPL_STATSLINKINFO, // = 211, // "<linkname> <sendq> <sent messages> <sent bytes> <received messages> <received bytes> <time open>" 204 RPL_STATSCOMMAND, // = 212, // "<command> <count>" 205 RPL_STATSCLINE, // = 213, // "C <host> * <name> <port> <class>" 206 RPL_STATSNLINE, // = 214, // "N <host> * <name> <port> <class>" 207 RPL_STATSILINE, // = 215, // "I <host> * <host> <port> <class>" 208 RPL_STATSKLINE, // = 216, // "K <host> * <username> <port> <class>" 209 RPL_STATSPLINE, // = 217, // CONFLICT 210 RPL_STATSQLINE, // = 217, 211 RPL_STATSYLINE, // = 218 // "Y <class> <ping frequency> <connect frequency> <max sendq>" 212 RPL_ENDOFSTATS, // = 219, // "<stats letter> :End of /STATS report" 213 RPL_STATSBLINE, // = 220, // CONFLICT 214 RPL_STATSWLINE, // = 220, // CONFLICT 215 //RPL_STATSPLINE, // = 220, 216 RPL_UMODEIS, // = 221, // "<user mode string>" 217 //RPL_STATSBLINE, // = 222, // CONFLICT 218 RPL_SQLINE_NICK, // = 222, // CONFLICT 219 RPL_CODEPAGE, // = 222, // CONFLICT 220 RPL_STATSJLINE, // = 222, // CONFLICT 221 RPL_MODLIST, // = 222, 222 RPL_STATSGLINE, // = 223, // CONFLICT 223 RPL_CHARSET, // = 223, // CONFLICT 224 RPL_STATSELINE, // = 223, 225 RPL_STATSTLINE, // = 224, // CONFLICT 226 RPL_STATSFLINE, // = 224, 227 //RPL_STATSELINE, // = 225, // CONFLICT 228 RPL_STATSZLINE, // = 225, // CONFLICT 229 RPL_STATSCLONE, // = 225, // CONFLICT 230 RPL_STATSDLINE, // = 225, 231 //RPL_STATSNLINE, // = 226, // CONFLICT 232 RPL_STATSALINE, // = 226, // CONFLICT 233 RPL_STATSCOUNT, // = 226, 234 //RPL_STATSGLINE, // = 227, // CONFLICT 235 RPL_STATSVLINE, // = 227, // CONFLICT 236 //RPL_STATSBLINE, // = 227, 237 RPL_STATSBANVER, // = 228, // CONFLICT 238 //RPL_STATSQLINE, // = 228, 239 RPL_STATSSPAMF, // = 229, 240 RPL_STATSEXCEPTTKL, // = 230, 241 RPL_SERVICEINFO, // = 231, // (reserved numeric) 242 RPL_RULES, // = 232, // CONFLICT 243 RPL_ENDOFSERVICES, // = 232, // (reserved numeric) 244 RPL_SERVICE, // = 233, // (reserved numeric) 245 RPL_SERVLIST, // = 234, // (reserved numeric) 246 RPL_SERVLISTEND, // = 235, // (reserved numeric) 247 RPL_STATSVERBOSE, // = 236, // Verbose server list? 248 RPL_STATSENGINE, // = 237, // Engine name? 249 //RPL_STATSFLINE, // = 238, // Feature lines? 250 RPL_STATSIAUTH, // = 239, 251 RPL_STATSXLINE, // = 240, // CONFLICT 252 //RPL_STATSVLINE, // = 240, 253 RPL_STATSLLINE, // = 241, // "L <hostmask> * <servername> <maxdepth>" 254 RPL_STATSUPTIME, // = 242, // ":Server Up %d days %d:%02d:%02d" 255 RPL_STATSOLINE, // = 243, // "O <hostmask> * <name>" 256 RPL_STATSHLINE, // = 244, // "H <hostmask> * <servername>" 257 //RPL_STATSTLINE, // = 245, // CONFLICT 258 RPL_STATSSLINE, // = 245, 259 RPL_STATSSERVICE, // = 246, // CONFLICT 260 //RPL_STATSTLINE, // = 246, // CONFLICT 261 RPL_STATSULINE, // = 246, // CONFLICT 262 RPL_STATSPING, // = 246, 263 //RPL_STATSXLINE, // = 247, // CONFLICT 264 //RPL_STATSGLINE, // = 247, // CONFLICT 265 //RPL_STATSBLINE, // = 247, 266 RPL_STATSDEFINE, // = 248, // CONFLICT 267 //RPL_STATSULINE, // = 248, 268 RPL_STATSDEBUG, // = 249, // CONFLICT 269 //RPL_STATSULINE, // = 249, 270 //RPL_STATSDLINE, // = 250, // CONFLICT 271 RPL_STATSCONN, // = 250, 272 RPL_LUSERCLIENT, // = 251, // ":There are <integer> users and <integer> invisible on <integer> servers" 273 RPL_LUSEROP, // = 252, // "<integer> :operator(s) online" 274 RPL_LUSERUNKNOWN, // = 253, // "<integer> :unknown connection(s)" 275 RPL_LUSERCHANNELS, // = 254, // "<integer> :channels formed" 276 RPL_LUSERME, // = 255, // ":I have <integer> clients and <integer> servers" 277 RPL_ADMINME, // = 256, // "<server> :Administrative info" 278 RPL_ADMINLOC1, // = 257, // ":<admin info>" 279 RPL_ADMINLOC2, // = 258, // ":<admin info>" 280 RPL_ADMINEMAIL, // = 259, // ":<admin info>" 281 RPL_TRACELOG, // = 261, // "File <logfile> <debug level>" 282 RPL_TRACEPING, // = 262, // CONFLICT 283 RPL_TRACEEND, // = 262, // "<server_name> <version>[.<debug_level>] :<info>" 284 RPL_TRYAGAIN, // = 263, // "<command> :<info>" 285 RPL_USINGSSL, // = 264, 286 RPL_LOCALUSERS, // = 265, // Also known as RPL_CURRENT_LOCAL 287 RPL_GLOBALUSERS, // = 266, // Also known as RPL_CURRENT_GLOBAL 288 RPL_START_NETSTAT, // = 267, 289 RPL_NETSTAT, // = 268, 290 RPL_END_NETSTAT, // = 269, 291 RPL_MAPUSERS, // = 270, // CONFLICT 292 RPL_PRIVS, // = 270, 293 RPL_SILELIST, // = 271, 294 RPL_ENDOFSILELIST, // = 272, 295 RPL_NOTIFY, // = 273, 296 RPL_STATSDELTA, // = 274, // CONFLICT 297 RPL_ENDNOTIFY, // = 274, 298 //RPL_USINGSSL, // = 275, // CONFLICT 299 //RPL_STATSDLINE, // = 275, 300 RPL_VCHANEXIST, // = 276, // CONFLICT 301 RPL_WHOISCERTFP, // = 276, // CONFLICT 302 RPL_STATSRLINE, // = 276, 303 RPL_VCHANLIST, // = 277, 304 RPL_VCHANHELP, // = 278, 305 RPL_GLIST, // = 280 306 RPL_ENDOFGLIST, // = 281, // CONFLICT 307 RPL_ACCEPTLIST, // = 281, 308 RPL_JUPELIST, // = 282, // CONFLICT 309 RPL_ENDOFACCEPT, // = 282, 310 RPL_ENDOFJUPELIST, // = 283, // CONFLICT 311 RPL_ALIST, // = 283, 312 RPL_FEATURE, // = 284, // CONFLICT 313 RPL_ENDOFALIST, // = 284, 314 RPL_CHANINFO_HANDLE, // = 285, // CONFLICT 315 RPL_NEWHOSTIS, // = 285, // CONFLICT 316 RPL_GLIST_HASH, // = 285, 317 RPL_CHKHEAD, // = 286, // CONFLICT 318 RPL_CHANINFO_USERS, // = 286, 319 RPL_CHANUSER, // = 287 // CONFLICT 320 RPL_CHANINFO_CHOPS, // = 287, 321 RPL_PATCHHEAD, // = 288, // CONFLICT 322 RPL_CHANINFO_VOICES, // = 288, 323 RPL_PATCHCON, // = 289, // CONFLICT 324 RPL_CHANINFO_AWAY, // = 289, 325 RPL_CHANINFO_HELPHDR, // = 290, // CONFLICT 326 RPL_DATASTR, // = 290, // CONFLICT 327 RPL_HELPHDR, // = 290, // CONFLICT 328 RPL_CHANINFO_OPERS, // = 290, 329 RPL_ENDOFCHECK, // = 291, // CONFLICT 330 RPL_HELPOP, // = 291, // CONFLICT 331 RPL_CHANINFO_BANNED, // = 291, 332 ERR_SEARCHNOMATCH, // = 292 , // CONFLICT 333 RPL_HELPTLR, // = 292, // CONFLICT 334 RPL_CHANINFO_BANS, // = 292, 335 RPL_HELPHLP, // = 293, // CONFLICT 336 RPL_CHANINFO_INVITE, // = 293, 337 RPL_HELPFWD, // = 294, // CONFLICT 338 RPL_CHANINFO_INVITES, // = 294, 339 RPL_HELPIGN, // = 295, // CONFLICT 340 RPL_CHANINFO_KICK, // = 295, 341 RPL_CHANINFO_KICKS, // = 296, 342 RPL_END_CHANINFO, // = 299, 343 344 RPL_NONE, // = 300, // Dummy reply number. Not used. 345 RPL_AWAY, // = 301 // "<nick> :<away message>" 346 RPL_USERHOST, // = 302 // ":[<reply>{<space><reply>}]" 347 RPL_ISON, // = 303, // ":[<nick> {<space><nick>}]" 348 RPL_SYNTAX, // = 304, // CONFLICT 349 RPL_TEXT, // = 304, 350 RPL_UNAWAY, // = 305, // ":You are no longer marked as being away" 351 RPL_NOWAWAY, // = 306, // ":You have been marked as being away" 352 RPL_SUSERHOST, // = 307, // CONFLICT 353 RPL_USERIP, // = 307, // CONFLICT 354 RPL_WHOISREGNICK, // = 307 // <nickname> :has identified for this nick 355 RPL_WHOISADMIN, // = 308, // CONFLICT 356 RPL_RULESSTART, // = 308, // CONFLICT 357 RPL_NOTIFYACTION, // = 308, 358 RPL_WHOISHELPER, // = 309, // CONFLICT 359 RPL_ENDOFRULES, // = 309, // CONFLICT 360 //RPL_WHOISADMIN, // = 309, // CONFLICT 361 RPL_NICKTRACE, // = 309, 362 RPL_WHOISSERVICE, // = 310, // CONFLICT 363 RPL_WHOISHELPOP, // = 310, // CONFLICT 364 RPL_WHOISSVCMSG, // = 310, 365 RPL_WHOISUSER, // = 311, // "<nick> <user> <host> * :<real name>" 366 RPL_WHOISSERVER, // = 312, // "<nick> <server> :<server info>" 367 RPL_WHOISOPERATOR, // = 313, // "<nick> :is an IRC operator" 368 RPL_WHOWASUSER, // = 314, // "<nick> <user> <host> * :<real name>" 369 RPL_ENDOFWHO, // = 315, // "<name> :End of /WHO list" 370 RPL_WHOISPRIVDEAF, // = 316 // CONFLICT 371 RPL_WHOISCHANOP, // = 316, // (reserved numeric) 372 RPL_WHOISIDLE, // = 317, // "<nick> <integer> :seconds idle" 373 RPL_ENDOFWHOIS, // = 318, // "<nick> :End of /WHOIS list" 374 RPL_WHOISCHANNELS, // = 319, // "<nick> :{[@|+]<channel><space>}" 375 RPL_WHOISVIRT, // = 320, // CONFLICT 376 RPL_WHOIS_HIDDEN, // = 320, // CONFLICT 377 RPL_WHOISSPECIAL, // = 320, 378 RPL_LISTSTART, // = 321, // "Channel :Users Name" 379 RPL_LIST, // = 322, // "<channel> <# visible> :<topic>" 380 RPL_LISTEND, // = 323, // ":End of /LIST" 381 RPL_CHANNELMODEIS, // = 324, // "<channel> <mode> <mode params>" 382 RPL_WHOISWEBIRC, // = 325, // CONFLICT 383 RPL_CHANNELMLOCKIS, // = 325, // CONFLICT 384 RPL_UNIQOPIS, // = 325, // CONFLICT 385 RPL_CHANNELPASSIS, // = 325, 386 RPL_NOCHANPASS, // = 326, 387 //RPL_WHOISHOST, // = 327, // CONFLICT 388 RPL_CHPASSUNKNOWN, // = 327, 389 RPL_CHANNEL_URL, // = 328 // "http://linux.chat" 390 RPL_CREATIONTIME, // = 329, 391 RPL_WHOWAS_TIME, // = 330, // CONFLICT 392 RPL_WHOISACCOUNT, // = 330 // "<nickname> <account> :is logged in as" 393 RPL_NOTOPIC, // = 331, // "<channel> :No topic is set" 394 RPL_TOPIC, // = 332, // "<channel> :<topic>" 395 RPL_TOPICWHOTIME, // = 333, // "#channel user!~ident@address 1476294377" 396 RPL_COMMANDSYNTAX, // = 334, // CONFLICT 397 RPL_LISTSYNTAX, // = 334, // CONFLICT 398 RPL_LISTUSAGE, // = 334, 399 RPL_WHOISTEXT, // = 335, // CONFLICT 400 RPL_WHOISACCOUNTONLY, // = 335, // CONFLICT 401 RPL_WHOISBOT, // = 335, // "<nick> <othernick> :is a Bot on <server>" 402 //RPL_WHOISBOT, // = 336, // CONFLICT 403 RPL_INVITELIST, // = 336, 404 //RPL_WHOISTEXT, // = 337, // CONFLICT 405 RPL_ENDOFINVITELIST, // = 337, // CONFLICT 406 RPL_CHANPASSOK, // = 338, // CONFLICT 407 RPL_WHOISACTUALLY, // = 338, 408 RPL_WHOISMARKS, // = 339, // CONFLICT 409 RPL_BADCHANPASS, // = 339, 410 //RPL_USERIP, // = 340, 411 RPL_INVITING, // = 341, // "<channel> <nick>" 412 RPL_SUMMONING, // = 342, // "<user> :Summoning user to IRC" 413 RPL_WHOISKILL, // = 343, 414 RPL_REOPLIST, // = 344, // "<channel> <mask>" 415 RPL_ENDOFREOPLIST, // = 345, // CONFLICT 416 RPL_INVITED, // = 345, 417 //RPL_INVITELIST, // = 346, 418 //RPL_ENDOFINVITELIST, // = 347, 419 RPL_EXCEPTLIST, // = 348, 420 RPL_ENDOFEXCEPTLIST, // = 349, 421 RPL_VERSION, // = 351, // "<version>.<debuglevel> <server> :<comments>" 422 RPL_WHOREPLY, // = 352, // "<channel> <user> <host> <server> <nick> | <H|G>[*][@|+] :<hopcount> <real name>" 423 RPL_NAMREPLY, // = 353, // "<channel> :[[@|+]<nick> [[@|+]<nick> [...]]]" 424 RPL_WHOSPCRPL, // = 354, 425 RPL_NAMREPLY_, // = 355, 426 //RPL_MAP, // = 357, 427 //RPL_MAPMORE, // = 358, 428 //RPL_MAPEND, // = 359, 429 RPL_WHOWASREAL, // = 360, 430 RPL_KILLDONE, // = 361, // (reserved numeric) 431 RPL_CLOSING, // = 362, // (reserved numeric) 432 RPL_CLOSEEND, // = 363, // (reserved numeric) 433 RPL_LINKS, // = 364, // "<mask> <server> :<hopcount> <server info>" 434 RPL_ENDOFLINKS, // = 365, // "<mask> :End of /LINKS list" 435 RPL_ENDOFNAMES, // = 366, // "<channel> :End of /NAMES list" 436 RPL_BANLIST, // = 367, // "<channel> <banid>" 437 RPL_ENDOFBANLIST, // = 368, // "<channel> :End of channel ban list" 438 RPL_ENDOFWHOWAS, // = 369, // "<nick> :End of WHOWAS" 439 RPL_INFO, // = 371, // ":<string>" 440 RPL_MOTD, // = 372, // ":- <text>" 441 RPL_INFOSTART, // = 373, // (reserved numeric) 442 RPL_ENDOFINFO, // = 374, // ":End of /INFO list" 443 RPL_MOTDSTART, // = 375, // ":- <server> Message of the day - " 444 RPL_ENDOFMOTD, // = 376, // ":End of /MOTD command" 445 RPL_SPAM, // = 377, // CONFLICT 446 RPL_KICKEXPIRED, // = 377, 447 RPL_BANEXPIRED, // = 378, // CONFLICT 448 //RPL_MOTD, // = 378, // CONFLICT 449 RPL_WHOISHOST, // = 378 // <nickname> :is connecting from *@<address> <ip> 450 RPL_KICKLINKED, // = 379, // CONFLICT 451 RPL_WHOWASIP, // = 379, // CONFLICT 452 RPL_WHOISMODES, // = 379, // <nickname> :is using modes <modes> 453 RPL_YOURHELPER, // = 380, // CONFLICT 454 RPL_BANLINKED, // = 380, 455 RPL_YOUREOPER, // = 381, // ":You are now an IRC operator" 456 RPL_REHASHING, // = 382, // "<config file> :Rehashing" 457 RPL_YOURESERVICE, // = 383, 458 RPL_MYPORTIS, // = 384, 459 RPL_NOTOPERANYMORE, // = 385, 460 RPL_IRCOPS, // = 386, // CONFLICT 461 RPL_IRCOPSHEADER, // = 386, // CONFLICT 462 RPL_RSACHALLENGE, // = 386, // CONFLICT 463 RPL_QLIST, // = 386, 464 RPL_ENDOFIRCOPS, // = 387, // CONFLICT 465 //RPL_IRCOPS, // = 387, // CONFLICT 466 RPL_ENDOFQLIST, // = 387, 467 //RPL_ENDOFIRCOPS, // = 388, // CONFLICT 468 //RPL_ALIST, // = 388, 469 //RPL_ENDOFALIST, // = 389, 470 RPL_TIME, // = 391, // "<server> :<string showing server's local time>" 471 RPL_USERSTART, // = 392, // ":UserID Terminal Host" 472 RPL_USERS, // = 393, // ":%-8s %-9s %-8s" 473 RPL_ENDOFUSERS, // = 394, // ":End of users" 474 RPL_NOUSERS, // = 395, // ":Nobody logged in" 475 RPL_VISIBLEHOST, // = 396, // CONFLICT 476 RPL_HOSTHIDDEN, // = 396, // <nickname> <host> :is now your hidden host 477 478 ERR_UNKNOWNERROR, // = 400, 479 ERR_NOSUCHNICK, // = 401, // "<nickname> :No such nick/channel" 480 ERR_NOSUCHSERVER, // = 402, // "<server name> :No such server" 481 ERR_NOSUCHCHANNEL, // = 403, // "<channel name> :No such channel" 482 ERR_CANNOTSENDTOCHAN, // = 404, // "<channel name> :Cannot send to channel" 483 ERR_TOOMANYCHANNELS, // = 405, // "<channel name> :You have joined too many channels" 484 ERR_WASNOSUCHNICK, // = 406, // "<nickname> :There was no such nickname" 485 ERR_TOOMANYTARGETS, // = 407, // "<target> :Duplicate recipients. No message delivered"" 486 ERR_NOCTRLSONCHAN, // = 408, // CONFLICT 487 ERR_NOCOLORSONCHAN, // = 408, // CONFLICT 488 ERR_NOSUCHSERVICE, // = 408, 489 ERR_NOORIGIN, // = 409, // ":No origin specified" 490 ERR_INVALIDCAPCMD, // = 410, 491 ERR_NORECIPIENT, // = 411, // ":No recipient given (<command>)" 492 ERR_NOTEXTTOSEND, // = 412, // ":No text to send" 493 ERR_NOTOPLEVEL, // = 413, // "<mask> :No toplevel domain specified" 494 ERR_WILDTOPLEVEL, // = 414, // "<mask> :Wildcard in toplevel domain" 495 ERR_BADMASK, // = 415, 496 ERR_QUERYTOOLONG, // = 416, // CONFLICT 497 ERR_TOOMANYMATCHES, // = 416, 498 ERR_INPUTTOOLONG, // = 417, 499 ERR_LENGTHTRUNCATED, // = 419, 500 ERR_UNKNOWNCOMMAND, // = 421, // "<command> :Unknown command" 501 ERR_NOMOTD, // = 422, // ":MOTD File is missing" 502 ERR_NOADMININFO, // = 423, // "<server> :No administrative info available" 503 ERR_FILEERROR, // = 424, // ":File error doing <file op> on <file>" 504 ERR_NOOPERMOTD, // = 425, 505 ERR_TOOMANYAWAY, // = 429, 506 ERR_EVENTNICKCHANGE, // = 430, 507 ERR_NONICKNAMEGIVEN, // = 431, // ":No nickname given" 508 ERR_ERRONEOUSNICKNAME, // = 432,// "<nick> :Erroneus nickname" 509 ERR_NICKNAMEINUSE, // = 433, // "<nick> :Nickname is already in use" 510 ERR_SERVICENAMEINUSE, // = 434, //CONFLICT 511 ERR_NORULES, // = 434, 512 ERR_SERVICECONFUSED, // = 435 // CONFLICT 513 ERR_BANONCHAN, // = 435 // <nickname> <target nickname> <channel> :Cannot change nickname while banned on channel 514 ERR_NICKCOLLISION, // = 436, // "<nick> :Nickname collision KILL" 515 ERR_BANNICKCHANGE, // = 437, // CONFLICT 516 ERR_UNAVAILRESOURCE, // = 437, // <nickname> <channel> :Nick/channel is temporarily unavailable 517 ERR_DEAD, // = 438, // CONFLICT 518 ERR_NICKTOOFAST, // = 438, 519 ERR_TARGETTOOFAST, // = 439, // <nickname> :This server has anti-spambot mechanisms enabled. 520 ERR_SERVICESDOWN, // = 440, 521 ERR_USERNOTINCHANNEL, // = 441, // "<nick> <channel> :They aren't on that channel" 522 ERR_NOTONCHANNEL, // = 442, // "<channel> :You're not on that channel" 523 ERR_USERONCHANNEL, // = 443, // "<user> <channel> :is already on channel" 524 ERR_NOLOGIN, // = 444, // "<user> :User not logged in" 525 ERR_SUMMONDISABLED, // = 445, // ":SUMMON has been disabled" 526 ERR_USERSDISABLED, // = 446, // ":USERS has been disabled" 527 ERR_NONICKCHANGE, // = 447, 528 ERR_FORBIDDENCHANNEL, // = 448, 529 ERR_NOTIMPLEMENTED, // = 449, 530 ERR_NOTREGISTERED, // = 451, // ":You have not registered" 531 ERR_IDCOLLISION, // = 452, 532 ERR_NICKLOST, // = 453, 533 //ERR_IDCOLLISION, // = 455 // <nickname> :Your username <nickname> contained the invalid character(s) <characters> and has been changed to mrkaufma. Please use only the characters 0-9 a-z A-Z _ - or . in your username. Your username is the part before the @ in your email address. 534 ERR_HOSTILENAME, // = 455, 535 ERR_ACCEPTFULL, // = 456 536 ERR_ACCEPTEXIST, // = 457, 537 ERR_ACCEPTNOT, // = 458, 538 ERR_NOHIDING, // = 459, 539 ERR_NOTFORHALFOPS, // = 460, 540 ERR_NEEDMOREPARAMS, // = 461, // "<command> :Not enough parameters" 541 ERR_ALREADYREGISTERED, // = 462,// ":You may not reregister" 542 ERR_NOPERMFORHOST, // = 463, // ":Your host isn't among the privileged" 543 ERR_PASSWDMISMATCH, // = 464, // ":Password incorrect" 544 ERR_YOUREBANNEDCREEP, // = 465, // ":You are banned from this server" 545 ERR_YOUWILLBEBANNED, // = 466 // (reserved numeric) 546 ERR_KEYSET, // = 467, // "<channel> :Channel key already set" 547 ERR_NOCODEPAGE, // = 468, // CONFLICT 548 ERR_ONLYSERVERSCANCHANGE, // = 468,// CONFLICT 549 ERR_INVALIDUSERNAME, // = 468, 550 ERR_LINKSET, // = 469, 551 ERR_7BIT, // = 470, // CONFLICT 552 ERR_KICKEDFROMCHAN, // = 470, // CONFLICT 553 ERR_LINKCHANNEL, // = 470 // <#original> <#new> :Forwarding to another channel 554 ERR_CHANNELISFULL, // = 471, // "<channel> :Cannot join channel (+l)" 555 ERR_UNKNOWNMODE, // = 472, // "<char> :is unknown mode char to me" 556 ERR_INVITEONLYCHAN, // = 473, // "<channel> :Cannot join channel (+i)" 557 ERR_BANNEDFROMCHAN, // = 474, // "<channel> :Cannot join channel (+b)" 558 ERR_BADCHANNELKEY, // = 475, // "<channel> :Cannot join channel (+k)" 559 ERR_BADCHANMASK, // = 476, // (reserved numeric) 560 ERR_NOCHANMODES, // = 477 // CONFLICT 561 ERR_NEEDREGGEDNICK, // = 477 // <nickname> <channel> :Cannot join channel (+r) - you need to be identified with services 562 ERR_BANLISTFULL, // = 478, 563 ERR_NOCOLOR, // = 479, // CONFLICT 564 ERR_BADCHANNAME, // = 479, 565 ERR_LINKFAIL, // = 479, // CONFLICT 566 ERR_THROTTLE, // = 480, // CONFLICT 567 ERR_NOWALLOP, // = 480, // CONFLICT 568 ERR_SSLONLYCHAN, // = 480, // CONFLICT 569 ERR_NOULINE, // = 480, // CONFLICT 570 ERR_CANNOTKNOCK, // = 480, 571 ERR_NOPRIVILEGES, // = 481, // ":Permission Denied- You're not an IRC operator" 572 ERR_CHANOPRIVSNEEDED, // = 482, // [sic] "<channel> :You're not channel operator" 573 ERR_CANTKILLSERVER, // = 483, // ":You cant kill a server!" 574 ERR_ATTACKDENY, // = 484, // CONFLICT 575 ERR_DESYNC, // = 484, // CONFLICT 576 ERR_ISCHANSERVICE, // = 484, // CONFLICT 577 ERR_RESTRICTED, // = 484, 578 ERR_BANNEDNICK, // = 485, // CONFLICT 579 ERR_CHANBANREASON, // = 485, // CONFLICT 580 ERR_KILLDENY, // = 485, // CONFLICT 581 ERR_CANTKICKADMIN, // = 485, // CONFLICT 582 ERR_ISREALSERVICE, // = 485, // CONFLICT 583 ERR_UNIQPRIVSNEEDED, // = 485, 584 ERR_ACCOUNTONLY, // = 486, // CONFLICT 585 ERR_RLINED, // = 486, // CONFLICT 586 ERR_HTMDIABLED, // = 486, // CONFLICT 587 ERR_NONONREG, // = 486, 588 ERR_NONONSSL, // = 487, // CONFLICT 589 ERR_NOTFORUSERS, // = 487, // CONFLICT 590 ERR_CHANTOORECENT, // = 487, // CONFLICT 591 ERR_MSGSERVICES, // = 487 // <nickname> :Error! "/msg NickServ" is no longer supported. Use "/msg NickServ@services.dal.net" or "/NickServ" instead. 592 ERR_HTMDISABLED, // = 488, // CONFLICT 593 ERR_NOSSL, // = 488, // CONFLICT 594 ERR_TSLESSCHAN, // = 488, 595 ERR_VOICENEEDED, // = 489, // CONFLICT 596 ERR_SECUREONLYCHAN, // = 489, 597 ERR_NOSWEAR, // = 490, // CONFLICT 598 ERR_ALLMUSTSSL, // = 490, 599 ERR_NOOPERHOST, // = 491, // ":No O-lines for your host" 600 ERR_CANNOTSENDTOUSER, // = 492, // CONFLICT 601 ERR_NOCTCP, // = 492, // CONFLICT 602 ERR_NOTCP, // = 492, // CONFLICT 603 ERR_NOSERVICEHOST, // = 492, // (reserved numeric) 604 ERR_NOSHAREDCHAN, // = 493 // CONFLICT 605 ERR_NOFEATURE, // = 493, 606 ERR_OWNMODE, // = 494, // CONFLICT 607 ERR_BADFEATVALUE, // = 494, 608 ERR_DELAYREJOIN, // = 495, // CONFLICT 609 ERR_BADLOGTYPE, // = 495, 610 ERR_BADLOGSYS, // = 496, 611 ERR_BADLOGVALUE, // = 497, 612 ERR_ISOPERLCHAN, // = 498, 613 ERR_CHANOWNPRIVNEEDED, // = 499, 614 615 ERR_NOREHASHPARAM, // = 500, // CONFLICT 616 ERR_TOOMANYJOINS, // = 500, 617 ERR_UNKNOWNSNOMASK, // = 501, // CONFLICT 618 ERR_UMODEUNKNOWNFLAG, // = 501, // ":Unknown MODE flag" 619 ERR_USERSDONTMATCH, // = 502, // ":Cant change mode for other users" 620 ERR_VWORLDWARN, // = 503, // CONFLICT 621 ERR_GHOSTEDCLIENT, // = 503, 622 ERR_USERNOTONSERV, // = 504, 623 ERR_SILELISTFULL, // = 511, 624 ERR_NOSUCHGLINE, // = 512, // CONFLICT 625 ERR_TOOMANYWATCH, // = 512, 626 //ERR_BADPING, // 513, // CONFLICT 627 ERR_NEEDPONG, // = 513, // <nickname> :To connect type /QUOTE PONG <number> 628 ERR_NOSUCHJUPE, // = 514, // CONFLICT 629 ERR_TOOMANYDCC, // = 514, // CONFLICT 630 ERR_INVALID_ERROR, // = 514, 631 ERR_BADEXPIRE, // = 515, 632 ERR_DONTCHEAT, // = 516, 633 ERR_DISABLED, // = 517, 634 ERR_NOINVITE, // = 518, // CONFLICT 635 ERR_LONGMASK, // = 518, 636 ERR_ADMONLY, // = 519, // CONFLICT 637 ERR_TOOMANYUSERS, // = 519, 638 ERR_WHOTRUNC, // = 520, // CONFLICT 639 ERR_MASKTOOWIDE, // = 520, // CONFLICT 640 ERR_OPERONLY, // = 520, 641 //ERR_NOSUCHGLINE, // = 521, // CONFLICT 642 ERR_LISTSYNTAX, // = 521, 643 ERR_WHOSYNTAX, // = 522, 644 ERR_WHOLIMEXCEED, // = 523, 645 ERR_OPERSPVERIFY, // = 524, // CONFLICT 646 ERR_QUARANTINED, // = 524, // CONFLICT 647 ERR_HELPNOTFOUND, // = 524, 648 ERR_INVALIDKEY, // = 525, // CONFLICT 649 ERR_REMOTEPFX, // = 525, 650 ERR_PFXUNROUTABLE, // = 526, 651 ERR_CANTSENDTOUSER, // = 531, 652 ERR_BADHOSTMASK, // = 550, 653 ERR_HOSTUNAVAIL, // = 551, 654 ERR_USINGSLINE, // = 552, 655 ERR_STATSSLINE, // = 553, 656 ERR_NOTLOWEROPLEVEL, // = 560, 657 ERR_NOTMANAGER, // = 561, 658 ERR_CHANSECURED, // = 562, 659 ERR_UPASSSET, // = 563, 660 ERR_UPASSNOTSET, // = 564, 661 ERR_NOMANAGER, // = 566, 662 ERR_UPASS_SAME_APASS, // = 567, 663 RPL_NOMOTD, // = 568 // CONFLICT 664 ERR_LASTERROR, // = 568, 665 RPL_REAWAY, // = 597, 666 RPL_GONEAWAY, // = 598, 667 RPL_NOTAWAY, // = 599, 668 669 RPL_LOGON, // = 600, 670 RPL_LOGOFF, // = 601, 671 RPL_WATCHOFF, // = 602, 672 RPL_WATCHSTAT, // = 603, 673 RPL_NOWON, // = 604, 674 RPL_NOWFF, // = 605, 675 RPL_WATCHLIST, // = 606, 676 RPL_ENDOFWATCHLIST, // = 607, 677 RPL_WATCHCLEAR, // = 608, 678 RPL_NOWISAWAY, // = 609, 679 RPL_ISOPER, // = 610 // CONFLICT 680 //RPL_MAPMORE, // = 610, 681 RPL_ISLOCOP, // = 611, 682 RPL_ISNOTOPER, // = 612, 683 RPL_ENDOFISOPER, // = 613, 684 //RPL_MAPMORE, // = 615, // CONFLICT 685 //RPL_WHOISMODES, // = 615, 686 //RPL_WHOISHOST, // = 616, 687 RPL_WHOISSSLFP, // = 617, // CONFLICT 688 //RPL_WHOISBOT, // = 617, // CONFLICT 689 RPL_DCCSTATUS, // = 617, 690 RPL_DCCLIST, // = 618, 691 RPL_WHOWASHOST, // = 619, // CONFLICT 692 RPL_ENDOFDCCLIST, // = 619, 693 //RPL_RULESSTART, // = 620, // CONFLICT 694 RPL_DCCINFO, // = 620, 695 //RPL_RULES, // = 621, 696 //RPL_ENDOFRULES, // = 622, 697 //RPL_MAPMORE, // = 623, 698 RPL_OMOTDSTART, // = 624, 699 RPL_OMOTD, // = 625 700 RPL_ENDOFO, // = 626, 701 RPL_SETTINGS, // = 630, 702 RPL_ENDOFSETTINGS, // = 631, 703 RPL_DUMPING, // = 640, 704 RPL_DUMPRPL, // = 641, 705 RPL_EODUMP, // = 642, 706 RPL_SPAMCMDFWD, // = 659, 707 RPL_TRACEROUTE_HOP, // = 660, 708 RPL_TRACEROUTE_START, // = 661, 709 RPL_MODECHANGEWARN, // = 662, 710 RPL_CHANREDIR, // = 663, 711 RPL_SERVMODEIS, // = 664, 712 RPL_OTHERUMODEIS, // = 665, 713 RPL_ENDOF_GENERIC, // = 666, 714 RPL_WHOWASDETAILS, // = 670, // CONFLICT 715 RPL_STARTTLS, // = 670, 716 RPL_WHOISSECURE, // = 671 // "<nickname> :is using a secure connection" 717 RPL_UNKNOWNMODES, // = 672, // CONFLICT 718 RPL_WHOISREALIP, // 672, 719 RPL_CANNOTSETMODES, // = 673, 720 RPL_WHOISYOURID, // = 674, 721 RPL_LUSERSTAFF, // = 678, 722 RPL_TIMEONSERVERIS, // = 679, 723 RPL_NETWORKS, // = 682, 724 RPL_YOURLANGUAGEIS, // = 687, 725 RPL_LANGUAGE, // = 688, 726 RPL_WHOISSTAFF, // = 689, 727 RPL_WHOISLANGUAGE, // = 690, 728 ERR_STARTTLS, // = 691, 729 730 //RPL_MODLIST, // = 702, // CONFLICT 731 RPL_COMMANDS, // = 702, 732 RPL_ENDOFMODLIST, // = 703, // CONFLICT 733 RPL_COMMANDSEND, // = 703, 734 RPL_HELPSTART, // = 704 // <nickname> index :Help topics available to users: 735 RPL_HELPTXT, // = 705 // <nickname> index :ACCEPT\tADMIN\tAWAY\tCHALLENGE 736 RPL_ENDOFHELP, // = 706 // <nickname> index :End of /HELP. 737 ERR_TARGCHANGE, // = 707, 738 RPL_ETRACEFULL, // = 708, 739 RPL_ETRACE, // = 709, 740 RPL_KNOCK, // = 710, 741 RPL_KNOCKDLVR, // = 711, 742 ERR_TOOMANYKNOCK, // = 712, 743 ERR_CHANOPEN, // = 713, 744 ERR_KNOCKONCHAN, // = 714, 745 ERR_KNOCKDISABLED, // = 715, // CONFLICT 746 ERR_TOOMANYINVITE, // = 715, // CONFLICT 747 RPL_INVITETHROTTLE, // = 715, 748 RPL_TARGUMODEG, // = 716, 749 RPL_TARGNOTIFY, // = 717, 750 RPL_UMODEGMSG, // = 718, 751 //RPL_OMOTDSTART, // = 720 752 //RPL_OMOTD, // = 721, 753 RPL_ENDOFOMOTD, // = 722, 754 ERR_NOPRIVS, // = 723, 755 RPL_TESTMASK, // = 724, 756 RPL_TESTLINE, // = 725, 757 RPL_NOTESTLINE, // = 726, 758 RPL_TESTMASKGECOS, // = 727, 759 RPL_QUIETLIST, // = 728, // also 344 on oftc 760 RPL_ENDOFQUIETLIST, // = 729, 761 RPL_MONONLINE, // = 730, 762 RPL_MONOFFLINE, // = 731, 763 RPL_MONLIST, // = 732, 764 RPL_ENDOFMONLIST, // = 733, 765 ERR_MONLISTFULL, // = 734, 766 RPL_RSACHALLENGE2, // = 740, 767 RPL_ENDOFRSACHALLENGE2, // = 741, 768 ERR_MLOCKRESTRICTED, // = 742, 769 ERR_INVALIDBAN, // = 743, 770 ERR_TOPICLOCK, // = 744, 771 RPL_SCANMATCHED, // = 750, 772 RPL_SCANUMODES, // = 751, 773 RPL_ETRACEEND, // = 759, 774 RPL_WHOISKEYVALUE, // = 760, 775 RPL_KEYVALUE, // = 761, 776 RPL_METADATAEND, // = 762, 777 ERR_METADATALIMIT, // = 764, 778 ERR_TARGETINVALID, // = 765, 779 ERR_NOMATCHINGKEY, // = 766, 780 ERR_KEYINVALID, // = 767, 781 ERR_KEYNOTSET, // = 768, 782 ERR_KEYNOPERMISSION, // = 769, 783 RPL_XINFO, // = 771, 784 RPL_XINFOSTART, // = 773 785 RPL_XINFOEND, // = 774, 786 787 RPL_CHECK, // = 802, 788 789 RPL_LOGGEDIN, // = 900, // <nickname>!<ident>@<address> <nickname> :You are now logged in as <nickname> 790 RPL_LOGGEDOUT, // = 901, 791 ERR_NICKLOCKED, // = 902, 792 RPL_SASLSUCCESS, // = 903, // :cherryh.freenode.net 903 kameloso^ :SASL authentication successful 793 ERR_SASLFAIL, // = 904, // :irc.rizon.no 904 kameloso^^ :SASL authentication failed" 794 ERR_SASLTOOLONG, // = 905, 795 ERR_SASLABORTED, // = 906, // :orwell.freenode.net 906 kameloso^ :SASL authentication aborted 796 ERR_SASLALREADY, // = 907, 797 RPL_SASLMECHS, // = 908, 798 ERR_WORDFILTERED, // = 936, 799 ERR_CANTUNLOADMODULE, // = 972, // CONFLICT 800 ERR_CANNOTDOCOMMAND, // = 972, 801 ERR_CANNOTCHANGEUMODE, // = 973, 802 ERR_CANTLOADMODULE, // = 974, // CONFLICT 803 ERR_CANNOTCHANGECHANMODE, // = 974, 804 ERR_CANNOTCHANGESERVERMODE, // = 975,// CONFLICT 805 //ERR_LASTERROR, // = 975, // CONFLICT 806 RPL_LOADEDMODULE, // = 975, 807 ERR_CANNOTSENDTONICK, // = 976, 808 ERR_UNKNOWNSERVERMODE, // = 977, 809 ERR_SERVERMODELOCK, // = 979, 810 ERR_BADCHARENCODING, // = 980, 811 ERR_TOOMANYLANGUAGES, // = 981, 812 ERR_NOLANGUAGE, // = 982, 813 ERR_TEXTTOOSHORT, // = 983, 814 815 ERR_NUMERIC_ERR, // = 999 816 } 817 818 /* 819 /++ 820 Run this to generate the Type[n] map. 821 822 HAS NOT BEEN TESTED IN YEARS. There's been no need for it. 823 Don't expect it to work. 824 +/ 825 void generateTypenums() 826 { 827 import std.regex; 828 import std.algorithm; 829 import std.stdio; 830 831 enum pattern = r" *([A-Z0-9_]+),? [/= ]* ([0-9]+),?.*"; 832 static engine = ctRegex!pattern; 833 string[1024] arr; 834 835 foreach (const line; s.splitter("\n")) 836 { 837 auto hits = line.matchFirst(engine); 838 if (hits.length < 2) continue; 839 840 try 841 { 842 size_t idx = hits[2].to!size_t; 843 if (arr[idx] != typeof(arr[idx]).init) stderr.writeln("DUPLICATE! ", idx); 844 arr[idx] = hits[1]; 845 } 846 catch (Exception e) 847 { 848 //writeln(e.msg, ": ", line); 849 } 850 } 851 852 writeln("static immutable Type[1024] typenums =\n["); 853 854 foreach (immutable i, const val; arr) 855 { 856 if (!val.length) continue; 857 858 writefln(" %-3d : Type.%s,", i, val); 859 } 860 861 writeln("];"); 862 } 863 */ 864 865 /++ 866 The event type, signifying what *kind* of event this is. 867 +/ 868 Type type; 869 870 /++ 871 With a numeric event, the number of the event type. 872 +/ 873 uint num; 874 875 /++ 876 The raw IRC string, untouched. 877 +/ 878 @Hidden string raw; 879 880 /++ 881 The name of whoever (or whatever) sent this event. 882 +/ 883 IRCUser sender; 884 885 /++ 886 The channel the event transpired in, or is otherwise related to. 887 +/ 888 string channel; 889 890 /++ 891 The target user of the event. 892 +/ 893 IRCUser target; 894 895 /++ 896 The main body of text of the event. 897 +/ 898 string content; 899 900 /++ 901 Auxiliary string array. 902 +/ 903 string[numAuxStrings] aux; 904 905 /++ 906 IRCv3 message tags attached to this event 907 +/ 908 string tags; 909 910 /++ 911 Count array. 912 +/ 913 Nullable!long[numCounts] count; 914 915 /++ 916 A timestamp of when the event transpired. 917 +/ 918 @Hidden long time; 919 920 /++ 921 What errors occurred during parsing, if any. 922 +/ 923 string errors; 924 925 version(TwitchSupport) 926 { 927 /++ 928 The Twitch emotes in the message, if any. 929 +/ 930 string emotes; 931 932 /++ 933 The Twitch ID of this message. 934 +/ 935 string id; 936 } 937 } 938 939 940 // IRCServer 941 /++ 942 Aggregate of all information and state pertaining to the connected IRC 943 server. Some fields are transient on a per-connection basis and should not 944 be serialised. 945 +/ 946 struct IRCServer 947 { 948 /++ 949 Server daemons, or families of server programs. 950 951 Many daemons handle some events slightly differently than others do, and 952 by tracking which daemon the server is running we can apply the 953 differences and always have an appropriate tables of events. 954 +/ 955 enum Daemon 956 { 957 unset, /// Unset or invalid daemon. 958 unknown, /// Reported but unknown daemon. 959 960 unreal, 961 solanum, 962 inspircd, 963 bahamut, 964 ratbox, 965 u2, 966 hybrid, 967 snircd, 968 rizon, 969 undernet, 970 ircdseven, 971 twitch, 972 bsdunix, 973 mfvx, 974 975 charybdis, 976 sorircd, 977 978 ircu, 979 aircd, 980 rfc1459, 981 rfc2812, 982 nefarious, 983 rusnet, 984 austhex, 985 ircnet, 986 ptlink, 987 ultimate, 988 anothernet, 989 bdqircd, 990 chatircd, 991 irch, 992 ithildin, 993 } 994 995 /++ 996 Case mappings used by an IRC server. 997 998 These decide how case-insensitivity works. 999 +/ 1000 enum CaseMapping 1001 { 1002 /// The lowercase of `[A-Z]` is `[a-z]`. 1003 ascii, 1004 /// `ascii`, plus the lowercase of `[]\^` is `{}|~`. 1005 rfc1459, 1006 /// `rfc1459`, except no `^` for `~`. 1007 strict_rfc1459, 1008 } 1009 1010 /++ 1011 Server address (or IP). 1012 +/ 1013 string address; 1014 1015 /++ 1016 The port to connect to, usually `6667`-`6669`. 1017 +/ 1018 ushort port; 1019 1020 @Unserialisable 1021 { 1022 /++ 1023 The server daemon family the server is running. 1024 +/ 1025 Daemon daemon; 1026 1027 /++ 1028 Server network string, like Freenode, QuakeNet, Rizon. 1029 +/ 1030 string network; 1031 1032 /++ 1033 The reported daemon, with version. 1034 +/ 1035 string daemonstring; 1036 1037 /++ 1038 The IRC server address handed to us by the round robin pool. 1039 +/ 1040 string resolvedAddress; 1041 1042 /++ 1043 Max nickname length as per IRC specs, but not the de facto standard. 1044 +/ 1045 uint maxNickLength = 9; 1046 1047 /++ 1048 Max channel name length as per IRC specs, or as reported. 1049 +/ 1050 uint maxChannelLength = 200; 1051 1052 /++ 1053 A = Mode that adds or removes a nick or address to a list. 1054 Always has a parameter. 1055 +/ 1056 string aModes; // = "eIbq"; 1057 1058 /++ 1059 B = Mode that changes a setting and always has a parameter. 1060 +/ 1061 string bModes; // = "k"; 1062 1063 /++ 1064 C = Mode that changes a setting and only has a parameter when set. 1065 +/ 1066 string cModes; // = "flj"; 1067 1068 /++ 1069 D = Mode that changes a setting and never has a parameter. 1070 +/ 1071 string dModes; // = "CFLMPQScgimnprstz"; 1072 1073 /++ 1074 Prefix characters by mode character; `o` by `@`, `v` by `+`, etc. 1075 +/ 1076 char[char] prefixchars; 1077 1078 /++ 1079 Character channel mode prefixes (`o`, `v`, `h`, ...) 1080 +/ 1081 string prefixes; 1082 1083 /++ 1084 Supported channel prefix characters, as announced by the server in 1085 the [dialect.defs.IRCEvent.Type.RPL_ISUPPORT|RPL_ISUPPORT]` event, 1086 before the MOTD. 1087 +/ 1088 string chantypes = "#"; 1089 1090 /++ 1091 Contents of the [IRCEvent.Type.RPL_ISUPPORT|RPL_ISUPPORT] response(s). 1092 +/ 1093 string supports; 1094 1095 /++ 1096 `EXTBAN` types. 1097 +/ 1098 string extbanTypes; 1099 1100 /++ 1101 The current case mapping, dictating how case-insensitivity works. 1102 +/ 1103 CaseMapping caseMapping; 1104 1105 /++ 1106 `EXTBAN` prefix character. 1107 +/ 1108 char extbanPrefix = '$'; 1109 1110 /++ 1111 The modechar for mode exceptions. 1112 +/ 1113 char exceptsChar = 'e'; 1114 1115 /++ 1116 The modechar for invite exceptions. 1117 +/ 1118 char invexChar = 'I'; 1119 } 1120 1121 /++ 1122 Constructor. 1123 +/ 1124 auto this( 1125 const string address, 1126 const ushort port) pure @safe nothrow @nogc 1127 { 1128 this.address = address; 1129 this.port = port; 1130 } 1131 } 1132 1133 1134 // IRCUser 1135 /++ 1136 An aggregate of fields representing a single user on IRC. 1137 1138 Instances of these should not survive a disconnect and reconnect; they are 1139 transient on a per-connection basis and should not be serialised. 1140 +/ 1141 struct IRCUser 1142 { 1143 /++ 1144 The user's nickname. 1145 +/ 1146 string nickname; 1147 1148 version(BotElements) 1149 { 1150 /++ 1151 Classifiers; roles which a user is one of. 1152 +/ 1153 enum Class 1154 { 1155 unset, /// Unknown, yet to be determined. 1156 blacklist, /// A blacklisted user. 1157 anyone, /// Any user. 1158 registered, /// A user registered with services. 1159 whitelist, /// A whitelisted user. 1160 elevated, /// An elevated user, something in between `whitelist` and `operator`. 1161 operator, /// A user enjoying operator (or moderator) privileges. 1162 staff, /// The owner of a channel; an elevated user but not a full administrator. 1163 admin, /// An administrator, in a bot-like context. 1164 } 1165 1166 /++ 1167 User classifier. 1168 +/ 1169 Class class_; 1170 } 1171 1172 version(TwitchSupport) 1173 { 1174 /++ 1175 The Twitch ID of this user's account. 1176 +/ 1177 uint id; 1178 } 1179 1180 /++ 1181 The user's GECOS/"real name". 1182 +/ 1183 string realName; 1184 1185 /++ 1186 The user's IDENT identification. 1187 +/ 1188 string ident; 1189 1190 /++ 1191 The reported user address, which may be a cloak. 1192 +/ 1193 string address; 1194 1195 /++ 1196 Services account name (to `NickServ`, `AuthServ`, `Q`, etc). 1197 +/ 1198 string account; 1199 1200 /++ 1201 Timestamp when the user was last modified. 1202 +/ 1203 @Hidden long updated; 1204 1205 version(TwitchSupport) 1206 { 1207 // Twitch has some extra features. 1208 1209 /++ 1210 The alternate "display name" of the user. 1211 +/ 1212 string displayName; 1213 1214 /++ 1215 The Twitch badges this user has. 1216 +/ 1217 string badges; 1218 1219 /++ 1220 The Twitch colour (RRGGBB) to tint the user's nickname with. 1221 +/ 1222 string colour; 1223 } 1224 1225 /++ 1226 Create a new [IRCUser] based on a `*!*@*` mask string. 1227 +/ 1228 this(string userstring) pure @safe 1229 { 1230 import std.format : formattedRead; 1231 1232 userstring.formattedRead("%s!%s@%s", nickname, ident, address); 1233 if (nickname == "*") nickname = string.init; 1234 if (ident == "*") ident = string.init; 1235 if (address == "*") address = string.init; 1236 } 1237 1238 /// 1239 unittest 1240 { 1241 { 1242 immutable user = IRCUser("nickname!~ident@address"); 1243 assert((user.nickname == "nickname"), user.nickname); 1244 assert((user.ident == "~ident"), user.ident); 1245 assert((user.address == "address"), user.address); 1246 } 1247 { 1248 immutable user = IRCUser("*!~ident@address"); 1249 assert(!user.nickname.length, user.nickname); 1250 assert((user.ident == "~ident"), user.ident); 1251 assert((user.address == "address"), user.address); 1252 } 1253 { 1254 immutable user = IRCUser("*!*@*"); 1255 assert(!user.nickname.length, user.nickname); 1256 assert(!user.ident.length, user.ident); 1257 assert(!user.address.length, user.address); 1258 } 1259 } 1260 1261 /++ 1262 Create a new [IRCUser] inheriting passed `nickname`, `ident`, and 1263 `address` strings. 1264 +/ 1265 auto this( 1266 const string nickname, 1267 const string ident, 1268 const string address) pure @safe nothrow @nogc 1269 { 1270 this.nickname = nickname; 1271 this.ident = ident; 1272 this.address = address; 1273 } 1274 1275 /++ 1276 Makes an educated guess that a sender is a server. 1277 1278 Returns: 1279 `true` if the sender nickname and/or address looks to be a server's, 1280 `false` if not. 1281 +/ 1282 auto isServer() const @property pure @safe nothrow @nogc 1283 { 1284 import std.string : indexOf; 1285 return !nickname.length && (address.indexOf('.') != -1); 1286 } 1287 1288 /// 1289 @safe unittest 1290 { 1291 IRCUser user; 1292 1293 user.address = "blah.freenode.net"; 1294 assert(user.isServer); 1295 1296 user.nickname = "foo"; 1297 assert(!user.isServer); 1298 1299 user.nickname = string.init; 1300 user.address = "nodots"; 1301 assert(!user.isServer); // unsure what to even make of no-dot addresses 1302 1303 // :kameloso MODE kameloso :+i 1304 user.nickname = "kameloso"; 1305 user.address = string.init; 1306 assert(!user.isServer); 1307 } 1308 1309 /++ 1310 Compares two [IRCUser]s with each other, ignoring members considered to 1311 be extra or optional. 1312 1313 Params: 1314 that = Second user to compare this one with. 1315 1316 Returns: 1317 `true` if the users match, `false` if not. 1318 +/ 1319 auto opEquals(const IRCUser that) const pure @safe nothrow @nogc 1320 { 1321 return 1322 (this.nickname == that.nickname) && 1323 (this.ident == that.ident) && 1324 (this.address == that.address); 1325 } 1326 1327 /++ 1328 Produces a hash for this [IRCUser]. 1329 1330 Returns: 1331 A hash. 1332 +/ 1333 auto toHash() const pure @safe 1334 { 1335 return this.hostmask.hashOf; 1336 } 1337 1338 // toString 1339 /++ 1340 Formats this [IRCUser] into a hostmask representing its values. 1341 Stores the result in the passed output range sink. 1342 1343 Params: 1344 sink = Output range sink to save the hostmask string to. 1345 +/ 1346 void toString(Sink)(auto ref Sink sink) const @safe 1347 { 1348 import std.format : formattedWrite; 1349 1350 immutable nickname = this.nickname.length ? this.nickname : "*"; 1351 immutable ident = this.ident.length ? this.ident : "*"; 1352 immutable address = this.address.length ? this.address : "*"; 1353 1354 sink.formattedWrite("%s!%s@%s", nickname, ident, address); 1355 } 1356 1357 // hostmask 1358 /++ 1359 Formats this [IRCUser] into a hostmask representing its values. 1360 Merely wraps [toString] and returns a newly allocated string. 1361 1362 Returns: 1363 A hostmask "*!*@*" string. 1364 +/ 1365 string hostmask() pure @safe const 1366 { 1367 import std.array : Appender; 1368 1369 Appender!(char[]) sink; 1370 sink.reserve(nickname.length + ident.length + address.length + 5); // for ! and @ as well as *** 1371 1372 this.toString(sink); 1373 return sink.data; 1374 } 1375 1376 /// 1377 @safe unittest 1378 { 1379 { 1380 const user = IRCUser("nickname", "ident", "address.tld"); 1381 immutable hostmask = user.hostmask; 1382 assert((hostmask == "nickname!ident@address.tld"), hostmask); 1383 } 1384 { 1385 const user = IRCUser("nickname", string.init, "address.tld"); 1386 immutable hostmask = user.hostmask; 1387 assert((hostmask == "nickname!*@address.tld"), hostmask); 1388 } 1389 { 1390 const user = IRCUser(string.init, string.init, "address.tld"); 1391 immutable hostmask = user.hostmask; 1392 assert((hostmask == "*!*@address.tld"), hostmask); 1393 } 1394 { 1395 const IRCUser user; 1396 immutable hostmask = user.hostmask; 1397 assert((hostmask == "*!*@*"), hostmask); 1398 } 1399 } 1400 } 1401 1402 1403 // Typenums 1404 /++ 1405 Reverse mappings of *numerics* to [IRCEvent.Type|Type]s. 1406 1407 One `base` table that covers most cases, and then specialised arrays for 1408 different server daemons, to meld into `base` for a union of the two 1409 (or more). This speeds up translation greatly and allows us to have 1410 different mappings for different daemons. 1411 +/ 1412 struct Typenums 1413 { 1414 private: 1415 alias Type = IRCEvent.Type; 1416 1417 public: 1418 /++ 1419 Default mappings. 1420 +/ 1421 static immutable Type[1024] base = 1422 [ 1423 1 : Type.RPL_WELCOME, 1424 2 : Type.RPL_YOURHOST, 1425 3 : Type.RPL_CREATED, 1426 4 : Type.RPL_MYINFO, 1427 5 : Type.RPL_ISUPPORT, 1428 6 : Type.RPL_MAP, 1429 7 : Type.RPL_MAPEND, 1430 8 : Type.RPL_SNOMASK, 1431 9 : Type.RPL_STATMEMTOT, 1432 10 : Type.THISSERVERINSTEAD, // was Type.RPL_STATMEM 1433 14 : Type.RPL_YOURCOOKIE, 1434 15 : Type.RPL_MAP, 1435 16 : Type.RPL_MAPMORE, 1436 17 : Type.RPL_MAPEND, 1437 20 : Type.RPL_HELLO, 1438 30 : Type.RPL_APASSWARN_SET, 1439 31 : Type.RPL_APASSWARN_SECRET, 1440 32 : Type.RPL_APASSWARN_CLEAR, 1441 42 : Type.RPL_YOURID, 1442 43 : Type.RPL_SAVENICK, 1443 50 : Type.RPL_ATTEMPTINGJUNC, 1444 51 : Type.RPL_ATTEMPTINGREROUTE, 1445 105 : Type.RPL_REMOTEISUPPORT, 1446 200 : Type.RPL_TRACELINK, 1447 201 : Type.RPL_TRACECONNECTING, 1448 202 : Type.RPL_TRACEHANDSHAKE, 1449 203 : Type.RPL_TRACEUNKNOWN, 1450 204 : Type.RPL_TRACEOPERATOR, 1451 205 : Type.RPL_TRACEUSER, 1452 206 : Type.RPL_TRACESERVER, 1453 207 : Type.RPL_TRACESERVICE, 1454 208 : Type.RPL_TRACENEWTYPE, 1455 209 : Type.RPL_TRACECLASS, 1456 210 : Type.RPL_STATS, 1457 211 : Type.RPL_STATSLINKINFO, 1458 212 : Type.RPL_STATSCOMMAND, 1459 213 : Type.RPL_STATSCLINE, 1460 214 : Type.RPL_STATSNLINE, 1461 215 : Type.RPL_STATSILINE, 1462 216 : Type.RPL_STATSKLINE, 1463 217 : Type.RPL_STATSQLINE, 1464 218 : Type.RPL_STATSYLINE, 1465 219 : Type.RPL_ENDOFSTATS, 1466 220 : Type.RPL_STATSPLINE, 1467 221 : Type.RPL_UMODEIS, 1468 222 : Type.RPL_MODLIST, 1469 223 : Type.RPL_STATSELINE, 1470 224 : Type.RPL_STATSFLINE, 1471 225 : Type.RPL_STATSDLINE, 1472 226 : Type.RPL_STATSCOUNT, 1473 227 : Type.RPL_STATSBLINE, 1474 228 : Type.RPL_STATSQLINE, 1475 229 : Type.RPL_STATSSPAMF, 1476 230 : Type.RPL_STATSEXCEPTTKL, 1477 231 : Type.RPL_SERVICEINFO, 1478 232 : Type.RPL_ENDOFSERVICES, 1479 233 : Type.RPL_SERVICE, 1480 234 : Type.RPL_SERVLIST, 1481 235 : Type.RPL_SERVLISTEND, 1482 236 : Type.RPL_STATSVERBOSE, 1483 237 : Type.RPL_STATSENGINE, 1484 238 : Type.RPL_STATSFLINE, 1485 239 : Type.RPL_STATSIAUTH, 1486 240 : Type.RPL_STATSVLINE, 1487 241 : Type.RPL_STATSLLINE, 1488 242 : Type.RPL_STATSUPTIME, 1489 243 : Type.RPL_STATSOLINE, 1490 244 : Type.RPL_STATSHLINE, 1491 245 : Type.RPL_STATSSLINE, 1492 246 : Type.RPL_STATSPING, 1493 247 : Type.RPL_STATSBLINE, 1494 248 : Type.RPL_STATSULINE, 1495 249 : Type.RPL_STATSULINE, 1496 250 : Type.RPL_STATSCONN, 1497 251 : Type.RPL_LUSERCLIENT, 1498 252 : Type.RPL_LUSEROP, 1499 253 : Type.RPL_LUSERUNKNOWN, 1500 254 : Type.RPL_LUSERCHANNELS, 1501 255 : Type.RPL_LUSERME, 1502 256 : Type.RPL_ADMINME, 1503 257 : Type.RPL_ADMINLOC1, 1504 258 : Type.RPL_ADMINLOC2, 1505 259 : Type.RPL_ADMINEMAIL, 1506 261 : Type.RPL_TRACELOG, 1507 262 : Type.RPL_TRACEEND, 1508 263 : Type.RPL_TRYAGAIN, 1509 264 : Type.RPL_USINGSSL, 1510 265 : Type.RPL_LOCALUSERS, 1511 266 : Type.RPL_GLOBALUSERS, 1512 267 : Type.RPL_START_NETSTAT, 1513 268 : Type.RPL_NETSTAT, 1514 269 : Type.RPL_END_NETSTAT, 1515 270 : Type.RPL_PRIVS, 1516 271 : Type.RPL_SILELIST, 1517 272 : Type.RPL_ENDOFSILELIST, 1518 273 : Type.RPL_NOTIFY, 1519 274 : Type.RPL_ENDNOTIFY, 1520 275 : Type.RPL_STATSDLINE, 1521 276 : Type.RPL_STATSRLINE, 1522 277 : Type.RPL_VCHANLIST, 1523 278 : Type.RPL_VCHANHELP, 1524 280 : Type.RPL_GLIST, 1525 281 : Type.RPL_ACCEPTLIST, 1526 282 : Type.RPL_ENDOFACCEPT, 1527 283 : Type.RPL_ALIST, 1528 284 : Type.RPL_ENDOFALIST, 1529 285 : Type.RPL_GLIST_HASH, 1530 286 : Type.RPL_CHANINFO_USERS, 1531 287 : Type.RPL_CHANINFO_CHOPS, 1532 288 : Type.RPL_CHANINFO_VOICES, 1533 289 : Type.RPL_CHANINFO_AWAY, 1534 290 : Type.RPL_CHANINFO_OPERS, 1535 291 : Type.RPL_CHANINFO_BANNED, 1536 292 : Type.RPL_CHANINFO_BANS, 1537 293 : Type.RPL_CHANINFO_INVITE, 1538 294 : Type.RPL_CHANINFO_INVITES, 1539 295 : Type.RPL_CHANINFO_KICK, 1540 296 : Type.RPL_CHANINFO_KICKS, 1541 299 : Type.RPL_END_CHANINFO, 1542 300 : Type.RPL_NONE, 1543 301 : Type.RPL_AWAY, 1544 302 : Type.RPL_USERHOST, 1545 303 : Type.RPL_ISON, 1546 304 : Type.RPL_TEXT, 1547 305 : Type.RPL_UNAWAY, 1548 306 : Type.RPL_NOWAWAY, 1549 307 : Type.RPL_WHOISREGNICK, 1550 308 : Type.RPL_NOTIFYACTION, 1551 309 : Type.RPL_NICKTRACE, 1552 310 : Type.RPL_WHOISSVCMSG, 1553 311 : Type.RPL_WHOISUSER, 1554 312 : Type.RPL_WHOISSERVER, 1555 313 : Type.RPL_WHOISOPERATOR, 1556 314 : Type.RPL_WHOWASUSER, 1557 315 : Type.RPL_ENDOFWHO, 1558 316 : Type.RPL_WHOISCHANOP, 1559 317 : Type.RPL_WHOISIDLE, 1560 318 : Type.RPL_ENDOFWHOIS, 1561 319 : Type.RPL_WHOISCHANNELS, 1562 320 : Type.RPL_WHOISSPECIAL, 1563 321 : Type.RPL_LISTSTART, 1564 322 : Type.RPL_LIST, 1565 323 : Type.RPL_LISTEND, 1566 324 : Type.RPL_CHANNELMODEIS, 1567 325 : Type.RPL_CHANNELPASSIS, 1568 326 : Type.RPL_NOCHANPASS, 1569 327 : Type.RPL_CHPASSUNKNOWN, 1570 328 : Type.RPL_CHANNEL_URL, 1571 329 : Type.RPL_CREATIONTIME, 1572 330 : Type.RPL_WHOISACCOUNT, 1573 331 : Type.RPL_NOTOPIC, 1574 332 : Type.RPL_TOPIC, 1575 333 : Type.RPL_TOPICWHOTIME, 1576 334 : Type.RPL_LISTUSAGE, 1577 335 : Type.RPL_WHOISBOT, 1578 336 : Type.RPL_INVITELIST, 1579 337 : Type.RPL_ENDOFINVITELIST, 1580 338 : Type.RPL_WHOISACTUALLY, 1581 339 : Type.RPL_BADCHANPASS, 1582 340 : Type.RPL_USERIP, 1583 341 : Type.RPL_INVITING, 1584 342 : Type.RPL_SUMMONING, 1585 343 : Type.RPL_WHOISKILL, 1586 345 : Type.RPL_INVITED, 1587 346 : Type.RPL_INVITELIST, 1588 347 : Type.RPL_ENDOFINVITELIST, 1589 348 : Type.RPL_EXCEPTLIST, 1590 349 : Type.RPL_ENDOFEXCEPTLIST, 1591 351 : Type.RPL_VERSION, 1592 352 : Type.RPL_WHOREPLY, 1593 353 : Type.RPL_NAMREPLY, 1594 354 : Type.RPL_WHOSPCRPL, 1595 355 : Type.RPL_NAMREPLY_, 1596 357 : Type.RPL_MAP, 1597 358 : Type.RPL_MAPMORE, 1598 359 : Type.RPL_MAPEND, 1599 360 : Type.RPL_WHOWASREAL, 1600 361 : Type.RPL_KILLDONE, 1601 362 : Type.RPL_CLOSING, 1602 363 : Type.RPL_CLOSEEND, 1603 364 : Type.RPL_LINKS, 1604 365 : Type.RPL_ENDOFLINKS, 1605 366 : Type.RPL_ENDOFNAMES, 1606 367 : Type.RPL_BANLIST, 1607 368 : Type.RPL_ENDOFBANLIST, 1608 369 : Type.RPL_ENDOFWHOWAS, 1609 371 : Type.RPL_INFO, 1610 372 : Type.RPL_MOTD, 1611 373 : Type.RPL_INFOSTART, 1612 374 : Type.RPL_ENDOFINFO, 1613 375 : Type.RPL_MOTDSTART, 1614 376 : Type.RPL_ENDOFMOTD, 1615 377 : Type.RPL_KICKEXPIRED, 1616 378 : Type.RPL_WHOISHOST, 1617 379 : Type.RPL_WHOISMODES, 1618 380 : Type.RPL_BANLINKED, 1619 381 : Type.RPL_YOUREOPER, 1620 382 : Type.RPL_REHASHING, 1621 383 : Type.RPL_YOURESERVICE, 1622 384 : Type.RPL_MYPORTIS, 1623 385 : Type.RPL_NOTOPERANYMORE, 1624 386 : Type.RPL_QLIST, 1625 387 : Type.RPL_ENDOFQLIST, 1626 388 : Type.RPL_ALIST, 1627 389 : Type.RPL_ENDOFALIST, 1628 391 : Type.RPL_TIME, 1629 392 : Type.RPL_USERSTART, 1630 393 : Type.RPL_USERS, 1631 394 : Type.RPL_ENDOFUSERS, 1632 395 : Type.RPL_NOUSERS, 1633 396 : Type.RPL_HOSTHIDDEN, 1634 400 : Type.ERR_UNKNOWNERROR, 1635 401 : Type.ERR_NOSUCHNICK, 1636 402 : Type.ERR_NOSUCHSERVER, 1637 403 : Type.ERR_NOSUCHCHANNEL, 1638 404 : Type.ERR_CANNOTSENDTOCHAN, 1639 405 : Type.ERR_TOOMANYCHANNELS, 1640 406 : Type.ERR_WASNOSUCHNICK, 1641 407 : Type.ERR_TOOMANYTARGETS, 1642 408 : Type.ERR_NOSUCHSERVICE, 1643 409 : Type.ERR_NOORIGIN, 1644 410 : Type.ERR_INVALIDCAPCMD, 1645 411 : Type.ERR_NORECIPIENT, 1646 412 : Type.ERR_NOTEXTTOSEND, 1647 413 : Type.ERR_NOTOPLEVEL, 1648 414 : Type.ERR_WILDTOPLEVEL, 1649 415 : Type.ERR_BADMASK, 1650 416 : Type.ERR_TOOMANYMATCHES, 1651 417 : Type.ERR_INPUTTOOLONG, 1652 419 : Type.ERR_LENGTHTRUNCATED, 1653 421 : Type.ERR_UNKNOWNCOMMAND, 1654 422 : Type.ERR_NOMOTD, 1655 423 : Type.ERR_NOADMININFO, 1656 424 : Type.ERR_FILEERROR, 1657 425 : Type.ERR_NOOPERMOTD, 1658 429 : Type.ERR_TOOMANYAWAY, 1659 430 : Type.ERR_EVENTNICKCHANGE, 1660 431 : Type.ERR_NONICKNAMEGIVEN, 1661 432 : Type.ERR_ERRONEOUSNICKNAME, 1662 433 : Type.ERR_NICKNAMEINUSE, 1663 434 : Type.ERR_NORULES, 1664 435 : Type.ERR_BANONCHAN, 1665 436 : Type.ERR_NICKCOLLISION, 1666 437 : Type.ERR_UNAVAILRESOURCE, 1667 438 : Type.ERR_NICKTOOFAST, 1668 439 : Type.ERR_TARGETTOOFAST, 1669 440 : Type.ERR_SERVICESDOWN, 1670 441 : Type.ERR_USERNOTINCHANNEL, 1671 442 : Type.ERR_NOTONCHANNEL, 1672 443 : Type.ERR_USERONCHANNEL, 1673 444 : Type.ERR_NOLOGIN, 1674 445 : Type.ERR_SUMMONDISABLED, 1675 446 : Type.ERR_USERSDISABLED, 1676 447 : Type.ERR_NONICKCHANGE, 1677 448 : Type.ERR_FORBIDDENCHANNEL, 1678 449 : Type.ERR_NOTIMPLEMENTED, 1679 451 : Type.ERR_NOTREGISTERED, 1680 452 : Type.ERR_IDCOLLISION, 1681 453 : Type.ERR_NICKLOST, 1682 455 : Type.ERR_HOSTILENAME, 1683 456 : Type.ERR_ACCEPTFULL, 1684 457 : Type.ERR_ACCEPTEXIST, 1685 458 : Type.ERR_ACCEPTNOT, 1686 459 : Type.ERR_NOHIDING, 1687 460 : Type.ERR_NOTFORHALFOPS, 1688 461 : Type.ERR_NEEDMOREPARAMS, 1689 462 : Type.ERR_ALREADYREGISTERED, 1690 463 : Type.ERR_NOPERMFORHOST, 1691 464 : Type.ERR_PASSWDMISMATCH, 1692 465 : Type.ERR_YOUREBANNEDCREEP, 1693 466 : Type.ERR_YOUWILLBEBANNED, 1694 467 : Type.ERR_KEYSET, 1695 468 : Type.ERR_INVALIDUSERNAME, 1696 469 : Type.ERR_LINKSET, 1697 470 : Type.ERR_LINKCHANNEL, 1698 471 : Type.ERR_CHANNELISFULL, 1699 472 : Type.ERR_UNKNOWNMODE, 1700 473 : Type.ERR_INVITEONLYCHAN, 1701 474 : Type.ERR_BANNEDFROMCHAN, 1702 475 : Type.ERR_BADCHANNELKEY, 1703 476 : Type.ERR_BADCHANMASK, 1704 477 : Type.ERR_NEEDREGGEDNICK, 1705 478 : Type.ERR_BANLISTFULL, 1706 479 : Type.ERR_BADCHANNAME, 1707 480 : Type.ERR_CANNOTKNOCK, 1708 481 : Type.ERR_NOPRIVILEGES, 1709 482 : Type.ERR_CHANOPRIVSNEEDED, 1710 483 : Type.ERR_CANTKILLSERVER, 1711 484 : Type.ERR_RESTRICTED, 1712 485 : Type.ERR_UNIQPRIVSNEEDED, 1713 486 : Type.ERR_NONONREG, 1714 487 : Type.ERR_MSGSERVICES, 1715 488 : Type.ERR_TSLESSCHAN, 1716 489 : Type.ERR_SECUREONLYCHAN, 1717 490 : Type.ERR_ALLMUSTSSL, 1718 491 : Type.ERR_NOOPERHOST, 1719 492 : Type.ERR_NOSERVICEHOST, 1720 493 : Type.ERR_NOFEATURE, 1721 494 : Type.ERR_BADFEATVALUE, 1722 495 : Type.ERR_BADLOGTYPE, 1723 496 : Type.ERR_BADLOGSYS, 1724 497 : Type.ERR_BADLOGVALUE, 1725 498 : Type.ERR_ISOPERLCHAN, 1726 499 : Type.ERR_CHANOWNPRIVNEEDED, 1727 500 : Type.ERR_TOOMANYJOINS, 1728 501 : Type.ERR_UMODEUNKNOWNFLAG, 1729 502 : Type.ERR_USERSDONTMATCH, 1730 503 : Type.ERR_GHOSTEDCLIENT, 1731 504 : Type.ERR_USERNOTONSERV, 1732 511 : Type.ERR_SILELISTFULL, 1733 512 : Type.ERR_TOOMANYWATCH, 1734 513 : Type.ERR_NEEDPONG, 1735 514 : Type.ERR_INVALID_ERROR, 1736 515 : Type.ERR_BADEXPIRE, 1737 516 : Type.ERR_DONTCHEAT, 1738 517 : Type.ERR_DISABLED, 1739 518 : Type.ERR_LONGMASK, 1740 519 : Type.ERR_TOOMANYUSERS, 1741 520 : Type.ERR_OPERONLY, 1742 521 : Type.ERR_LISTSYNTAX, 1743 522 : Type.ERR_WHOSYNTAX, 1744 523 : Type.ERR_WHOLIMEXCEED, 1745 524 : Type.ERR_HELPNOTFOUND, 1746 525 : Type.ERR_REMOTEPFX, 1747 526 : Type.ERR_PFXUNROUTABLE, 1748 531 : Type.ERR_CANTSENDTOUSER, 1749 550 : Type.ERR_BADHOSTMASK, 1750 551 : Type.ERR_HOSTUNAVAIL, 1751 552 : Type.ERR_USINGSLINE, 1752 553 : Type.ERR_STATSSLINE, 1753 560 : Type.ERR_NOTLOWEROPLEVEL, 1754 561 : Type.ERR_NOTMANAGER, 1755 562 : Type.ERR_CHANSECURED, 1756 563 : Type.ERR_UPASSSET, 1757 564 : Type.ERR_UPASSNOTSET, 1758 566 : Type.ERR_NOMANAGER, 1759 567 : Type.ERR_UPASS_SAME_APASS, 1760 568 : Type.ERR_LASTERROR, 1761 597 : Type.RPL_REAWAY, 1762 598 : Type.RPL_GONEAWAY, 1763 599 : Type.RPL_NOTAWAY, 1764 600 : Type.RPL_LOGON, 1765 601 : Type.RPL_LOGOFF, 1766 602 : Type.RPL_WATCHOFF, 1767 603 : Type.RPL_WATCHSTAT, 1768 604 : Type.RPL_NOWON, 1769 605 : Type.RPL_NOWFF, 1770 606 : Type.RPL_WATCHLIST, 1771 607 : Type.RPL_ENDOFWATCHLIST, 1772 608 : Type.RPL_WATCHCLEAR, 1773 609 : Type.RPL_NOWISAWAY, 1774 610 : Type.RPL_MAPMORE, 1775 611 : Type.RPL_ISLOCOP, 1776 612 : Type.RPL_ISNOTOPER, 1777 613 : Type.RPL_ENDOFISOPER, 1778 615 : Type.RPL_WHOISMODES, 1779 616 : Type.RPL_WHOISHOST, 1780 617 : Type.RPL_DCCSTATUS, 1781 618 : Type.RPL_DCCLIST, 1782 619 : Type.RPL_ENDOFDCCLIST, 1783 620 : Type.RPL_DCCINFO, 1784 621 : Type.RPL_RULES, 1785 622 : Type.RPL_ENDOFRULES, 1786 623 : Type.RPL_MAPMORE, 1787 624 : Type.RPL_OMOTDSTART, 1788 625 : Type.RPL_OMOTD, 1789 626 : Type.RPL_ENDOFO, 1790 630 : Type.RPL_SETTINGS, 1791 631 : Type.RPL_ENDOFSETTINGS, 1792 640 : Type.RPL_DUMPING, 1793 641 : Type.RPL_DUMPRPL, 1794 642 : Type.RPL_EODUMP, 1795 659 : Type.RPL_SPAMCMDFWD, 1796 660 : Type.RPL_TRACEROUTE_HOP, 1797 661 : Type.RPL_TRACEROUTE_START, 1798 662 : Type.RPL_MODECHANGEWARN, 1799 663 : Type.RPL_CHANREDIR, 1800 664 : Type.RPL_SERVMODEIS, 1801 665 : Type.RPL_OTHERUMODEIS, 1802 666 : Type.RPL_ENDOF_GENERIC, 1803 670 : Type.RPL_STARTTLS, 1804 671 : Type.RPL_WHOISSECURE, 1805 672 : Type.RPL_WHOISREALIP, 1806 673 : Type.RPL_CANNOTSETMODES, 1807 674 : Type.RPL_WHOISYOURID, 1808 678 : Type.RPL_LUSERSTAFF, 1809 679 : Type.RPL_TIMEONSERVERIS, 1810 682 : Type.RPL_NETWORKS, 1811 687 : Type.RPL_YOURLANGUAGEIS, 1812 688 : Type.RPL_LANGUAGE, 1813 689 : Type.RPL_WHOISSTAFF, 1814 690 : Type.RPL_WHOISLANGUAGE, 1815 691 : Type.ERR_STARTTLS, 1816 702 : Type.RPL_COMMANDS, 1817 703 : Type.RPL_COMMANDSEND, 1818 704 : Type.RPL_HELPSTART, 1819 705 : Type.RPL_HELPTXT, 1820 706 : Type.RPL_ENDOFHELP, 1821 707 : Type.ERR_TARGCHANGE, 1822 708 : Type.RPL_ETRACEFULL, 1823 709 : Type.RPL_ETRACE, 1824 710 : Type.RPL_KNOCK, 1825 711 : Type.RPL_KNOCKDLVR, 1826 712 : Type.ERR_TOOMANYKNOCK, 1827 713 : Type.ERR_CHANOPEN, 1828 714 : Type.ERR_KNOCKONCHAN, 1829 715 : Type.RPL_INVITETHROTTLE, 1830 716 : Type.RPL_TARGUMODEG, 1831 717 : Type.RPL_TARGNOTIFY, 1832 718 : Type.RPL_UMODEGMSG, 1833 720 : Type.RPL_OMOTDSTART, 1834 721 : Type.RPL_OMOTD, 1835 722 : Type.RPL_ENDOFOMOTD, 1836 723 : Type.ERR_NOPRIVS, 1837 724 : Type.RPL_TESTMASK, 1838 725 : Type.RPL_TESTLINE, 1839 726 : Type.RPL_NOTESTLINE, 1840 727 : Type.RPL_TESTMASKGECOS, 1841 728 : Type.RPL_QUIETLIST, 1842 729 : Type.RPL_ENDOFQUIETLIST, 1843 730 : Type.RPL_MONONLINE, 1844 731 : Type.RPL_MONOFFLINE, 1845 732 : Type.RPL_MONLIST, 1846 733 : Type.RPL_ENDOFMONLIST, 1847 734 : Type.ERR_MONLISTFULL, 1848 740 : Type.RPL_RSACHALLENGE2, 1849 741 : Type.RPL_ENDOFRSACHALLENGE2, 1850 742 : Type.ERR_MLOCKRESTRICTED, 1851 743 : Type.ERR_INVALIDBAN, 1852 744 : Type.ERR_TOPICLOCK, 1853 750 : Type.RPL_SCANMATCHED, 1854 751 : Type.RPL_SCANUMODES, 1855 759 : Type.RPL_ETRACEEND, 1856 760 : Type.RPL_WHOISKEYVALUE, 1857 761 : Type.RPL_KEYVALUE, 1858 762 : Type.RPL_METADATAEND, 1859 764 : Type.ERR_METADATALIMIT, 1860 765 : Type.ERR_TARGETINVALID, 1861 766 : Type.ERR_NOMATCHINGKEY, 1862 767 : Type.ERR_KEYINVALID, 1863 768 : Type.ERR_KEYNOTSET, 1864 769 : Type.ERR_KEYNOPERMISSION, 1865 771 : Type.RPL_XINFO, 1866 773 : Type.RPL_XINFOSTART, 1867 774 : Type.RPL_XINFOEND, 1868 802 : Type.RPL_CHECK, 1869 900 : Type.RPL_LOGGEDIN, 1870 901 : Type.RPL_LOGGEDOUT, 1871 902 : Type.ERR_NICKLOCKED, 1872 903 : Type.RPL_SASLSUCCESS, 1873 904 : Type.ERR_SASLFAIL, 1874 905 : Type.ERR_SASLTOOLONG, 1875 906 : Type.ERR_SASLABORTED, 1876 907 : Type.ERR_SASLALREADY, 1877 908 : Type.RPL_SASLMECHS, 1878 911 : Type.ENDOFCHANNELACCLIST, 1879 960 : Type.ENDOFMODELIST, 1880 961 : Type.MODELIST, 1881 931 : Type.BOTSNOTWELCOME, 1882 926 : Type.CHANNELFORBIDDEN, 1883 936 : Type.ERR_WORDFILTERED, 1884 940 : Type.ENDOFSPAMFILTERLIST, 1885 941 : Type.SPAMFILTERLIST, 1886 945 : Type.NICKUNLOCKED, 1887 946 : Type.NICKNOTLOCKED, 1888 972 : Type.ERR_CANNOTDOCOMMAND, 1889 973 : Type.ERR_CANNOTCHANGEUMODE, 1890 974 : Type.ERR_CANNOTCHANGECHANMODE, 1891 975 : Type.RPL_LOADEDMODULE, 1892 976 : Type.ERR_CANNOTSENDTONICK, 1893 977 : Type.ERR_UNKNOWNSERVERMODE, 1894 979 : Type.ERR_SERVERMODELOCK, 1895 980 : Type.ERR_BADCHARENCODING, 1896 981 : Type.ERR_TOOMANYLANGUAGES, 1897 982 : Type.ERR_NOLANGUAGE, 1898 983 : Type.ERR_TEXTTOOSHORT, 1899 999 : Type.ERR_NUMERIC_ERR, 1900 ]; 1901 1902 /++ 1903 Delta typenum mappings for servers running the `UnrealIRCd` daemon. 1904 1905 - https://www.unrealircd.org 1906 +/ 1907 static immutable Type[975] unreal = 1908 [ 1909 6 : Type.RPL_MAP, 1910 7 : Type.RPL_MAPEND, 1911 210 : Type.RPL_STATSHELP, 1912 220 : Type.RPL_STATSBLINE, 1913 222 : Type.RPL_SQLINE_NICK, 1914 223 : Type.RPL_STATSGLINE, 1915 224 : Type.RPL_STATSTLINE, 1916 225 : Type.RPL_STATSELINE, 1917 226 : Type.RPL_STATSNLINE, 1918 227 : Type.RPL_STATSVLINE, 1919 228 : Type.RPL_STATSBANVER, 1920 232 : Type.RPL_RULES, 1921 247 : Type.RPL_STATSXLINE, 1922 250 : Type.RPL_STATSCONN, 1923 290 : Type.RPL_HELPHDR, 1924 291 : Type.RPL_HELPOP, 1925 292 : Type.RPL_HELPTLR, 1926 293 : Type.RPL_HELPHLP, 1927 294 : Type.RPL_HELPFWD, 1928 295 : Type.RPL_HELPIGN, 1929 307 : Type.RPL_WHOISREGNICK, 1930 308 : Type.RPL_RULESSTART, 1931 309 : Type.RPL_ENDOFRULES, 1932 310 : Type.RPL_WHOISHELPOP, 1933 320 : Type.RPL_WHOISSPECIAL, 1934 334 : Type.RPL_LISTSYNTAX, 1935 335 : Type.RPL_WHOISBOT, 1936 378 : Type.RPL_WHOISHOST, 1937 379 : Type.RPL_WHOISMODES, 1938 386 : Type.RPL_QLIST, 1939 387 : Type.RPL_ENDOFQLIST, 1940 388 : Type.RPL_ALIST, 1941 434 : Type.ERR_NORULES, 1942 435 : Type.ERR_SERVICECONFUSED, 1943 438 : Type.ERR_ONLYSERVERSCANCHANGE, 1944 470 : Type.ERR_LINKCHANNEL, 1945 477 : Type.ERR_NEEDREGGEDNICK, 1946 479 : Type.ERR_LINKFAIL, 1947 480 : Type.ERR_CANNOTKNOCK, 1948 484 : Type.ERR_ATTACKDENY, 1949 485 : Type.ERR_KILLDENY, 1950 486 : Type.ERR_HTMDISABLED, // CONFLICT ERR_NONONREG 1951 487 : Type.ERR_NOTFORUSERS, 1952 488 : Type.ERR_HTMDISABLED, // again? 1953 489 : Type.ERR_SECUREONLYCHAN, // AKA ERR_SSLONLYCHAN 1954 490 : Type.ERR_ALLMUSTSSL, // CONFLICT ERR_NOSWEAR 1955 492 : Type.ERR_NOCTCP, 1956 500 : Type.ERR_TOOMANYJOINS, 1957 518 : Type.ERR_NOINVITE, 1958 519 : Type.ERR_ADMONLY, 1959 520 : Type.ERR_OPERONLY, 1960 524 : Type.ERR_OPERSPVERIFY, 1961 610 : Type.RPL_MAPMORE, 1962 972 : Type.ERR_CANNOTDOCOMMAND, 1963 974 : Type.ERR_CANNOTCHANGECHANMODE, 1964 ]; 1965 1966 /++ 1967 Delta typenum mappings for servers running the `ircu` (Undernet) daemon. 1968 1969 - http://coder-com.undernet.org 1970 +/ 1971 static immutable Type[569] ircu = 1972 [ 1973 15 : Type.RPL_MAP, 1974 16 : Type.RPL_MAPMORE, 1975 17 : Type.RPL_MAPEND, 1976 222 : Type.RPL_STATSJLINE, 1977 228 : Type.RPL_STATSQLINE, 1978 238 : Type.RPL_STATSFLINE, 1979 246 : Type.RPL_STATSTLINE, 1980 247 : Type.RPL_STATSGLINE, 1981 248 : Type.RPL_STATSULINE, 1982 250 : Type.RPL_STATSCONN, 1983 270 : Type.RPL_PRIVS, 1984 275 : Type.RPL_STATSDLINE, 1985 276 : Type.RPL_STATSRLINE, 1986 281 : Type.RPL_ENDOFGLIST, 1987 282 : Type.RPL_JUPELIST, 1988 283 : Type.RPL_ENDOFJUPELIST, 1989 284 : Type.RPL_FEATURE, 1990 330 : Type.RPL_WHOISACCOUNT, 1991 334 : Type.RPL_LISTUSAGE, 1992 338 : Type.RPL_WHOISACTUALLY, 1993 391 : Type.RPL_TIME, 1994 437 : Type.ERR_BANNICKCHANGE, 1995 438 : Type.ERR_NICKTOOFAST, 1996 468 : Type.ERR_INVALIDUSERNAME, 1997 477 : Type.ERR_NEEDREGGEDNICK, 1998 493 : Type.ERR_NOFEATURE, 1999 494 : Type.ERR_BADFEATVALUE, 2000 495 : Type.ERR_BADLOGTYPE, 2001 512 : Type.ERR_NOSUCHGLINE, 2002 514 : Type.ERR_INVALID_ERROR, 2003 518 : Type.ERR_LONGMASK, 2004 519 : Type.ERR_TOOMANYUSERS, 2005 520 : Type.ERR_MASKTOOWIDE, 2006 524 : Type.ERR_QUARANTINED, 2007 568 : Type.ERR_LASTERROR, 2008 ]; 2009 2010 /++ 2011 Delta typenum mappings for servers running the `aircd` (?) daemon. 2012 2013 "After AnotherNet had become a commercial and proprietary-client chat 2014 network, the former users of AnotherNet's #trax decided to found their 2015 own network - "where free speech and ideas would be able to run 2016 unbounded through the pastures of #trax and #coders". They use the 2017 "`aircd`" IRC daemon, coded by an ex-member of the demoscene, simon 2018 kirby." 2019 +/ 2020 static immutable Type[471] aircd = 2021 [ 2022 210 : Type.RPL_STATS, 2023 274 : Type.RPL_ENDNOTIFY, 2024 285 : Type.RPL_CHANINFO_HANDLE, 2025 286 : Type.RPL_CHANINFO_USERS, 2026 287 : Type.RPL_CHANINFO_CHOPS, 2027 288 : Type.RPL_CHANINFO_VOICES, 2028 289 : Type.RPL_CHANINFO_AWAY, 2029 290 : Type.RPL_CHANINFO_OPERS, 2030 291 : Type.RPL_CHANINFO_BANNED, 2031 292 : Type.RPL_CHANINFO_BANS, 2032 293 : Type.RPL_CHANINFO_INVITE, 2033 294 : Type.RPL_CHANINFO_INVITES, 2034 295 : Type.RPL_CHANINFO_KICKS, 2035 308 : Type.RPL_NOTIFYACTION, 2036 309 : Type.RPL_NICKTRACE, 2037 377 : Type.RPL_KICKEXPIRED, 2038 378 : Type.RPL_BANEXPIRED, 2039 379 : Type.RPL_KICKLINKED, 2040 380 : Type.RPL_BANLINKED, 2041 470 : Type.ERR_KICKEDFROMCHAN, 2042 ]; 2043 2044 /++ 2045 Delta typenum mappings for servers adhering to the `RFC1459` draft. 2046 2047 - https://tools.ietf.org/html/rfc1459 2048 +/ 2049 static immutable Type[502] rfc1459 = 2050 [ 2051 214 : Type.RPL_STATSNLINE, 2052 217 : Type.RPL_STATSQLINE, 2053 232 : Type.RPL_ENDOFSERVICES, 2054 316 : Type.RPL_WHOISCHANOP, // deprecated 2055 391 : Type.RPL_TIME, 2056 492 : Type.ERR_NOSERVICEHOST, 2057 501 : Type.ERR_UMODEUNKNOWNFLAG, 2058 ]; 2059 2060 /++ 2061 Delta typenum mappings for servers adhering to the `RFC2812` draft. 2062 2063 - https://tools.ietf.org/html/rfc2812 2064 +/ 2065 static immutable Type[485] rfc2812 = 2066 [ 2067 240 : Type.RPL_STATSVLINE, 2068 246 : Type.RPL_STATSPING, 2069 247 : Type.RPL_STATSBLINE, 2070 250 : Type.RPL_STATSDLINE, 2071 262 : Type.RPL_TRACEEND, 2072 325 : Type.RPL_UNIQOPIS, 2073 437 : Type.ERR_UNAVAILRESOURCE, 2074 477 : Type.ERR_NOCHANMODES, 2075 484 : Type.ERR_RESTRICTED, 2076 ]; 2077 2078 /++ 2079 Delta typenum mappings for servers running the `IRCD-Hybrid` daemon. 2080 2081 - http://www.ircd-hybrid.org 2082 +/ 2083 static immutable Type[716] hybrid = 2084 [ 2085 220 : Type.RPL_STATSPLINE, 2086 224 : Type.RPL_STATSFLINE, 2087 225 : Type.RPL_STATSDLINE, 2088 226 : Type.RPL_STATSALINE, 2089 245 : Type.RPL_STATSSLINE, // CONFLICT: Type.RPL_STATSTLINE 2090 246 : Type.RPL_STATSSERVICE, // CONFLICT: Type.RPL_STATSULINE 2091 247 : Type.RPL_STATSXLINE, 2092 249 : Type.RPL_STATSDEBUG, 2093 276 : Type.RPL_WHOISCERTFP, // oftc-hybrid? 2094 335 : Type.RPL_WHOISTEXT, 2095 336 : Type.RPL_INVITELIST, 2096 337 : Type.RPL_ENDOFINVITELIST, // CONFLICT: Type.RPL_WHOISTEXT 2097 344 : Type.RPL_QUIETLIST, // oftc 2098 345 : Type.RPL_ENDOFQUIETLIST, // CONFLICT: Type.RPL_INVITED, oftc 2099 386 : Type.RPL_RSACHALLENGE, 2100 396 : Type.RPL_VISIBLEHOST, 2101 408 : Type.ERR_NOCTRLSONCHAN, 2102 479 : Type.ERR_BADCHANNAME, 2103 480 : Type.ERR_SSLONLYCHAN, // deprecated 2104 484 : Type.ERR_DESYNC, 2105 485 : Type.ERR_CHANBANREASON, 2106 492 : Type.ERR_NOCTCP, 2107 503 : Type.ERR_GHOSTEDCLIENT, 2108 524 : Type.ERR_HELPNOTFOUND, 2109 715 : Type.ERR_TOOMANYINVITE, 2110 ]; 2111 2112 /++ 2113 Delta typenum mappings for servers running the `Solanum` daemon. 2114 2115 - https://github.com/solanum-ircd/solanum 2116 +/ 2117 static immutable Type[250] solanum = 2118 [ 2119 249 : Type.RPL_STATSPLINE, 2120 ]; 2121 2122 /++ 2123 Delta typenum mappings for servers running the `Bahamut` daemon 2124 (DALnet). 2125 2126 - https://www.dal.net/?page=bahamut 2127 +/ 2128 static immutable Type[621] bahamut = 2129 [ 2130 220 : Type.RPL_STATSBLINE, 2131 222 : Type.RPL_STATSBLINE, 2132 223 : Type.RPL_STATSELINE, 2133 224 : Type.RPL_STATSFLINE, 2134 225 : Type.RPL_STATSCLONE, // DEPRECATED CONFLICT: Type.RPL_STATSZLINE 2135 226 : Type.RPL_STATSCOUNT, 2136 227 : Type.RPL_STATSGLINE, 2137 245 : Type.RPL_STATSSLINE, 2138 275 : Type.RPL_USINGSSL, 2139 307 : Type.RPL_WHOISREGNICK, 2140 308 : Type.RPL_WHOISADMIN, 2141 309 : Type.RPL_WHOISADMIN, // duplicate? 2142 310 : Type.RPL_WHOISSVCMSG, 2143 334 : Type.RPL_COMMANDSYNTAX, 2144 338 : Type.RPL_WHOISACTUALLY, 2145 408 : Type.ERR_NOCOLORSONCHAN, 2146 435 : Type.ERR_BANONCHAN, 2147 468 : Type.ERR_ONLYSERVERSCANCHANGE, 2148 477 : Type.ERR_NEEDREGGEDNICK, 2149 484 : Type.ERR_DESYNC, 2150 487 : Type.ERR_MSGSERVICES, 2151 488 : Type.ERR_NOSSL, 2152 493 : Type.ERR_NOSHAREDCHAN, 2153 494 : Type.ERR_OWNMODE, 2154 512 : Type.ERR_TOOMANYWATCH, 2155 514 : Type.ERR_TOOMANYDCC, 2156 521 : Type.ERR_LISTSYNTAX, 2157 617 : Type.RPL_DCCSTATUS, 2158 619 : Type.RPL_ENDOFDCCLIST, 2159 620 : Type.RPL_DCCINFO, 2160 ]; 2161 2162 /++ 2163 Delta typenum mappings for servers running the `snircd` daemon 2164 (QuakeNet), based on `ircu`. 2165 2166 - https://development.quakenet.org 2167 +/ 2168 static immutable Type[554] snircd = 2169 [ 2170 285 : Type.RPL_NEWHOSTIS, 2171 286 : Type.RPL_CHKHEAD, 2172 287 : Type.RPL_CHANUSER, 2173 288 : Type.RPL_PATCHHEAD, 2174 289 : Type.RPL_PATCHCON, 2175 290 : Type.RPL_DATASTR, 2176 291 : Type.RPL_ENDOFCHECK, 2177 485 : Type.ERR_ISREALSERVICE, 2178 486 : Type.ERR_ACCOUNTONLY, 2179 553 : Type.ERR_STATSSLINE, 2180 ]; 2181 2182 /++ 2183 Delta typenum mappings for servers running the `Nefarious` or 2184 `Nefarious2` daemons, based on `ircu`. 2185 2186 - https://github.com/evilnet/nefarious 2187 - https://github.com/evilnet/nefarious2 2188 +/ 2189 static immutable Type[976] nefarious = 2190 [ 2191 220 : Type.RPL_STATSWLINE, 2192 292 : Type.ERR_SEARCHNOMATCH, 2193 316 : Type.RPL_WHOISPRIVDEAF, 2194 320 : Type.RPL_WHOISWEBIRC, 2195 335 : Type.RPL_WHOISACCOUNTONLY, 2196 336 : Type.RPL_WHOISBOT, 2197 339 : Type.RPL_WHOISMARKS, 2198 386 : Type.RPL_IRCOPSHEADER, 2199 387 : Type.RPL_IRCOPS, 2200 388 : Type.RPL_ENDOFIRCOPS, 2201 521 : Type.ERR_NOSUCHGLINE, 2202 568 : Type.RPL_NOMOTD, 2203 617 : Type.RPL_WHOISSSLFP, 2204 975 : Type.ERR_LASTERROR, 2205 ]; 2206 2207 /++ 2208 Delta typenum mappings for `RusNet` servers. Unsure of what daemon they 2209 run. 2210 2211 - http://www.rus-net.org 2212 +/ 2213 static immutable Type[501] rusnet = 2214 [ 2215 222 : Type.RPL_CODEPAGE, 2216 223 : Type.RPL_CHARSET, 2217 327 : Type.RPL_WHOISHOST, 2218 468 : Type.ERR_NOCODEPAGE, 2219 470 : Type.ERR_7BIT, 2220 479 : Type.ERR_NOCOLOR, 2221 480 : Type.ERR_NOWALLOP, 2222 486 : Type.ERR_RLINED, 2223 500 : Type.ERR_NOREHASHPARAM, 2224 ]; 2225 2226 /++ 2227 Delta typenum mappings for `Rizon` network servers. Supposedly they use 2228 a mixture of Hybrid typenums, plus a few of their own. 2229 2230 - https://www.rizon.net 2231 +/ 2232 static immutable Type[716] rizon = 2233 [ 2234 227 : Type.RPL_STATSBLINE, 2235 672 : Type.RPL_WHOISREALIP, 2236 715 : Type.RPL_INVITETHROTTLE, 2237 ]; 2238 2239 /++ 2240 Delta typenum mappings for `austHex` AUSTNet Development servers. 2241 2242 - https://sourceforge.net/projects/austhex 2243 +/ 2244 static immutable Type[521] austHex = 2245 [ 2246 240 : Type.RPL_STATSXLINE, 2247 307 : Type.RPL_SUSERHOST, 2248 309 : Type.RPL_WHOISHELPER, 2249 310 : Type.RPL_WHOISSERVICE, 2250 320 : Type.RPL_WHOISVIRT, 2251 357 : Type.RPL_MAP, 2252 358 : Type.RPL_MAPMORE, 2253 359 : Type.RPL_MAPEND, 2254 377 : Type.RPL_SPAM, // deprecated 2255 378 : Type.RPL_MOTD, 2256 380 : Type.RPL_YOURHELPER, 2257 434 : Type.ERR_SERVICENAMEINUSE, 2258 480 : Type.ERR_NOULINE, 2259 503 : Type.ERR_VWORLDWARN, 2260 520 : Type.ERR_WHOTRUNC, // deprecated 2261 ]; 2262 2263 /++ 2264 Delta typenum mappings for the `IRCnet` network of servers. Unsure of 2265 what server daemon they run. 2266 2267 - http://www.ircnet.org 2268 +/ 2269 static immutable Type[489] ircNet = 2270 [ 2271 245 : Type.RPL_STATSSLINE, 2272 248 : Type.RPL_STATSDEFINE, 2273 274 : Type.RPL_STATSDELTA, 2274 344 : Type.RPL_REOPLIST, 2275 345 : Type.RPL_ENDOFREOPLIST, 2276 438 : Type.ERR_DEAD, 2277 487 : Type.ERR_CHANTOORECENT, 2278 488 : Type.ERR_TSLESSCHAN, 2279 ]; 2280 2281 /++ 2282 Delta typenum mappings for servers running the `PTlink` daemon. 2283 2284 - https://sourceforge.net/projects/ptlinksoft 2285 +/ 2286 static immutable Type[616] ptlink = 2287 [ 2288 247 : Type.RPL_STATSXLINE, 2289 484 : Type.ERR_DESYNC, 2290 485 : Type.ERR_CANTKICKADMIN, 2291 615 : Type.RPL_MAPMORE, 2292 ]; 2293 2294 /++ 2295 Delta typenum mappings for servers running the `InspIRCd` daemon. 2296 2297 - http://www.inspircd.org 2298 +/ 2299 static immutable Type[976] inspIRCd = 2300 [ 2301 270 : Type.RPL_MAPUSERS, 2302 304 : Type.RPL_SYNTAX, 2303 379 : Type.RPL_WHOWASIP, // also encountered as Type.RPL_WHOISMODES? 2304 495 : Type.ERR_DELAYREJOIN, 2305 501 : Type.ERR_UNKNOWNSNOMASK, 2306 702 : Type.RPL_COMMANDS, 2307 703 : Type.RPL_COMMANDSEND, 2308 953 : Type.ENDOFEXEMPTOPSLIST, 2309 972 : Type.ERR_CANTUNLOADMODULE, 2310 974 : Type.ERR_CANTLOADMODULE, 2311 975 : Type.RPL_LOADEDMODULE 2312 ]; 2313 2314 /++ 2315 Delta typenum mapping for servers running the `ultimate` daemon. 2316 Based off of `Bahamut`. 2317 +/ 2318 static immutable Type[624] ultimate = 2319 [ 2320 275 : Type.RPL_USINGSSL, 2321 386 : Type.RPL_IRCOPS, 2322 387 : Type.RPL_ENDOFIRCOPS, 2323 434 : Type.ERR_NORULES, 2324 610 : Type.RPL_ISOPER, 2325 615 : Type.RPL_WHOISMODES, 2326 616 : Type.RPL_WHOISHOST, 2327 617 : Type.RPL_WHOISBOT, 2328 619 : Type.RPL_WHOWASHOST, 2329 620 : Type.RPL_RULESSTART, 2330 621 : Type.RPL_RULES, 2331 622 : Type.RPL_ENDOFRULES, 2332 623 : Type.RPL_MAPMORE, 2333 ]; 2334 2335 /++ 2336 Delta typenum mappings extending `ircu` typenums, for UnderNet. 2337 2338 - https://github.com/UndernetIRC/ircu2 2339 +/ 2340 static immutable Type[490] undernet = 2341 [ 2342 396 : Type.RPL_HOSTHIDDEN, 2343 484 : Type.ERR_ISCHANSERVICE, 2344 489 : Type.ERR_VOICENEEDED, 2345 ]; 2346 2347 /++ 2348 Delta typenum mapping for servers running the `ratbox` daemon. It is 2349 primarily used on EFnet. 2350 2351 - https://www.ratbox.org 2352 +/ 2353 static immutable Type[716] ratBox = 2354 [ 2355 480 : Type.ERR_THROTTLE, 2356 485 : Type.ERR_BANNEDNICK, // deprecated 2357 702 : Type.RPL_MODLIST, 2358 703 : Type.RPL_ENDOFMODLIST, 2359 715 : Type.ERR_KNOCKDISABLED, 2360 ]; 2361 2362 /++ 2363 Delta typenum mappings for servers running the `charybdis` daemon. 2364 2365 - https://github.com/charybdis-ircd/charybdis 2366 +/ 2367 static immutable Type[495] charybdis = 2368 [ 2369 492 : Type.ERR_CANNOTSENDTOUSER, 2370 494 : Type.ERR_OWNMODE, 2371 ]; 2372 2373 /++ 2374 Delta typenum mappings for servers running the `sorircd` daemon 2375 (SorceryNet). 2376 2377 - http://www.nongnu.org/snservices/sorircd.html 2378 +/ 2379 static immutable Type[326] sorircd = 2380 [ 2381 325 : Type.RPL_CHANNELMLOCKIS, // deprecated 2382 ]; 2383 2384 /* 2385 static immutable Type[321] anothernet = 2386 [ 2387 320 : Type.RPL_WHOIS_HIDDEN, 2388 ]; 2389 2390 static immutable Type[392] bdqIRCd = 2391 [ 2392 391 : Type.RPL_TIME, 2393 ]; 2394 2395 static immutable Type[488] chatIRCd = 2396 [ 2397 487 : Type.ERR_NONONSSL, 2398 ]; 2399 2400 static immutable Type[515] irch = 2401 [ 2402 514 : Type.ERR_NOSUCHJUPE, 2403 ]; 2404 2405 static immutable Type[672] ithildin = 2406 [ 2407 672 : Type.RPL_UNKNOWNMODES, 2408 ]; 2409 */ 2410 } 2411 2412 2413 // IRCChannel 2414 /++ 2415 Aggregate personifying an IRC channel and its state. 2416 2417 An IRC channel may have a topic, a creation date, and one or more *modes*. 2418 Modes define how the channel behaves and how it treats its users, including 2419 which ones have operator and voice status, as well as which are banned, and more. 2420 +/ 2421 struct IRCChannel 2422 { 2423 /++ 2424 A channel mode. 2425 2426 Some modes overwrite themselves; a channel may be `+i` or `-i`, never 2427 `i` twice. Others stack; a channel may have an arbitrary number of `b` 2428 bans. We try our best to support both. 2429 +/ 2430 static struct Mode 2431 { 2432 /++ 2433 The character that implies this [Mode] (`i`, `z`, `l` ...). 2434 +/ 2435 char modechar; 2436 2437 /++ 2438 The data associated with the [Mode], if applicable. This is often a 2439 number, such as what `l` takes (join limit). 2440 +/ 2441 string data; 2442 2443 /++ 2444 The user associated with the [Mode], when it is not just [Mode.data|data]. 2445 +/ 2446 IRCUser user; 2447 2448 /++ 2449 The channel this mode refers to, where applicable. 2450 +/ 2451 string channel; 2452 2453 /++ 2454 Users that are explicitly exempt from the [Mode]. 2455 +/ 2456 IRCUser[] exceptions; 2457 2458 /++ 2459 Whether or not this [Mode] should be considered to be its own antithesis. 2460 +/ 2461 bool negated; 2462 2463 /++ 2464 Compare two [Mode]s with each other to see if they are both of the 2465 same type, as well as having the same [data] and/or [user]. 2466 2467 Params: 2468 that = Other [Mode] to compare this one with. 2469 2470 Returns: 2471 `true` if the [Mode]s match, `false` if not. 2472 +/ 2473 auto opEquals(const Mode that) const pure @safe nothrow @nogc 2474 { 2475 // Ignore exemptions when comparing Modes 2476 immutable charMatch = (this.modechar == that.modechar); 2477 immutable dataMatch = (this.data == that.data); 2478 immutable userMatch = (this.user == that.user); // IRCUser.opEquals 2479 immutable chanMatch = (this.channel == that.channel); 2480 2481 immutable match = (charMatch && dataMatch && userMatch && chanMatch); 2482 return negated ? !match : match; 2483 } 2484 2485 /++ 2486 Produces a hash for this [Mode]. 2487 2488 Returns: 2489 A hash. 2490 +/ 2491 auto toHash() const pure @safe 2492 { 2493 import std.conv : text; 2494 return text(modechar, data, user.hashOf, channel, negated).hashOf; 2495 } 2496 } 2497 2498 /++ 2499 The channel name. 2500 +/ 2501 string name; 2502 2503 /++ 2504 The current topic of the channel, as set by operators. 2505 +/ 2506 string topic; 2507 2508 /++ 2509 The current non-[data]-sporting [Mode]s of the channel. 2510 +/ 2511 string modechars; 2512 2513 /++ 2514 Array of all [Mode]s that are not simply represented in [modechars]. 2515 +/ 2516 Mode[] modes; 2517 2518 /++ 2519 Associative array of all the nicknames inhabiting the channel. 2520 +/ 2521 bool[string] users; 2522 2523 /++ 2524 Associative array of nicknames with a prefixing channel mode (operator, 2525 halfops, voiced, ...) keyed by modechar. 2526 +/ 2527 bool[string][char] mods; 2528 2529 /++ 2530 Template to deduplicate code for mods shorthands. 2531 2532 Params: 2533 prefix = Mode character. 2534 2535 Returns: 2536 A `bool[string]` hashmap of all users with the given mode character 2537 as keys. 2538 +/ 2539 ref bool[string] modsShorthand(char prefix)() 2540 { 2541 auto modsOp = prefix in mods; 2542 2543 if (!modsOp) 2544 { 2545 this.mods[prefix][string.init] = false; 2546 modsOp = prefix in this.mods; 2547 (*modsOp).remove(string.init); 2548 } 2549 2550 return *modsOp; 2551 } 2552 2553 /++ 2554 Array of channel operators. 2555 +/ 2556 alias ops = modsShorthand!'o'; 2557 2558 /++ 2559 Array of channel halfops. 2560 +/ 2561 alias halfops = modsShorthand!'h'; 2562 2563 /++ 2564 Array of voiced channel users. 2565 +/ 2566 alias voiced = modsShorthand!'v'; 2567 2568 /++ 2569 When the channel was created, expressed in UNIX time. 2570 +/ 2571 long created; 2572 } 2573 2574 2575 // IRCClient 2576 /++ 2577 Aggregate collecting all the relevant settings, options and state needed for 2578 a connection to an IRC server. 2579 2580 Many fields are transient and unfit to be saved to disk. 2581 +/ 2582 struct IRCClient 2583 { 2584 /++ 2585 Client nickname. 2586 +/ 2587 string nickname; // = "kameloso"; 2588 2589 /++ 2590 Client "user". 2591 +/ 2592 string user; // = "kameloso"; 2593 2594 /++ 2595 Client GECOS/"real name". 2596 +/ 2597 string realName; // = "kameloso IRC bot"; 2598 2599 @Unserialisable 2600 { 2601 /++ 2602 The original client nickname before connecting, in case it changed. 2603 +/ 2604 string origNickname; 2605 2606 /++ 2607 Client IDENT identifier. Defaults to "~`user`". 2608 Unused but keep for future expansion. 2609 +/ 2610 string ident; 2611 2612 version(TwitchSupport) 2613 { 2614 /++ 2615 Our Twitch display name or alias. 2616 +/ 2617 string displayName; 2618 } 2619 2620 /++ 2621 The current modechars active on the client (e.g. "ix"); 2622 +/ 2623 string modes; 2624 } 2625 }