2 Commits

Author SHA1 Message Date
a193831ed4 fix: extract repeated IRC command string literals to constants (goconst)
All checks were successful
check / check (push) Successful in 2m18s
2026-03-09 15:07:02 -07:00
clawbot
8d26df60db feat: implement IRC numerics batch 2 — connection registration, channel ops, user queries
Add comprehensive IRC numeric reply support:

Connection registration (001-005):
- 002 RPL_YOURHOST, 003 RPL_CREATED, 004 RPL_MYINFO, 005 RPL_ISUPPORT
- All sent automatically during session creation after RPL_WELCOME

Server statistics (251-255):
- RPL_LUSERCLIENT, RPL_LUSEROP, RPL_LUSERCHANNELS, RPL_LUSERME
- Sent during connection registration and via LUSERS command

Channel operations:
- MODE command: query channel modes (324 RPL_CHANNELMODEIS, 329 RPL_CREATIONTIME)
- MODE command: query user modes (221 RPL_UMODEIS)
- NAMES command: query channel member list (353/366)
- LIST command: list all channels (322 RPL_LIST, 323 end of list)

User queries:
- WHOIS command: 311/312/318/319 numerics
- WHO command: 352 RPL_WHOREPLY, 315 RPL_ENDOFWHO

Database additions:
- GetChannelCount, ListAllChannelsWithCounts
- GetChannelCreatedAt, GetSessionCreatedAt

Also adds StartTime to Globals for RPL_CREATED and updates README
with comprehensive documentation of all new commands and numerics.

closes #52
2026-03-09 15:04:10 -07:00

View File

