All checks were successful
check / check (push) Successful in 4s
- Rename MessageType to IRCMessageType (custom int type) - .Name() returns just the name (e.g. "RPL_LUSEROP") - .String() returns name + code (e.g. "RPL_LUSEROP <252>") - .Code() returns zero-padded 3-digit string (e.g. "252") - .Int() returns the bare int value - Add FromInt() package-level function with validation - Update all call sites to use new type and methods
392 lines
14 KiB
Go
392 lines
14 KiB
Go
// Package irc provides constants and utilities for the
|
|
// IRC protocol, including numeric reply codes from
|
|
// RFC 1459 and RFC 2812, and standard command names.
|
|
package irc
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
// IRCMessageType represents an IRC numeric reply or error code.
|
|
type IRCMessageType int //nolint:revive // Name requested by project owner.
|
|
|
|
// Name returns the standard IRC name for this numeric code
|
|
// (e.g., IRCMessageType(252).Name() returns "RPL_LUSEROP").
|
|
// Returns an empty string if the code is unknown.
|
|
func (t IRCMessageType) Name() string {
|
|
return names[t]
|
|
}
|
|
|
|
// String returns the name and numeric code in angle brackets
|
|
// (e.g., IRCMessageType(252).String() returns "RPL_LUSEROP <252>").
|
|
// If the code is unknown, returns "UNKNOWN <NNN>".
|
|
func (t IRCMessageType) String() string {
|
|
n := names[t]
|
|
if n == "" {
|
|
n = "UNKNOWN"
|
|
}
|
|
|
|
return fmt.Sprintf("%s <%03d>", n, int(t))
|
|
}
|
|
|
|
// Code returns the three-digit zero-padded string representation
|
|
// of the numeric code (e.g., IRCMessageType(252).Code() returns "252").
|
|
func (t IRCMessageType) Code() string {
|
|
return fmt.Sprintf("%03d", int(t))
|
|
}
|
|
|
|
// Int returns the bare integer value of the numeric code.
|
|
func (t IRCMessageType) Int() int {
|
|
return int(t)
|
|
}
|
|
|
|
// ErrUnknownNumeric is returned by FromInt when the numeric code is not recognized.
|
|
var ErrUnknownNumeric = errors.New("unknown IRC numeric code")
|
|
|
|
// FromInt converts an integer to an IRCMessageType, returning an error
|
|
// if the numeric code is not a known IRC reply or error code.
|
|
func FromInt(n int) (IRCMessageType, error) {
|
|
t := IRCMessageType(n)
|
|
if _, ok := names[t]; !ok {
|
|
return 0, fmt.Errorf("%w: %d", ErrUnknownNumeric, n)
|
|
}
|
|
|
|
return t, nil
|
|
}
|
|
|
|
// Connection registration replies (001-005).
|
|
const (
|
|
RplWelcome IRCMessageType = 1
|
|
RplYourHost IRCMessageType = 2
|
|
RplCreated IRCMessageType = 3
|
|
RplMyInfo IRCMessageType = 4
|
|
RplBounce IRCMessageType = 5 // RFC 2812; also known as RPL_ISUPPORT in practice
|
|
RplIsupport IRCMessageType = 5 // De-facto standard (same numeric as RplBounce)
|
|
)
|
|
|
|
// Command responses (200-399).
|
|
const (
|
|
// RFC 2812 trace/stats/links replies (200-219).
|
|
RplTraceLink IRCMessageType = 200
|
|
RplTraceConnecting IRCMessageType = 201
|
|
RplTraceHandshake IRCMessageType = 202
|
|
RplTraceUnknown IRCMessageType = 203
|
|
RplTraceOperator IRCMessageType = 204
|
|
RplTraceUser IRCMessageType = 205
|
|
RplTraceServer IRCMessageType = 206
|
|
RplTraceService IRCMessageType = 207
|
|
RplTraceNewType IRCMessageType = 208
|
|
RplTraceClass IRCMessageType = 209
|
|
RplStatsLinkInfo IRCMessageType = 211
|
|
RplStatsCommands IRCMessageType = 212
|
|
RplStatsCLine IRCMessageType = 213
|
|
RplStatsNLine IRCMessageType = 214
|
|
RplStatsILine IRCMessageType = 215
|
|
RplStatsKLine IRCMessageType = 216
|
|
RplStatsQLine IRCMessageType = 217
|
|
RplStatsYLine IRCMessageType = 218
|
|
RplEndOfStats IRCMessageType = 219
|
|
|
|
RplUmodeIs IRCMessageType = 221
|
|
RplServList IRCMessageType = 234
|
|
RplServListEnd IRCMessageType = 235
|
|
RplStatsLLine IRCMessageType = 241
|
|
RplStatsUptime IRCMessageType = 242
|
|
RplStatsOLine IRCMessageType = 243
|
|
RplStatsHLine IRCMessageType = 244
|
|
RplLuserClient IRCMessageType = 251
|
|
RplLuserOp IRCMessageType = 252
|
|
RplLuserUnknown IRCMessageType = 253
|
|
|
|
RplLuserChannels IRCMessageType = 254
|
|
RplLuserMe IRCMessageType = 255
|
|
RplAdminMe IRCMessageType = 256
|
|
RplAdminLoc1 IRCMessageType = 257
|
|
RplAdminLoc2 IRCMessageType = 258
|
|
RplAdminEmail IRCMessageType = 259
|
|
RplTraceLog IRCMessageType = 261
|
|
RplTraceEnd IRCMessageType = 262
|
|
RplTryAgain IRCMessageType = 263
|
|
|
|
RplAway IRCMessageType = 301
|
|
RplUserHost IRCMessageType = 302
|
|
RplIson IRCMessageType = 303
|
|
RplUnaway IRCMessageType = 305
|
|
RplNowAway IRCMessageType = 306
|
|
RplWhoisUser IRCMessageType = 311
|
|
RplWhoisServer IRCMessageType = 312
|
|
RplWhoisOperator IRCMessageType = 313
|
|
RplWhoWasUser IRCMessageType = 314
|
|
RplEndOfWho IRCMessageType = 315
|
|
RplWhoisIdle IRCMessageType = 317
|
|
RplEndOfWhois IRCMessageType = 318
|
|
RplWhoisChannels IRCMessageType = 319
|
|
RplListStart IRCMessageType = 321
|
|
RplList IRCMessageType = 322
|
|
RplListEnd IRCMessageType = 323
|
|
RplChannelModeIs IRCMessageType = 324
|
|
|
|
RplUniqOpIs IRCMessageType = 325
|
|
RplCreationTime IRCMessageType = 329
|
|
RplNoTopic IRCMessageType = 331
|
|
RplTopic IRCMessageType = 332
|
|
RplTopicWhoTime IRCMessageType = 333
|
|
RplInviting IRCMessageType = 341
|
|
RplSummoning IRCMessageType = 342
|
|
RplInviteList IRCMessageType = 346
|
|
RplEndOfInviteList IRCMessageType = 347
|
|
RplExceptList IRCMessageType = 348
|
|
RplEndOfExceptList IRCMessageType = 349
|
|
RplVersion IRCMessageType = 351
|
|
RplWhoReply IRCMessageType = 352
|
|
RplNamReply IRCMessageType = 353
|
|
RplLinks IRCMessageType = 364
|
|
RplEndOfLinks IRCMessageType = 365
|
|
RplEndOfNames IRCMessageType = 366
|
|
RplBanList IRCMessageType = 367
|
|
RplEndOfBanList IRCMessageType = 368
|
|
RplEndOfWhowas IRCMessageType = 369
|
|
RplInfo IRCMessageType = 371
|
|
RplMotd IRCMessageType = 372
|
|
RplEndOfInfo IRCMessageType = 374
|
|
RplMotdStart IRCMessageType = 375
|
|
RplEndOfMotd IRCMessageType = 376
|
|
RplYoureOper IRCMessageType = 381
|
|
RplRehashing IRCMessageType = 382
|
|
RplYoureService IRCMessageType = 383
|
|
RplTime IRCMessageType = 391
|
|
RplUsersStart IRCMessageType = 392
|
|
RplUsers IRCMessageType = 393
|
|
RplEndOfUsers IRCMessageType = 394
|
|
RplNoUsers IRCMessageType = 395
|
|
)
|
|
|
|
// Error replies (400-599).
|
|
const (
|
|
ErrNoSuchNick IRCMessageType = 401
|
|
ErrNoSuchServer IRCMessageType = 402
|
|
ErrNoSuchChannel IRCMessageType = 403
|
|
ErrCannotSendToChan IRCMessageType = 404
|
|
ErrTooManyChannels IRCMessageType = 405
|
|
ErrWasNoSuchNick IRCMessageType = 406
|
|
ErrTooManyTargets IRCMessageType = 407
|
|
ErrNoSuchService IRCMessageType = 408
|
|
ErrNoOrigin IRCMessageType = 409
|
|
ErrNoRecipient IRCMessageType = 411
|
|
ErrNoTextToSend IRCMessageType = 412
|
|
ErrNoTopLevel IRCMessageType = 413
|
|
ErrWildTopLevel IRCMessageType = 414
|
|
ErrBadMask IRCMessageType = 415
|
|
ErrUnknownCommand IRCMessageType = 421
|
|
ErrNoMotd IRCMessageType = 422
|
|
ErrNoAdminInfo IRCMessageType = 423
|
|
ErrFileError IRCMessageType = 424
|
|
ErrNoNicknameGiven IRCMessageType = 431
|
|
ErrErroneusNickname IRCMessageType = 432
|
|
ErrNicknameInUse IRCMessageType = 433
|
|
ErrNickCollision IRCMessageType = 436
|
|
ErrUnavailResource IRCMessageType = 437
|
|
|
|
ErrUserNotInChannel IRCMessageType = 441
|
|
ErrNotOnChannel IRCMessageType = 442
|
|
ErrUserOnChannel IRCMessageType = 443
|
|
ErrNoLogin IRCMessageType = 444
|
|
ErrSummonDisabled IRCMessageType = 445
|
|
ErrUsersDisabled IRCMessageType = 446
|
|
ErrNotRegistered IRCMessageType = 451
|
|
ErrNeedMoreParams IRCMessageType = 461
|
|
ErrAlreadyRegistered IRCMessageType = 462
|
|
ErrNoPermForHost IRCMessageType = 463
|
|
ErrPasswdMismatch IRCMessageType = 464
|
|
ErrYoureBannedCreep IRCMessageType = 465
|
|
ErrYouWillBeBanned IRCMessageType = 466
|
|
ErrKeySet IRCMessageType = 467
|
|
ErrChannelIsFull IRCMessageType = 471
|
|
ErrUnknownMode IRCMessageType = 472
|
|
ErrInviteOnlyChan IRCMessageType = 473
|
|
ErrBannedFromChan IRCMessageType = 474
|
|
ErrBadChannelKey IRCMessageType = 475
|
|
ErrBadChanMask IRCMessageType = 476
|
|
ErrNoChanModes IRCMessageType = 477
|
|
ErrBanListFull IRCMessageType = 478
|
|
ErrNoPrivileges IRCMessageType = 481
|
|
ErrChanOpPrivsNeeded IRCMessageType = 482
|
|
ErrCantKillServer IRCMessageType = 483
|
|
ErrRestricted IRCMessageType = 484
|
|
ErrUniqOpPrivsNeeded IRCMessageType = 485
|
|
ErrNoOperHost IRCMessageType = 491
|
|
|
|
ErrUmodeUnknownFlag IRCMessageType = 501
|
|
ErrUsersDoNotMatch IRCMessageType = 502
|
|
)
|
|
|
|
// names maps numeric codes to their standard IRC names.
|
|
//
|
|
//nolint:gochecknoglobals
|
|
var names = map[IRCMessageType]string{
|
|
RplWelcome: "RPL_WELCOME",
|
|
RplYourHost: "RPL_YOURHOST",
|
|
RplCreated: "RPL_CREATED",
|
|
RplMyInfo: "RPL_MYINFO",
|
|
RplBounce: "RPL_BOUNCE",
|
|
|
|
RplTraceLink: "RPL_TRACELINK",
|
|
RplTraceConnecting: "RPL_TRACECONNECTING",
|
|
RplTraceHandshake: "RPL_TRACEHANDSHAKE",
|
|
RplTraceUnknown: "RPL_TRACEUNKNOWN",
|
|
RplTraceOperator: "RPL_TRACEOPERATOR",
|
|
RplTraceUser: "RPL_TRACEUSER",
|
|
RplTraceServer: "RPL_TRACESERVER",
|
|
RplTraceService: "RPL_TRACESERVICE",
|
|
RplTraceNewType: "RPL_TRACENEWTYPE",
|
|
RplTraceClass: "RPL_TRACECLASS",
|
|
RplStatsLinkInfo: "RPL_STATSLINKINFO",
|
|
RplStatsCommands: "RPL_STATSCOMMANDS",
|
|
RplStatsCLine: "RPL_STATSCLINE",
|
|
RplStatsNLine: "RPL_STATSNLINE",
|
|
RplStatsILine: "RPL_STATSILINE",
|
|
RplStatsKLine: "RPL_STATSKLINE",
|
|
RplStatsQLine: "RPL_STATSQLINE",
|
|
RplStatsYLine: "RPL_STATSYLINE",
|
|
RplEndOfStats: "RPL_ENDOFSTATS",
|
|
|
|
RplUmodeIs: "RPL_UMODEIS",
|
|
RplServList: "RPL_SERVLIST",
|
|
RplServListEnd: "RPL_SERVLISTEND",
|
|
RplStatsLLine: "RPL_STATSLLINE",
|
|
RplStatsUptime: "RPL_STATSUPTIME",
|
|
RplStatsOLine: "RPL_STATSOLINE",
|
|
RplStatsHLine: "RPL_STATSHLINE",
|
|
RplLuserClient: "RPL_LUSERCLIENT",
|
|
RplLuserOp: "RPL_LUSEROP",
|
|
RplLuserUnknown: "RPL_LUSERUNKNOWN",
|
|
|
|
RplLuserChannels: "RPL_LUSERCHANNELS",
|
|
RplLuserMe: "RPL_LUSERME",
|
|
RplAdminMe: "RPL_ADMINME",
|
|
RplAdminLoc1: "RPL_ADMINLOC1",
|
|
RplAdminLoc2: "RPL_ADMINLOC2",
|
|
RplAdminEmail: "RPL_ADMINEMAIL",
|
|
RplTraceLog: "RPL_TRACELOG",
|
|
RplTraceEnd: "RPL_TRACEEND",
|
|
RplTryAgain: "RPL_TRYAGAIN",
|
|
|
|
RplAway: "RPL_AWAY",
|
|
RplUserHost: "RPL_USERHOST",
|
|
RplIson: "RPL_ISON",
|
|
RplUnaway: "RPL_UNAWAY",
|
|
RplNowAway: "RPL_NOWAWAY",
|
|
RplWhoisUser: "RPL_WHOISUSER",
|
|
RplWhoisServer: "RPL_WHOISSERVER",
|
|
RplWhoisOperator: "RPL_WHOISOPERATOR",
|
|
RplWhoWasUser: "RPL_WHOWASUSER",
|
|
RplEndOfWho: "RPL_ENDOFWHO",
|
|
RplWhoisIdle: "RPL_WHOISIDLE",
|
|
RplEndOfWhois: "RPL_ENDOFWHOIS",
|
|
RplWhoisChannels: "RPL_WHOISCHANNELS",
|
|
RplListStart: "RPL_LISTSTART",
|
|
RplList: "RPL_LIST",
|
|
RplListEnd: "RPL_LISTEND", //nolint:misspell
|
|
RplChannelModeIs: "RPL_CHANNELMODEIS",
|
|
|
|
RplUniqOpIs: "RPL_UNIQOPIS",
|
|
RplCreationTime: "RPL_CREATIONTIME",
|
|
RplNoTopic: "RPL_NOTOPIC",
|
|
RplTopic: "RPL_TOPIC",
|
|
RplTopicWhoTime: "RPL_TOPICWHOTIME",
|
|
RplInviting: "RPL_INVITING",
|
|
RplSummoning: "RPL_SUMMONING",
|
|
RplInviteList: "RPL_INVITELIST",
|
|
RplEndOfInviteList: "RPL_ENDOFINVITELIST",
|
|
RplExceptList: "RPL_EXCEPTLIST",
|
|
RplEndOfExceptList: "RPL_ENDOFEXCEPTLIST",
|
|
RplVersion: "RPL_VERSION",
|
|
RplWhoReply: "RPL_WHOREPLY",
|
|
RplNamReply: "RPL_NAMREPLY",
|
|
RplLinks: "RPL_LINKS",
|
|
RplEndOfLinks: "RPL_ENDOFLINKS",
|
|
RplEndOfNames: "RPL_ENDOFNAMES",
|
|
RplBanList: "RPL_BANLIST",
|
|
RplEndOfBanList: "RPL_ENDOFBANLIST",
|
|
RplEndOfWhowas: "RPL_ENDOFWHOWAS",
|
|
RplInfo: "RPL_INFO",
|
|
RplMotd: "RPL_MOTD",
|
|
RplEndOfInfo: "RPL_ENDOFINFO",
|
|
RplMotdStart: "RPL_MOTDSTART",
|
|
RplEndOfMotd: "RPL_ENDOFMOTD",
|
|
RplYoureOper: "RPL_YOUREOPER",
|
|
RplRehashing: "RPL_REHASHING",
|
|
RplYoureService: "RPL_YOURESERVICE",
|
|
RplTime: "RPL_TIME",
|
|
RplUsersStart: "RPL_USERSSTART",
|
|
RplUsers: "RPL_USERS",
|
|
RplEndOfUsers: "RPL_ENDOFUSERS",
|
|
RplNoUsers: "RPL_NOUSERS",
|
|
|
|
ErrNoSuchNick: "ERR_NOSUCHNICK",
|
|
ErrNoSuchServer: "ERR_NOSUCHSERVER",
|
|
ErrNoSuchChannel: "ERR_NOSUCHCHANNEL",
|
|
ErrCannotSendToChan: "ERR_CANNOTSENDTOCHAN",
|
|
ErrTooManyChannels: "ERR_TOOMANYCHANNELS",
|
|
ErrWasNoSuchNick: "ERR_WASNOSUCHNICK",
|
|
ErrTooManyTargets: "ERR_TOOMANYTARGETS",
|
|
ErrNoSuchService: "ERR_NOSUCHSERVICE",
|
|
ErrNoOrigin: "ERR_NOORIGIN",
|
|
ErrNoRecipient: "ERR_NORECIPIENT",
|
|
ErrNoTextToSend: "ERR_NOTEXTTOSEND",
|
|
ErrNoTopLevel: "ERR_NOTOPLEVEL",
|
|
ErrWildTopLevel: "ERR_WILDTOPLEVEL",
|
|
ErrBadMask: "ERR_BADMASK",
|
|
ErrUnknownCommand: "ERR_UNKNOWNCOMMAND",
|
|
ErrNoMotd: "ERR_NOMOTD",
|
|
ErrNoAdminInfo: "ERR_NOADMININFO",
|
|
ErrFileError: "ERR_FILEERROR",
|
|
ErrNoNicknameGiven: "ERR_NONICKNAMEGIVEN",
|
|
ErrErroneusNickname: "ERR_ERRONEUSNICKNAME",
|
|
ErrNicknameInUse: "ERR_NICKNAMEINUSE",
|
|
ErrNickCollision: "ERR_NICKCOLLISION",
|
|
ErrUnavailResource: "ERR_UNAVAILRESOURCE",
|
|
|
|
ErrUserNotInChannel: "ERR_USERNOTINCHANNEL",
|
|
ErrNotOnChannel: "ERR_NOTONCHANNEL",
|
|
ErrUserOnChannel: "ERR_USERONCHANNEL",
|
|
ErrNoLogin: "ERR_NOLOGIN",
|
|
ErrSummonDisabled: "ERR_SUMMONDISABLED",
|
|
ErrUsersDisabled: "ERR_USERSDISABLED",
|
|
ErrNotRegistered: "ERR_NOTREGISTERED",
|
|
ErrNeedMoreParams: "ERR_NEEDMOREPARAMS",
|
|
ErrAlreadyRegistered: "ERR_ALREADYREGISTERED",
|
|
ErrNoPermForHost: "ERR_NOPERMFORHOST",
|
|
ErrPasswdMismatch: "ERR_PASSWDMISMATCH",
|
|
ErrYoureBannedCreep: "ERR_YOUREBANNEDCREEP",
|
|
ErrYouWillBeBanned: "ERR_YOUWILLBEBANNED",
|
|
ErrKeySet: "ERR_KEYSET",
|
|
ErrChannelIsFull: "ERR_CHANNELISFULL",
|
|
ErrUnknownMode: "ERR_UNKNOWNMODE",
|
|
ErrInviteOnlyChan: "ERR_INVITEONLYCHAN",
|
|
ErrBannedFromChan: "ERR_BANNEDFROMCHAN",
|
|
ErrBadChannelKey: "ERR_BADCHANNELKEY",
|
|
ErrBadChanMask: "ERR_BADCHANMASK",
|
|
ErrNoChanModes: "ERR_NOCHANMODES",
|
|
ErrBanListFull: "ERR_BANLISTFULL",
|
|
ErrNoPrivileges: "ERR_NOPRIVILEGES",
|
|
ErrChanOpPrivsNeeded: "ERR_CHANOPRIVSNEEDED",
|
|
ErrCantKillServer: "ERR_CANTKILLSERVER",
|
|
ErrRestricted: "ERR_RESTRICTED",
|
|
ErrUniqOpPrivsNeeded: "ERR_UNIQOPPRIVSNEEDED",
|
|
ErrNoOperHost: "ERR_NOOPERHOST",
|
|
|
|
ErrUmodeUnknownFlag: "ERR_UMODEUNKNOWNFLAG",
|
|
ErrUsersDoNotMatch: "ERR_USERSDONTMATCH",
|
|
}
|
|
|
|
// Name returns the standard IRC name for a numeric code
|
|
// (e.g., Name(2) returns "RPL_YOURHOST"). Returns an
|
|
// empty string if the code is unknown.
|
|
//
|
|
// Deprecated: Use IRCMessageType.Name() instead.
|
|
func Name(code IRCMessageType) string {
|
|
return names[code]
|
|
}
|