Fix bugs regarding disconnected players and unsanitized command input

This commit is contained in:
Till Affeldt 2020-05-16 16:19:28 +02:00
parent de512c172c
commit 082c789d6e
6 changed files with 49 additions and 19 deletions

View File

@ -14,6 +14,8 @@ local EFFECT_NAME = "climate_api:hud_overlay"
local handles = {} local handles = {}
local function apply_hud(pname, weather, hud) local function apply_hud(pname, weather, hud)
local player = minetest.get_player_by_name(pname) local player = minetest.get_player_by_name(pname)
if player == nil then return end
if handles[pname] == nil then handles[pname] = {} end if handles[pname] == nil then handles[pname] = {} end
if handles[pname][weather] ~= nil then if handles[pname][weather] ~= nil then
player:hud_remove(handles[pname][weather]) player:hud_remove(handles[pname][weather])
@ -48,9 +50,11 @@ local function apply_hud(pname, weather, hud)
end end
local function remove_hud(pname, weather, hud) local function remove_hud(pname, weather, hud)
if handles[pname] == nil or handles[pname][weather] == nil then return end
local handle = handles[pname][weather]
local player = minetest.get_player_by_name(pname) local player = minetest.get_player_by_name(pname)
if player == nil then return end
if handles[pname] == nil or handles[pname][weather] == nil then return end
local handle = handles[pname][weather]
player:hud_remove(handle) player:hud_remove(handle)
handles[pname][weather] = nil handles[pname][weather] = nil
end end

View File

@ -65,7 +65,7 @@ minetest.register_chatcommand("set_base_heat", {
return return
end end
if param == "auto" then param = 0 end if param == "auto" then param = 0 end
climate_mod.settings.heat = tonumber(param) climate_mod.settings.heat = tonumber(param) or 0
minetest.chat_send_player(playername, "Base heat changed") minetest.chat_send_player(playername, "Base heat changed")
end end
}) })
@ -84,7 +84,7 @@ minetest.register_chatcommand("set_heat", {
climate_mod.forced_enviroment.heat = nil climate_mod.forced_enviroment.heat = nil
minetest.chat_send_player(playername, "Heat value reset") minetest.chat_send_player(playername, "Heat value reset")
else else
climate_mod.forced_enviroment.heat = tonumber(param) climate_mod.forced_enviroment.heat = tonumber(param) or 0
minetest.chat_send_player(playername, "Heat value changed") minetest.chat_send_player(playername, "Heat value changed")
end end
end end
@ -96,12 +96,12 @@ minetest.register_chatcommand("set_base_humidity", {
description = "Override the weather algorithm's base humidity", description = "Override the weather algorithm's base humidity",
privs = { weather = true }, privs = { weather = true },
func = function(playername, param) func = function(playername, param)
if param == "auto" then param = 0 end
if param == nil or param == "" then if param == nil or param == "" then
minetest.chat_send_player(playername, "Provide a number to modify the base humidity") minetest.chat_send_player(playername, "Provide a number to modify the base humidity")
return return
end end
if param == "auto" then param = 0 end climate_mod.settings.humidity = tonumber(param) or 0
climate_mod.settings.humidity = tonumber(param)
minetest.chat_send_player(playername, "Base humidity changed") minetest.chat_send_player(playername, "Base humidity changed")
end end
}) })
@ -120,7 +120,7 @@ minetest.register_chatcommand("set_humidity", {
climate_mod.forced_enviroment.humidity = nil climate_mod.forced_enviroment.humidity = nil
minetest.chat_send_player(playername, "Humidity value reset") minetest.chat_send_player(playername, "Humidity value reset")
else else
climate_mod.forced_enviroment.humidity = tonumber(param) climate_mod.forced_enviroment.humidity = tonumber(param) or 0
minetest.chat_send_player(playername, "Humidity value changed") minetest.chat_send_player(playername, "Humidity value changed")
end end
end end
@ -138,21 +138,23 @@ minetest.register_chatcommand("set_wind", {
end end
local arguments = {} local arguments = {}
for w in param:gmatch("%S+") do table.insert(arguments, w) end for w in param:gmatch("%S+") do table.insert(arguments, w) end
local wind_x = arguments[1] local arg1 = arguments[1]
local wind_z = arguments[2] local wind_x = tonumber(arguments[1])
if wind_x == "auto" then local wind_z = tonumber(arguments[2])
if arg1 == "auto" then
climate_mod.forced_enviroment.wind = nil climate_mod.forced_enviroment.wind = nil
minetest.chat_send_player(playername, "Wind reset")
elseif wind_x == nil or wind_z == nil then elseif wind_x == nil or wind_z == nil then
minetest.chat_send_player(playername, "Invalid wind configuration") minetest.chat_send_player(playername, "Invalid wind configuration")
else else
climate_mod.forced_enviroment.wind = vector.new({ climate_mod.forced_enviroment.wind = vector.new({
x = tonumber(wind_x), x = wind_x,
y = 0, y = 0,
z = tonumber(wind_z) z = wind_z
}) })
end
minetest.chat_send_player(playername, "Wind changed") minetest.chat_send_player(playername, "Wind changed")
end end
end
}) })
-- display current mod config -- display current mod config

