diff --git a/build/scripts/config.js b/build/scripts/config.js index ff9e9d5a..e0e533ff 100644 --- a/build/scripts/config.js +++ b/build/scripts/config.js @@ -33,7 +33,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.rules = exports.tips = exports.FColor = exports.text = exports.prefixes = exports.Gamemode = exports.FishServer = exports.mapRepoURLs = exports.Mode = exports.backendIP = exports.stopAntiEvadeTime = exports.heuristics = exports.adminNames = exports.multiCharSubstitutions = exports.substitutions = exports.bannedWords = void 0; +exports.rules = exports.tips = exports.FColor = exports.text = exports.prefixes = exports.Gamemode = exports.FishServer = exports.mapRepoURLs = exports.Mode = exports.backendIP = exports.stopAntiEvadeTime = exports.heuristics = exports.adminNames = exports.multiCharSubstitutions = exports.substitutions = exports.tempMute = exports.bannedWords = void 0; var globals_1 = require("/globals"); var ranks_1 = require("/ranks"); var funcs_1 = require("/funcs"); @@ -88,6 +88,10 @@ exports.bannedWords = { "nig" + "ger", "nig" + "ga", "ni8" + "8er", "hit" + "ler", "fa" + "gg" + "ot", "nazis", ], }; +exports.tempMute = { + // temp mutes bakas if they use n word. oof. set duration of mute here. + nwordDurationMs: funcs_1.Duration.minutes(10), +}; //for some reason the external mindustry server does not read the files correctly, so we can only use ASCII exports.substitutions = Object.fromEntries(Object.entries({ "a": "\u0430\u1E9A\u1EA1\u1E01\u00E4\u03B1@\u0101\u0103\u0105\u03AC", diff --git a/build/scripts/utils.js b/build/scripts/utils.js index 14c66b02..60974e6c 100644 --- a/build/scripts/utils.js +++ b/build/scripts/utils.js @@ -673,6 +673,24 @@ function processChat(player, message, effects) { } Log.info("Censored message from player ".concat(player.name, ": \"").concat((0, funcs_1.escapeStringColorsServer)(message), "\"; contained \"").concat(filterTripText, "\"")); players_1.FishPlayer.messageStaff("[yellow]Censored message from player ".concat(fishPlayer.cleanedName, ": \"").concat(message, "\" contained \"").concat(filterTripText, "\"")); + if (!suspicious) { + var normalized = removeFoosChars(message).toLowerCase(); + var nwordPattern = /\bn[i1!][gq9]{2,}(?:[ea3]r|a)\b/; + if (nwordPattern.test(normalized)) { + var durationMs = config_1.tempMute.nwordDurationMs; + var muteTimestamp_1 = Date.now(); + fishPlayer._lastAutomodMuteAt = muteTimestamp_1; + void fishPlayer.mute("automod"); + player.sendMessage("[scarlet]You have been muted for ".concat(Math.round(durationMs / 60000), " minutes.[lightgray] Reason: Prohibited language")); + players_1.FishPlayer.messageStaff("[yellow]Temp-muted ".concat(fishPlayer.cleanedName, " for ").concat(Math.round(durationMs / 60000), " minutes: n-word")); + Log.info("[automod] Temp-muted ".concat(player.name, " (").concat(player.uuid(), ") for ").concat(Math.round(durationMs / 60000), "m: n-word")); + Timer.schedule(function () { + if (fishPlayer._lastAutomodMuteAt === muteTimestamp_1) { + void fishPlayer.unmute("automod"); + } + }, durationMs / 1000); + } + } } message = config_1.text.chatFilterReplacement.message(); highlight !== null && highlight !== void 0 ? highlight : (highlight = config_1.text.chatFilterReplacement.highlight()); diff --git a/src/config.ts b/src/config.ts index 5f2ed12a..e54737c1 100644 --- a/src/config.ts +++ b/src/config.ts @@ -73,6 +73,11 @@ export const bannedWords: { ], }; +export const tempMute = { + // temp mutes bakas if they use n word. oof. set duration of mute here. + nwordDurationMs: Duration.minutes(10), +}; + //for some reason the external mindustry server does not read the files correctly, so we can only use ASCII export const substitutions:Record = Object.fromEntries(Object.entries({ "a": "\u0430\u1E9A\u1EA1\u1E01\u00E4\u03B1@\u0101\u0103\u0105\u03AC", diff --git a/src/utils.ts b/src/utils.ts index 0ea2a3f9..1e78d1ef 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -5,7 +5,7 @@ For functions that don't need values from other files, see funcs.ts. */ import * as api from "/api"; -import { adminNames, bannedWords, Gamemode, GamemodeName, multiCharSubstitutions, substitutions, text } from "/config"; +import { adminNames, bannedWords, Gamemode, GamemodeName, multiCharSubstitutions, substitutions, text, tempMute } from "/config"; import { fail, PartialFormatString } from "/frameworks/commands"; import { crash, escapeStringColorsServer, escapeTextDiscord, parseError, random, StringIO } from "/funcs"; import { fishState, ipPattern, ipPortPattern, ipRangeCIDRPattern, ipRangeWildcardPattern, maxTime, tileHistory, uuidPattern } from "/globals"; @@ -546,6 +546,26 @@ export function processChat(player:mindustryPlayer, message:string, effects = fa } Log.info(`Censored message from player ${player.name}: "${escapeStringColorsServer(message)}"; contained "${filterTripText}"`); FishPlayer.messageStaff(`[yellow]Censored message from player ${fishPlayer.cleanedName}: "${message}" contained "${filterTripText}"`); + + if (!suspicious) { + const normalized = removeFoosChars(message).toLowerCase(); + const nwordPattern = /\bn[i1!][gq9]{2,}(?:[ea3]r|a)\b/; + + if (nwordPattern.test(normalized)) { + const durationMs = tempMute.nwordDurationMs; + const muteTimestamp = Date.now(); + (fishPlayer as any)._lastAutomodMuteAt = muteTimestamp; + void fishPlayer.mute("automod"); + player.sendMessage(`[scarlet]You have been muted for ${Math.round(durationMs / 60000)} minutes.[lightgray] Reason: Prohibited language`); + FishPlayer.messageStaff(`[yellow]Temp-muted ${fishPlayer.cleanedName} for ${Math.round(durationMs / 60000)} minutes: n-word`); + Log.info(`[automod] Temp-muted ${player.name} (${player.uuid()}) for ${Math.round(durationMs / 60000)}m: n-word`); + Timer.schedule(() => { + if ((fishPlayer as any)._lastAutomodMuteAt === muteTimestamp) { + void fishPlayer.unmute("automod"); + } + }, durationMs / 1000); + } + } } message = text.chatFilterReplacement.message(); highlight ??= text.chatFilterReplacement.highlight();