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
|
2016-12-12 06:19:22 +00:00
|
|
|
Prefix string
|
|
|
|
Nick string
|
|
|
|
Command string
|
|
|
|
Params []string
|
2015-06-05 22:34:13 +00:00
|
|
|
}
|
|
|
|
|
2016-12-16 23:11:44 +00:00
|
|
|
func (m *Message) LastParam() string {
|
2017-06-21 05:20:31 +00:00
|
|
|
if len(m.Params) > 0 {
|
|
|
|
return m.Params[len(m.Params)-1]
|
|
|
|
}
|
|
|
|
return ""
|
2016-12-16 23:11:44 +00:00
|
|
|
}
|
|
|
|
|
2020-05-21 03:24:26 +00:00
|
|
|
func (m *Message) IsFromServer() bool {
|
|
|
|
return m.Nick == "" || strings.Contains(m.Nick, ".")
|
|
|
|
}
|
|
|
|
|
2020-05-03 15:00:41 +00:00
|
|
|
func (m *Message) ToCTCP() *CTCP {
|
2020-05-20 02:19:40 +00:00
|
|
|
return DecodeCTCP(m.LastParam())
|
2020-05-03 15:00:41 +00:00
|
|
|
}
|
|
|
|
|
2019-01-11 03:53:50 +00:00
|
|
|
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], ";")
|
2016-12-16 22:49:37 +00:00
|
|
|
|
2018-04-29 01:49:02 +00:00
|
|
|
if len(tags) > 0 {
|
|
|
|
msg.Tags = map[string]string{}
|
|
|
|
|
2019-01-11 03:53:50 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-11 03:53:50 +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
|
2016-12-16 22:49:37 +00:00
|
|
|
}
|
2018-04-29 01:49:02 +00:00
|
|
|
msg.Prefix = line[1:next]
|
2015-06-05 22:34:13 +00:00
|
|
|
|
|
|
|
if i := strings.Index(msg.Prefix, "!"); i > 0 {
|
|
|
|
msg.Nick = msg.Prefix[:i]
|
2015-06-10 20:53:29 +00:00
|
|
|
} else if i := strings.Index(msg.Prefix, "@"); i > 0 {
|
|
|
|
msg.Nick = msg.Prefix[:i]
|
2015-06-05 22:34:13 +00:00
|
|
|
} else {
|
|
|
|
msg.Nick = msg.Prefix
|
|
|
|
}
|
|
|
|
|
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 := ""
|
2019-01-11 03:53:50 +00:00
|
|
|
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])
|
2018-04-27 00:56:35 +00:00
|
|
|
if len(cmd) == 0 {
|
2017-07-03 05:35:38 +00:00
|
|
|
return nil
|
|
|
|
}
|
2018-04-27 00:56:35 +00:00
|
|
|
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
|
|
|
}
|