From c2432518c6ae67afa40c68c2a466ba34728e5de6 Mon Sep 17 00:00:00 2001 From: ilotterytea Date: Sun, 3 Aug 2025 14:12:54 +0500 Subject: feat: parse irc messages --- internal/client.go | 9 ++++++-- internal/message.go | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 internal/message.go (limited to 'internal') diff --git a/internal/client.go b/internal/client.go index c0373a0..8adc12c 100644 --- a/internal/client.go +++ b/internal/client.go @@ -8,6 +8,7 @@ import ( "net" "net/textproto" "slices" + "strings" ) type IRCClient struct { @@ -50,11 +51,15 @@ func (c *IRCClient) Connect() (err error) { tp := textproto.NewReader(bufio.NewReader(c.conn)) for { - message, err := tp.ReadLine() + raw, err := tp.ReadLine() if err != nil { log.Panicf("Failed to read a line: %v\n", err) } - log.Printf("IRC message: %s\n", message) + + for _, line := range strings.Split(raw, "\r\n") { + message := ParseIRCMessage(line) + log.Printf("IRC message: %s\n", message) + } } } diff --git a/internal/message.go b/internal/message.go new file mode 100644 index 0000000..e8df9a4 --- /dev/null +++ b/internal/message.go @@ -0,0 +1,64 @@ +package irclogs + +import "strings" + +type IRCMessage struct { + Tags map[string]string + Nick string + Command string + Params []string +} + +func ParseIRCMessage(message string) IRCMessage { + message = strings.TrimRight(message, "\r\n") + msg := IRCMessage{ + Tags: make(map[string]string), + } + + if strings.HasPrefix(message, "@") { + end := strings.IndexByte(message, ' ') + rawTags := message[1:end] + + for _, tag := range strings.Split(rawTags, ";") { + parts := strings.SplitN(tag, "=", 2) + if len(parts) == 2 { + msg.Tags[parts[0]] = parts[1] + } else { + msg.Tags[parts[0]] = "true" + } + } + + message = message[end+1:] + } + + if strings.HasPrefix(message, ":") { + end := strings.IndexByte(message, ' ') + prefix := message[1:end] + if bang := strings.IndexByte(prefix, '!'); bang != -1 { + msg.Nick = prefix[:bang] + } + message = message[end+1:] + } + + parts := strings.Split(message, " ") + if len(parts) == 0 { + return msg + } + + msg.Command = parts[0] + parts = parts[1:] + + for i := 0; i < len(parts); i++ { + if len(parts[i]) == 0 { + continue + } + if parts[i][0] == ':' { + param := strings.Join(parts[i:], " ")[1:] + msg.Params = append(msg.Params, param) + break + } + msg.Params = append(msg.Params, parts[i]) + } + + return msg +} -- cgit v1.2.3