From c2292ad34b585e2a131aba60fe89b62c99c0cea1 Mon Sep 17 00:00:00 2001 From: Olivia May <133145888+olivia-may@users.noreply.github.com> Date: Mon, 15 Jul 2024 05:03:54 -0500 Subject: [PATCH] Refactor code, add API (#5) * Refactor code, add api `chat_anticurse.is_curse_found` * Add words from NoNameDude's deleted mod 'chat_filter' * Add more words * Remove deprecated files * Add small fixes * Make English and German words harder to read * Obfuscate Russian curse words * Fix formatting again * Add more curse words * Check for words with asterisks * oops --- README.txt | 4 +- depends.txt | 1 - description.txt | 1 - init.lua | 354 +++++++++++++++++++++++++++++++++--------------- mod.conf | 2 + 5 files changed, 252 insertions(+), 110 deletions(-) delete mode 100644 depends.txt delete mode 100644 description.txt diff --git a/README.txt b/README.txt index 220bb1d..cc82368 100644 --- a/README.txt +++ b/README.txt @@ -9,5 +9,5 @@ This mod is Free and Open Source Software, released under the LGPL 2.1 or later. http://www.gnu.org/licenses/lgpl-2.1.html -Kick player out when he type curse word in chat or using /me or /msg command. -Checks for some English and Russian curse words. +Kick player out when they type curse word in chat or using /me or /msg command. +Checks for some English, Russian and German curse words. diff --git a/depends.txt b/depends.txt deleted file mode 100644 index 21c2521..0000000 --- a/depends.txt +++ /dev/null @@ -1 +0,0 @@ -default? \ No newline at end of file diff --git a/description.txt b/description.txt deleted file mode 100644 index 17a45e7..0000000 --- a/description.txt +++ /dev/null @@ -1 +0,0 @@ -Kick player out when he type curse word in chat or using /me or /msg command. Checks for some English and Russian curse words. diff --git a/init.lua b/init.lua index 15f2dca..9b3e2e7 100644 --- a/init.lua +++ b/init.lua @@ -1,131 +1,273 @@ -- Minetest 0.4.10+ mod: chat_anticurse -- punish player for cursing by disconnecting them -- --- Created in 2015 by Andrey. +-- Created in 2015 by Andrey. +-- Updated in 2024 by Olivia May. +-- Some words from NoNameDude -- This mod is Free and Open Source Software, released under the LGPL 2.1 or later. --- +-- -- See README.txt for more information. chat_anticurse = {} -chat_anticurse.simplemask = {} --- some english and some russian curse words --- i don't want to keep these words as cleartext in code, so they are stored like this. -local x1="a" -local x2="i" -local x3="u" -local x4="e" -local x5="o" -local y1="y" -local y2="и" -local y3="о" -local y4="е" -local y5="я" -chat_anticurse.simplemask[1] = " "..x1.."s" .. "s " -chat_anticurse.simplemask[2] = " d" .. ""..x2.."ck" -chat_anticurse.simplemask[3] = " p"..x4.."n" .. "is" -chat_anticurse.simplemask[4] = " p" .. ""..x3.."ssy" -chat_anticurse.simplemask[5] = " h"..x5.."" .. "r".."ny " -chat_anticurse.simplemask[6] = " b"..x2.."" .. "tch " -chat_anticurse.simplemask[7] = " b"..x2.."" .. "tche" -chat_anticurse.simplemask[8] = " s"..x4.."" .. "x" -chat_anticurse.simplemask[9] = " "..y4.."б" .. "а" -chat_anticurse.simplemask[10] = " бл"..y5.."" .. " " -chat_anticurse.simplemask[11] = " ж" .. ""..y3.."п" -chat_anticurse.simplemask[12] = " х" .. ""..y1.."й" -chat_anticurse.simplemask[13] = " ч" .. "л"..y4.."н" -chat_anticurse.simplemask[14] = " п"..y2.."" .. "зд" -chat_anticurse.simplemask[15] = " в"..y3.."" .. "збуд" -chat_anticurse.simplemask[16] = " в"..y3.."з" .. "б"..y1.."ж" -chat_anticurse.simplemask[17] = " сп"..y4.."" .. "рм" -chat_anticurse.simplemask[18] = " бл"..y5.."" .. "д" -chat_anticurse.simplemask[19] = " бл"..y5.."" .. "ть" -chat_anticurse.simplemask[20] = " с" .. ""..y4.."кс" -chat_anticurse.simplemask[21] = " f" .. ""..x3.."ck" -chat_anticurse.simplemask[22] = ""..x1.."rs"..x4.."h"..x5.."l"..x4.."" -chat_anticurse.simplemask[23] = " c"..x3.."nt " +local v1 = "i" +local v2 = "a" +local v3 = "u" +local v4 = "e" +local v5 = "o" +-- Russian / Cyrilic +local v6 = "о" +local v7 = "е" +local v8 = "а" +local v9 = "з" +local v10 = "у" +local v11 = "и" +local v12 = "я" +-- List of curse words. Put spaces before and after word to prevent the +-- Scunthorpe problem: https://en.wikipedia.org/wiki/Scunthorpe_problem +-- Some words don't have spaces because they shouldn't be in any words. +local curse_words = { + -- English + " " .. v2 .. "ss ", + " d" .. v1 .. "ck ", + " p" .. v4 .. "n" .. v1 .. "s ", + "t" .. v4 .. "st" .. v1 .. "cl" .. v4 .. "", + " p" .. v3 .. "ssy ", + " h" .. v5 .. "rny ", + " b" .. v1 .. "tch ", + " b" .. v1 .. "tch" .. v4 .. " ", + " " .. v4 .. "s" .. v4 .. "x ", + " c" .. v3 .. "nt ", + " f" .. v3 .. "ck ", + "" .. v2 .. "rs" .. v4 .. "h" .. v5 .. "l" .. v4 .. "", + " c" .. v3 .. "m ", + " sh" .. v1 .. "t ", + "sh" .. v1 .. "tst" .. v5 .. "rm", + "sh" .. v1 .. "tst" .. v2 .. "" .. v1 .. "n", + " c" .. v5 .. "ck ", + "n" .. v1 .. "gg" .. v4 .. "r", + "f" .. v2 .. "gg" .. v5 .. "t", + " f" .. v2 .. "g ", + " wh" .. v5 .. "r" .. v4 .. " ", + " " .. v1 .. "nc" .. v4 .. "l ", + " c" .. v3 .. "ck ", + " f" .. v3 .. "ck" .. v4 .. "r ", + " f" .. v3 .. "ck" .. v1 .. "ng ", + "m" .. v5 .. "th" .. v4 .. "rf" .. v3 .. "ck", + " v" .. v2 .. "g" .. v1 .. "n" .. v2 .. " ", + " v" .. v2 .. "g ", + " v" .. v3 .. "lv" .. v2 .. " ", + " cl" .. v1 .. "t ", + " p" .. v4 .. "n" .. v1 .. "l" .. v4 .. " ", + " " .. v2 .. "" .. v3 .. "t" .. v1 .. "st ", + "m" .. v2 .. "st" .. v3 .. "rb" .. v2 .. "t", + "" .. v1 .. "nt" .. v4 .. "rc" .. v5 .. "" .. v3 .. "rs" .. v4 .. "", + "" .. v2 .. "ssh" .. v5 .. "l" .. v4 .. "", + "" .. v2 .. "sswh" .. v1 .. "p" .. v4 .. "", + "" .. v2 .. "ssw" .. v1 .. "p" .. v4 .. "", + "c" .. v5 .. "cks" .. v3 .. "ck" .. v4 .. "r", + "b" .. v1 .. "tch" .. v2 .. "ss", + "t" .. v1 .. "tt" .. v1 .. "" .. v4 .. "s", + " t" .. v1 .. "ts ", + "d" .. v4 .. "g" .. v4 .. "n" .. v4 .. "r" .. v2 .. "t" .. v4 .. "", + "b" .. v2 .. "st" .. v2 .. "rd", + " p" .. v5 .. "rn ", + "p" .. v5 .. "rn" .. v5 .. "gr" .. v2 .. "phy", + "tr" .. v2 .. "nny", + "ywnb" .. v2 .. "w", + "ywnb" .. v2 .. "m", + " k" .. v1 .. "k" .. v4 .. " ", + " kys ", + "k" .. v1 .. "ll y" .. v5 .. "" .. v3 .. "rs" .. v4 .. "lf", -chat_anticurse.check_message = function(name, message) - local checkingmessage=string.lower( name.." "..message .." " ) - local uncensored = 0 - for i=1, #chat_anticurse.simplemask do - if string.find(checkingmessage, chat_anticurse.simplemask[i], 1, true) ~=nil then - uncensored = 2 - break - end - end - - --additional checks - if - string.find(checkingmessage, " c"..x3.."" .. "m ", 1, true) ~=nil and - not (string.find(checkingmessage, " c"..x3.."" .. "m " .. "se", 1, true) ~=nil) and - not (string.find(checkingmessage, " c"..x3.."" .. "m " .. "to", 1, true) ~=nil) - then - uncensored = 2 - end - return uncensored + -- Russian + " " .. v7 .. "б" .. v8 .. " ", + " бл" .. v12 .. " ", + " ж" .. v6 .. "п ", + " х" .. v10 .. "й ", + " чл" .. v7 .. "н ", + " п" .. v11 .. "" .. v9 .. "д ", + " в" .. v6 .. "" .. v9 .. "б" .. v10 .. "д ", + " в" .. v6 .. "" .. v9 .. "бyж ", + " сп" .. v7 .. "рм ", + " бл" .. v12 .. "д ", + " бл" .. v12 .. "ть ", + " с" .. v6 .. "кс ", + " с" .. v10 .. "к" .. v8 .. " ", + " мл" .. v12 .. " ", + " бл" .. v11 .. "н ", + " тв" .. v6 .. "ю м" .. v8 .. "ть ", + " тв" .. v6 .. "ю ж" .. v7 .. " м" .. v8 .. "ть ", + " д" .. v11 .. "б" .. v11 .. "л ", + " " .. v8 .. "" .. v10 .. "т ", + " " .. v8 .. "" .. v10 .. "т" .. v11 .. "ст ", + " м" .. v8 .. "нд" .. v8 .. " ", + " " .. v7 .. "б" .. v8 .. "ть ", + " " .. v7 .. "б" .. v8 .. "л" .. v6 .. " " .. v9 .. "" .. v8 .. "кр" .. v6 .. "й ", + " " .. v9 .. "" .. v8 .. "" .. v7 .. "б" .. v8 .. "л ", + " " .. v6 .. "тв" .. v8 .. "л" .. v11 .. " ", + " " .. v9 .. "" .. v8 .. "ткн" .. v11 .. "сь ", + " м" .. v10 .. "д" .. v8 .. "к ", + " х" .. v10 .. "й ", + " " .. v6 .. "х" .. v10 .. "" .. v7 .. "л? ", + " эт" .. v6 .. " п" .. v11 .. "" .. v9 .. "д" .. v7 .. "ц ", + " п" .. v11 .. "" .. v9 .. "д" .. v8 .. " ", + " св" .. v6 .. "л" .. v6 .. "чь ", + " ж" .. v6 .. "п" .. v8 .. " ", + " г" .. v8 .. "вн" .. v6 .. " ", + " л" .. v6 .. "х ", + " г" .. v8 .. "нд" .. v6 .. "н ", + " " .. v10 .. "блюд" .. v6 .. "к ", + " ср" .. v8 .. "ть ", + " мн" .. v7 .. " н" .. v8 .. "ср" .. v8 .. "ть ", + " мн" .. v7 .. " п" .. v6 .. "х" .. v10 .. "й ", + " ч" .. v7 .. "рт ", + " тр" .. v8 .. "хн" .. v10 .. "ть ", + " тр" .. v8 .. "хн" .. v10 .. "л ", + " д" .. v7 .. "г" .. v7 .. "н" .. v7 .. "р" .. v8 .. "т ", + " хр" .. v7 .. "н ", + " х" .. v10 .. "й ", + " д" .. v7 .. "рьм" .. v6 .. " ", + " п" .. v6 .. "ш" .. v7 .. "л к ч" .. v6 .. "рт" .. v10 .. " ", + " мн" .. v7 .. " пл" .. v7 .. "в" .. v8 .. "ть ", + " х" .. v7 .. "рн" .. v12 .. " ", + " хр" .. v7 .. "нь ", + " " .. v6 .. "д" .. v11 .. "н хр" .. v7 .. "н ", + " н" .. v11 .. " хр" .. v7 .. "н" .. v8 .. " ", + " н" .. v10 .. " " .. v7 .. "г" .. v6 .. " н" .. v8 .. "хр" .. v7 .. "н ", + " " .. v11 .. "д" .. v11 .. " н" .. v8 .. "х" .. v7 .. "р ", + " н" .. v8 .. "хр" .. v7 .. "н ", + " п" .. v6 .. "шёл ", + " н" .. v8 .. "х" .. v7 .. "р ", + " н" .. v8 .. "хр" .. v7 .. "н ", + + -- German + " " .. v2 .. "rschl" .. v5 .. "ch ", + " " .. v2 .. "rsch ", + " schw" .. v2 .. "nz ", + " w" .. v1 .. "chs" .. v4 .. "r ", + " schl" .. v2 .. "mp" .. v4 .. " ", + " h" .. v3 .. "rr" .. v4 .. " ", + " f" .. v1 .. "ck d" .. v1 .. "ch ", + " m" .. v3 .. "tt" .. v4 .. "rf" .. v1 .. "ck" .. v4 .. "r ", + " h" .. v3 .. "r" .. v4 .. "ns" .. v5 .. "hn ", + " m" .. v2 .. "st" .. v3 .. "b" .. v1 .. "r" .. v4 .. "n ", + " sch" .. v4 .. "" .. v1 .. "d" .. v4 .. " ", + " g" .. v4 .. "schl" .. v4 .. "chtsv" .. v4 .. "rk" .. v4 .. "hr ", + " f" .. v5 .. "tz" .. v4 .. " ", + " m" .. v1 .. "ssg" .. v4 .. "b" .. v3 .. "rt ", + " m" .. v1 .. "ssg" .. v4 .. "b" .. v3 .. "rt ", + " v" .. v5 .. "ll" .. v1 .. "d" .. v1 .. "" .. v5 .. "t ", + " brüst" .. v4 .. " ", + " t" .. v1 .. "tt" .. v4 .. "n ", + " sch" .. v4 .. "" .. v1 .. "ß" .. v4 .. " ", + " sch" .. v4 .. "" .. v1 .. "ss" .. v4 .. " ", +} + +local i +local crs_wrds = {} + +-- All vowels asterisk'd +for i = 1, #curse_words do + + crs_wrds[i] = curse_words[i] + crs_wrds[i] = crs_wrds[i]:gsub(v1, "*") + crs_wrds[i] = crs_wrds[i]:gsub(v2, "*") + crs_wrds[i] = crs_wrds[i]:gsub(v3, "*") + crs_wrds[i] = crs_wrds[i]:gsub(v4, "*") + crs_wrds[i] = crs_wrds[i]:gsub(v5, "*") + +end + +local crse_words = {} +local j + +local switch = { + [v1] = true, + [v2] = true, + [v3] = true, + [v4] = true, + [v5] = true, +} + +-- First vowel asterisk'd +for i = 1, #curse_words do + + crse_words[i] = curse_words[i] + for j = 1, #crse_words[i] do + if switch[crse_words[i]:sub(j, j)] then + local new_str = "" + new_str = crse_words[i]:sub(1, j - 1) + new_str = new_str .. "*" + new_str = new_str .. crse_words[i]:sub(j + 1) + crse_words[i] = new_str + break + end + end +end + +-- Add asterisk'd words to list +for i = 1, #curse_words do + curse_words[#curse_words + 1] = crs_wrds[i] + curse_words[#curse_words + 1] = crse_words[i] +end + +-- Returns true if a curse word is found +function chat_anticurse.is_curse_found(name, message) + + local is_curse_found = false + local i + + message = string.lower(name.." "..message .." ") + + for i = 1, #curse_words do + if string.find(message, curse_words[i], + 1, true) ~= nil then + + is_curse_found = true + break + end + end + + if is_curse_found then + minetest.kick_player(name, "Cursing or words, inappropriate to game server. Kids may be playing here!") + minetest.chat_send_all("Player <"..name.."> warned for cursing" ) + minetest.log("action", "Player "..name.." warned for cursing. Chat:"..message) + end + + return is_curse_found end minetest.register_on_chat_message(function(name, message) - local uncensored = chat_anticurse.check_message(name, message) - - if uncensored == 1 then - minetest.kick_player(name, "Hey! Was there a bad word?") - minetest.log("action", "Player "..name.." warned for cursing. Chat:"..message) - return true - end - - if uncensored == 2 then - minetest.kick_player(name, "Cursing or words, inappropriate to game server. Kids may be playing here!") - minetest.chat_send_all("Player <"..name.."> warned for cursing" ) - minetest.log("action", "Player "..name.." warned for cursing. Chat:"..message) - return true - end - + return chat_anticurse.is_curse_found(name, message) end) if minetest.chatcommands["me"] then - local old_command = minetest.chatcommands["me"].func - minetest.chatcommands["me"].func = function(name, param) - local uncensored = chat_anticurse.check_message(name, param) - if uncensored == 1 then - minetest.kick_player(name, "Hey! Was there a bad word?") - minetest.log("action", "Player "..name.." warned for cursing. Msg:"..param) - return - end + local old_command = minetest.chatcommands["me"].func - if uncensored == 2 then - minetest.kick_player(name, "Cursing or words, inappropriate to game server. Kids may be playing here!") - minetest.chat_send_all("Player <"..name.."> warned for cursing" ) - minetest.log("action", "Player "..name.." warned for cursing. Me:"..param) - return - end - - return old_command(name, param) - end + minetest.chatcommands["me"].func = function(name, param) + + if chat_anticurse.is_curse_found(name, param) then + return nil + end + + return old_command(name, param) + end end if minetest.chatcommands["msg"] then - local old_command = minetest.chatcommands["msg"].func - minetest.chatcommands["msg"].func = function(name, param) - local uncensored = chat_anticurse.check_message(name, param) - if uncensored == 1 then - minetest.kick_player(name, "Hey! Was there a bad word?") - minetest.log("action", "Player "..name.." warned for cursing. Msg:"..param) - return - end + local old_command = minetest.chatcommands["msg"].func - if uncensored == 2 then - minetest.kick_player(name, "Cursing or words, inappropriate to game server. Kids may be playing here!") - minetest.chat_send_all("Player <"..name.."> warned for cursing" ) - minetest.log("action", "Player "..name.." warned for cursing. Msg:"..param) - return - end - - return old_command(name, param) - end + minetest.chatcommands["msg"].func = function(name, param) + + if chat_anticurse.is_curse_found(name, param) then + return nil + end + + return old_command(name, param) + end end diff --git a/mod.conf b/mod.conf index df90cc4..1fc5666 100644 --- a/mod.conf +++ b/mod.conf @@ -1 +1,3 @@ name = chat_anticurse +description = Kick player out when they type curse word in chat or using /me or /msg command. Checks for some English, Russian, and German curse words. +title = Chat Anticurse