mirror of
				https://github.com/t-affeldt/climate_api.git
				synced 2025-11-04 09:55:35 +01:00 
			
		
		
		
	Fix bugs regarding disconnected players and unsanitized command input
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										19
									
								
								lib/main.lua
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								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
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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 = {}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user