-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmessage_handler.go
More file actions
302 lines (282 loc) · 11 KB
/
message_handler.go
File metadata and controls
302 lines (282 loc) · 11 KB
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
package main
import (
"errors"
"fmt"
"strconv"
"strings"
"time"
"github.com/gempir/go-twitch-irc/v2"
)
func (rat *ChatRat) messageParser(message twitch.PrivateMessage) {
//If the user is ignored then just don't listen. Unless they're the streamer, then listen regardless.
if rat.isUserIgnored(message.User.Name) && !strings.EqualFold(message.User.Name, rat.ratSettings.StreamName) {
return
}
messageStrings := strings.Split(message.Message, " ")
for i, v := range rat.ratSettings.EmotesToSpam {
if contains(messageStrings, v) {
rat.log(Debug, "Heard "+v+" for emote spamming")
rat.timerCleaner(i)
rat.emoteTimers[i] = append(rat.emoteTimers[i], time.Now())
if (len(rat.emoteTimers[i]) >= rat.ratSettings.EmoteSpamThreshold) && rat.emoteLastTime[i].Add(rat.emoteSpamCooldown).Before(time.Now()) {
rat.speak(v)
rat.log(Info, "Triggered "+v+" emote spam")
rat.emoteLastTime[i] = time.Now()
}
}
}
messageLength := len(messageStrings)
//Checks if the message is a command. If it's not, then just listen and add it to what can be said if it should be.
if messageLength <= 0 || messageStrings[0] != rat.ratSettings.CommandStarter {
rat.writeText(message.Message)
loaded, badword := rat.LoadPhrase(message.Message)
if loaded {
rat.log(Info, "Heard \""+message.Message+"\" and added it to the model")
} else {
rat.log(Info, "Heard \""+message.Message+"\" and didn't add it to the model because I saw \""+badword+"\"")
}
return
}
if messageLength <= 1 {
return
}
if !rat.isUserTrusted(message.User.Name) && !strings.EqualFold(message.User.Name, rat.ratSettings.StreamName) {
rat.speak("Hi " + message.User.DisplayName + ", I only let trusted people tell me what to do, but I guess you can say my name if you like =^.^=")
rat.log(Info, "Heard command from "+message.User.Name+" but they're not trusted")
return
}
switch messageStrings[1] {
case "delay":
rat.speak(fmt.Sprintf("@%s the current delay is set to %s", message.User.Name, rat.chatDelay.duration))
case "set": //Setting ChatRat variables
if messageLength <= 2 {
rat.speak("@" + message.User.Name + " I couldn't understand you, I only saw you say \"" + rat.ratSettings.CommandStarter + " set\" without anything else.")
return
}
switch messageStrings[2] {
case "delay": //Setting the delay between messages
dur, err := durationParse(messageStrings[3:])
if err != nil {
rat.speak(err.Error())
}
rat.chatDelay.mu.RLock()
rat.log(Info, fmt.Sprintf("chat delay duration updating from [%s] to [%s]", rat.chatDelay.duration, dur))
rat.chatDelay.ticker.Stop()
rat.chatDelay.duration = dur
rat.chatDelay.ticker.Reset(dur)
rat.chatDelay.mu.RUnlock()
rat.ratSettings.ChatDelay = dur.String()
rat.ratSettings.saveSettings()
case "contextDepth": //Setting the context depth of the markov chain text generation
if messageLength <= 3 {
rat.speak(fmt.Sprintf("Current context depth is %d", rat.ratSettings.ChatContextDepth))
return
}
num, err := strconv.ParseInt(messageStrings[3], 10, 0)
if err != nil {
rat.log(Warning, "Couldn't read the context depth given. command was \""+message.Message+"\" error given: "+err.Error())
return
}
if num < 0 {
rat.speak("I can't have less than 0 context")
return
}
rat.log(Debug, fmt.Sprintf("Starting to reload context depth to %d at %s", num, time.Now().String()))
rat.speak("@" + message.User.Name + " I'm re-learning what to say, this may take a bit...")
rat.reloadGraph(int(num))
rat.speak("Okay, I know how to talk again.")
rat.ratSettings.ChatContextDepth = int(num)
rat.log(Debug, "Finished reloading context depth at "+time.Now().String())
rat.ratSettings.saveSettings()
case "emoteSpamThreshold":
if messageLength <= 3 {
rat.speak(fmt.Sprintf("Current emote spam threshold is %d", rat.ratSettings.ChatContextDepth))
return
}
num, err := strconv.ParseInt(messageStrings[3], 10, 0)
if err != nil {
rat.log(Warning, "Couldn't read the emote spam threshold given. command was \""+message.Message+"\" error given: "+err.Error())
return
}
if num < 0 {
rat.log(Warning, "Emote spam threshold set to 0, may cause excessive spamming")
rat.speak("I will respond after every emote sent I guess")
}
rat.ratSettings.EmoteSpamThreshold = int(num)
rat.speak(fmt.Sprintf("I'll join in saying emotes I know after %d people have said them in %s", num, rat.ratSettings.emoteSpamTimeout.String()))
rat.log(Info, "Emote spam threshold set to "+messageStrings[3])
rat.ratSettings.saveSettings()
case "emoteSpamTimeout":
dur, err := durationParse(messageStrings[3:])
if err != nil {
rat.speak(err.Error())
}
rat.speak(fmt.Sprintf("emote spam timeout changed from [%s] to [%s]", rat.ratSettings.emoteSpamTimeout, dur.String()))
rat.log(Info, "Emote spam timeout set to "+dur.String())
rat.ratSettings.emoteSpamTimeout = dur
rat.ratSettings.EmoteSpamTimeout = dur.String()
rat.ratSettings.saveSettings()
case "emoteSpamCooldown":
dur, err := durationParse(messageStrings[3:])
if err != nil {
rat.speak(err.Error())
}
rat.speak(fmt.Sprintf("emote spam cooldown changed from [%s] to [%s]", rat.ratSettings.emoteSpamTimeout, dur.String()))
rat.log(Info, "Emote spam cooldown set to "+dur.String())
rat.ratSettings.emoteSpamCooldown = dur
rat.ratSettings.EmoteSpamCooldown = dur.String()
rat.ratSettings.saveSettings()
}
case "stop":
rat.chatDelay.mu.RLock()
rat.chatDelay.ticker.Stop()
rat.chatDelay.paused = true
rat.chatDelay.mu.RUnlock()
rat.speak("Alright, I'll stop talking for now")
rat.log(Warning, "Chatrat was stopped by "+message.User.DisplayName)
case "start":
rat.chatDelay.mu.RLock()
rat.chatDelay.ticker.Reset(rat.chatDelay.duration)
rat.chatDelay.paused = false
rat.chatDelay.mu.RUnlock()
rat.speak("Yay I get to talk again!")
rat.log(Warning, "Chatrat was started by "+message.User.DisplayName)
case "ignore":
if messageLength > 2 {
rat.speak("Sorry @" + messageStrings[2] + ", I can't talk to you anymore")
rat.ratSettings.ignoreUser(messageStrings[2])
rat.log(Warning, message.User.DisplayName+" ignored "+messageStrings[2])
return
}
rat.speak("@" + message.User.Name + " I didn't see a user to ignore.")
case "unignore":
if messageLength <= 2 {
return
}
unignored := rat.ratSettings.unignoreUser(messageStrings[2])
if unignored {
rat.speak("Okay, I'll listen to what @" + messageStrings[2] + " has to say again.")
rat.log(Warning, message.User.DisplayName+" unignored "+messageStrings[2])
} else {
rat.speak("@" + message.User.Name + ", " + messageStrings[2] + " wasn't ignored before.")
}
case "trust":
if messageLength > 2 {
rat.speak("Okay @" + messageStrings[2] + ", I'll let you tell me things to do")
rat.ratSettings.trustUser(messageStrings[2])
rat.log(Warning, message.User.DisplayName+" trusted "+messageStrings[2])
return
}
rat.speak("@" + message.User.Name + " I didn't see a user to trust.")
case "untrust":
if messageLength <= 2 {
return
}
untrusted := rat.ratSettings.untrustUser(messageStrings[2])
if untrusted {
rat.speak("Sorry @" + messageStrings[2] + ", I can't listen to commands from you anymore")
rat.log(Warning, message.User.DisplayName+" untrusted "+messageStrings[2])
} else {
rat.speak("@" + message.User.Name + ", " + messageStrings[2] + " wasn't trusted before.")
}
case "speak":
words := rat.graph.GenerateMarkovString()
spoken := rat.speak(words)
for !spoken {
words = rat.graph.GenerateMarkovString()
spoken = rat.speak(words)
}
rat.log(Info, "Saying \""+words+"\" after being told to speak")
case "reloadBlacklist":
err := rat.ratSettings.reloadBlacklist()
if err != nil {
rat.speak("I couldn't understand the blacklist anymore")
rat.log(Warning, err.Error())
return
}
rat.log(Info, "Reloading blacklist at request of "+message.User.DisplayName)
rat.speak("I'm re-learning what to say while ignoring the new bad words. This may take a bit.")
rat.reloadGraph(rat.ratSettings.ChatContextDepth)
rat.speak("Okay, I know how to talk now.")
case "spam":
if len(messageStrings) > 2 {
if !contains(rat.ratSettings.EmotesToSpam, messageStrings[2]) {
rat.ratSettings.EmotesToSpam = append(rat.ratSettings.EmotesToSpam, messageStrings[2])
rat.emoteTimers = append(rat.emoteTimers, make([]time.Time, 0))
rat.emoteLastTime = append(rat.emoteLastTime, time.Now())
}
}
rat.ratSettings.saveSettings()
rat.speak("I will now spam " + messageStrings[2] + " with the crowd.")
rat.log(Info, message.User.Name+" requested spamming of "+messageStrings[2]+" with the crowd")
case "dontspam", "dontSpam", "stopSpamming", "stopspamming":
emotestospam := make([]string, 0)
emotetimers := make([][]time.Time, 0)
emotelasttime := make([]time.Time, 0)
if len(messageStrings) > 2 {
for i, v := range rat.ratSettings.EmotesToSpam {
if v != messageStrings[2] {
emotestospam = append(emotestospam, v)
emotetimers = append(emotetimers, rat.emoteTimers[i])
emotelasttime = append(emotelasttime, rat.emoteLastTime[i])
}
}
}
rat.emoteTimers = emotetimers
rat.emoteLastTime = emotelasttime
rat.ratSettings.EmotesToSpam = emotestospam
rat.ratSettings.saveSettings()
rat.speak("Okay, I'll stop spamming " + messageStrings[2] + " with the crowd.")
rat.log(Info, message.User.Name+" requested stopping spamming of "+messageStrings[2])
default:
rat.speak("@" + message.User.Name + " I couldn't understand you, I only saw you say \"" + rat.ratSettings.CommandStarter + "\" before I got confused.")
}
}
func (rat *ChatRat) timerCleaner(index int) {
arr := make([]time.Time, 0)
for _, v := range rat.emoteTimers[index] {
if v.Add(rat.emoteTimeout).After(time.Now()) {
arr = append(arr, v)
}
}
rat.emoteTimers[index] = arr
}
func durationParse(message []string) (time.Duration, error) {
messageLength := len(message)
if messageLength == 0 {
return 9999 * time.Hour, errors.New("no input to duration parser")
}
if messageLength == 1 {
dur, err := time.ParseDuration(message[0])
if err != nil {
return 9999 * time.Hour, errors.New("improperly formatted duration string")
}
return dur, nil
}
//Message length must be 2 or greater now.
s, err := strconv.ParseFloat(message[0], 32)
if err != nil {
return 9999 * time.Hour, errors.New("couldn't parse " + message[1] + " as a number")
}
if s < 0 {
return 9999 * time.Hour, errors.New("negative durations don't make sense in this context")
}
parseTimeExtension := func(message string) (string, error) {
switch message {
case "seconds", "Seconds", "second", "Second":
return "s", nil
case "minutes", "Minutes", "minute", "Minute":
return "m", nil
case "hours", "Hours", "hour", "Hour":
return "h", nil
default:
return "", errors.New("unknown time extension format")
}
}
timeExtension, err := parseTimeExtension(message[1])
if err != nil {
return 9999 * time.Hour, errors.New(message[1] + " is not a valid unit of time")
}
dur, err := time.ParseDuration(message[0] + timeExtension)
return dur, err
}