This repository has been archived by the owner on Aug 20, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Fix #228
- Loading branch information
Showing
3 changed files
with
204 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
names_per_ip | ||
============ | ||
|
||
A mod for Minetest to stop annoyed kids | ||
|
||
It will limit the accounts to 2 (+3 if the player is whitelisted) per IP and delete IP history. | ||
|
||
Initial mod creator: Krock | ||
|
||
License: WTFPL | ||
|
||
Depends: nothing | ||
|
||
Chat commands | ||
------------- | ||
|
||
``` | ||
/ipnames | ||
whois <name> -> Gets all accounts of <name> | ||
list -> Lists all exceptions/whitelist entries (players which can have "unlimited" accounts) | ||
ignore <name> -> Adds an exception/whitelist entry for <name> | ||
unignore <name> -> Removes an exception/whitelist entry for <name> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
function ipnames.command_list(name) | ||
local names = "" | ||
for k, v in pairs(ipnames.whitelist) do | ||
names = names.." "..k | ||
end | ||
minetest.chat_send_player(name, "All exceptions: "..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 | ||
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 | ||
end | ||
end | ||
minetest.chat_send_player(name, "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 | ||
end | ||
|
||
ipnames.whitelist[param] = true | ||
minetest.chat_send_player(name, "Added an exception!") | ||
ipnames.save_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 | ||
end | ||
|
||
ipnames.whitelist[param] = nil | ||
minetest.chat_send_player(name, "Removed an exception!") | ||
ipnames.save_whitelist() | ||
end | ||
|
||
function ipnames.load_data() | ||
local file = io.open(ipnames.file, "r") | ||
if not file then | ||
return | ||
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]} | ||
end | ||
end | ||
end | ||
end | ||
io.close(file) | ||
end | ||
|
||
function ipnames.save_data() | ||
if not ipnames.changes then | ||
return | ||
end | ||
ipnames.changes = false | ||
local file = io.open(ipnames.file, "w") | ||
for k, v in pairs(ipnames.data) do | ||
v[2] = v[2] or os.time() | ||
file:write(k.."|"..v[1].."|"..v[2].."\n") | ||
end | ||
io.close(file) | ||
end | ||
|
||
function ipnames.load_whitelist() | ||
local file = io.open(ipnames.whitelist_file, "r") | ||
if not file then | ||
return | ||
end | ||
for line in file:lines() do | ||
if line ~= "" then | ||
ipnames.whitelist[line] = true | ||
end | ||
end | ||
end | ||
|
||
function ipnames.save_whitelist() | ||
local file = io.open(ipnames.whitelist_file, "w") | ||
for k, v in pairs(ipnames.whitelist) do | ||
if v ~= nil then | ||
file:write(k.."\n") | ||
end | ||
end | ||
io.close(file) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,110 +1,106 @@ | ||
minetest.register_privilege("whois", { | ||
description = "Allows player to see other player IPs"}) | ||
|
||
-- Created by Krock to stop mass-account-creators | ||
-- License: WTFPL | ||
|
||
ipnames = {} | ||
ipnames.data = {} | ||
ipnames.tmp_data = {} | ||
ipnames.whitelist = {} | ||
ipnames.changes = false | ||
ipnames.file = minetest.get_worldpath().."/ipnames.txt" | ||
ipnames.save_time = 0 | ||
ipnames.file = minetest.get_worldpath().."/ipnames.data" | ||
ipnames.whitelist_file = minetest.get_worldpath().."/ipnames_whitelist.data" | ||
|
||
-- Limit 2 = maximal 2 accounts, the 3rd under the same IP gets blocked | ||
ipnames.name_per_ip_limit = tonumber(minetest.setting_get("max_names_per_ip")) or 2 | ||
-- 2 + 3 = 5 accounts as limit for "ignored" players | ||
ipnames.extended_limit = 3 | ||
|
||
-- Interval where the IP list gets saved/updated | ||
ipnames.save_interval = 240 | ||
|
||
ipnames.name_per_ip_limit = tonumber(minetest.setting_get("max_names_per_ip")) or 5 | ||
dofile(minetest.get_modpath("names_per_ip").."/functions.lua") | ||
|
||
-- Get accounts self: | ||
minetest.register_chatcommand("whois", { | ||
description = "Gets all players who have the same IP as the specified player", | ||
privs = {whois = true}, | ||
minetest.register_chatcommand("ipnames", { | ||
description = "Get the features of names_per_ip", | ||
privs = {ban=true}, | ||
func = function(name, param) | ||
if not ipnames.data[param] then | ||
minetest.chat_send_player(name, "The player \"" .. param .. "\" did not join yet.") | ||
if param == "" then | ||
minetest.chat_send_player(name, "Available commands: ") | ||
minetest.chat_send_player(name, "Get all accounts of <name>: /ipnames whois <name>") | ||
minetest.chat_send_player(name, "List all exceptions: /ipnames list") | ||
minetest.chat_send_player(name, "Remove/add an exception: /ipnames (un)ignore <name>") | ||
return | ||
end | ||
if param == "list" then | ||
ipnames.command_list(name) | ||
return | ||
end | ||
|
||
local ip = ipnames.data[param] | ||
local names = ""; | ||
for k, v in pairs(ipnames.data) do | ||
if v == ip then | ||
if names ~= "" then | ||
names = names .. ", " .. k | ||
else | ||
names = names .. " " .. k | ||
end | ||
end | ||
local args = param:split(" ") | ||
if #args < 2 then | ||
minetest.chat_send_player(name, "Error: Please check again '/ipnames' for correct usage.") | ||
return | ||
end | ||
minetest.chat_send_player(name, "Players for IP address " .. ip .. ": " .. names) | ||
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].."'") | ||
end | ||
end | ||
}) | ||
|
||
-- Get IP if player tries to join, ban if there are too much names per IP: | ||
-- Get IP if player tries to join, ban if there are too much names per IP | ||
minetest.register_on_prejoinplayer(function(name, ip) | ||
-- Only stop new accounts: | ||
-- Only stop new accounts | ||
ipnames.tmp_data[name] = ip | ||
if not ipnames.data[name] then | ||
local count = 1 | ||
local names = "" | ||
for k, v in pairs(ipnames.data) do | ||
if v == ip then | ||
count = count + 1 | ||
names = names .. k .. ", " | ||
end | ||
end | ||
|
||
if count <= ipnames.name_per_ip_limit and count > 1 then | ||
minetest.log("action", name .. " now has " .. count .. " accounts. Other accounts: " .. names) | ||
end | ||
if ipnames.data[name] then | ||
return | ||
end | ||
|
||
if count > ipnames.name_per_ip_limit then | ||
ipnames.tmp_data[name] = nil | ||
if tostring(ip) ~= "127.0.0.1" then | ||
return ("\nYou exceeded the limit of accounts (" .. ipnames.name_per_ip_limit .. | ||
").\nYou already have the following accounts:\n" .. names) | ||
local count = 1 | ||
local names = "" | ||
local limit_ext = false | ||
for k, v in pairs(ipnames.data) do | ||
if v[1] == ip then | ||
if not limit_ext and ipnames.whitelist[k] then | ||
count = count - ipnames.extended_limit | ||
limit_ext = true | ||
end | ||
count = count + 1 | ||
names = names..k..", " | ||
end | ||
end | ||
-- Return error message if too many accounts have been created | ||
if count > 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) | ||
end | ||
end) | ||
|
||
-- Save IP if player joined: | ||
-- Save IP if player joined | ||
minetest.register_on_joinplayer(function(player) | ||
local name = player:get_player_name() | ||
ipnames.data[name] = ipnames.tmp_data[name] | ||
local t = os.time() | ||
ipnames.data[name] = {ipnames.tmp_data[name], t} | ||
ipnames.tmp_data[name] = nil | ||
ipnames.changes = true | ||
ipnames.save_data() | ||
end) | ||
|
||
function ipnames.load_data() | ||
local file = io.open(ipnames.file, "r") | ||
if not file then | ||
return | ||
end | ||
for line in file:lines() do | ||
if line ~= "" then | ||
local data = line:split("|") | ||
if #data >= 2 then | ||
ipnames.data[data[1]] = data[2] | ||
end | ||
end | ||
end | ||
io.close(file) | ||
end | ||
|
||
function ipnames.save_data() | ||
if not ipnames.changes then | ||
minetest.register_globalstep(function(t) | ||
ipnames.save_time = ipnames.save_time + t | ||
if ipnames.save_time < ipnames.save_interval then | ||
return | ||
end | ||
ipnames.changes = false | ||
local file = io.open(ipnames.file, "w") | ||
for i, v in pairs(ipnames.data) do | ||
if v ~= nil then | ||
file:write(i .. "|" .. v .. "\n") | ||
end | ||
end | ||
io.close(file) | ||
end | ||
|
||
ipnames.save_time = 0 | ||
ipnames.save_data() | ||
end) | ||
|
||
minetest.register_on_shutdown(function() ipnames.save_data() end) | ||
|
||
minetest.after(3, function() ipnames.load_data() end) | ||
minetest.after(3, function() ipnames.load_whitelist() end) |