dispatch/pkg/irc/message.go

135 lines
2.2 KiB
Go
Raw Normal View History

2015-06-05 22:34:13 +00:00
package irc
import (
"strings"
)
type Message struct {
2018-04-29 01:49:02 +00:00
Tags map[string]string
Sender string
Ident string
Host string
2016-12-12 06:19:22 +00:00
Command string
Params []string
meta interface{}
2015-06-05 22:34:13 +00:00
}
2016-12-16 23:11:44 +00:00
func (m *Message) LastParam() string {
if len(m.Params) > 0 {
return m.Params[len(m.Params)-1]
}
return ""
2016-12-16 23:11:44 +00:00
}
func (m *Message) IsFromServer() bool {
return m.Sender == "" || strings.Contains(m.Sender, ".")
}
func (m *Message) ToCTCP() *CTCP {
2020-05-20 02:19:40 +00:00
return DecodeCTCP(m.LastParam())
}
func ParseMessage(line string) *Message {
2015-06-05 22:34:13 +00:00
msg := Message{}
2018-04-29 01:49:02 +00:00
if strings.HasPrefix(line, "@") {
next := strings.Index(line, " ")
if next == -1 {
return nil
}
tags := strings.Split(line[1:next], ";")
2018-04-29 01:49:02 +00:00
if len(tags) > 0 {
msg.Tags = map[string]string{}
for _, tag := range tags {
key, val := splitParam(tag)
if key == "" {
continue
}
if val != "" {
msg.Tags[key] = unescapeTag(val)
} else {
msg.Tags[key] = ""
}
2018-04-29 01:49:02 +00:00
}
}
for line[next+1] == ' ' {
next++
}
2018-04-29 01:49:02 +00:00
line = line[next+1:]
}
if strings.HasPrefix(line, ":") {
next := strings.Index(line, " ")
if next == -1 {
2017-07-03 05:35:38 +00:00
return nil
}
prefix := line[1:next]
2015-06-05 22:34:13 +00:00
if i := strings.Index(prefix, "!"); i > 0 {
msg.Sender = prefix[:i]
prefix = prefix[i+1:]
if i = strings.Index(prefix, "@"); i > 0 {
msg.Ident = prefix[:i]
msg.Host = prefix[i+1:]
} else {
msg.Ident = prefix
}
} else if i = strings.Index(prefix, "@"); i > 0 {
msg.Sender = prefix[:i]
msg.Host = prefix[i+1:]
2015-06-05 22:34:13 +00:00
} else {
msg.Sender = prefix
2015-06-05 22:34:13 +00:00
}
2018-04-29 01:49:02 +00:00
line = line[next+1:]
}
2016-12-12 06:19:22 +00:00
2018-04-29 01:49:02 +00:00
cmdEnd := len(line)
trailing := ""
if i := strings.Index(line, " :"); i >= 0 {
2015-06-05 22:34:13 +00:00
cmdEnd = i
2016-12-12 06:19:22 +00:00
trailing = line[i+2:]
2015-06-05 22:34:13 +00:00
}
2018-04-29 01:49:02 +00:00
cmd := strings.Fields(line[:cmdEnd])
if len(cmd) == 0 {
2017-07-03 05:35:38 +00:00
return nil
}
msg.Command = cmd[0]
2017-07-03 05:35:38 +00:00
2015-06-05 22:34:13 +00:00
if len(cmd) > 1 {
msg.Params = cmd[1:]
}
2017-07-03 05:35:38 +00:00
if cmdEnd != len(line) {
2016-12-12 06:19:22 +00:00
msg.Params = append(msg.Params, trailing)
2015-06-05 22:34:13 +00:00
}
return &msg
}
2018-04-28 18:31:44 +00:00
2018-04-29 01:49:02 +00:00
func splitParam(param string) (string, string) {
parts := strings.SplitN(param, "=", 2)
if len(parts) == 2 {
return parts[0], parts[1]
}
return parts[0], ""
}
2019-01-11 01:19:57 +00:00
var unescapeTagReplacer = strings.NewReplacer(
"\\:", ";",
"\\s", " ",
"\\\\", "\\",
"\\r", "\r",
"\\n", "\n",
)
2018-04-29 01:49:02 +00:00
func unescapeTag(s string) string {
2019-01-11 01:19:57 +00:00
return unescapeTagReplacer.Replace(s)
2018-04-29 01:49:02 +00:00
}