forked from minetest-mods/mesecons
		
	LuaC: add lightweight interrupts (#449)
This commit is contained in:
		| @@ -266,13 +266,26 @@ local function remove_functions(x) | |||||||
| 	return x | 	return x | ||||||
| end | end | ||||||
|  |  | ||||||
| -- itbl: Flat table of functions to run after sandbox cleanup, used to prevent various security hazards | -- The setting affects API so is not intended to be changeable at runtime | ||||||
| local function get_interrupt(pos, itbl, send_warning) | local get_interrupt | ||||||
|  | if mesecon.setting("luacontroller_lightweight_interrupts", false) then | ||||||
|  | 	-- use node timer | ||||||
|  | 	get_interrupt = function(pos, itbl, send_warning) | ||||||
|  | 		return (function(time, iid) | ||||||
|  | 			if type(time) ~= "number" then error("Delay must be a number") end | ||||||
|  | 			if iid ~= nil then send_warning("Interrupt IDs are disabled on this server") end | ||||||
|  | 			table.insert(itbl, function() minetest.get_node_timer(pos):start(time) end) | ||||||
|  | 		end) | ||||||
|  | 	end | ||||||
|  | else | ||||||
|  | 	-- use global action queue | ||||||
|  | 	-- itbl: Flat table of functions to run after sandbox cleanup, used to prevent various security hazards | ||||||
|  | 	get_interrupt = function(pos, itbl, send_warning) | ||||||
| 		-- iid = interrupt id | 		-- iid = interrupt id | ||||||
| 		local function interrupt(time, iid) | 		local function interrupt(time, iid) | ||||||
| 			-- NOTE: This runs within string metatable sandbox, so don't *rely* on anything of the form (""):y | 			-- NOTE: This runs within string metatable sandbox, so don't *rely* on anything of the form (""):y | ||||||
| 			-- Hence the values get moved out. Should take less time than original, so totally compatible | 			-- Hence the values get moved out. Should take less time than original, so totally compatible | ||||||
| 		if type(time) ~= "number" then return end | 			if type(time) ~= "number" then error("Delay must be a number") end | ||||||
| 			table.insert(itbl, function () | 			table.insert(itbl, function () | ||||||
| 				-- Outside string metatable sandbox, can safely run this now | 				-- Outside string metatable sandbox, can safely run this now | ||||||
| 				local luac_id = minetest.get_meta(pos):get_int("luac_id") | 				local luac_id = minetest.get_meta(pos):get_int("luac_id") | ||||||
| @@ -289,9 +302,9 @@ local function get_interrupt(pos, itbl, send_warning) | |||||||
| 			end) | 			end) | ||||||
| 		end | 		end | ||||||
| 		return interrupt | 		return interrupt | ||||||
|  | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
|  |  | ||||||
| -- Given a message object passed to digiline_send, clean it up into a form | -- Given a message object passed to digiline_send, clean it up into a form | ||||||
| -- which is safe to transmit over the network and compute its "cost" (a very | -- which is safe to transmit over the network and compute its "cost" (a very | ||||||
| -- rough estimate of its memory usage). | -- rough estimate of its memory usage). | ||||||
| @@ -414,7 +427,6 @@ local function get_digiline_send(pos, itbl, send_warning) | |||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
|  |  | ||||||
| local safe_globals = { | local safe_globals = { | ||||||
| 	-- Don't add pcall/xpcall unless willing to deal with the consequences (unless very careful, incredibly likely to allow killing server indirectly) | 	-- Don't add pcall/xpcall unless willing to deal with the consequences (unless very careful, incredibly likely to allow killing server indirectly) | ||||||
| 	"assert", "error", "ipairs", "next", "pairs", "select", | 	"assert", "error", "ipairs", "next", "pairs", "select", | ||||||
| @@ -651,6 +663,14 @@ local function reset(pos) | |||||||
| 	set_port_states(pos, {a=false, b=false, c=false, d=false}) | 	set_port_states(pos, {a=false, b=false, c=false, d=false}) | ||||||
| end | end | ||||||
|  |  | ||||||
|  | local function node_timer(pos) | ||||||
|  | 	if minetest.registered_nodes[minetest.get_node(pos).name].is_burnt then | ||||||
|  | 		return false | ||||||
|  | 	end | ||||||
|  | 	run(pos, {type="interrupt"}) | ||||||
|  | 	return false | ||||||
|  | end | ||||||
|  |  | ||||||
| ----------------------- | ----------------------- | ||||||
| -- A.Queue callbacks -- | -- A.Queue callbacks -- | ||||||
| ----------------------- | ----------------------- | ||||||
| @@ -823,6 +843,7 @@ for d = 0, 1 do | |||||||
| 			mesecon.receptor_off(pos, output_rules) | 			mesecon.receptor_off(pos, output_rules) | ||||||
| 		end, | 		end, | ||||||
| 		is_luacontroller = true, | 		is_luacontroller = true, | ||||||
|  | 		on_timer = node_timer, | ||||||
| 		on_blast = mesecon.on_blastnode, | 		on_blast = mesecon.on_blastnode, | ||||||
| 	}) | 	}) | ||||||
| end | end | ||||||
|   | |||||||
| @@ -24,6 +24,10 @@ mesecon.luacontroller_digiline_maxlen (Digiline message size limit) int 50000 10 | |||||||
| mesecon.luacontroller_maxevents (Controller execution time limit) int 10000 1000 100000 | mesecon.luacontroller_maxevents (Controller execution time limit) int 10000 1000 100000 | ||||||
| mesecon.luacontroller_memsize (Controller memory limit) int 100000 10000 1000000 | mesecon.luacontroller_memsize (Controller memory limit) int 100000 10000 1000000 | ||||||
|  |  | ||||||
|  | # Use node timer for interrupts (runs in active blocks only). | ||||||
|  | # IID is ignored and at most one interrupt may be queued if this setting is enabled. | ||||||
|  | mesecon.luacontroller_lightweight_interrupts (Lightweight interrupts) bool false | ||||||
|  |  | ||||||
|  |  | ||||||
| [mesecons_movestones] | [mesecons_movestones] | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user