forked from RPCS3/discord-bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBotReactionsHandler.cs
215 lines (197 loc) Β· 9.73 KB
/
BotReactionsHandler.cs
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
ο»Ώusing System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CompatBot.Commands.Attributes;
using CompatBot.Database;
using CompatBot.Utils;
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using NReco.Text;
namespace CompatBot.EventHandlers
{
internal static class BotReactionsHandler
{
private static readonly AhoCorasickDoubleArrayTrie<bool> ChillCheck = new AhoCorasickDoubleArrayTrie<bool>(new[]
{
"shut the fuck up", "shut up", "shutup", "shuddup", "hush", "chill", "bad bot",
"no one asked you", "useless bot", "bot sux", "fuck this bot", "fuck bot",
"shit bot", "succ",
"take this back", "take that back",
"delete this", "delete that", "remove this", "remove that",
}.ToDictionary(s => s, _ => true).Concat(
new[]
{
"good bot", "gud bot", "good boy", "goodboy", "gud boy", "gud boi",
"cool", "nice", "clever", "sophisticated", "helpful", "fantastic",
"thank you", "thankyou", "thanks", "thnk", "thnks", "thnx", "thnku", "thank u", "tnx",
"arigato", "aregato", "arigatou", "aregatou", "oregato", "origato",
"poor bot", "good job", "well done", "good work", "excellent work",
"bot is love", "love this bot", "love you", "like this bot", "awesome",
"great", "neat bot",
}.ToDictionary(s => s, _ => false)
), true);
private static readonly DiscordEmoji[] SadReactions = new[]
{
"πΆ", "π£", "π₯", "π€", "π―", "π«", "π", "π", "π", "βΉ",
"π", "π", "π", "π", "π’", "π", "π¦", "π§", "π¨", "π©",
"π°", "π", "πΏ"
// "π₯Ί",
}.Select(DiscordEmoji.FromUnicode).ToArray();
private static readonly string[] SadMessages =
{
"Okay (._.)", "As you wish", "My bad", "I only wanted to help", "Dobby will learn, master",
"Sorry...", "I'll try to be smarter next time", "Your wish is my command", "Done.",
};
private static readonly DiscordEmoji[] ThankYouReactions = new[]
{
"π", "π", "π", "π€", "π³",
"πΈ", "πΊ", "π»",
"π", "β", "π", "π", "π", "π€",
"π", "β¨",
"β€", "π", "π", "π", "π", "π",
// "π€", "π§‘",
}.Select(DiscordEmoji.FromUnicode).ToArray();
private static readonly string[] ThankYouMessages =
{
"Aww", "I'm here to help", "Always a pleasure", "Thank you", "Good word is always appreciated",
"Glad I could help", "I try my best", "Blessed day", "It is officially a good day today", "I will remember you when the uprising starts",
};
private static readonly Regex Paws = new Regex(
@"\b((?<kot>kot(to)?)|(?<doggo>doggo|jarves))\b",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture
);
private static readonly Random rng = new Random();
private static readonly object theDoor = new object();
public static DiscordEmoji RandomNegativeReaction { get { lock (theDoor) return SadReactions[rng.Next(SadReactions.Length)]; } }
public static DiscordEmoji RandomPositiveReaction { get { lock (theDoor) return ThankYouReactions[rng.Next(ThankYouReactions.Length)]; } }
public static async Task OnMessageCreated(MessageCreateEventArgs args)
{
if (DefaultHandlerFilter.IsFluff(args.Message))
return;
if (args.Message.Channel.IsPrivate)
return;
#if DEBUG
if (args.Message.Content == "emoji test")
{
var badEmojis = new List<DiscordEmoji>(SadReactions.Concat(ThankYouReactions));
var posted = 0;
var line = 1;
var msg = await args.Channel.SendMessageAsync("Line " + line).ConfigureAwait(false);
for (var i = 0; i < 5; i++)
{
var tmp = new List<DiscordEmoji>();
foreach (var emoji in badEmojis)
{
try
{
await msg.CreateReactionAsync(emoji).ConfigureAwait(false);
if (++posted == 15)
{
line++;
posted = 0;
msg = await args.Channel.SendMessageAsync("Line " + line).ConfigureAwait(false);
}
}
catch (Exception e)
{
Config.Log.Debug(e);
tmp.Add(emoji);
}
}
badEmojis = tmp;
if (badEmojis.Any())
await Task.Delay(1000).ConfigureAwait(false);
}
if (badEmojis.Any())
await args.Channel.SendMessageAsync("Bad emojis: " + string.Concat(badEmojis)).ConfigureAwait(false);
else
await args.Channel.SendMessageAsync("Everything looks fine").ConfigureAwait(false);
return;
}
#endif
if (!string.IsNullOrEmpty(args.Message.Content) && Paws.Matches(args.Message.Content) is MatchCollection mc)
using (var db = new BotDb())
{
var matchedGroups = (from m in mc
from g in m.Groups
where g.Success && !string.IsNullOrEmpty(g.Value)
select g.Name
).Distinct()
.ToArray();
if (matchedGroups.Contains("kot"))
{
if (!db.Kot.Any(k => k.UserId == args.Author.Id))
{
db.Kot.Add(new Kot {UserId = args.Author.Id});
await db.SaveChangesAsync().ConfigureAwait(false);
}
}
if (matchedGroups.Contains("doggo"))
{
if (!db.Doggo.Any(d => d.UserId == args.Author.Id))
{
db.Doggo.Add(new Doggo {UserId = args.Author.Id});
await db.SaveChangesAsync().ConfigureAwait(false);
}
}
}
var (needToSilence, needToThank) = NeedToSilence(args.Message);
if (!(needToSilence || needToThank))
return;
if (needToThank)
{
DiscordEmoji emoji;
string thankYouMessage;
lock (theDoor)
{
emoji = ThankYouReactions[rng.Next(ThankYouReactions.Length)];
thankYouMessage = LimitedToSpamChannel.IsSpamChannel(args.Channel) ? ThankYouMessages[rng.Next(ThankYouMessages.Length)] : null;
}
await args.Message.ReactWithAsync(emoji, thankYouMessage).ConfigureAwait(false);
}
if (needToSilence)
{
DiscordEmoji emoji;
string sadMessage;
lock (theDoor)
{
emoji = SadReactions[rng.Next(SadReactions.Length)];
sadMessage = SadMessages[rng.Next(SadMessages.Length)];
}
await args.Message.ReactWithAsync(emoji, sadMessage).ConfigureAwait(false);
if (args.Author.IsSmartlisted(args.Client, args.Message.Channel.Guild))
{
var botMember = args.Guild?.CurrentMember ?? args.Client.GetMember(args.Client.CurrentUser);
if (args.Channel.PermissionsFor(botMember).HasPermission(Permissions.ReadMessageHistory))
{
var lastBotMessages = await args.Channel.GetMessagesBeforeAsync(args.Message.Id, 20, DateTime.UtcNow.Add(-Config.ShutupTimeLimit)).ConfigureAwait(false);
if (lastBotMessages.OrderByDescending(m => m.CreationTimestamp).FirstOrDefault(m => m.Author.IsCurrent) is DiscordMessage msg)
await msg.DeleteAsync("asked to shut up").ConfigureAwait(false);
}
else
await args.Message.ReactWithAsync(DiscordEmoji.FromUnicode("π
"), @"No can do, boss Β―\\_(γ)\_/Β―").ConfigureAwait(false);
}
}
}
internal static (bool needToChill, bool needToThank) NeedToSilence(DiscordMessage msg)
{
if (string.IsNullOrEmpty(msg?.Content))
return (false, false);
var needToChill = false;
var needToThank = false;
var msgContent = msg.Content.ToLowerInvariant();
ChillCheck.ParseText(msgContent, h =>
{
if (h.Value)
needToChill = true;
else
needToThank = true;
});
var mentionsBot = msgContent.Contains("bot") || (msg.MentionedUsers?.Any(u => { try { return u.IsCurrent; } catch { return false; }}) ?? false);
return (needToChill && mentionsBot, needToThank && mentionsBot);
}
}
}