Compare commits

2 Commits

Author SHA1 Message Date
87ed4ade88 Allow players that already exist
This prevents players from getting locked out due to a name policy
change or bug.
2017-06-21 18:17:41 -04:00
1e6d9e01b7 Strip whitespace-like characters from names before checking them for similarity
Previously, these characters whern't considered when checking for
conflicts, but they weren't removed -- meaning that a player named
"foo_" would prevent a player named "foo" from logging in, but not
the other way around.
2017-06-21 18:02:21 -04:00

202
init.lua
View File

@ -17,128 +17,84 @@ temp = nil
exemptions[minetest.setting_get("name")] = true exemptions[minetest.setting_get("name")] = true
exemptions["singleplayer"] = true exemptions["singleplayer"] = true
local disallowed_names
local function load_forbidden_names() local function player_exempted(name)
disallowed_names = {} -- Allow specifically exempted players
local path = minetest.setting_get("name_restrictions.forbidden_names_list_path") or if exemptions[name] then
minetest.get_worldpath("name_restrictions") .. "/forbidden_names.txt" return true
local file = io.open(path, 'r')
if file then
local count = 0
for line in file:lines() do
local low_line = line:lower()
disallowed_names[low_line] = true
count = count + 1
end
file:close()
return true, count .. " forbidden names loaded", 'verbose'
else
disallowed_names = {}
return true, path .. " doesn't exist, no forbidden names have been loaded", 'warning'
end end
-- Allow players that already exist
local auth = minetest.get_auth_handler()
if auth.get_auth(name) then
return true
end
return false
end end
do
local ret, msg, lvl = load_forbidden_names()
if msg and lvl then
minetest.log(lvl, msg)
end
end
--------------------- ---------------------
-- Simple matching -- -- Simple matching --
--------------------- ---------------------
local disallowed local msg_guest = "Guest accounts are disallowed on this server. "..
"Please choose a proper name and try again."
local msg_misleading = "Your player name is misleading. "..
"Please choose a more appropriate name."
local disallowed = {
["^guest[0-9]+"] = msg_guest,
["^squeakecrafter[0-9]+"] = msg_guest,
["adm[1il]n"] = msg_misleading,
["[0o]wn[e3]r"] = msg_misleading,
["^[0-9]+$"] = "All-numeric usernames are disallowed on this server.",
}
local function load_disallowed() minetest.register_on_prejoinplayer(function(name, ip)
local path = minetest.setting_get("name_restrictions.forbidden_name_patterns_list_path") or if player_exempted(name) then return end
minetest.get_worldpath("name_restrictions") .. "/forbidden_names_patterns.txt"
local file = io.open(path, 'r') -- Check for disallowed names
if file then local lname = name:lower()
local content = file:read('*all') for re, reason in pairs(disallowed) do
local imported = minetest.deserialize(content) if lname:find(re) then
local ret, msg, lvl = true, nil, nil return reason
if imported == nil then
disallowed = disallowed or {}
ret, msg, lvl = false, "Failed to parse " .. path .. "; patterns not imported", 'error'
elseif type(imported) ~= 'table' then
disallowed = disallowed or {}
ret, msg, lvl = false, "Parsing " .. path .. " returned a " .. type(imported) ..
" where a table was expected; patterns not imported", 'error'
else
disallowed = imported
local count = 0
for _ in pairs(disallowed) do
count = count + 1
end
msg, lvl = count .. " forbidden name patterns loaded", 'verbose'
end end
file:close()
return ret, msg, lvl
else
disallowed = {}
return true, path .. " doesn't exist, no forbidden name patterns have been loaded", 'warning'
end end
end end)
do
local ret, msg, lvl = load_disallowed()
if msg and lvl then
minetest.log(lvl, msg)
end
end
--------------------------------------
-- Simple matching config reloading --
--------------------------------------
minetest.register_chatcommand("forbidden_names_reload", {
params = "",
description = "Reloads forbidden_names match lists",
privs = {ban= true},
func = function(name)
local ret1, msg, lvl = load_forbidden_names()
if msg and lvl then
minetest.log(lvl, msg)
minetest.chat_send_player(name, msg)
end
local ret2
ret2, msg, lvl = load_disallowed()
if msg and lvl then
minetest.log(lvl, msg)
minetest.chat_send_player(name, msg)
end
return ret1 and ret2
end
})
------------------------ ------------------------
-- Case-insensitivity -- -- Case-insensitivity --
------------------------ ------------------------
minetest.register_on_prejoinplayer(function(name, ip)
if player_exempted(name) then return end
-- Check for used names
local lname = name:lower()
for iname, data in pairs(minetest.auth_table) do
if iname:lower() == lname and iname ~= name then
return "Sorry, someone else is already using this"
.." name. Please pick another name."
.." Annother possibility is that you used the"
.." wrong case for your name."
end
end
end)
-- Compatability, for old servers with conflicting players -- Compatability, for old servers with conflicting players
minetest.register_chatcommand("choosecase", { minetest.register_chatcommand("choosecase", {
description = "Choose the casing that a player name should have", description = "Choose the casing that a player name should have.",
params = "<name>", params = "<name>",
privs = {server = true}, privs = {server=true},
func = function(name, params) func = function(name, params)
local lname = params:lower() local lname = params:lower()
local worldpath = minetest.get_worldpath() local worldpath = minetest.get_worldpath()
local enumerate, e1, e2, e3 = minetest.get_auth_handler().enumerate_auths for iname, data in pairs(minetest.auth_table) do
if enumerate then e1 = enumerate() else e1, e2, e3 = pairs(minetest.auth_table) end
for iname, data in e1, e2, e3 do
if iname:lower() == lname and iname ~= params then if iname:lower() == lname and iname ~= params then
local delete = minetest.get_auth_handler().delete_auth minetest.auth_table[iname] = nil
if delete then
delete(iname)
else
minetest.auth_table[iname] = nil
end
assert(not iname:find("[/\\]")) assert(not iname:find("[/\\]"))
os.remove(worldpath .. "/players/" .. iname) os.remove(worldpath.."/players/"..iname)
end end
end end
return true, "Done." return true, "Done."
@ -152,7 +108,7 @@ minetest.register_chatcommand("choosecase", {
-- Prevents names that are too similar to another player's name. -- Prevents names that are too similar to another player's name.
local similar_chars = { local similar_chars = {
-- Only A-Z, a-z, 1-9, dash, and underscore are allowed in playernames -- Only A-Z, a-z, 1-9, dash, and underscore are allowed in player names
"A4", "A4",
"B8", "B8",
"COco0", "COco0",
@ -189,40 +145,19 @@ all_chars = all_chars .. "]"
minetest.register_on_prejoinplayer(function(name, ip) minetest.register_on_prejoinplayer(function(name, ip)
--MFF crabman (fix new player disallow old player with similaire name) if player_exempted(name) then return end
local exists = minetest.get_auth_handler().get_auth(name)
if exists then return end
local lname = name:lower() -- String off dashes and underscores from the start and end of the name.
for re, reason in pairs(disallowed) do local stripped_name = name:match("^[_-]*(.-)[_-]*$")
if lname:find(re) then if not stripped_name or stripped_name == "" then
return reason return "Your name is composed solely of whitespace-like characters."
end
end end
if disallowed_names[lname] then
return "Sorry. This name is forbidden."
end
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 iname, data in e1, e2, e3 do
if iname:lower() == lname and iname ~= name then
return "Sorry, someone else is already using this"
.." name. Please pick another name."
.." Another possibility is that you used the"
.." wrong case for your name."
end
end
if exemptions[name] then return end
-- Generate a regular expression to match all similar names -- Generate a regular expression to match all similar names
local re = name:gsub(all_chars, char_map) local re = stripped_name:gsub(all_chars, char_map)
re = "^[_-]*" .. re .. "[_-]*$" re = "^[_-]*" .. re .. "[_-]*$"
local enumerate, e1, e2, e3 = minetest.get_auth_handler().enumerate_auths for authName, _ in pairs(minetest.auth_table) do
if enumerate then e1 = enumerate() else e1, e2, e3 = pairs(minetest.auth_table) end
for authName, _ in e1, e2, e3 do
if authName ~= name and authName:match(re) then if authName ~= name and authName:match(re) then
return "Your name is too similar to another player's name." return "Your name is too similar to another player's name."
end end
@ -235,22 +170,13 @@ end)
-- Name length -- -- Name length --
----------------- -----------------
local min_name_len = tonumber(minetest.setting_get("name_restrictions.minimum_name_length")) or 2 local min_name_len = tonumber(minetest.setting_get("name_restrictions.minimum_name_length")) or 3
local max_name_len = tonumber(minetest.setting_get("name_restrictions.maximum_name_length")) or 17
minetest.register_on_prejoinplayer(function(name, ip) minetest.register_on_prejoinplayer(function(name, ip)
if exemptions[name] then return end if player_exempted(name) then return end
if #name < min_name_len then if #name < min_name_len then
return "Your player name is too short" return "Your player name is too short, please try a longer name."
.. " (" .. #name .. " characters, must be " .. min_name_len .. " characters at least)."
.. " Please try a longer name."
end
if #name > max_name_len then
return "Your player name is too long"
.. " (" .. #name .. " characters, must be " .. max_name_len .. " characters at most)."
.. " Please try a shorter name."
end end
end) end)
@ -310,7 +236,7 @@ end
local pronounceability = tonumber(minetest.setting_get("name_restrictions.pronounceability")) local pronounceability = tonumber(minetest.setting_get("name_restrictions.pronounceability"))
if pronounceability then if pronounceability then
minetest.register_on_prejoinplayer(function(name, ip) minetest.register_on_prejoinplayer(function(name, ip)
if exemptions[name] then return end if player_exempted(name) then return end
if not pronounceable(pronounceability, name) then if not pronounceable(pronounceability, name) then
return "Your player name does not seem to be pronounceable." return "Your player name does not seem to be pronounceable."