Compare commits

...

10 Commits

Author SHA1 Message Date
Auke Kok
869cbb0d61 Update a local. 2023-02-14 11:22:44 -08:00
Auke Kok
a0a22bc69e Avoid dependency on default - causes potential crash. 2023-02-14 11:21:31 -08:00
Auke Kok
61bee7742c Remove obsolete files. 2023-02-05 16:43:59 -08:00
Anand S
b3d58cd83d Add desc. and depends to mod.conf 2018-06-29 23:23:52 -07:00
Auke Kok
9de8a2e6f7 Add screenshot. 2018-05-28 17:49:30 -07:00
Anand S
a820ae6503 Priv-check before unmuting 2018-04-25 20:04:39 -07:00
rubenwardy
99100857af Fix conflict with chat commands 2018-02-05 23:03:19 -08:00
rubenwardy
9422add415 Add support for the email mod 2018-02-05 23:03:19 -08:00
rubenwardy
a240c39a64 Fix loss of shout privilege if server shuts down during mute 2018-02-05 23:03:19 -08:00
rubenwardy
dae7d9939e Add on_violation callback 2018-02-05 23:03:19 -08:00
7 changed files with 108 additions and 23 deletions

View File

@ -3,7 +3,7 @@ allow_defined_top = true
read_globals = {
"DIR_DELIM",
"minetest", "core",
"core",
"dump",
"vector", "nodeupdate",
"VoxelManip", "VoxelArea",
@ -11,5 +11,10 @@ read_globals = {
"intllib",
"default",
"rules",
"email",
table = { fields = { "copy", "getn" } }
}
globals = {
"minetest"
}

View File

@ -1 +0,0 @@
rules?

View File

@ -1 +0,0 @@
A chat filter for servers.

View File

@ -25,7 +25,7 @@
]]--
filter = {}
filter = { registered_on_violations = {} }
local words = {}
local muted = {}
local violations = {}
@ -57,6 +57,10 @@ function filter.import_file(filepath)
end
end
function filter.register_on_violation(func)
table.insert(filter.registered_on_violations, func)
end
function filter.check_message(name, message)
for _, w in ipairs(words) do
if string.find(message:lower(), "%f[%a]" .. w .. "%f[%A]") then
@ -73,22 +77,27 @@ function filter.mute(name, duration)
privs.shout = nil
minetest.set_player_privs(name, privs)
end
minetest.chat_send_player(name, "Watch your language! You have been temporarily muted")
muted[name] = true
minetest.after(duration * 60, function()
local privs = minetest.get_player_privs(name)
if privs.shout == true then
return
end
muted[name] = nil
minetest.chat_send_player(name, "Chat privilege reinstated. Please do not abuse chat.")
local privs = minetest.get_player_privs(name)
privs.shout = true
minetest.set_player_privs(name, privs)
end)
end
function filter.show_warning_formspec(name)
local formspec = "size[7,3]bgcolor[#080808BB;true]" .. default.gui_bg .. default.gui_bg_img .. [[
local formspec = "size[7,3]bgcolor[#080808BB;true]" .. [[
image[0,0;2,2;filter_warning.png]
label[2.3,0.5;Please watch your language!]
]]
@ -111,21 +120,39 @@ function filter.on_violation(name, message)
local resolution
if violations[name] == 1 and minetest.get_player_by_name(name) then
resolution = "warned"
filter.show_warning_formspec(name)
elseif violations[name] <= 3 then
resolution = "muted"
filter.mute(name, 1)
else
resolution = "kicked"
minetest.kick_player(name, "Please mind your language!")
for _, cb in pairs(filter.registered_on_violations) do
if cb(name, message, violations) then
resolution = "custom"
end
end
minetest.log("action", "VIOLATION (" .. resolution .. "): <" .. name .. "> ".. message)
if not resolution then
if violations[name] == 1 and minetest.get_player_by_name(name) then
resolution = "warned"
filter.show_warning_formspec(name)
elseif violations[name] <= 3 then
resolution = "muted"
filter.mute(name, 1)
else
resolution = "kicked"
minetest.kick_player(name, "Please mind your language!")
end
end
local logmsg = "VIOLATION (" .. resolution .. "): <" .. name .. "> ".. message
minetest.log("action", logmsg)
local email_to = minetest.settings:get("filter.email_to")
if email_to and minetest.global_exists("email") then
email.send_mail(name, email_to, logmsg)
end
end
table.insert(minetest.registered_on_chat_messages, 1, function(name, message)
if message:sub(1, 1) == "/" then
return
end
local privs = minetest.get_player_privs(name)
if not privs.shout and muted[name] then
minetest.chat_send_player(name, "You are temporarily muted.")
@ -138,6 +165,33 @@ table.insert(minetest.registered_on_chat_messages, 1, function(name, message)
end
end)
local function make_checker(old_func)
return function(name, param)
if not filter.check_message(name, param) then
filter.on_violation(name, param)
return false
end
return old_func(name, param)
end
end
for name, def in pairs(minetest.registered_chatcommands) do
if def.privs and def.privs.shout then
def.func = make_checker(def.func)
end
end
local old_register_chatcommand = minetest.register_chatcommand
function minetest.register_chatcommand(name, def)
if def.privs and def.privs.shout then
def.func = make_checker(def.func)
end
return old_register_chatcommand(name, def)
end
local function step()
for name, v in pairs(violations) do
violations[name] = math.floor(v * 0.5)
@ -145,9 +199,9 @@ local function step()
violations[name] = nil
end
end
minetest.after(2*60, step)
minetest.after(10*60, step)
end
minetest.after(2*60, step)
minetest.after(10*60, step)
minetest.register_chatcommand("filter", {
params = "filter server",
@ -184,4 +238,12 @@ if minetest.global_exists("rules") and rules.show then
end)
end
minetest.register_on_shutdown(function()
for name, _ in pairs(muted) do
local privs = minetest.get_player_privs(name)
privs.shout = true
minetest.set_player_privs(name, privs)
end
end)
filter.init()

View File

@ -1 +1,3 @@
name = filter
description = A chat filter for servers.
optional_depends = rules,email

View File

@ -1,5 +1,4 @@
## filter mod
# filter mod
This mod adds a simple chat filter. There is no default word list,
and adding words to the filter list is done through the `/filter`
@ -14,7 +13,26 @@ muted for 1 minute. After that, their `shout` privilege is restored.
If they leave, their `shout` privilege is still restored, but only after
the time expires, not before.
## Bugs
## API
- the `shout` priv is permanently lost if the server shuts down while
a player is muted.
### Callbacks
* filter.register_on_violation(func(name, message, violations))
* Violations is the value of the player's violation counter - which is
incremented on a violation, and halved every 10 minutes.
* Return true if you've handled the violation. No more callbacks will be
executation, and the default behaviour (warning/mute/kick) on violation
will be skipped.
### Methods
* filter.import_file(path)
* Input bad words from a file (`path`) where each line is a new word.
* filter.check_message(name, message)
* Checks message for violation. Returns true if okay, false if bad.
If it returns false, you should cancel the sending of the message and
call filter.on_violation()
* filter.on_violation(name, message)
* Increments violation count, runs callbacks, and punishes the players.
* filter.mute(name, duration)
* filter.show_warning_formspec(name)

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB