Add kick above certain number of violations (#2)
Keep track of muted players, prevents players without shout being shown wrong message Add kick after 3 mutes in 5 minutes (ish) Split chat message callback in to functions, this would allow other mods to use the functions to check for spam and write their own violation mechanisms (although I'd like to add a callback) Add word count to chat command Add support for words.txt file in mod, to avoid having to manually enter loads of items. In future support for reading from world files using /filter import words.txt could be added. Make filter case insensitive Add gitignore
This commit is contained in:
parent
da43e4aabd
commit
fea7973687
113
.gitignore
vendored
Normal file
113
.gitignore
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
words*.txt
|
||||
|
||||
|
||||
# Created by https://www.gitignore.io/api/lua,linux,macos,windows
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
### Lua ###
|
||||
# Compiled Lua sources
|
||||
luac.out
|
||||
|
||||
# luarocks build files
|
||||
*.src.rock
|
||||
*.zip
|
||||
*.tar.gz
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.os
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
*.def
|
||||
*.exp
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
|
||||
### macOS ###
|
||||
*.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### Windows ###
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
# End of https://www.gitignore.io/api/lua,linux,macos,windows
|
110
init.lua
110
init.lua
@ -24,43 +24,99 @@
|
||||
|
||||
]]--
|
||||
|
||||
filter = {}
|
||||
local words = {}
|
||||
local muted = {}
|
||||
local violations = {}
|
||||
local s = minetest.get_mod_storage()
|
||||
assert(s, "minetest version too old")
|
||||
|
||||
local words
|
||||
local sw = s:get_string("words")
|
||||
function filter.init()
|
||||
local sw = s:get_string("words")
|
||||
if sw and sw ~= "" then
|
||||
words = minetest.parse_json(sw)
|
||||
end
|
||||
|
||||
if sw and sw ~= "" then
|
||||
words = minetest.parse_json(sw)
|
||||
else
|
||||
words = {}
|
||||
if #words == 0 then
|
||||
filter.import_file(minetest.get_modpath("filter") .. "/words.txt")
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_chat_message(function(name, message)
|
||||
function filter.import_file(filepath)
|
||||
local file = io.open(filepath, "r")
|
||||
if file then
|
||||
for line in file:lines() do
|
||||
line = line:trim()
|
||||
if line ~= "" then
|
||||
words[#words + 1] = line:trim()
|
||||
end
|
||||
end
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function filter.check_message(name, message)
|
||||
for _, w in ipairs(words) do
|
||||
if string.find(message:lower(), "%f[%a]" .. w .. "%f[%A]") then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function filter.on_violation(name, message)
|
||||
violations[name] = (violations[name] or 0) + 1
|
||||
|
||||
local resolution
|
||||
|
||||
if violations[name] >= 3 then
|
||||
resolution = "kicked"
|
||||
minetest.kick_player(name, "Please mind your language!")
|
||||
else
|
||||
resolution = "muted"
|
||||
local privs = minetest.get_player_privs(name)
|
||||
privs.shout = nil
|
||||
minetest.set_player_privs(name, privs)
|
||||
minetest.chat_send_player(name, "Watch your language! You have been temporarily muted")
|
||||
|
||||
muted[name] = true
|
||||
|
||||
minetest.after(60, function()
|
||||
muted[name] = nil
|
||||
minetest.chat_send_player(name, "Chat privilege reinstated. Please do not abuse chat.")
|
||||
privs.shout = true
|
||||
minetest.set_player_privs(name, privs)
|
||||
end)
|
||||
end
|
||||
|
||||
minetest.log("action", "VIOLATION (" .. resolution .. "): <" .. name .. "> ".. message)
|
||||
end
|
||||
|
||||
table.insert(minetest.registered_on_chat_messages, 1, function(name, message)
|
||||
local privs = minetest.get_player_privs(name)
|
||||
if not privs.shout then
|
||||
if not privs.shout and muted[name] then
|
||||
minetest.chat_send_player(name, "You are temporarily muted.")
|
||||
return true
|
||||
end
|
||||
|
||||
for _, w in ipairs(words) do
|
||||
if string.find(message, "%f[%a]" .. w .. "%f[%A]") then
|
||||
privs.shout = nil
|
||||
minetest.set_player_privs(name, privs)
|
||||
minetest.chat_send_player(name, "Chat temporarily disabled due to language.")
|
||||
if not filter.check_message(name, message) then
|
||||
filter.on_violation(name, message)
|
||||
return true
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.after(60, function()
|
||||
minetest.chat_send_player(name, "Chat privilege reinstated. Please do not abuse chat.")
|
||||
privs.shout = true
|
||||
minetest.set_player_privs(name, privs)
|
||||
end)
|
||||
|
||||
return true
|
||||
local function step()
|
||||
for name, v in pairs(violations) do
|
||||
violations[name] = math.floor(v * 0.5)
|
||||
if violations[name] < 1 then
|
||||
violations[name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end)
|
||||
minetest.after(2*60, step)
|
||||
end
|
||||
minetest.after(2*60, step)
|
||||
|
||||
minetest.register_chatcommand("filter", {
|
||||
params = "filter server",
|
||||
@ -69,7 +125,7 @@ minetest.register_chatcommand("filter", {
|
||||
func = function(name, param)
|
||||
local cmd, val = param:match("(%w+) (.+)")
|
||||
if param == "list" then
|
||||
return true, table.concat(words, ", ")
|
||||
return true, #words .. " words: " .. table.concat(words, ", ")
|
||||
elseif cmd == "add" then
|
||||
table.insert(words, val)
|
||||
s:set_string("words", minetest.write_json(words))
|
||||
@ -84,7 +140,9 @@ minetest.register_chatcommand("filter", {
|
||||
end
|
||||
return true, "\"" .. val .. "\" not found in list."
|
||||
else
|
||||
return true, "Usage: /filter <add|remove|list> [<word>]"
|
||||
return true, "I know " .. #words .. " words.\nUsage: /filter <add|remove|list> [<word>]"
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
filter.init()
|
||||
|
Loading…
Reference in New Issue
Block a user