@@ -27,7 +27,15 @@ const (
defaultMaxBodySize = 4096
defaultHistLimit = 50
maxHistLimit = 500
cmdJoin = "JOIN"
cmdList = "LIST"
cmdNick = "NICK"
cmdPart = "PART"
cmdPrivmsg = "PRIVMSG"
cmdQuit = "QUIT"
cmdTopic = "TOPIC"
cmdWho = "WHO"
cmdWhois = "WHOIS"
)
func (hdlr *Handlers) maxBodySize() int64 {
@@ -756,32 +764,32 @@ func (hdlr *Handlers) dispatchCommand(
sessionID, clientID, nick,
command, target, body, bodyLines,
)
case "JOIN":
case cmdJoin:
hdlr.handleJoin(
writer, request,
sessionID, clientID, nick, target,
)
case "PART":
case cmdPart:
hdlr.handlePart(
writer, request,
sessionID, clientID, nick, target, body,
)
case "NICK":
case cmdNick:
hdlr.handleNick(
writer, request,
sessionID, clientID, nick, bodyLines,
)
case "TOPIC":
case cmdTopic:
hdlr.handleTopic(
writer, request,
sessionID, clientID, nick,
target, body, bodyLines,
)
case "QUIT":
case cmdQuit:
hdlr.handleQuit(
writer, request, sessionID, nick, body,
)
case "MOTD", "LIST", "WHO", "WHOIS", "PING":
case "MOTD", cmdList, cmdWho, cmdWhois, "PING":
hdlr.dispatchInfoCommand(
writer, request,
sessionID, clientID, nick,
@@ -815,18 +823,18 @@ func (hdlr *Handlers) dispatchQueryCommand(
writer, request,
sessionID, clientID, nick, target,
)
case "LIST":
case cmdList:
hdlr.handleList(
writer, request,
sessionID, clientID, nick,
)
case "WHOIS":
case cmdWhois:
hdlr.handleWhois(
writer, request,
sessionID, clientID, nick,
target, bodyLines,
)
case "WHO":
case cmdWho:
hdlr.handleWho(
writer, request,
sessionID, clientID, nick, target,
@@ -1073,7 +1081,7 @@ func (hdlr *Handlers) handleJoin(
if target == "" {
hdlr.respondIRCError(
writer, request, clientID, sessionID,
"461", nick, []string{"JOIN"},
"461", nick, []string{cmdJoin},
"Not enough parameters",
)
@@ -1144,7 +1152,7 @@ func (hdlr *Handlers) executeJoin(
)
_ = hdlr.fanOutSilent(
request, "JOIN", nick, channel, nil, memberIDs,
request, cmdJoin, nick, channel, nil, memberIDs,
)
hdlr.deliverJoinNumerics(
@@ -1242,7 +1250,7 @@ func (hdlr *Handlers) handlePart(
if target == "" {
hdlr.enqueueNumeric(
request.Context(), clientID,
"461", nick, []string{"PART"},
"461", nick, []string{cmdPart},
"Not enough parameters",
)
hdlr.broker.Notify(sessionID)
@@ -1280,7 +1288,7 @@ func (hdlr *Handlers) handlePart(
)
_ = hdlr.fanOutSilent(
request, "PART", nick, channel, body, memberIDs,
request, cmdPart, nick, channel, body, memberIDs,
)
err = hdlr.params.Database.PartChannel(
@@ -1322,7 +1330,7 @@ func (hdlr *Handlers) handleNick(
if len(lines) == 0 {
hdlr.respondIRCError(
writer, request, clientID, sessionID,
"461", nick, []string{"NICK"},
"461", nick, []string{cmdNick},
"Not enough parameters",
)
@@ -1420,7 +1428,7 @@ func (hdlr *Handlers) broadcastNick(
}
dbID, _, _ := hdlr.params.Database.InsertMessage(
request.Context(), "NICK", oldNick, "",
request.Context(), cmdNick, oldNick, "",
nil, json.RawMessage(nickBody), nil,
)
@@ -1461,7 +1469,7 @@ func (hdlr *Handlers) handleTopic(
if target == "" {
hdlr.respondIRCError(
writer, request, clientID, sessionID,
"461", nick, []string{"TOPIC"},
"461", nick, []string{cmdTopic},
"Not enough parameters",
)
@@ -1472,7 +1480,7 @@ func (hdlr *Handlers) handleTopic(
if len(lines) == 0 {
hdlr.respondIRCError(
writer, request, clientID, sessionID,
"461", nick, []string{"TOPIC"},
"461", nick, []string{cmdTopic},
"Not enough parameters",
)
@@ -1534,7 +1542,7 @@ func (hdlr *Handlers) executeTopic(
)
_ = hdlr.fanOutSilent(
request, "TOPIC", nick, channel, body, memberIDs,
request, cmdTopic, nick, channel, body, memberIDs,
)
hdlr.enqueueNumeric(
@@ -1567,16 +1575,16 @@ func (hdlr *Handlers) dispatchInfoCommand(
hdlr.deliverMOTD(
request, clientID, sessionID, nick,
)
case "LIST":
case cmdList:
hdlr.handleListCmd(
request, clientID, sessionID, nick,
)
case "WHO":
case cmdWho:
hdlr.handleWhoCmd(
request, clientID, sessionID, nick,
target,
)
case "WHOIS":
case cmdWhois:
hdlr.handleWhoisCmd(
request, clientID, sessionID, nick,
target, bodyLines,
@@ -1657,7 +1665,7 @@ func (hdlr *Handlers) handleWhoCmd(
if target == "" {
hdlr.enqueueNumeric(
ctx, clientID, "461", nick,
[]string{"WHO"}, "Not enough parameters",
[]string{cmdWho}, "Not enough parameters",
)
hdlr.broker.Notify(sessionID)
@@ -1728,7 +1736,7 @@ func (hdlr *Handlers) handleWhoisCmd(
if whoisNick == "" {
hdlr.enqueueNumeric(
ctx, clientID, "461", nick,
[]string{"WHOIS"}, "Not enough parameters",
[]string{cmdWhois}, "Not enough parameters",
)
hdlr.broker.Notify(sessionID)
@@ -1831,7 +1839,7 @@ func (hdlr *Handlers) handleQuit(
if len(channels) > 0 {
dbID, _, _ = hdlr.params.Database.InsertMessage(
request.Context(), "QUIT", nick, "",
request.Context(), cmdQuit, nick, "",
nil, body, nil,
)
}
@@ -2100,7 +2108,7 @@ func (hdlr *Handlers) handleWhois(
if queryNick == "" {
hdlr.respondIRCError(
writer, request, clientID, sessionID,
"461", nick, []string{"WHOIS"},
"461", nick, []string{cmdWhois},
"Not enough parameters",
)
@@ -2211,7 +2219,7 @@ func (hdlr *Handlers) handleWho(
if target == "" {
hdlr.respondIRCError(
writer, request, clientID, sessionID,
"461", nick, []string{"WHO"},
"461", nick, []string{cmdWho},
"Not enough parameters",
)
@@ -2499,7 +2507,7 @@ func (hdlr *Handlers) cleanupUser(
if len(channels) > 0 {
quitDBID, _, _ = hdlr.params.Database.InsertMessage(
ctx, "QUIT", nick, "",
ctx, cmdQuit, nick, "",
nil, nil, nil,
)
}