forked from minetest-mods/xban2
		
	Compare commits
	
		
			10 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0f62057622 | |||
|  | e870b8d1d6 | ||
|  | c850d11a3c | ||
| 1faa658651 | |||
|  | d2cda4f73a | ||
| 72a99b2b18 | |||
|  | 37cdbf014e | ||
|  | e937f5ff67 | ||
| 43acd1c620 | |||
|  | 3b70045365 | 
							
								
								
									
										24
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| BSD 2-Clause License | ||||
|  | ||||
| Copyright (c) 2014-2023, Diego Martínez | ||||
|  | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are met: | ||||
|  | ||||
| 1. Redistributions of source code must retain the above copyright notice, this | ||||
|    list of conditions and the following disclaimer. | ||||
|  | ||||
| 2. Redistributions in binary form must reproduce the above copyright notice, | ||||
|    this list of conditions and the following disclaimer in the documentation | ||||
|    and/or other materials provided with the distribution. | ||||
|  | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||||
| FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
| OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| @@ -104,3 +104,9 @@ the supported import plugins at the time of writing: | ||||
| * `v2`: Old format used by xban (`players.iplist.v2`). | ||||
|  | ||||
| **Example:** `/xban_dbi minetest` | ||||
|  | ||||
| ### `xban_cleanup` | ||||
|  | ||||
| Removes all non-banned entries from the xban db. | ||||
|  | ||||
| **Usage:** `/xban_cleanup` | ||||
|   | ||||
							
								
								
									
										9
									
								
								gui.lua
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								gui.lua
									
									
									
									
									
								
							| @@ -9,9 +9,7 @@ local ESC = minetest.formspec_escape | ||||
| local function make_list(filter) | ||||
| 	filter = filter or "" | ||||
| 	local list, n, dropped = { }, 0, false | ||||
| 	local enumerate, e1, e2, e3 = minetest.get_auth_handler().enumerate_auths | ||||
| 	if enumerate then e1 = enumerate() else e1, e2, e3 = pairs(minetest.auth_table) end | ||||
| 	for k in e1, e2, e3 do | ||||
| 	for k in minetest.get_auth_handler().iterate() do | ||||
| 		if strfind(k, filter, 1, true) then | ||||
| 			if n >= MAXLISTSIZE then | ||||
| 				dropped = true | ||||
| @@ -63,7 +61,8 @@ local function make_fs(name) | ||||
| 		"size[16,12]", | ||||
| 		"label[0,-.1;Filter]", | ||||
| 		"field[1.5,0;12.8,1;filter;;"..ESC(filter).."]", | ||||
| 		"button[14,-.3;2,1;search;Search]", | ||||
| 		"field_close_on_enter[filter;false]", | ||||
| 		"button[14,-.3;2,1;search_submit;Search]", | ||||
| 	} | ||||
| 	local fsn = #fs | ||||
| 	fsn=fsn+1 fs[fsn] = format("textlist[0,.8;4,9.3;player;%s;%d;0]", | ||||
| @@ -124,7 +123,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) | ||||
| 		end | ||||
| 		return | ||||
| 	end | ||||
| 	if fields.search then | ||||
| 	if fields.search_submit or fields.filter then | ||||
| 		local filter = fields.filter or "" | ||||
| 		state.filter = filter | ||||
| 		state.list = make_list(filter) | ||||
|   | ||||
							
								
								
									
										54
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								init.lua
									
									
									
									
									
								
							| @@ -25,6 +25,7 @@ end | ||||
