More aggressive priv caching strategy
Instead of caching privs only for the current tick, and only for NodeCore itself, change the base API to use caching universally, including for naive mod code. Privs are cached until invalidated by a change; it's assumed here that the "auth_reload" command exists in the first place because this kind of caching is allowed and accounted for, even if it's not actually done by the engine or builtin.
This commit is contained in:
parent
a15146dc4c
commit
ee99c24d52
44
mods/nc_api/compat_authcache.lua
Normal file
44
mods/nc_api/compat_authcache.lua
Normal file
@ -0,0 +1,44 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local minetest, type
|
||||
= minetest, type
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local function player_name(player)
|
||||
if not player then return end
|
||||
if type(player) == "string" then return player end
|
||||
player = player.get_player_name and player:get_player_name()
|
||||
if type(player) == "string" then return player end
|
||||
end
|
||||
|
||||
local priv_cache = {}
|
||||
|
||||
local function invalidateon(method)
|
||||
local oldfunc = minetest[method]
|
||||
minetest[method] = function(player, ...)
|
||||
local function helper(...)
|
||||
local name = player_name(player)
|
||||
if name then priv_cache[name] = nil end
|
||||
return ...
|
||||
end
|
||||
return helper(oldfunc(player, ...))
|
||||
end
|
||||
end
|
||||
invalidateon("set_privileges")
|
||||
invalidateon("remove_player_auth")
|
||||
|
||||
local oldreload = minetest.auth_reload
|
||||
function minetest.auth_reload(...)
|
||||
priv_cache = {}
|
||||
return oldreload(...)
|
||||
end
|
||||
|
||||
local oldget = minetest.get_player_privs
|
||||
function minetest.get_player_privs(player)
|
||||
player = player_name(player)
|
||||
if not player then return {} end
|
||||
local cached = priv_cache[player]
|
||||
if cached then return cached end
|
||||
cached = oldget(player)
|
||||
priv_cache[player] = cached
|
||||
return cached
|
||||
end
|
@ -90,6 +90,7 @@ include("compat_creative")
|
||||
include("compat_issue10127")
|
||||
include("compat_legacyent")
|
||||
include("compat_nodealpha")
|
||||
include("compat_authcache")
|
||||
|
||||
include("util_settings")
|
||||
include("util_privs")
|
||||
|
@ -1,48 +1,17 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local minetest, nodecore, type
|
||||
= minetest, nodecore, type
|
||||
local minetest, nodecore
|
||||
= minetest, nodecore
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local function player_name(player)
|
||||
if not player then return end
|
||||
if type(player) == "string" then return player end
|
||||
player = player.get_player_name and player:get_player_name()
|
||||
if type(player) == "string" then return player end
|
||||
end
|
||||
|
||||
local dirty
|
||||
local priv_cache = {}
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
if dirty then
|
||||
|
||||
priv_cache = {}
|
||||
|
||||
dirty = false
|
||||
end
|
||||
end)
|
||||
|
||||
function nodecore.get_player_privs_cached(player)
|
||||
player = player_name(player)
|
||||
if not player then return {} end
|
||||
local cached = priv_cache[player]
|
||||
if cached then return cached end
|
||||
cached = minetest.get_player_privs(player)
|
||||
priv_cache[player] = cached
|
||||
dirty = true
|
||||
return cached
|
||||
end
|
||||
|
||||
local oldset = minetest.set_player_privs
|
||||
function minetest.set_player_privs(player, ...)
|
||||
local function helper(...)
|
||||
local name = player_name(player)
|
||||
if name then priv_cache[name] = nil end
|
||||
return ...
|
||||
local warned
|
||||
function nodecore.get_player_privs_cached(...)
|
||||
if not warned then
|
||||
nodecore.log("warning", "deprecated nodecore.get_player_privs_cached(...)")
|
||||
warned = true
|
||||
end
|
||||
return helper(oldset(player, ...))
|
||||
return minetest.get_player_privs(...)
|
||||
end
|
||||
|
||||
function nodecore.interact(player)
|
||||
return nodecore.get_player_privs_cached(player).interact
|
||||
return minetest.get_player_privs(player).interact
|
||||
end
|
||||
|
@ -170,7 +170,7 @@ nodecore.register_playerstep({
|
||||
label = "hint tab watch interact",
|
||||
action = function(player, data)
|
||||
local privs = {}
|
||||
for k, v in pairs(nodecore.get_player_privs_cached(data.pname)) do
|
||||
for k, v in pairs(minetest.get_player_privs(data.pname)) do
|
||||
if v then privs[#privs + 1] = k end
|
||||
end
|
||||
table_sort(privs)
|
||||
|
@ -39,7 +39,7 @@ local function gethint(player)
|
||||
|
||||
local found, done = nodecore.hint_state(pname)
|
||||
local future
|
||||
if nodecore.get_player_privs_cached(pname).debug then
|
||||
if minetest.get_player_privs(pname).debug then
|
||||
local seen = {}
|
||||
for _, v in pairs(found) do seen[v] = true end
|
||||
for _, v in pairs(done) do seen[v] = true end
|
||||
|
@ -24,7 +24,7 @@ minetest.register_privilege("ncdqd", {
|
||||
|
||||
function nodecore.player_can_take_damage(player)
|
||||
return not player:get_armor_groups().immortal
|
||||
and not nodecore.get_player_privs_cached(player).ncdqd
|
||||
and not minetest.get_player_privs(player).ncdqd
|
||||
end
|
||||
|
||||
function nodecore.register_virtual_item(name, def)
|
||||
|
@ -21,7 +21,7 @@ local cheats = {
|
||||
|
||||
local function ischeating(player)
|
||||
local cheating = false
|
||||
local privs = nodecore.get_player_privs_cached(player:get_player_name())
|
||||
local privs = minetest.get_player_privs(player:get_player_name())
|
||||
if privs.interact then
|
||||
cheating = cheating or not nodecore.player_can_take_damage(player)
|
||||
cheating = cheating or not nodecore.player_visible(player)
|
||||
|
@ -47,7 +47,7 @@ nodecore.player_skin = nodecore.player_skin or function(player, options)
|
||||
|
||||
getcolors(name, layers)
|
||||
|
||||
local privs = options.privs or nodecore.get_player_privs_cached(
|
||||
local privs = options.privs or minetest.get_player_privs(
|
||||
options.privname or name)
|
||||
if options.noarms or not privs.interact then
|
||||
layers[#layers + 1] = modname .. "_no_interact.png"
|
||||
|
@ -29,7 +29,7 @@ local function patchplayers()
|
||||
function meta:set_pos(pos, ...)
|
||||
if (not self) or (not self.is_player) or (not self:is_player())
|
||||
or (not pos) or type(pos) ~= "table" or pos.keepinv
|
||||
or nodecore.get_player_privs_cached(self)[keepname] then
|
||||
or minetest.get_player_privs(self)[keepname] then
|
||||
return setraw(self, pos, ...)
|
||||
end
|
||||
local old = self:get_pos()
|
||||
|
@ -55,7 +55,7 @@ nodecore.register_playerstep({
|
||||
action = function(player, data, dtime)
|
||||
local function reset() data.pushout = nil end
|
||||
|
||||
if nodecore.get_player_privs_cached(player).noclip
|
||||
if minetest.get_player_privs(player).noclip
|
||||
or nodecore.player_pushout_disable(player, data)
|
||||
then return reset() end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user