forked from whyrusleeping/hellabot
/
message.go
145 lines (111 loc) · 2.72 KB
/
message.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package hbot
import (
"strings"
"time"
)
type Message struct {
// The message prefix contains information about who sent the message
*Prefix
// Content generally refers to the text of a PRIVMSG
Content string
// Message command, ie PRIVMSG, MODE, JOIN, NICK, etc
Command string
// Command parameters
// For example, which mode for MODE commands
Params []string
//Time at which this message was recieved
TimeStamp time.Time
// Entity that this message was addressed to (channel or user)
To string
// Nick of the messages sender (equivalent to Prefix.Name)
// Outdated, please use .Name
From string
// For debugging only, do not rely on this staying in the API
Raw string
}
type Prefix struct {
// The senders nick
Name string
// The senders username
User string
// The senders hostname
Host string
}
// Parse a string of text from the irc server into a Message struct
// Taken from: https://github.com/sorcix/irc
// All credit for this function goes to github user sorcix
func ParseMessage(line string) *Message {
// Ignore empty messages.
if line = strings.Trim(line, "\x20\r\n\x00"); len(line) < 2 {
return nil
}
mes := new(Message)
mes.Raw = line
var pref int
if line[0] == ':' {
pref = strings.IndexByte(line, ' ')
// Require prefix
if pref < 2 {
return nil
}
mes.Prefix = ParsePrefix(line[1:pref])
// Skip space at the end of the prefix
pref++
}
// Find end of command
cmd := pref + strings.IndexByte(line[pref:], ' ')
// Extract command
if cmd > pref {
mes.Command = line[pref:cmd]
} else {
mes.Command = line[pref:]
return mes
}
// Skip space
cmd++
// Find prefix for trailer
pref = strings.IndexByte(line[cmd:], ':')
if pref < 0 {
// There is no trailing argument!
mes.Params = strings.Split(line[cmd:], " ")
return mes
}
pref += cmd
if pref > cmd {
mes.Params = strings.Split(line[cmd:pref-1], " ")
}
// Everything after the last colon is the message contents
mes.Content = line[pref+1:]
if len(mes.Params) > 0 {
mes.To = mes.Params[0]
}
if mes.Prefix != nil {
mes.From = mes.Prefix.Name
}
mes.TimeStamp = time.Now()
return mes
}
// Parse user information from string
// format: nick!user@hostname
// Taken from: https://github.com/sorcix/irc
// All credit for this function goes to github user sorcix
func ParsePrefix(prefix string) *Prefix {
p := new(Prefix)
user := strings.IndexByte(prefix, '!')
host := strings.IndexByte(prefix, '@')
switch {
case user > 0 && host > user:
p.Name = prefix[:user]
p.User = prefix[user+1 : host]
p.Host = prefix[host+1:]
case user > 0:
p.Name = prefix[:user]
p.User = prefix[user+1:]
case host > 0:
p.Name = prefix[:host]
p.Host = prefix[host+1:]
default:
p.Name = prefix
}
return p
}