From e3627f96d1b4136c019e75d3dbc48f07fb40f4ff Mon Sep 17 00:00:00 2001 From: Vladislav Tsendrovskii Date: Sun, 31 Oct 2021 11:57:22 +0300 Subject: [PATCH] Save granted and revoked privs to meta --- mods/lord/lord_classes/init.lua | 115 ++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 35 deletions(-) diff --git a/mods/lord/lord_classes/init.lua b/mods/lord/lord_classes/init.lua index c35b126d1..f694ba9cc 100644 --- a/mods/lord/lord_classes/init.lua +++ b/mods/lord/lord_classes/init.lua @@ -130,19 +130,6 @@ end races.load() ensure_table_struct() --- Serialize and save the races --- Returns false when failed, true otherwise -function races.save() - local output = io.open(races.save_path, "w") - if not output then - return false - end - local content = minetest.serialize(cache) - output:write(content) - output:close() - return true -end - local function table_contains(t, v) for k, _ in pairs(t) do if k == v then @@ -256,15 +243,51 @@ function races.get_gender(name) return races.get_race_and_gender(name)[2] end +function races.get_granted_privs(name) + local player = minetest.get_player_by_name(name) + local pmeta = player:get_meta() + + local privs = pmeta:get_string("classes:granted_privs") + if privs ~= "" then + return minetest.deserialize(privs) + elseif table_contains(cache.granted_privs, name) then + return cache.granted_privs[name] + else + local race = races.get_race(name) + return races.list[race].granted_privs or {} + end +end + +function races.get_revoked_privs(name) + local player = minetest.get_player_by_name(name) + local pmeta = player:get_meta() + + local privs = pmeta:get_string("classes:revoked_privs") + if privs ~= "" then + return minetest.deserialize(privs) + elseif table_contains(cache.revoked_privs, name) then + return cache.revoked_privs[name] + else + local race = races.get_race(name) + return races.list[race].revoked_privs or {} + end +end + function races.set_race_and_gender(name, race_and_gender, show_message) local valid = races.validate(race_and_gender) if not valid then return false end + local old_granted_privs = races.get_granted_privs(name) + local old_revoked_privs = races.get_revoked_privs(name) + local race = race_and_gender[1] - races.update_privileges(name, races.list[race].granted_privs, - races.list[race].revoked_privs) + local new_granted_privs = races.list[race].granted_privs + local new_revoked_privs = races.list[race].revoked_privs + + races.update_privileges(name, old_granted_privs, old_revoked_privs, + new_granted_privs, new_revoked_privs) -- Notify player if show_message then @@ -305,44 +328,67 @@ function races.set_skin(name, skin) end -- Tinker with privs -function races.update_privileges(name, granted_privs, revoked_privs) - local privs = minetest.get_player_privs(name) +local function has_value(array, val) + for _, v in ipairs(array) do + if v == val then + return true + end + end + return false +end - -- Create tables if they don't exist - cache.granted_privs[name] = cache.granted_privs[name] or {} - cache.revoked_privs[name] = cache.revoked_privs[name] or {} +function races.update_privileges(name, old_granted_privs, old_revoked_privs, + new_granted_privs, new_revoked_privs) + + local privs = minetest.get_player_privs(name) -- Step #1: Restore normal privileges - for priv_name, _ in pairs(privs) do - if cache.granted_privs[name][priv_name] then - cache.granted_privs[name][priv_name] = nil - privs[priv_name] = nil + if old_granted_privs then + for priv_name, _ in pairs(privs) do + if has_value(old_granted_privs, priv_name) then + privs[priv_name] = nil + end end end - for priv_name, _ in pairs(cache.revoked_privs[name]) do - cache.revoked_privs[name][priv_name] = nil - privs[priv_name] = true + if old_revoked_privs then + for _,priv_name in ipairs(old_revoked_privs) do + privs[priv_name] = true + end end -- Step #2: Grant/revoke new privileges - if granted_privs then - for _, priv_name in pairs(granted_privs) do + if new_granted_privs then + for _, priv_name in ipairs(new_granted_privs) do if not privs[priv_name] then -- Player hasn't this privilege privs[priv_name] = true - cache.granted_privs[name][priv_name] = true end end end - - if revoked_privs then - for _, priv_name in pairs(revoked_privs) do + + if new_revoked_privs then + for _, priv_name in ipairs(new_revoked_privs) do privs[priv_name] = nil - cache.revoked_privs[name][priv_name] = true end end minetest.set_player_privs(name, privs) + + local player = minetest.get_player_by_name(name) + local pmeta = player:get_meta() + + if new_granted_privs then + pmeta:set_string("classes:granted_privs", minetest.serialize(new_granted_privs)) + else + pmeta:set_string("classes:granted_privs", minetest.serialize({})) + end + + if new_revoked_privs then + pmeta:set_string("classes:revoked_privs", minetest.serialize(new_revoked_privs)) + else + pmeta:set_string("classes:revoked_privs", minetest.serialize({})) + end + end -- Converts user-friendly names to the corresponding internal names @@ -497,7 +543,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) minetest.after(0.1, races.show_change_form, name) elseif fields.ok then races.set_skin(name, tonumber(fields.skin)) - races.save() elseif fields.skin then local r = races.get_race_and_gender(name) minetest.after(0.1, races.show_skin_change_form, r[1], r[2], tonumber(fields.skin), name)