oldplayer/init.lua

204 lines
5.2 KiB
Lua

-- OLD PLAYER : keep only serious players data on server
--(c) 2015-2016 rnd
--
-- modified by SaKeL for Survival X server
-- - Linux support
-- - Protector (redo) support (@todo)
oldplayer = {}
-- SETTINGS
oldplayer.requirement = { "default:stick 1", "default:steel_ingot 1" }
oldplayer.welcome = "*** IMPORTANT *** Hi new player, please have at least 1 STICK and 1 STEEL INGOT in your inventory when leaving the game to register as serious player. If not, your player data will be deleted!"
-- CORE
oldplayer.players = {}
local worldpath = minetest.get_worldpath()
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
if name == nil then return end
-- read player inventory data
local inv = player:get_inventory()
local isoldplayer = inv:get_stack("oldplayer", 1):get_count()
inv:set_size("oldplayer", 2)
local ip = minetest.get_player_ip(name)
if not ip then return end
inv:set_stack("oldplayer", 2, ItemStack("IP".. ip)) -- string.gsub(ip,".","_")));
if isoldplayer > 0 then
oldplayer.players[name] = 1
minetest.chat_send_player(name, "<SERVER> Welcome back, have fun!")
else
local privs = minetest.get_player_privs(name)
if privs.kick then
inv:set_stack("oldplayer", 1, ItemStack("oldplayer"))
minetest.chat_send_player(name, "<SERVER> Welcome moderator. Will remember you as an old player and will not remove your player data. Have fun!")
oldplayer.players[name] = 1
else
oldplayer.players[name] = 0
local form = "size [6,2] textarea[0,0;6.6,3.5;help;WELCOME TO SURVIVAL X SERVER;".. oldplayer.welcome.."]"
minetest.show_formspec(name, "oldplayer:welcome", form)
-- minetest.chat_send_player(name, oldplayer.welcome)
end
end
end)
minetest.register_on_leaveplayer(function(player, timed_out)
local name = player:get_player_name()
if name == nil then return end
if oldplayer.players[name] == 1 then return end -- already old, do nothing
local delete = false -- should we delete player?
-- read player inventory data
local inv = player:get_inventory()
-- does player have all the required items in inventory?
for _,item in pairs(oldplayer.requirement) do
if not inv:contains_item("main", item) then
delete = true
end
end
if not delete then -- set up oldplayer inventory so we know player is old next time
inv:set_size("oldplayer", 2)
inv:set_stack("oldplayer", 1, ItemStack("oldplayer"))
else -- delete player profile
local filename = worldpath.."/players/"..name
-- PROBLEM: deleting doesnt always work? seems minetest itself is saving stuff.
-- so we wait a little and then delete
minetest.after(10, function()
minetest.log("action", "[oldplayer] removing player filename "..filename)
local err,msg = os.remove(filename)
if err == nil then
minetest.log("warning", "[oldplayer] Error while removing player data "..filename.." error message: "..msg)
end
-- TO DO: how to remove players from auth.txt easily without editing file manually like below
end)
end
end
)
-- delete file if not old player
local function remove_non_old_player_file(name)
local filename = worldpath.."/players/"..name
local f = io.open(filename, "r")
local s = f:read("*all")
f:close()
if string.find(s,"Item oldplayer") then
return false
else
os.remove(filename)
return true
end
end
-- deletes data with no corresponding playerfiles from auth.txt and creates auth_new.txt
local function player_file_exists(name)
local f = io.open(worldpath.."/players/"..name, "r")
if not f then
return false
else
io.close(f)
return true
end
end
local function remove_missing_players_from_auth()
local playerfilelist = minetest.get_dir_list(worldpath.."/players", false)
local f = io.open(worldpath.."/auth.txt", "r")
if not f then return end
local s = f:read("*a")
f:close()
local p1, p2
f = io.open(worldpath.."/auth_new.txt", "w")
if not f then return end
local playerlist = {}
for _, name in ipairs(playerfilelist) do
playerlist[name] = true
end
local i = 0
local j = 0
local k = 0
local name
local count = 0
-- parse through auth and remove missing players data
while j do
j = string.find(s, ":", i)
if j then
if i ~= 1 then
name = string.sub(s, i + 1, j - 1)
else
name = string.sub(s, 1, j - 1)
end
if j then
k = string.find(s, "\n", i + 1)
if not k then
j = nil
if playerlist[name] then
f:write(string.sub(s, i + 1))
else
count = count + 1
end
else
if playerlist[name] then
f:write(string.sub(s, i + 1, k))
else
count = count + 1
end
i = k
end
end
end
end
f:close()
minetest.log("action", "[oldplayer] Removed "..count.." entries from auth.txt. Replace auth.txt with auth_new.txt")
end
local function remove_non_old_player_files()
local playerfilelist = minetest.get_dir_list(worldpath.."/players", false);
local count = 0;
for _,name in ipairs(playerfilelist) do
if remove_non_old_player_file(name) then
count = count + 1
end
end
minetest.log("action", "[oldplayer] Removed "..count.." non oldplayer player files")
end
minetest.register_on_shutdown(function()
remove_non_old_player_files()
remove_missing_players_from_auth()
end)