//META{"name":"ChatFilter"}*// class ChatFilter { initConstructor () { this.configs = ["case","exact"]; this.css = ` ${BDFDB.dotCNS.messagegroup + BDFDB.dotCN.messageaccessory}.blocked:not(.revealed), ${BDFDB.dotCNS.messagegroup + BDFDB.dotCN.messagemarkup}.blocked:not(.revealed) { font-weight: bold; font-style: italic; } ${BDFDB.dotCNS.messagegroup + BDFDB.dotCN.messageaccessory}.censored:not(.revealed), ${BDFDB.dotCNS.messagegroup + BDFDB.dotCN.messagemarkup}:not(.revealed) { }`; this.defaults = { replaces: { blocked: {value:"~~BLOCKED~~", title:"Block:", description:"Default Replace Word for blocked Messages:"}, censored: {value:"$!%&%!&", title:"Censor:", description:"Default Replace Word for censored Messages:"} }, settings: { showMessageOnClick: {value:{blocked:true, censored:true}, enabled:{blocked:true, censored:true}, description:"Show original Message on Click:"}, hideMessage: {value:{blocked:false, censored:false}, enabled:{blocked:true, censored:false}, description:"Completely hide targeted Messages:"} } }; } getName () {return "ChatFilter";} getDescription () {return "Allows the user to censor words or block complete messages based on words in the chatwindow.";} getVersion () {return "3.2.3";} getAuthor () {return "DevilBro";} getSettingsPanel () { if (!this.started || typeof BDFDB !== "object") return; var replaces = BDFDB.getAllData(this, "replaces"); var settings = BDFDB.getAllData(this, "settings"); var settingshtml = `
${this.getName()}
`; for (let rtype in replaces) { var words = BDFDB.loadData(rtype, this, "words"); settingshtml += `

${this.defaults.replaces[rtype].title}

With:

`; for (let key in settings) { settingshtml += `

${this.defaults.settings[key].description}

`; } settingshtml += `

${this.defaults.replaces[rtype].description}

`; settingshtml += `

List of ${rtype} Words:

CASE
EXACT
`; for (let word in words) { settingshtml += `
${BDFDB.encodeToHTML(word)} (${BDFDB.encodeToHTML(words[word].replace)})
` for (let config of this.configs) { settingshtml += `
`; } settingshtml += `
`; } settingshtml += `
` settingshtml += `

Remove all added words.

