diff options
| author | ilotterytea <iltsu@alright.party> | 2025-08-03 14:12:54 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2025-08-03 14:12:54 +0500 |
| commit | c2432518c6ae67afa40c68c2a466ba34728e5de6 (patch) | |
| tree | ca6f6205af364bcbf68ee18b25b31efa31480ea1 | |
| parent | 33e5475c770a9fda9ca98bb9d4d012349e4b5beb (diff) | |
feat: parse irc messages
| -rw-r--r-- | internal/client.go | 9 | ||||
| -rw-r--r-- | internal/message.go | 64 |
2 files changed, 71 insertions, 2 deletions
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 +} |