|  | ||||
| local ACTION = make_logger("action") | ||||
| local WARNING = make_logger("warning") | ||||
| local ERROR = make_logger("error") | ||||
|  | ||||
| local unit_to_secs = { | ||||
| 	s = 1, m = 60, h = 3600, | ||||
| @@ -40,6 +41,14 @@ local function parse_time(t) --> secs | ||||
| 	return secs | ||||
| end | ||||
|  | ||||
| local function concat_keys(t, sep) | ||||
| 	local keys = {} | ||||
| 	for k, _ in pairs(t) do | ||||
| 		keys[#keys + 1] = k | ||||
| 	end | ||||
| 	return table.concat(keys, sep) | ||||
| end | ||||
|  | ||||
| function xban.find_entry(player, create) --> entry, index | ||||
| 	for index, e in ipairs(db) do | ||||
| 		for name in pairs(e.names) do | ||||
| @@ -111,7 +120,7 @@ function xban.ban_player(player, source, expires, reason) --> bool, err | ||||
| 	end | ||||
| 	ACTION("%s bans %s until %s for reason: %s", source, player, | ||||
| 	  date, reason) | ||||
| 	ACTION("Banned Names/IPs: %s", table.concat(e.names, ", ")) | ||||
| 	ACTION("Banned Names/IPs: %s", concat_keys(e.names, ", ")) | ||||
| 	return true | ||||
| end | ||||
|  | ||||
| @@ -131,7 +140,7 @@ function xban.unban_player(player, source) --> bool, err | ||||
| 	e.expires = nil | ||||
| 	e.time = nil | ||||
| 	ACTION("%s unbans %s", source, player) | ||||
| 	ACTION("Unbanned Names/IPs: %s", table.concat(e.names, ", ")) | ||||
| 	ACTION("Unbanned Names/IPs: %s", concat_keys(e.names, ", ")) | ||||
| 	return true | ||||
| end | ||||
|  | ||||
| @@ -314,6 +323,7 @@ minetest.register_chatcommand("xban_wl", { | ||||
| 	end, | ||||
| }) | ||||
|  | ||||
|  | ||||
| local function check_temp_bans() | ||||
| 	minetest.after(60, check_temp_bans) | ||||
| 	local to_rm = { } | ||||
| @@ -334,18 +344,12 @@ end | ||||
|  | ||||
| local function save_db() | ||||
| 	minetest.after(SAVE_INTERVAL, save_db) | ||||
| 	local f, e = io.open(DB_FILENAME, "wt") | ||||
| 	db.timestamp = os.time() | ||||
| 	if f then | ||||
| 		local ok, err = f:write(xban.serialize(db)) | ||||
| 		if not ok then | ||||
| 			WARNING("Unable to save database: %s", err) | ||||
| 		end | ||||
| 	else | ||||
| 		WARNING("Unable to save database: %s", e) | ||||
| 	local contents = assert(xban.serialize_db(db)) | ||||
| 	local ok = minetest.safe_file_write(DB_FILENAME, contents) | ||||
| 	if not ok then | ||||
| 		ERROR("Unable to save database") | ||||
| 	end | ||||
| 	if f then f:close() end | ||||
| 	return | ||||
| end | ||||
|  | ||||
| local function load_db() | ||||
| @@ -359,7 +363,7 @@ local function load_db() | ||||
| 		WARNING("Unable to load database: %s", "Read failed") | ||||
| 		return | ||||
| 	end | ||||
| 	local t, e2 = minetest.deserialize(cont) | ||||
| 	local t, e2 = xban.deserialize_db(cont) | ||||
| 	if not t then | ||||
| 		WARNING("Unable to load database: %s", | ||||
| 		  "Deserialization failed: "..(e2 or "unknown error")) | ||||
| @@ -374,6 +378,30 @@ local function load_db() | ||||
| 	end | ||||
| end | ||||
|  | ||||
| minetest.register_chatcommand("xban_cleanup", { | ||||
| 	description = "Removes all non-banned entries from the xban db", | ||||
| 	privs = { server=true }, | ||||
| 	func = function(name, params) | ||||
| 		local old_count = #db | ||||
|  | ||||
| 		local i = 1 | ||||
| 		while i <= #db do | ||||
| 			if not db[i].banned then | ||||
| 				-- not banned, remove from db | ||||
| 				table.remove(db, i) | ||||
| 			else | ||||
| 				-- banned, hold entry back | ||||
| 				i = i + 1 | ||||
| 			end | ||||
| 		end | ||||
|  | ||||
| 		-- save immediately | ||||
| 		save_db() | ||||
|  | ||||
| 		return true, "Removed " .. (old_count - #db) .. " entries, new db entry-count: " .. #db | ||||
| 	end, | ||||
| }) | ||||
|  | ||||
| minetest.register_on_shutdown(save_db) | ||||
| minetest.after(SAVE_INTERVAL, save_db) | ||||
| load_db() | ||||
|   | ||||
| @@ -27,5 +27,44 @@ local function my_serialize_2(t, level) | ||||
| end | ||||
|  | ||||
| function xban.serialize(t) | ||||
| 	minetest.log("warning", "[xban2] xban.serialize() is deprecated") | ||||
| 	return "return {\n"..my_serialize_2(t, 1).."\n}" | ||||
| end | ||||
|  | ||||
| -- JSON doesn't allow combined string+number keys, this function moves any | ||||
| -- number keys into an "entries" table | ||||
| function xban.serialize_db(t) | ||||
| 	local res = {} | ||||
| 	local entries = {} | ||||
| 	for k, v in pairs(t) do | ||||
| 		if type(k) == "number" then | ||||
| 			entries[k] = v | ||||
| 		else | ||||
| 			res[k] = v | ||||
| 		end | ||||
| 	end | ||||
| 	res.entries = entries | ||||
| 	return minetest.write_json(res, true) | ||||
| end | ||||
|  | ||||
| function xban.deserialize_db(s) | ||||
| 	if s:sub(1, 1) ~= "{" then | ||||
| 		-- Load legacy databases | ||||
| 		return minetest.deserialize(s) | ||||
| 	end | ||||
|  | ||||
| 	local res, err = minetest.parse_json(s) | ||||
| 	if not res then | ||||
| 		return nil, err | ||||
| 	end | ||||
|  | ||||
| 	-- Remove all "null"s added by empty tables | ||||
| 	for i, entry in ipairs(res.entries or {}) do | ||||
| 		entry.names = entry.names or {} | ||||
| 		entry.record = entry.record or {} | ||||
| 		res[i] = entry | ||||
| 	end | ||||
| 	res.entries = nil | ||||
|  | ||||
| 	return res | ||||
| end | ||||
|   | ||||
		Reference in New Issue
	
	Block a user