spongy/spongyd/irc.go

132 lines
2.1 KiB
Go

package main
import (
"strconv"
"strings"
)
type Message struct {
Unparsed string
Command string
FullSender string
Sender string
Forum string
Args []string
Text string
}
func NewMessage(v string) (Message, error) {
var m Message
var parts []string
var lhs string
m.Unparsed = v
parts = strings.SplitN(v, " :", 2)
if len(parts) == 2 {
lhs = parts[0]
m.Text = parts[1]
} else {
lhs = v
m.Text = ""
}
m.FullSender = "."
m.Forum = "."
m.Sender = "."
parts = strings.Split(lhs, " ")
if parts[0][0] == ':' {
m.FullSender = parts[0][1:]
parts = parts[1:]
n, u, _ := SplitTarget(m.FullSender)
if u != "" {
m.Sender = n
}
}
m.Command = strings.ToUpper(parts[0])
switch m.Command {
case "PRIVMSG", "NOTICE":
switch {
case IsChannel(parts[1]):
m.Forum = parts[1]
case m.FullSender == ".":
m.Forum = parts[1]
default:
m.Forum = m.Sender
}
case "PART", "MODE", "TOPIC", "KICK":
m.Forum = parts[1]
m.Args = parts[2:]
case "JOIN":
if len(parts) == 1 {
m.Forum = m.Text
m.Text = ""
} else {
m.Forum = parts[1]
}
case "INVITE":
if m.Text != "" {
m.Forum = m.Text
m.Text = ""
} else {
m.Forum = parts[2]
}
case "NICK":
if len(parts) > 1 {
m.Sender = parts[1]
m.Args = parts[2:]
} else {
m.Sender = m.Text
m.Text = ""
m.Args = parts[1:]
}
m.Forum = m.Sender
case "353":
m.Forum = parts[3]
default:
numeric, _ := strconv.Atoi(m.Command)
if numeric >= 300 {
if len(parts) > 2 {
m.Forum = parts[2]
}
}
m.Args = parts[1:]
}
return m, nil
}
func (m Message) String() string {
return m.Unparsed
}
func SplitTarget(s string) (string, string, string) {
var parts []string
parts = strings.SplitN(s, "!", 2)
if len(parts) == 1 {
return s, "", ""
}
nick := parts[0]
parts = strings.SplitN(parts[1], "@", 2)
if len(parts) == 1 {
return s, "", ""
}
return nick, parts[0], parts[1]
}
func IsChannel(s string) bool {
if s == "" {
return false
}
switch s[0] {
case '#', '+', '!', '&':
return true
default:
return false
}
}