From 082c789d6e7fead3c60352cefaa66013f7c9a8f0 Mon Sep 17 00:00:00 2001 From: Till Affeldt Date: Sat, 16 May 2020 16:19:28 +0200 Subject: [PATCH] Fix bugs regarding disconnected players and unsanitized command input --- ca_effects/hud_overlay.lua | 8 ++++++-- lib/commands.lua | 24 +++++++++++++----------- lib/influences.lua | 6 +++--- lib/main.lua | 19 +++++++++++++++++++ lib/skybox_merger.lua | 4 ++-- lib/trigger.lua | 7 ++++++- 6 files changed, 49 insertions(+), 19 deletions(-) diff --git a/ca_effects/hud_overlay.lua b/ca_effects/hud_overlay.lua index 214e140..10edb8e 100644 --- a/ca_effects/hud_overlay.lua +++ b/ca_effects/hud_overlay.lua @@ -14,6 +14,8 @@ local EFFECT_NAME = "climate_api:hud_overlay" local handles = {} local function apply_hud(pname, weather, hud) 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][weather] ~= nil then player:hud_remove(handles[pname][weather]) @@ -48,9 +50,11 @@ local function apply_hud(pname, weather, hud) end 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) + 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) handles[pname][weather] = nil end diff --git a/lib/commands.lua b/lib/commands.lua index f7a1511..7e9ea19 100644 --- a/lib/commands.lua +++ b/lib/commands.lua @@ -65,7 +65,7 @@ minetest.register_chatcommand("set_base_heat", { return 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") end }) @@ -84,7 +84,7 @@ minetest.register_chatcommand("set_heat", { climate_mod.forced_enviroment.heat = nil minetest.chat_send_player(playername, "Heat value reset") 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") end end @@ -96,12 +96,12 @@ minetest.register_chatcommand("set_base_humidity", { description = "Override the weather algorithm's base humidity", privs = { weather = true }, func = function(playername, param) + if param == "auto" then param = 0 end if param == nil or param == "" then minetest.chat_send_player(playername, "Provide a number to modify the base humidity") return end - if param == "auto" then param = 0 end - climate_mod.settings.humidity = tonumber(param) + climate_mod.settings.humidity = tonumber(param) or 0 minetest.chat_send_player(playername, "Base humidity changed") end }) @@ -120,7 +120,7 @@ minetest.register_chatcommand("set_humidity", { climate_mod.forced_enviroment.humidity = nil minetest.chat_send_player(playername, "Humidity value reset") 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") end end @@ -138,20 +138,22 @@ minetest.register_chatcommand("set_wind", { end local arguments = {} for w in param:gmatch("%S+") do table.insert(arguments, w) end - local wind_x = arguments[1] - local wind_z = arguments[2] - if wind_x == "auto" then + local arg1 = arguments[1] + local wind_x = tonumber(arguments[1]) + local wind_z = tonumber(arguments[2]) + if arg1 == "auto" then climate_mod.forced_enviroment.wind = nil + minetest.chat_send_player(playername, "Wind reset") elseif wind_x == nil or wind_z == nil then minetest.chat_send_player(playername, "Invalid wind configuration") else climate_mod.forced_enviroment.wind = vector.new({ - x = tonumber(wind_x), + x = wind_x, y = 0, - z = tonumber(wind_z) + z = wind_z }) + minetest.chat_send_player(playername, "Wind changed") end - minetest.chat_send_player(playername, "Wind changed") end }) diff --git a/lib/influences.lua b/lib/influences.lua index 8338219..d10e345 100644 --- a/lib/influences.lua +++ b/lib/influences.lua @@ -50,14 +50,14 @@ end) climate_api.register_influence("light", function(pos) 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) climate_api.register_influence("daylight", function(pos) 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) climate_api.register_global_influence("time", - minetest.get_timeofday() + minetest.get_timeofday ) \ No newline at end of file diff --git a/lib/main.lua b/lib/main.lua index e0228c4..3639278 100644 --- a/lib/main.lua +++ b/lib/main.lua @@ -1,6 +1,15 @@ 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 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 world_timer = 0 minetest.register_globalstep(function(dtime) @@ -15,7 +24,17 @@ minetest.register_globalstep(function(dtime) climate_mod.global_environment = climate_mod.trigger.get_global_environment() end + 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() for name, effect in pairs(climate_mod.effects) do diff --git a/lib/skybox_merger.lua b/lib/skybox_merger.lua index ea10430..69a85b1 100644 --- a/lib/skybox_merger.lua +++ b/lib/skybox_merger.lua @@ -64,7 +64,7 @@ end local function set_skybox(playername, sky) 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_clouds(sky.cloud_data) player:set_moon(sky.moon_data) @@ -85,7 +85,7 @@ function skybox.update(playername) if right.priority == nil then right.priority = 1 end return left.priority < right.priority end) - for i=1,#numbered_layers do + for i = 1, #numbered_layers do sky = merge_tables(sky, numbered_layers[i]) end set_skybox(playername, sky) diff --git a/lib/trigger.lua b/lib/trigger.lua index a0847f3..5fd8a6a 100644 --- a/lib/trigger.lua +++ b/lib/trigger.lua @@ -76,7 +76,12 @@ end function trigger.get_active_effects() local environments = {} 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 local effects = {}