summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/client.go9
-rw-r--r--internal/message.go64
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
+}