mirror of
https://github.com/gissleh/irc.git
synced 2026-10-19 00:12:53 +00:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
package irc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var unescapeTags = strings.NewReplacer("\\\\", "\\", "\\:", ";", "\\s", " ", "\\r", "\r", "\\n", "\n")
|
||||
|
||||
// ParsePacket parses and irc line and returns an event that's either of kind `packet`, `ctcp` or `ctcpreply`
|
||||
func ParsePacket(line string) (Event, error) {
|
||||
event := Event{Time: time.Now()}
|
||||
|
||||
if len(line) == 0 {
|
||||
return event, errors.New("irc: empty line")
|
||||
}
|
||||
|
||||
// Parse tags
|
||||
if line[0] == '@' {
|
||||
split := strings.SplitN(line, " ", 2)
|
||||
if len(split) < 2 {
|
||||
return event, errors.New("irc: incomplete packet")
|
||||
}
|
||||
|
||||
tagTokens := strings.Split(split[0][1:], ";")
|
||||
for _, token := range tagTokens {
|
||||
kv := strings.SplitN(token, "=", 2)
|
||||
|
||||
if len(kv) == 2 {
|
||||
event.Tags[kv[0]] = unescapeTags.Replace(kv[1])
|
||||
} else {
|
||||
event.Tags[kv[0]] = ""
|
||||
}
|
||||
}
|
||||
|
||||
line = split[1]
|
||||
}
|
||||
|
||||
// Parse prefix
|
||||
if line[0] == ':' {
|
||||
split := strings.SplitN(line, " ", 2)
|
||||
if len(split) < 2 {
|
||||
return event, errors.New("ParsePacket: incomplete packet")
|
||||
}
|
||||
|
||||
prefixTokens := strings.Split(split[0][1:], "!")
|
||||
|
||||
event.Nick = prefixTokens[0]
|
||||
if len(split) > 1 {
|
||||
userhost := strings.Split(prefixTokens[1], "@")
|
||||
|
||||
if len(userhost) < 2 {
|
||||
return event, errors.New("ParsePacket: invalid user@host format")
|
||||
}
|
||||
|
||||
event.User = userhost[0]
|
||||
event.Host = userhost[1]
|
||||
}
|
||||
|
||||
line = split[1]
|
||||
}
|
||||
|
||||
// Parse body
|
||||
split := strings.Split(line, " :")
|
||||
tokens := strings.Split(split[0], " ")
|
||||
|
||||
if len(split) == 2 {
|
||||
event.Text = split[1]
|
||||
}
|
||||
|
||||
event.verb = tokens[0]
|
||||
event.Args = tokens[1:]
|
||||
|
||||
// Parse CTCP
|
||||
if (event.verb == "PRIVMSG" || event.verb == "NOTICE") && strings.HasPrefix(event.Text, "\x01") {
|
||||
verbtext := strings.SplitN(strings.Replace(event.Text, "\x01", "", 2), " ", 2)
|
||||
|
||||
event.verb = verbtext[0]
|
||||
if len(verbtext) == 2 {
|
||||
event.Text = verbtext[1]
|
||||
} else {
|
||||
event.Text = ""
|
||||
}
|
||||
|
||||
if event.verb == "PRIVMSG" {
|
||||
event.kind = "ctcp"
|
||||
} else {
|
||||
event.kind = "ctcp-reply"
|
||||
}
|
||||
}
|
||||
|
||||
return event, nil
|
||||
}
|
||||
Reference in New Issue
Block a user