Complete IRC numerics module and move to pkg/irc/ (refs #52) #71

Merged
sneak merged 5 commits from feat/complete-irc-numerics into main 2026-03-10 18:41:27 +01:00
3 changed files with 171 additions and 153 deletions
Showing only changes of commit 164fec3fc8 - Show all commits

View File

@@ -746,7 +746,7 @@ func scanMessages(
code, _ := strconv.Atoi(msg.Command)
msg.Code = code
if name := irc.Name(code); name != "" {
if name := irc.Name(irc.MessageType(code)); name != "" {
msg.Command = name
}
}

View File

@@ -398,12 +398,12 @@ func (hdlr *Handlers) serverName() string {
func (hdlr *Handlers) enqueueNumeric(
ctx context.Context,
clientID int64,
code int,
code irc.MessageType,
nick string,
params []string,
text string,
) {
command := fmt.Sprintf("%03d", code)
command := code.String()
body, err := json.Marshal([]string{text})
if err != nil {
@@ -969,7 +969,7 @@ func (hdlr *Handlers) respondIRCError(
writer http.ResponseWriter,
request *http.Request,
clientID, sessionID int64,
code int,
code irc.MessageType,
nick string,
params []string,
text string,

View File

@@ -3,176 +3,194 @@
// RFC 1459 and RFC 2812, and standard command names.
package irc
import "fmt"
// MessageType represents an IRC numeric reply or error code.
type MessageType int
// Name returns the standard IRC name for this numeric code
// (e.g., MessageType(2).Name() returns "RPL_YOURHOST").
// Returns an empty string if the code is unknown.
func (t MessageType) Name() string {
return names[t]
}
// String returns the three-digit zero-padded string representation
// of the numeric code (e.g., MessageType(1).String() returns "001").
func (t MessageType) String() string {
return fmt.Sprintf("%03d", int(t))
}
// Connection registration replies (001-005).
const (
RplWelcome = 1
RplYourHost = 2
RplCreated = 3
RplMyInfo = 4
RplBounce = 5 // RFC 2812; also known as RPL_ISUPPORT in practice
RplIsupport = 5 // De-facto standard (same numeric as RplBounce)
RplWelcome MessageType = 1
RplYourHost MessageType = 2
RplCreated MessageType = 3
RplMyInfo MessageType = 4
RplBounce MessageType = 5 // RFC 2812; also known as RPL_ISUPPORT in practice
RplIsupport MessageType = 5 // De-facto standard (same numeric as RplBounce)
)
// Command responses (200-399).
const (
// RFC 2812 trace/stats/links replies (200-219).
RplTraceLink = 200
RplTraceConnecting = 201
RplTraceHandshake = 202
RplTraceUnknown = 203
RplTraceOperator = 204
RplTraceUser = 205
RplTraceServer = 206
RplTraceService = 207
RplTraceNewType = 208
RplTraceClass = 209
RplStatsLinkInfo = 211
RplStatsCommands = 212
RplStatsCLine = 213
RplStatsNLine = 214
RplStatsILine = 215
RplStatsKLine = 216
RplStatsQLine = 217
RplStatsYLine = 218
RplEndOfStats = 219
RplTraceLink MessageType = 200
RplTraceConnecting MessageType = 201
RplTraceHandshake MessageType = 202
RplTraceUnknown MessageType = 203
RplTraceOperator MessageType = 204
RplTraceUser MessageType = 205
RplTraceServer MessageType = 206
RplTraceService MessageType = 207
RplTraceNewType MessageType = 208
RplTraceClass MessageType = 209
RplStatsLinkInfo MessageType = 211
RplStatsCommands MessageType = 212
RplStatsCLine MessageType = 213
RplStatsNLine MessageType = 214
RplStatsILine MessageType = 215
RplStatsKLine MessageType = 216
RplStatsQLine MessageType = 217
RplStatsYLine MessageType = 218
RplEndOfStats MessageType = 219
RplUmodeIs = 221
RplServList = 234
RplServListEnd = 235
RplStatsLLine = 241
RplStatsUptime = 242
RplStatsOLine = 243
RplStatsHLine = 244
RplLuserClient = 251
RplLuserOp = 252
RplLuserUnknown = 253
RplUmodeIs MessageType = 221
RplServList MessageType = 234
RplServListEnd MessageType = 235
RplStatsLLine MessageType = 241
RplStatsUptime MessageType = 242
RplStatsOLine MessageType = 243
RplStatsHLine MessageType = 244
RplLuserClient MessageType = 251
RplLuserOp MessageType = 252
RplLuserUnknown MessageType = 253
RplLuserChannels = 254
RplLuserMe = 255
RplAdminMe = 256
RplAdminLoc1 = 257
RplAdminLoc2 = 258
RplAdminEmail = 259
RplTraceLog = 261
RplTraceEnd = 262
RplTryAgain = 263
RplLuserChannels MessageType = 254
RplLuserMe MessageType = 255
RplAdminMe MessageType = 256
RplAdminLoc1 MessageType = 257
RplAdminLoc2 MessageType = 258
RplAdminEmail MessageType = 259
RplTraceLog MessageType = 261
RplTraceEnd MessageType = 262
RplTryAgain MessageType = 263
RplAway = 301
RplUserHost = 302
RplIson = 303
RplUnaway = 305
RplNowAway = 306
RplWhoisUser = 311
RplWhoisServer = 312
RplWhoisOperator = 313
RplWhoWasUser = 314
RplEndOfWho = 315
RplWhoisIdle = 317
RplEndOfWhois = 318
RplWhoisChannels = 319
RplListStart = 321
RplList = 322
RplListEnd = 323
RplChannelModeIs = 324
RplAway MessageType = 301
RplUserHost MessageType = 302
RplIson MessageType = 303
RplUnaway MessageType = 305
RplNowAway MessageType = 306
RplWhoisUser MessageType = 311
RplWhoisServer MessageType = 312
RplWhoisOperator MessageType = 313
RplWhoWasUser MessageType = 314
RplEndOfWho MessageType = 315
RplWhoisIdle MessageType = 317
RplEndOfWhois MessageType = 318
RplWhoisChannels MessageType = 319
RplListStart MessageType = 321
RplList MessageType = 322
RplListEnd MessageType = 323
RplChannelModeIs MessageType = 324
RplUniqOpIs = 325
RplCreationTime = 329
RplNoTopic = 331
RplTopic = 332
RplTopicWhoTime = 333
RplInviting = 341
RplSummoning = 342
RplInviteList = 346
RplEndOfInviteList = 347
RplExceptList = 348
RplEndOfExceptList = 349
RplVersion = 351
RplWhoReply = 352
RplNamReply = 353
RplLinks = 364
RplEndOfLinks = 365
RplEndOfNames = 366
RplBanList = 367
RplEndOfBanList = 368
RplEndOfWhowas = 369
RplInfo = 371
RplMotd = 372
RplEndOfInfo = 374
RplMotdStart = 375
RplEndOfMotd = 376
RplYoureOper = 381
RplRehashing = 382
RplYoureService = 383
RplTime = 391
RplUsersStart = 392
RplUsers = 393
RplEndOfUsers = 394
RplNoUsers = 395
RplUniqOpIs MessageType = 325
RplCreationTime MessageType = 329
RplNoTopic MessageType = 331
RplTopic MessageType = 332
RplTopicWhoTime MessageType = 333
RplInviting MessageType = 341
RplSummoning MessageType = 342
RplInviteList MessageType = 346
RplEndOfInviteList MessageType = 347
RplExceptList MessageType = 348
RplEndOfExceptList MessageType = 349
RplVersion MessageType = 351
RplWhoReply MessageType = 352
RplNamReply MessageType = 353
RplLinks MessageType = 364
RplEndOfLinks MessageType = 365
RplEndOfNames MessageType = 366
RplBanList MessageType = 367
RplEndOfBanList MessageType = 368
RplEndOfWhowas MessageType = 369
RplInfo MessageType = 371
RplMotd MessageType = 372
RplEndOfInfo MessageType = 374
RplMotdStart MessageType = 375
RplEndOfMotd MessageType = 376
RplYoureOper MessageType = 381
RplRehashing MessageType = 382
RplYoureService MessageType = 383
RplTime MessageType = 391
RplUsersStart MessageType = 392
RplUsers MessageType = 393
RplEndOfUsers MessageType = 394
RplNoUsers MessageType = 395
)
// Error replies (400-599).
const (
ErrNoSuchNick = 401
ErrNoSuchServer = 402
ErrNoSuchChannel = 403
ErrCannotSendToChan = 404
ErrTooManyChannels = 405
ErrWasNoSuchNick = 406
ErrTooManyTargets = 407
ErrNoSuchService = 408
ErrNoOrigin = 409
ErrNoRecipient = 411
ErrNoTextToSend = 412
ErrNoTopLevel = 413
ErrWildTopLevel = 414
ErrBadMask = 415
ErrUnknownCommand = 421
ErrNoMotd = 422
ErrNoAdminInfo = 423
ErrFileError = 424
ErrNoNicknameGiven = 431
ErrErroneusNickname = 432
ErrNicknameInUse = 433
ErrNickCollision = 436
ErrUnavailResource = 437
ErrNoSuchNick MessageType = 401
ErrNoSuchServer MessageType = 402
ErrNoSuchChannel MessageType = 403
ErrCannotSendToChan MessageType = 404
ErrTooManyChannels MessageType = 405
ErrWasNoSuchNick MessageType = 406
ErrTooManyTargets MessageType = 407
ErrNoSuchService MessageType = 408
ErrNoOrigin MessageType = 409
ErrNoRecipient MessageType = 411
ErrNoTextToSend MessageType = 412
ErrNoTopLevel MessageType = 413
ErrWildTopLevel MessageType = 414
ErrBadMask MessageType = 415
ErrUnknownCommand MessageType = 421
ErrNoMotd MessageType = 422
ErrNoAdminInfo MessageType = 423
ErrFileError MessageType = 424
ErrNoNicknameGiven MessageType = 431
ErrErroneusNickname MessageType = 432
ErrNicknameInUse MessageType = 433
ErrNickCollision MessageType = 436
ErrUnavailResource MessageType = 437
ErrUserNotInChannel = 441
ErrNotOnChannel = 442
ErrUserOnChannel = 443
ErrNoLogin = 444
ErrSummonDisabled = 445
ErrUsersDisabled = 446
ErrNotRegistered = 451
ErrNeedMoreParams = 461
ErrAlreadyRegistered = 462
ErrNoPermForHost = 463
ErrPasswdMismatch = 464
ErrYoureBannedCreep = 465
ErrYouWillBeBanned = 466
ErrKeySet = 467
ErrChannelIsFull = 471
ErrUnknownMode = 472
ErrInviteOnlyChan = 473
ErrBannedFromChan = 474
ErrBadChannelKey = 475
ErrBadChanMask = 476
ErrNoChanModes = 477
ErrBanListFull = 478
ErrNoPrivileges = 481
ErrChanOpPrivsNeeded = 482
ErrCantKillServer = 483
ErrRestricted = 484
ErrUniqOpPrivsNeeded = 485
ErrNoOperHost = 491
ErrUserNotInChannel MessageType = 441
ErrNotOnChannel MessageType = 442
ErrUserOnChannel MessageType = 443
ErrNoLogin MessageType = 444
ErrSummonDisabled MessageType = 445
ErrUsersDisabled MessageType = 446
ErrNotRegistered MessageType = 451
ErrNeedMoreParams MessageType = 461
ErrAlreadyRegistered MessageType = 462
ErrNoPermForHost MessageType = 463
ErrPasswdMismatch MessageType = 464
ErrYoureBannedCreep MessageType = 465
ErrYouWillBeBanned MessageType = 466
ErrKeySet MessageType = 467
ErrChannelIsFull MessageType = 471
ErrUnknownMode MessageType = 472
ErrInviteOnlyChan MessageType = 473
ErrBannedFromChan MessageType = 474
ErrBadChannelKey MessageType = 475
ErrBadChanMask MessageType = 476
ErrNoChanModes MessageType = 477
ErrBanListFull MessageType = 478
ErrNoPrivileges MessageType = 481
ErrChanOpPrivsNeeded MessageType = 482
ErrCantKillServer MessageType = 483
ErrRestricted MessageType = 484
ErrUniqOpPrivsNeeded MessageType = 485
ErrNoOperHost MessageType = 491
ErrUmodeUnknownFlag = 501
ErrUsersDoNotMatch = 502
ErrUmodeUnknownFlag MessageType = 501
ErrUsersDoNotMatch MessageType = 502
)
// names maps numeric codes to their standard IRC names.
//
//nolint:gochecknoglobals
var names = map[int]string{
var names = map[MessageType]string{
RplWelcome: "RPL_WELCOME",
RplYourHost: "RPL_YOURHOST",
RplCreated: "RPL_CREATED",
@@ -332,6 +350,6 @@ var names = map[int]string{
// 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.
func Name(code int) string {
func Name(code MessageType) string {
return names[code]
}