From 16e1fa84c2fc186f373beaa6ca8253cb4729b925 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sat, 9 Feb 2019 16:48:34 +0100 Subject: [PATCH] Big mod renewal: License CC0 Use minetest.safe_file_write Pass chat answers by return value Close file handle in load_whitelist (bugfix) --- README.md | 2 +- functions.lua | 80 +++++++++++++++++++++++++++------------------------ init.lua | 61 ++++++++++++++++++++------------------- 3 files changed, 75 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index 2278674..6994c46 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ It will limit the accounts to 2 (+3 if the player is whitelisted) per IP and del Initial mod creator: Krock -License: WTFPL +License: CC0 Depends: nothing diff --git a/functions.lua b/functions.lua index f74a7e8..82fcf6a 100644 --- a/functions.lua +++ b/functions.lua @@ -1,49 +1,57 @@ +-- WARNING: ipnames.command_* are reserved for chat commands! + function ipnames.command_list(name) - local names = "" + local names = {} -- faster than string concat for k, v in pairs(ipnames.whitelist) do - names = names.." "..k + if v then + names[#names + 1] = k + end end - minetest.chat_send_player(name, "All exceptions: "..names) + return true, "All exceptions: " .. table.concat(names, ", ") end function ipnames.command_whois(name, param) if not ipnames.data[param] then - minetest.chat_send_player(name, "The player '"..param.."' did not join yet.") - return + return false, "The player '" .. param .. "' did not join yet." end local ip = ipnames.data[param][1] local names = "" for k, v in pairs(ipnames.data) do if v[1] == ip then - names = names.." "..k + names = names .. " " .. k end end - minetest.chat_send_player(name, "Following players share an IP: "..names) + return true, "Following players share an IP: " .. names end function ipnames.command_ignore(name, param) if not ipnames.data[param] then - minetest.chat_send_player(name, "The player '"..param.."' did not join yet.") - return + return false, "The player '" .. param .. "' did not join yet." end ipnames.whitelist[param] = true - minetest.chat_send_player(name, "Added an exception!") ipnames.save_whitelist() + return true, "Added '" .. param .. "' to the name whitelist." end function ipnames.command_unignore(name, param) if not ipnames.whitelist[param] then - minetest.chat_send_player(name, "The player '"..param.."' is not on the whitelist.") - return + return false, "The player '" .. param .. "' is not on the whitelist." end ipnames.whitelist[param] = nil - minetest.chat_send_player(name, "Removed an exception!") ipnames.save_whitelist() + return true, "Removed '" .. param .. "' from the name whitelist." end +local player_auth_exists = minetest.player_exists + or function(name) + -- 0.4.x support: If you get a nil error here -> update Minetest + return minetest.auth_table[name] + end + +-- TODO: Use mod storage function ipnames.load_data() local file = io.open(ipnames.file, "r") if not file then @@ -51,25 +59,21 @@ function ipnames.load_data() end local t = os.time() for line in file:lines() do - if line ~= "" then - local data = line:split("|") - if #data >= 2 then - -- Special stuff - only save if player has not been deleted yet - local ignore = false - if not minetest.auth_table[data[1]] then - ignore = true - end - if not ignore then - data[3] = tonumber(data[3]) or 0 - -- Remove IP after 2 weeks - if data[3] > 0 and t - data[3] > (3600 * 24 * 14) then - ignore = true - end - end - if not ignore then - ipnames.data[data[1]] = {data[2], data[3]} + local data = line:split("|") + if #data >= 2 then + -- Ignore players which were removed (according to auth) + local player_exists = player_auth_exists(data[1]) + + if player_exists then + data[3] = tonumber(data[3]) or 0 + -- Remove IP after 2 weeks: Expired + if data[3] > 0 and t - data[3] > (3600 * 24 * 14) then + player_exists = false end end + if player_exists then + ipnames.data[data[1]] = {data[2], data[3]} + end end end io.close(file) @@ -80,12 +84,13 @@ function ipnames.save_data() return end ipnames.changes = false - local file = io.open(ipnames.file, "w") + + local contents = {} -- faster than string concat for k, v in pairs(ipnames.data) do v[2] = v[2] or os.time() - file:write(k.."|"..v[1].."|"..v[2].."\n") + contents[#contents + 1] = k.."|"..v[1].."|"..v[2] end - io.close(file) + minetest.safe_file_write(ipnames.file, table.concat(contents, "\n")) end function ipnames.load_whitelist() @@ -98,14 +103,15 @@ function ipnames.load_whitelist() ipnames.whitelist[line] = true end end + io.close(file) end function ipnames.save_whitelist() - local file = io.open(ipnames.whitelist_file, "w") + local names = {} -- faster than string concat for k, v in pairs(ipnames.whitelist) do - if v ~= nil then - file:write(k.."\n") + if v then + names[#names + 1] = k end end - io.close(file) + minetest.safe_file_write(ipnames.whitelist_file, table.concat(names, "\n")) end diff --git a/init.lua b/init.lua index 7edd2a1..d046d97 100644 --- a/init.lua +++ b/init.lua @@ -1,5 +1,11 @@ -- Created by Krock to stop mass-account-creators --- License: WTFPL +-- License: CC0 + +if not minetest.safe_file_write then + error("[simple_protection] Your Minetest version is no longer supported." + .. " (version < 0.4.17)") +end + ipnames = {} ipnames.data = {} ipnames.tmp_data = {} @@ -24,32 +30,28 @@ minetest.register_chatcommand("ipnames", { privs = {ban=true}, func = function(name, param) if param == "" then - minetest.chat_send_player(name, "Available commands: ") - minetest.chat_send_player(name, "Get all accounts of : /ipnames whois ") - minetest.chat_send_player(name, "List all exceptions: /ipnames list") - minetest.chat_send_player(name, "Remove/add an exception: /ipnames (un)ignore ") - return + return true, + "Available commands:\n" .. + "Get all accounts of : /ipnames whois \n" .. + "Show all whitelisted names: /ipnames list\n" .. + "Add/remove whitelist entry: /ipnames (un)ignore " end if param == "list" then - ipnames.command_list(name) - return + return ipnames.command_list(name) end - + + -- Commands with two arguments local args = param:split(" ") if #args < 2 then - minetest.chat_send_player(name, "Error: Please check again '/ipnames' for correct usage.") - return + return false, "Error: Too few command arguments." end - - if args[1] == "whois" then - ipnames.command_whois(name, args[2]) - elseif args[1] == "ignore" then - ipnames.command_ignore(name, args[2]) - elseif args[1] == "unignore" then - ipnames.command_unignore(name, args[2]) - else - minetest.chat_send_player(name, "Error: No known argument for #1 '"..args[1].."'") + + local func = ipnames["command_" .. args[1]] + if func then + return func(name, args[2]) end + + return false, "Error: No known action for argument #1 ('"..args[1].."')" end }) @@ -61,9 +63,8 @@ minetest.register_on_prejoinplayer(function(name, ip) if ipnames.data[name] then return end - - local count = 1 - local names = "" + + local names = {} -- faster than string concat local limit_ext = false for k, v in pairs(ipnames.data) do if v[1] == ip then @@ -71,14 +72,14 @@ minetest.register_on_prejoinplayer(function(name, ip) count = count - ipnames.extended_limit limit_ext = true end - count = count + 1 - names = names..k..", " + names[#names + 1] = k end end -- Return error message if too many accounts have been created - if count > ipnames.name_per_ip_limit then + if #names > ipnames.name_per_ip_limit then ipnames.tmp_data[name] = nil - return ("\nYou exceeded the limit of accounts.\nYou already own the following accounts:\n"..names) + return "\nYou exceeded the limit of accounts.\n" .. + "You already own the following accounts:\n" .. table.concat(names, ", ") end end) @@ -100,7 +101,7 @@ minetest.register_globalstep(function(t) ipnames.save_data() end) -minetest.register_on_shutdown(function() ipnames.save_data() end) +minetest.register_on_shutdown(ipnames.save_data) -minetest.after(3, function() ipnames.load_data() end) -minetest.after(3, function() ipnames.load_whitelist() end) \ No newline at end of file +minetest.after(3, ipnames.load_data) +minetest.after(3, ipnames.load_whitelist) \ No newline at end of file