View File

@ -50,14 +50,14 @@ end)
climate_api.register_influence("light", function(pos) climate_api.register_influence("light", function(pos)
pos = vector.add(pos, {x = 0, y = 1, z = 0}) pos = vector.add(pos, {x = 0, y = 1, z = 0})
return minetest.env:get_node_light(pos) return minetest.env:get_node_light(pos) or 0
end) end)
climate_api.register_influence("daylight", function(pos) climate_api.register_influence("daylight", function(pos)
pos = vector.add(pos, {x = 0, y = 1, z = 0}) pos = vector.add(pos, {x = 0, y = 1, z = 0})
return minetest.env:get_node_light(pos, 0.5) return minetest.env:get_node_light(pos, 0.5) or 0
end) end)
climate_api.register_global_influence("time", climate_api.register_global_influence("time",
minetest.get_timeofday() minetest.get_timeofday
) )

View File

@ -1,6 +1,15 @@
local GSCYCLE = 0.03 * climate_mod.settings.tick_speed -- only process event loop after this amount of time local GSCYCLE = 0.03 * climate_mod.settings.tick_speed -- only process event loop after this amount of time
local WORLD_CYCLE = 15.00 * climate_mod.settings.tick_speed -- only update global environment influences after this amount of time local WORLD_CYCLE = 15.00 * climate_mod.settings.tick_speed -- only update global environment influences after this amount of time
local function is_connected(playername)
local connected = minetest.get_connected_players()
for _, player in ipairs(connected) do
local name = player:get_player_name()
if playername == name then return true end
end
return false
end
local gs_timer = 0 local gs_timer = 0
local world_timer = 0 local world_timer = 0
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
@ -15,7 +24,17 @@ minetest.register_globalstep(function(dtime)
climate_mod.global_environment = climate_mod.trigger.get_global_environment() climate_mod.global_environment = climate_mod.trigger.get_global_environment()
end end
local previous_effects = table.copy(climate_mod.current_effects) local previous_effects = table.copy(climate_mod.current_effects)
-- skip weather changes for offline players
for effect, data in pairs(previous_effects) do
for playername, _ in pairs(data) do
if not is_connected(playername) then
previous_effects[effect][playername] = nil
end
end
end
local current_effects = climate_mod.trigger.get_active_effects() local current_effects = climate_mod.trigger.get_active_effects()
for name, effect in pairs(climate_mod.effects) do for name, effect in pairs(climate_mod.effects) do

View File

@ -64,7 +64,7 @@ end
local function set_skybox(playername, sky) local function set_skybox(playername, sky)
local player = minetest.get_player_by_name(playername) local player = minetest.get_player_by_name(playername)
if not player.get_stars then return end if player == nil or not player.get_stars then return end
player:set_sky(sky.sky_data) player:set_sky(sky.sky_data)
player:set_clouds(sky.cloud_data) player:set_clouds(sky.cloud_data)
player:set_moon(sky.moon_data) player:set_moon(sky.moon_data)
@ -85,7 +85,7 @@ function skybox.update(playername)
if right.priority == nil then right.priority = 1 end if right.priority == nil then right.priority = 1 end
return left.priority < right.priority return left.priority < right.priority
end) end)
for i=1,#numbered_layers do for i = 1, #numbered_layers do
sky = merge_tables(sky, numbered_layers[i]) sky = merge_tables(sky, numbered_layers[i])
end end
set_skybox(playername, sky) set_skybox(playername, sky)

View File

@ -76,7 +76,12 @@ end
function trigger.get_active_effects() function trigger.get_active_effects()
local environments = {} local environments = {}
for _, player in ipairs(minetest.get_connected_players()) do for _, player in ipairs(minetest.get_connected_players()) do
environments[player:get_player_name()] = trigger.get_player_environment(player) local playername = player:get_player_name()
local hp = player:get_hp()
-- skip weather presets for dead players
if hp ~= nil and hp > 0 then
environments[playername] = trigger.get_player_environment(player)
end
end end
local effects = {} local effects = {}