From 636f51ac958d6ef196f11f10359af29c88c0fa38 Mon Sep 17 00:00:00 2001 From: CatCraftYT <37033401+CatCraftYT@users.noreply.github.com> Date: Thu, 7 Mar 2024 00:27:23 +1030 Subject: [PATCH] feature complete v1 --- src/plugins/blockKeywords/index.ts | 127 +++++++++++++---------------- 1 file changed, 56 insertions(+), 71 deletions(-) diff --git a/src/plugins/blockKeywords/index.ts b/src/plugins/blockKeywords/index.ts index 8c5402baf..0dec54fa2 100644 --- a/src/plugins/blockKeywords/index.ts +++ b/src/plugins/blockKeywords/index.ts @@ -1,75 +1,36 @@ import definePlugin, { OptionType } from "@utils/types"; -import { Settings } from "@api/Settings"; +import { Settings, definePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; import { MessageJSON } from "discord-types/general"; -// o: has ._channelMessages and .commit() -// o is ChannelMessages -// o is h class -// foreach iterates through _messages -// D is RelationshipStore? +var blockedKeywords: Array; -// o.default.forEach(e=>{o.default.commit(e.reset(e.map(e=>e.set('blocked',$self.containsBlockedKeywords($1)))))}) +const settings = definePluginSettings({ + blockedWords: { + type: OptionType.STRING, + description: "Comma-seperated list of words to block", + default: "", + restartNeeded: true + }, + 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: [ - /* - { - // alternative find string: "d.getPrivateChannelIntegrationRemovedSystemMessageASTContent)({" - find: '.MessageTypes.PRIVATE_CHANNEL_INTEGRATION_ADDED)return(', - replacement: { - match: /default\.isBlocked\((.{1,2})\.author.id\)/g, - replace: "$&||$self.containsBlockedKeywords($1)" - } - }, - { - find: 'displayName="MessageStore"', - replacement: { - match: /default\.isBlocked\((.{1,2})\.author.id\)/g, - replace: "$&||$self.containsBlockedKeywords($1)" - } - }, - { - find: 'displayName="ReadStateStore"', - replacement: { - match: /default\.isBlocked\((.{1,2})\.author.id\)/g, - replace: "$&||$self.containsBlockedKeywords($1)" - } - }, - { - find: 'default.Messages.NEW_MESSAGES_ESTIMATED_SUMMARIES):(', - replacement: { - match: /default\.isBlocked\((.{1,2})\.author.id\)/g, - replace: "$&||$self.containsBlockedKeywords($1)" - } - }, - { - find: '.default.Messages.BLOCKED_MESSAGE_COUNT:(', - replacement: { - match: /default\.isBlocked\((.{1,2})\.author.id\)/g, - replace: "$&||$self.containsBlockedKeywords($1)" - } - }, - { - find: '.displayName="ChannelPinsStore"', - replacement: { - match: /default\.isBlocked\((.{1,2})\.author.id\)/g, - replace: "$&||$self.containsBlockedKeywords($1)" - } - }, - { - // alternative find string: "()},MESSAGE_CREATE:function" - // replace arg with arg.set('blocked', $self.containsBlockedKeywords(arg)) - find: 'LOAD_MESSAGE_INTERACTION_DATA_SUCCESS:function', - replacement: { - match: /(\)\),.{0,2}\.default\.commit\()(.{0,2})(\)\},MESSAGE_SEND_FAILED:function)/g, - replace: "$1$self.blockMessagesWithKeywords($2)$3" - } - }, - */ { find: '.default("ChannelMessages")', replacement: { @@ -79,25 +40,49 @@ export default definePlugin({ }, ], - options: { - blockedWords: { - type: OptionType.STRING, - description: "Comma-seperated list of words to block.", - default: "" + settings, + + start() { + let blockedWordsList: Array = Settings.plugins.BlockKeywords.blockedWords.split(","); + if (Settings.plugins.BlockKeywords.useRegex) { + blockedKeywords = blockedWordsList.map((word) => { + return new RegExp(word, Settings.plugins.BlockKeywords.caseSensitive ? "" : "i"); + }); } + else { + blockedKeywords = blockedWordsList.map((word) => { + // escape regex chars in word https://stackoverflow.com/a/6969486 + return new RegExp(`\\b${word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, Settings.plugins.BlockKeywords.caseSensitive ? "" : "i"); + }); + } + console.log(blockedKeywords); }, containsBlockedKeywords(message: MessageJSON) { - if (!Settings.plugins.BlockKeywords.blockedWords) { return false; } - const blockedWordsList: Array = Settings.plugins.BlockKeywords.blockedWords.split(","); + if (blockedKeywords.length === 0) { return false; } - // can't use blockedWordsList.forEach because we need to return from inside the loop - for (let wordIndex = 0; wordIndex < blockedWordsList.length; wordIndex++) { - if (message.content.includes(blockedWordsList[wordIndex])) { + // 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]; + if (embed["rawDescription"] == null || embed["rawTitle"] == null) { continue; } + 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; },