`; settingshtml += `
`; } var infoHidden = BDFDB.loadData("hideInfo", this, "hideInfo"); settingshtml += `
Information
`; settingshtml += `
Case: Will block/censor words while comparing lowercase/uppercase. apple => apple, not APPLE or AppLe
Not Case: Will block/censor words while ignoring lowercase/uppercase. apple => apple, APPLE and AppLe
Exact: Will block/censor words that are exactly the selected word. apple => apple, not applepie or pineapple
Not Exact: Will block/censor all words containing the selected word. apple => apple, applepie and pineapple
`; settingshtml += `
`; var settingspanel = $(settingshtml)[0]; BDFDB.initElements(settingspanel); $(settingspanel) .on("click", BDFDB.dotCN.switchinner, () => {this.updateSettings(settingspanel);}) .on("keypress", ".wordInputs", (e) => {if (e.which == 13) this.updateContainer(settingspanel, e.currentTarget);}) .on("keyup", ".defaultInputs", (e) => {this.saveReplace(e.currentTarget);}) .on("click", ".btn-addword, .remove-word, .remove-all", (e) => {this.updateContainer(settingspanel, e.currentTarget);}) .on("click", BDFDB.dotCN.checkboxinput, (e) => {this.updateConfig(e.currentTarget);}) .on("click", ".toggle-info", (e) => {this.toggleInfo(settingspanel, e.currentTarget);}); for (let key in settings) { for (let rtype in this.defaults.settings[key].enabled) { if (!this.defaults.settings[key].enabled[rtype]) $(settingspanel).find(`${BDFDB.dotCN.flex}[value='${key}'][rtype='${rtype}']`).hide(); } } return settingspanel; } //legacy load () {} start () { var libraryScript = null; if (typeof BDFDB !== "object" || typeof BDFDB.isLibraryOutdated !== "function" || BDFDB.isLibraryOutdated()) { libraryScript = document.querySelector('head script[src="https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"]'); if (libraryScript) libraryScript.remove(); libraryScript = document.createElement("script"); libraryScript.setAttribute("type", "text/javascript"); libraryScript.setAttribute("src", "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.js"); document.head.appendChild(libraryScript); } this.startTimeout = setTimeout(() => {this.initialize();}, 30000); if (typeof BDFDB === "object" && typeof BDFDB.isLibraryOutdated === "function") this.initialize(); else libraryScript.addEventListener("load", () => {this.initialize();}); } initialize () { if (typeof BDFDB === "object") { BDFDB.loadMessage(this); var observer = null; observer = new MutationObserver((changes, _) => { changes.forEach( (change, i) => { if (change.type == "characterData") { this.hideMessage(change.target.parentElement); } if (change.addedNodes) { change.addedNodes.forEach((node) => { if (node && node.tagName && node.classList.contains(BDFDB.disCN.message)) this.hideMessage(node.querySelector(BDFDB.dotCN.messagemarkup)); }); } } ); }); BDFDB.addObserver(this, null, {name:"messageChangeObserver",instance:observer,multi:true}, {childList:true, characterData:true, subtree:true}); observer = new MutationObserver((changes, _) => { changes.forEach( (change, i) => { if (change.addedNodes) { change.addedNodes.forEach((node) => { if (node && node.tagName && node.querySelector(BDFDB.dotCN.message)) { BDFDB.addObserver(this, node, {name:"messageChangeObserver",multi:true}, {childList:true, characterData:true, subtree:true}); node.querySelectorAll(BDFDB.dotCNC.messagemarkup + BDFDB.dotCN.messageaccessory).forEach(message => { this.hideMessage(message); }); } }); } } ); }); BDFDB.addObserver(this, BDFDB.dotCN.messages, {name:"chatWindowObserver",instance:observer}, {childList:true}); observer = new MutationObserver((changes, _) => { changes.forEach( (change, i) => { if (change.removedNodes) { change.removedNodes.forEach((node) => { if (node && $(node).attr("layer-id") == "user-settings") this.hideAllMessages(); }); } } ); }); BDFDB.addObserver(this, BDFDB.dotCN.layers, {name:"settingsWindowObserver",instance:observer}, {childList:true}); this.hideAllMessages(); } else { console.error(this.getName() + ": Fatal Error: Could not load BD functions!"); } } stop () { if (typeof BDFDB === "object") { document.querySelectorAll(`${BDFDB.dotCN.messagemarkup}.blocked, ${BDFDB.dotCN.messageaccessory}.censored, ${BDFDB.dotCN.messagemarkup}.blocked, ${BDFDB.dotCN.messageaccessory}.censored`).forEach(message => { this.resetMessage(message); }); BDFDB.unloadMessage(this); } } onSwitch () { if (typeof BDFDB === "object") { this.hideAllMessages(); BDFDB.addObserver(this, BDFDB.dotCN.messages, {name:"chatWindowObserver"}, {childList:true, subtree:true}); } } // begin of own functions updateContainer (settingspanel, ele) { var update = false, wordvalue = null, replacevalue = null; var action = ele.getAttribute("action"), rtype = ele.getAttribute("rtype"); var words = BDFDB.loadData(rtype, this, "words") || {}; if (action == "add") { var wordinput = settingspanel.querySelector("#input-" + rtype + "-wordvalue"); var replaceinput = settingspanel.querySelector("#input-" + rtype + "-replacevalue"); wordvalue = wordinput.value; replacevalue = replaceinput.value; if (wordvalue && wordvalue.trim().length > 0) { wordvalue = wordvalue.trim(); replacevalue = replacevalue.trim(); words[wordvalue] = { replace: replacevalue, case: false, exact: true, regex: false, }; wordinput.value = null; replaceinput.value = null; update = true; } } else if (action == "remove") { wordvalue = ele.getAttribute("word"); if (wordvalue) { delete words[wordvalue]; update = true; } } else if (action == "removeall") { if (confirm("Are you sure you want to remove all added Words from your list?")) { words = {}; update = true; } } if (update) { BDFDB.saveData(rtype, words, this, "words"); words = BDFDB.loadData(rtype, this, "words"); var containerhtml = ``; for (let word in words) { containerhtml += `
${BDFDB.encodeToHTML(word)} (${BDFDB.encodeToHTML(words[word].replace)})
` for (let config of this.configs) { containerhtml += `
`; } containerhtml += `
`; } containerhtml += `
`; $(settingspanel).find("." + rtype + "-list").html(containerhtml); BDFDB.initElements(settingspanel); } } saveReplace (input) { var rtype = input.getAttribute("rtype"); var wordvalue = input.value; if (rtype) { var replaces = BDFDB.getData(rtype, this, "replaces"); BDFDB.saveData(rtype, wordvalue.trim(), this, "replaces"); } } updateSettings (settingspanel) { var settings = {}; for (var input of settingspanel.querySelectorAll(BDFDB.dotCN.switchinner)) { let key = input.getAttribute("value"); let rtype = input.getAttribute("rtype"); if (!settings[key]) settings[key] = {}; settings[key][rtype] = input.checked; } BDFDB.saveAllData(settings, this, "settings"); } updateConfig (ele) { var wordvalue = ele.getAttribute("word"); var config = ele.getAttribute("config"); var rtype = ele.getAttribute("rtype"); var words = BDFDB.loadData(rtype, this, "words") || {}; if (wordvalue && words[wordvalue] && config) { words[wordvalue][config] = ele.checked; BDFDB.saveData(rtype, words, this, "words"); } } toggleInfo (settingspanel, ele) { ele.classList.toggle(BDFDB.disCN.categorywrappercollapsed); ele.classList.toggle(BDFDB.disCN.categorywrapperdefault); var svg = ele.querySelector(BDFDB.dotCN.categoryicontransition); svg.classList.toggle(BDFDB.disCN.closed); svg.classList.toggle(BDFDB.disCN.categoryiconcollapsed); svg.classList.toggle(BDFDB.disCN.categoryicondefault); var visible = $(settingspanel).find(".info-container").is(":visible"); $(settingspanel).find(".info-container").toggle(!visible); BDFDB.saveData("hideInfo", visible, this, "hideInfo"); } hideAllMessages () { document.querySelectorAll(`${BDFDB.dotCN.messagemarkup}.blocked, ${BDFDB.dotCN.messageaccessory}.censored, ${BDFDB.dotCN.messagemarkup}.blocked, ${BDFDB.dotCN.messageaccessory}.censored`).forEach(message => { this.resetMessage(message); }); document.querySelectorAll(BDFDB.dotCN.messagegroup).forEach(messageContainer => { BDFDB.addObserver(this, messageContainer, {name:"messageChangeObserver",multi:true}, {childList:true, characterData:true, subtree:true}); messageContainer.querySelectorAll(BDFDB.dotCNC.messagemarkup + BDFDB.dotCN.messageaccessory).forEach(message => { this.hideMessage(message); }); }); } hideMessage (message) { if (!$(message).hasClass("blocked") && !$(message).hasClass("censored")) { var orightml = $(message).html(); var newhtml = ""; if (orightml) { var blocked = null; var strings = []; var count = 0; orightml.split("").forEach((chara) => { if (chara == "<") { if (strings[count]) count++; } strings[count] = strings[count] ? strings[count] + chara : chara; if (chara == ">") { count++; } }); var settings = BDFDB.getAllData(this, "settings"); var replaces = BDFDB.getAllData(this, "replaces"); var blockedWords = BDFDB.loadData("blocked", this, "words"); var blocked = false; for (let bWord in blockedWords) { var blockedReplace = blockedWords[bWord].replace || replaces.blocked; var reg = this.createReg(bWord, blockedWords[bWord]); strings.forEach(string => { let emojiname = this.getEmojiName(string); if (emojiname && reg.test(emojiname)) blocked = true; else if (string.indexOf(' 0 ? string.split('src="')[1] : null; url = url ? url.split('"')[0] : null; if (reg.test(url)) blocked = true; } else if (string.indexOf("<") != 0) { string.split(" ").forEach((word) => { if (reg.test(word)) blocked = true; }); } }); if (blocked) break; } if (blocked) { if (settings.hideMessage.blocked) $(message).hide(); newhtml = BDFDB.encodeToHTML(blockedReplace); $(message) .html(newhtml) .addClass("blocked") .data("newhtmlChatFilter",newhtml) .data("orightmlChatFilter",orightml); this.addClickListener(message, settings.showMessageOnClick.blocked); } else { var censoredWords = BDFDB.loadData("censored", this, "words"); for (let cWord in censoredWords) { var censoredReplace = censoredWords[cWord].replace || replaces.censored; var reg = this.createReg(cWord, censoredWords[cWord]); strings.forEach((string,i) => { let emojiname = this.getEmojiName(string); if (emojiname && reg.test(emojiname)) { strings[i] = BDFDB.encodeToHTML(censoredReplace); if (strings[i+1] && strings[i+1].indexOf(" 0 ? string.split('src="')[1] : null; url = url ? url.split('"')[0] : null; if (reg.test(url)) { strings = [BDFDB.encodeToHTML(censoredReplace)]; } } else if (string.indexOf("<") != 0) { var newstring = []; string.split(" ").forEach((word) => { newstring.push(reg.test(word) ? BDFDB.encodeToHTML(censoredReplace) : word); }); strings[i] = newstring.join(" "); } }); } newhtml = strings.join(""); if (newhtml != orightml) { $(message) .html(newhtml) .addClass("censored") .data("newhtmlChatFilter",newhtml) .data("orightmlChatFilter",orightml); this.addClickListener(message, settings.showMessageOnClick.censored); } } } } } createReg (word, config) { return new RegExp(BDFDB.encodeToHTML(config.exact ? "^" + BDFDB.regEscape(word) + "$" : BDFDB.regEscape(word)), config.case ? "" : "i"); } getEmojiName (string) { if (string.indexOf(" -1)) { var emojiname = string.split('alt="').length > 0 ? string.split('alt="')[1] : null; emojiname = emojiname ? emojiname.split('" src')[0] : null; return emojiname = emojiname ? emojiname.replace(new RegExp(":", 'g'), "") : null; } } resetMessage (message) { $(message) .html($(message).data("orightmlChatFilter")) .off("click." + this.getName()) .removeClass("blocked") .removeClass("censored") .removeClass("revealed"); } addClickListener (message, add) { $(message) .off("click." + this.getName()); if (add) { var orightml = $(message).data("orightmlChatFilter"); var newhtml = $(message).data("newhtmlChatFilter"); $(message) .on("click." + this.getName(), () => { if ($(message).hasClass("revealed")) { $(message) .html(newhtml) .removeClass("revealed"); } else { $(message) .html(orightml) .addClass("revealed"); } }); } } }