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
|
import { Highlight, type BushMessage, type HighlightWord } from '#lib';
import type { Snowflake } from 'discord.js';
export class HighlightManager {
public cachedHighlights: Map</* guild */ Snowflake, Map</* word */ HighlightWord, /* users */ Set<Snowflake>>> = new Map();
public userLastTalkedCooldown = new Map<Snowflake, Map<Snowflake, Date>>();
public lastedDMedUserCooldown = new Map</* user */ Snowflake, /* last dm */ Date>();
public async syncCache() {
const highlights = await Highlight.findAll();
this.cachedHighlights.clear();
for (const highlight of highlights) {
highlight.words.forEach((word) => {
if (!this.cachedHighlights.has(highlight.guild)) this.cachedHighlights.set(highlight.guild, new Map());
const guildCache = this.cachedHighlights.get(highlight.guild)!;
if (!guildCache.get(word)) guildCache.set(word, new Set());
guildCache.get(word)!.add(highlight.user);
});
}
}
public checkMessage(message: BushMessage): Map<Snowflake, string> {
// even if there are multiple matches, only the first one is returned
const ret = new Map<Snowflake, string>();
if (!message.content || !message.inGuild()) return ret;
if (!this.cachedHighlights.has(message.guildId)) return ret;
const guildCache = this.cachedHighlights.get(message.guildId)!;
for (const [word, users] of guildCache.entries()) {
if (this.isMatch(message.content, word)) {
for (const user of users) {
if (!ret.has(user)) ret.set(user, word.word);
}
}
}
return ret;
}
public async checkPhraseForUser(guild: Snowflake, user: Snowflake, phrase: string): Promise<Map<string, boolean>> {
const highlights = await Highlight.findAll({ where: { guild, user } });
const results = new Map<string, boolean>();
for (const highlight of highlights) {
for (const word of highlight.words) {
if (this.isMatch(phrase, word)) {
results.set(word.word, true);
}
}
}
return results;
}
private isMatch(phrase: string, word: HighlightWord) {
if (word.regex) {
return new RegExp(word.word, 'gi').test(phrase);
} else {
if (word.word.includes(' ')) {
return phrase.includes(word.word);
} else {
const words = phrase.split(/\s*\b\s/);
return words.includes(word.word);
}
}
}
}
|