Neale Pickett
·
2016-01-18
irc.go
1package main
2
3import (
4 "strconv"
5 "strings"
6)
7
8type Message struct {
9 Unparsed string
10 Command string
11 FullSender string
12 Sender string
13 Forum string
14 Args []string
15 Text string
16}
17
18func NewMessage(v string) (Message, error) {
19 var m Message
20 var parts []string
21 var lhs string
22
23 m.Unparsed = v
24 parts = strings.SplitN(v, " :", 2)
25 if len(parts) == 2 {
26 lhs = parts[0]
27 m.Text = parts[1]
28 } else {
29 lhs = v
30 m.Text = ""
31 }
32
33 m.FullSender = "."
34 m.Forum = "."
35 m.Sender = "."
36
37 parts = strings.Split(lhs, " ")
38 if parts[0][0] == ':' {
39 m.FullSender = parts[0][1:]
40 parts = parts[1:]
41
42 n, u, _ := SplitTarget(m.FullSender)
43 if u != "" {
44 m.Sender = n
45 }
46 }
47
48 m.Command = strings.ToUpper(parts[0])
49 switch m.Command {
50 case "PRIVMSG", "NOTICE":
51 switch {
52 case IsChannel(parts[1]):
53 m.Forum = parts[1]
54 case m.FullSender == ".":
55 m.Forum = parts[1]
56 default:
57 m.Forum = m.Sender
58 }
59 case "PART", "MODE", "TOPIC", "KICK":
60 m.Forum = parts[1]
61 m.Args = parts[2:]
62 case "JOIN":
63 if len(parts) == 1 {
64 m.Forum = m.Text
65 m.Text = ""
66 } else {
67 m.Forum = parts[1]
68 }
69 case "INVITE":
70 if m.Text != "" {
71 m.Forum = m.Text
72 m.Text = ""
73 } else {
74 m.Forum = parts[2]
75 }
76 case "NICK":
77 if len(parts) > 1 {
78 m.Sender = parts[1]
79 m.Args = parts[2:]
80 } else {
81 m.Sender = m.Text
82 m.Text = ""
83 m.Args = parts[1:]
84 }
85 m.Forum = m.Sender
86 case "353":
87 m.Forum = parts[3]
88 default:
89 numeric, _ := strconv.Atoi(m.Command)
90 if numeric >= 300 {
91 if len(parts) > 2 {
92 m.Forum = parts[2]
93 }
94 }
95 m.Args = parts[1:]
96 }
97
98 return m, nil
99}
100
101func (m Message) String() string {
102 return m.Unparsed
103}
104
105func SplitTarget(s string) (string, string, string) {
106 var parts []string
107
108 parts = strings.SplitN(s, "!", 2)
109 if len(parts) == 1 {
110 return s, "", ""
111 }
112 nick := parts[0]
113 parts = strings.SplitN(parts[1], "@", 2)
114 if len(parts) == 1 {
115 return s, "", ""
116 }
117 return nick, parts[0], parts[1]
118}
119
120func IsChannel(s string) bool {
121 if s == "" {
122 return false
123 }
124
125 switch s[0] {
126 case '#', '+', '!', '&':
127 return true
128 default:
129 return false
130 }
131}