Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Plugin] BlockKeywords #2238

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f2f31dc
first working version :3
CatCraftYT Mar 6, 2024
636f51a
feature complete v1
CatCraftYT Mar 6, 2024
d930601
removed old if statement and added caseSensitiveFlag const
CatCraftYT Mar 6, 2024
5ce74e5
fixed issue preventing messages from blocked people actually being bl…
CatCraftYT Mar 7, 2024
53282ff
synced with upstream
CatCraftYT Mar 30, 2024
c3e619a
Merge with upstream
CatCraftYT Apr 25, 2024
a90bafd
Merge upstream changes
CatCraftYT May 1, 2024
7921b4d
Merge upstream changes
CatCraftYT May 24, 2024
b258028
Merge branch 'main' into main
CatCraftYT Jun 13, 2024
5015515
Merge remote-tracking branch 'upstream/main'
CatCraftYT Jun 19, 2024
734e4bc
Fixed for new update
CatCraftYT Jun 19, 2024
bd1400c
Merge remote-tracking branch 'upstream/main'
CatCraftYT Jun 19, 2024
8c5c4c7
Merge remote-tracking branch 'upstream/main'
CatCraftYT Jun 30, 2024
5d64c2a
Merge branch 'Vendicated:main' into main
CatCraftYT Jul 29, 2024
52c35cb
Merge branch 'Vendicated:main' into main
CatCraftYT Aug 2, 2024
7c4c04d
Merge branch 'Vendicated:main' into main
CatCraftYT Aug 11, 2024
ced2e51
Merge branch 'Vendicated:main' into main
CatCraftYT Aug 26, 2024
49c3afe
Merge branch 'Vendicated:main' into main
CatCraftYT Sep 1, 2024
5c5582c
Merge branch 'Vendicated:main' into main
CatCraftYT Sep 25, 2024
78334d1
Merge branch 'Vendicated:main' into main
CatCraftYT Sep 30, 2024
a4a3a2b
Merge branch 'Vendicated:main' into main
CatCraftYT Oct 8, 2024
8f65f70
Merge branch 'Vendicated:main' into main
CatCraftYT Nov 8, 2024
db0d208
Merge branch 'Vendicated:main' into main
CatCraftYT Nov 15, 2024
f37de2b
Merge branch 'Vendicated:main' into main
CatCraftYT Dec 13, 2024
74cc1a1
Merge branch 'Vendicated:main' into main
CatCraftYT Jan 23, 2025
40fd44a
Merge branch 'Vendicated:main' into main
CatCraftYT Jan 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions src/plugins/blockKeywords/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import definePlugin, { OptionType } from "@utils/types";
import { Settings, definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import { MessageJSON } from "discord-types/general";

var blockedKeywords: Array<RegExp>;

const settings = definePluginSettings({
blockedWords: {
type: OptionType.STRING,
description: "Comma-seperated list of words to block",
default: "",
restartNeeded: true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a restart actually needed for all of these settings? If not, an onChange function that updates blockedKeywords could instead be added to these setting definitions. Maybe the code in start() could be moved to a top-level function that is used as the value of start and the onChanges.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a new branch on my repo with changes that almost implement this, but it only actually visibly blocks the messages when the user switches channels. The messages in the currently viewed channel aren't updated when the message list is updated for some reason. The block feature gets around this but I'm not sure how rn

},
useRegex: {
type: OptionType.BOOLEAN,
description: "Use each value as a regular expression when checking message content (advanced)",
default: false,
restartNeeded: true
},
caseSensitive: {
type: OptionType.BOOLEAN,
description: "Whether to use a case sensitive search or not",
default: false,
restartNeeded: true
}
});

export default definePlugin({
name: "BlockKeywords",
description: "Blocks messages containing specific user-defined keywords, as if the user sending them was blocked.",
authors: [Devs.catcraft],
patches: [
{
find: '.default("ChannelMessages")',
replacement: {
match: /static commit\((.{1,2})\){/g,
replace: "$&$1=$self.blockMessagesWithKeywords($1);"
}
},
],

settings,

start() {
let blockedWordsList: Array<string> = Settings.plugins.BlockKeywords.blockedWords.split(",");
const caseSensitiveFlag = Settings.plugins.BlockKeywords.caseSensitive ? "" : "i";

if (Settings.plugins.BlockKeywords.useRegex) {
blockedKeywords = blockedWordsList.map((word) => {
return new RegExp(word, caseSensitiveFlag);
});
}
else {
blockedKeywords = blockedWordsList.map((word) => {
// escape regex chars in word https://stackoverflow.com/a/6969486
return new RegExp(`\\b${word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, caseSensitiveFlag);
});
}
console.log(blockedKeywords);
},

containsBlockedKeywords(message: MessageJSON) {
if (blockedKeywords.length === 0) { return false; }

// can't use forEach because we need to return from inside the loop
// message content loop
for (let wordIndex = 0; wordIndex < blockedKeywords.length; wordIndex++) {
if (blockedKeywords[wordIndex].test(message.content)) {
return true;
}
}

// embed content loop (e.g. twitter embeds)
for (let embedIndex = 0; embedIndex < message.embeds.length; embedIndex++) {
const embed = message.embeds[embedIndex];
for (let wordIndex = 0; wordIndex < blockedKeywords.length; wordIndex++) {
// doing this because undefined strings get converted to the string "undefined" in regex tests
const descriptionHasKeywords = embed["rawDescription"] != null && blockedKeywords[wordIndex].test(embed["rawDescription"]);
const titleHasKeywords = embed["rawTitle"] != null && blockedKeywords[wordIndex].test(embed["rawTitle"]);
if (descriptionHasKeywords || titleHasKeywords) {
return true;
}
}
}

return false;
},

blockMessagesWithKeywords(messageList: any) {
return messageList.reset(messageList.map(
message => message.set("blocked", message["blocked"] || this.containsBlockedKeywords(message))
));
}
});
4 changes: 4 additions & 0 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
Av32000: {
name: "Av32000",
id: 593436735380127770n,
},
catcraft: {
name: "catcraft",
id: 290162449213292546n,
}
} satisfies Record<string, Dev>);

Expand Down