From 63e360035284393291a33c7cefef4931dd72199f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Mart=C3=ADnez?= Date: Mon, 10 Oct 2016 03:58:53 -0300 Subject: [PATCH 1/9] Disallow banning already-banned players. Fixes #9. --- init.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/init.lua b/init.lua index 81818a8..2075a83 100644 --- a/init.lua +++ b/init.lua @@ -73,6 +73,9 @@ end function xban.ban_player(player, source, expires, reason) --> bool, err local e = xban.find_entry(player, true) + if e.banned then + return nil, "Already banned" + end local rec = { source = source, time = os.time(), @@ -195,8 +198,8 @@ minetest.register_chatcommand("xban", { if not (plname and reason) then return false, "Usage: /xban " end - xban.ban_player(plname, name, nil, reason) - return true, ("Banned %s."):format(plname) + local ok, e = xban.ban_player(plname, name, nil, reason) + return ok, ok and ("Banned %s."):format(plname) or e end, }) @@ -214,8 +217,9 @@ minetest.register_chatcommand("xtempban", { return false, "You must ban for at least 60 seconds." end local expires = os.time() + time - xban.ban_player(plname, name, expires, reason) - return true, ("Banned %s until %s."):format(plname, os.date("%c", expires)) + local ok, e = xban.ban_player(plname, name, expires, reason) + return ok, (ok and ("Banned %s until %s."):format( + plname, os.date("%c", expires)) or e) end, }) From 49db5aa8883cc35438a526ed427b6bff470ed308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Mart=C3=ADnez?= Date: Wed, 19 Oct 2016 20:19:16 -0300 Subject: [PATCH 2/9] Add whitelisting. --- init.lua | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/init.lua b/init.lua index 2075a83..d8b20e7 100644 --- a/init.lua +++ b/init.lua @@ -72,6 +72,9 @@ function xban.get_info(player) --> ip_name_list, banned, last_record end function xban.ban_player(player, source, expires, reason) --> bool, err + if xban.get_whitelist(player) then + return nil, "Player is whitelisted; remove from whitelist first" + end local e = xban.find_entry(player, true) if e.banned then return nil, "Already banned" @@ -134,6 +137,28 @@ function xban.unban_player(player, source) --> bool, err return true end +function xban.get_whitelist(name_or_ip) + return db.whitelist and db.whitelist[name_or_ip] +end + +function xban.remove_whitelist(name_or_ip) + if db.whitelist then + db.whitelist[name_or_ip] = nil + end +end + +function xban.add_whitelist(name_or_ip, source) + local wl = db.whitelist + if not wl then + wl = { } + db.whitelist = wl + end + wl[name_or_ip] = { + source=source, + } + return true +end + function xban.get_record(player) local e = xban.find_entry(player) if not e then @@ -161,6 +186,8 @@ function xban.get_record(player) end minetest.register_on_prejoinplayer(function(name, ip) + local wl = db.whitelist or { } + if wl[name] or wl[ip] then return end local e = xban.find_entry(name) or xban.find_entry(ip) if not e then return end if e.banned then @@ -264,6 +291,31 @@ minetest.register_chatcommand("xban_record", { end, }) +minetest.register_chatcommand("xban_wl", { + description = "Manages the whitelist", + params = "(add|del|get) ", + privs = { ban=true }, + func = function(name, params) + local cmd, plname = params:match("%s*(%S+)%s*(%S+)") + if cmd == "add" then + xban.add_whitelist(plname, name) + ACTION("%s adds %s to whitelist", source, plname) + return true, "Added to whitelist: "..plname + elseif cmd == "del" then + xban.remove_whitelist(plname) + ACTION("%s removes %s to whitelist", source, plname) + return true, "Removed from whitelist: "..plname + elseif cmd == "get" then + local e = xban.get_whitelist(plname) + if e then + return true, "Source: "..(e.source or "Unknown") + else + return true, "No whitelist for: "..plname + end + end + end, +}) + local function check_temp_bans() minetest.after(60, check_temp_bans) local to_rm = { } From 320abd34dea23163dcd015c43325b4c64bfc5669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Mart=C3=ADnez?= Date: Thu, 20 Oct 2016 10:24:44 -0300 Subject: [PATCH 3/9] GUI: Make `/xban_gui` only usable by players with `ban` priv. --- gui.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/gui.lua b/gui.lua index fb0c1df..710adb0 100644 --- a/gui.lua +++ b/gui.lua @@ -128,6 +128,7 @@ end) minetest.register_chatcommand("xban_gui", { description = "Show XBan GUI", params = "", + privs = { ban=true, }, func = function(name, params) minetest.show_formspec(name, FORMNAME, make_fs(name)) end, From 33e3fcd15b48afae5fa409aea134385408ee2912 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Tue, 15 Nov 2016 09:25:27 -0800 Subject: [PATCH 4/9] Create mod.conf --- mod.conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 mod.conf diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..b046e3c --- /dev/null +++ b/mod.conf @@ -0,0 +1 @@ +name = xban2 From 877e55078718047323ce2d5b07d004c05414aaf5 Mon Sep 17 00:00:00 2001 From: Agaran Date: Sat, 26 Nov 2016 20:28:17 +0100 Subject: [PATCH 5/9] Filter fields submission by privs. --- gui.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gui.lua b/gui.lua index 710adb0..d3306e2 100644 --- a/gui.lua +++ b/gui.lua @@ -100,6 +100,11 @@ end minetest.register_on_player_receive_fields(function(player, formname, fields) if formname ~= FORMNAME then return end local name = player:get_player_name() + if not minetest.check_player_privs(name, { ban=true }) then + minetest.log("warning", + "[xban2] Received fields from unauthorized user: "..name) + return + end local state = get_state(name) if fields.player then local t = minetest.explode_textlist_event(fields.player) From 97fb251ad954a5927a4ba59e72cffd277e6d244c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Mart=C3=ADnez?= Date: Sun, 11 Dec 2016 17:57:29 -0300 Subject: [PATCH 6/9] Better diagnostics in case of DB load error. --- init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init.lua b/init.lua index d8b20e7..b3c42a6 100644 --- a/init.lua +++ b/init.lua @@ -361,10 +361,10 @@ local function load_db() WARNING("Unable to load database: %s", "Read failed") return end - local t = minetest.deserialize(cont) + local t, e = minetest.deserialize(cont) if not t then WARNING("Unable to load database: %s", - "Deserialization failed") + "Deserialization failed: "..(e or "unknown error")) return end db = t From 89303b4a01e59157e813ee44e2a85b6e5ed02a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Mart=C3=ADnez?= Date: Fri, 17 Feb 2017 02:30:30 -0300 Subject: [PATCH 7/9] Add `.luacheckrc` and fix warnings. --- .luacheckrc | 7 +++++++ dbimport.lua | 8 ++++---- importers/v2.lua | 10 +++++----- init.lua | 10 ++++------ 4 files changed, 20 insertions(+), 15 deletions(-) create mode 100644 .luacheckrc diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..8ef1636 --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,7 @@ + +unused_args = false +allow_defined_top = true + +read_globals = { + "minetest", +} diff --git a/dbimport.lua b/dbimport.lua index ec9293d..0d342bf 100644 --- a/dbimport.lua +++ b/dbimport.lua @@ -11,13 +11,13 @@ minetest.register_chatcommand("xban_dbi", { privs = { server=true }, func = function(name, params) if params == "--list" then - local names = { } - for name in pairs(xban.importers) do - table.insert(names, name) + local importers = { } + for importer in pairs(xban.importers) do + table.insert(importers, importer) end minetest.chat_send_player(name, ("[xban] Known importers: %s"):format( - table.concat(names, ", "))) + table.concat(importers, ", "))) return elseif not xban.importers[params] then minetest.chat_send_player(name, diff --git a/importers/v2.lua b/importers/v2.lua index fd29966..739063f 100644 --- a/importers/v2.lua +++ b/importers/v2.lua @@ -8,19 +8,19 @@ function xban.importers.v2() local text = f:read("*a") f:close() local db = minetest.deserialize(text) - for _, e in ipairs(db) do - for name in pairs(e.names) do + for _, ent in ipairs(db) do + for name in pairs(ent.names) do local entry = xban.find_entry(name, true) if entry.source ~= "xban:importer_v2" then for nm in pairs(e.names) do entry.names[nm] = true end - if e.banned then + if ent.banned then entry.banned = true entry.reason = e.banned entry.source = "xban:importer_v2" - entry.time = e.time - entry.expires = e.expires + entry.time = ent.time + entry.expires = ent.expires table.insert(entry.record, { source = entry.source, reason = entry.reason, diff --git a/init.lua b/init.lua index b3c42a6..dad13af 100644 --- a/init.lua +++ b/init.lua @@ -24,9 +24,7 @@ local function make_logger(level) end local ACTION = make_logger("action") -local INFO = make_logger("info") local WARNING = make_logger("warning") -local ERROR = make_logger("error") local unit_to_secs = { s = 1, m = 60, h = 3600, @@ -299,11 +297,11 @@ minetest.register_chatcommand("xban_wl", { local cmd, plname = params:match("%s*(%S+)%s*(%S+)") if cmd == "add" then xban.add_whitelist(plname, name) - ACTION("%s adds %s to whitelist", source, plname) + ACTION("%s adds %s to whitelist", name, plname) return true, "Added to whitelist: "..plname elseif cmd == "del" then xban.remove_whitelist(plname) - ACTION("%s removes %s to whitelist", source, plname) + ACTION("%s removes %s to whitelist", name, plname) return true, "Removed from whitelist: "..plname elseif cmd == "get" then local e = xban.get_whitelist(plname) @@ -361,10 +359,10 @@ local function load_db() WARNING("Unable to load database: %s", "Read failed") return end - local t, e = minetest.deserialize(cont) + local t, e2 = minetest.deserialize(cont) if not t then WARNING("Unable to load database: %s", - "Deserialization failed: "..(e or "unknown error")) + "Deserialization failed: "..(e2 or "unknown error")) return end db = t From 6738109c15f53b8f57b711719c2334b1c575bd2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Mart=C3=ADnez?= Date: Mon, 24 Apr 2017 04:44:47 -0300 Subject: [PATCH 8/9] Create README.md --- README.md | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..90eed0d --- /dev/null +++ b/README.md @@ -0,0 +1,106 @@ + +# Extended Ban Mod for Minetest + +This mod attempts to be an improvement to Minetest's ban system. + +* It supports normal bans and temporary bans (from 60 seconds up to the end of + time, with 1 second granularity). +* Records and joins all accounts using the same IP address and several IP + addresses using the same name into a single record, and can ban/unban them as + a single user. +* Can ban offline players if you know their IP or username. +* Holds a record of bans for each user, so moderators and administrators can + consult it to know if a player is a repeat offender. +* Does not modify the default ban database in any way (`ipban.txt'). +* Has an API to ban and check the ban database to allows other mods to manage + users (for example, anticheat mods). + +## Chat commands + +The mod provides the following chat commands. All commands require the `ban` +privilege. + +### `xban` + +Bans a player permanently. + +**Usage:** `/xban ` + +**Example:** `/xban 127.0.0.1 Some reason.` + +### `xtempban` + +Bans a player temporarily. + +**Usage:** `/xtempban