feat: add traditional IRC wire protocol listener on configurable port
All checks were successful
check / check (push) Successful in 58s

Add a backward-compatible IRC protocol listener (RFC 1459/2812) that
allows standard IRC clients (irssi, weechat, hexchat, etc.) to connect
directly via TCP.

Key features:
- TCP listener on configurable port (IRC_LISTEN_ADDR env var, e.g. :6667)
- Full IRC wire protocol parsing and formatting
- Connection registration (NICK + USER + optional PASS)
- Channel operations: JOIN, PART, MODE, TOPIC, NAMES, LIST, KICK, INVITE
- Messaging: PRIVMSG, NOTICE (channel and direct)
- Info commands: WHO, WHOIS, LUSERS, MOTD, AWAY
- Operator support: OPER (with configured credentials)
- PING/PONG keepalive
- CAP negotiation (for modern client compatibility)
- Full bridge to HTTP/JSON API (shared DB, broker, sessions)
- Real-time message relay via broker notifications
- Comprehensive test suite (parser + integration tests)

The IRC listener is an optional component — disabled when IRC_LISTEN_ADDR
is empty (the default). The Broker is now an Fx-provided dependency shared
between HTTP handlers and the IRC server.

closes #89
This commit is contained in:
user
2026-03-25 13:00:39 -07:00
parent e62962d192
commit 42157a7b23
15 changed files with 3814 additions and 2 deletions

View File

@@ -2,11 +2,13 @@
package main
import (
"git.eeqj.de/sneak/neoirc/internal/broker"
"git.eeqj.de/sneak/neoirc/internal/config"
"git.eeqj.de/sneak/neoirc/internal/db"
"git.eeqj.de/sneak/neoirc/internal/globals"
"git.eeqj.de/sneak/neoirc/internal/handlers"
"git.eeqj.de/sneak/neoirc/internal/healthcheck"
"git.eeqj.de/sneak/neoirc/internal/ircserver"
"git.eeqj.de/sneak/neoirc/internal/logger"
"git.eeqj.de/sneak/neoirc/internal/middleware"
"git.eeqj.de/sneak/neoirc/internal/server"
@@ -28,16 +30,22 @@ func main() {
fx.New(
fx.Provide(
broker.New,
config.New,
db.New,
globals.New,
handlers.New,
ircserver.New,
logger.New,
server.New,
middleware.New,
healthcheck.New,
stats.New,
),
fx.Invoke(func(*server.Server) {}),
fx.Invoke(func(
_ *server.Server,
_ *ircserver.Server,
) {
}),
).Run()
}