restrict text size

restrict detector, mover and keypad filter/text size,
update signs list,
limit keypad replacements to 16,
update mover hardness table
This commit is contained in:
waxtatect 2023-04-07 18:00:08 +02:00
parent fc5243ffa6
commit d48f180cce
4 changed files with 97 additions and 53 deletions

View File

@ -4,39 +4,42 @@ local machines_minstep = basic_machines.properties.machines_minstep
local machines_timer = basic_machines.properties.machines_timer
local mover_no_large_stacks = basic_machines.settings.mover_no_large_stacks
local string_byte = string.byte
local signs = { -- when activated with keypad these will be "punched" to update their text too
["basic_signs:sign_wall_glass"] = true,
["basic_signs:sign_wall_locked"] = true,
["basic_signs:sign_wall_obsidian_glass"] = true,
["basic_signs:sign_wall_plastic"] = true,
["basic_signs:sign_wall_steel_blue"] = true,
["basic_signs:sign_wall_steel_brown"] = true,
["basic_signs:sign_wall_steel_green"] = true,
["basic_signs:sign_wall_steel_orange"] = true,
["basic_signs:sign_wall_steel_red"] = true,
["basic_signs:sign_wall_steel_white_black"] = true,
["basic_signs:sign_wall_steel_white_red"] = true,
["basic_signs:sign_wall_steel_yellow"] = true,
["default:sign_wall_steel"] = true,
["default:sign_wall_wood"] = true
}
local signs -- when activated with keypad their text will be updated
local use_signs_lib = minetest.global_exists("signs_lib")
local use_unifieddyes = minetest.global_exists("unifieddyes")
if use_signs_lib then
signs = {}
for _, sign_name in ipairs(signs_lib.lbm_restore_nodes or {}) do
signs[sign_name] = true
end
else -- minetest_game default mod
signs = {
["default:sign_wall_steel"] = true,
["default:sign_wall_wood"] = true
}
end
-- position, time to live (how many times can signal travel before vanishing to prevent infinite recursion),
-- do we want to stop repeating
basic_machines.use_keypad = function(pos, ttl, reset, reset_msg)
if ttl < 1 then return end
local meta = minetest.get_meta(pos)
local msg
-- temperature
local t0, t1 = meta:get_int("t"), minetest.get_gametime()
local T = meta:get_int("T") -- temperature
if t0 > t1 - machines_minstep then -- activated before natural time
T = T + 1
elseif T > 0 then
if t1 - t0 > machines_timer then T = 0 else T = T - 1 end
if t1 - t0 > machines_timer then -- reset temperature if more than 5s (by default) elapsed since last activation
T = 0; msg = ""
else
T = T - 1
end
end
meta:set_int("t", t1); meta:set_int("T", T)
@ -46,13 +49,18 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg)
return
end
if minetest.is_protected(pos, meta:get_string("owner")) then
-- protection check
local owner = meta:get_string("owner")
if minetest.is_protected(pos, owner) then
meta:set_int("count", 0)
meta:set_string("infotext", S("Protection fail. Reset."))
return
end
local iter = meta:get_int("iter"); if iter == 0 then return end
-- repeating activation
local iter = meta:get_int("iter")
if iter == 0 then if msg then meta:set_string("infotext", msg) end; return end
local count = 0 -- counts repeats
if iter > 1 then
@ -79,11 +87,12 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg)
end
end
-- set text on target
local text = meta:get_string("text")
if text ~= "" then -- TEXT MODE; set text on target
if text ~= "" then
if text == "@" and meta:get_string("pass") ~= "" then -- keyboard mode, set text from input
text = meta:get_string("input")
meta:set_string("input", "") -- clear input again
meta:set_string("input", "") -- clear input
end
local bit = string_byte(text)
@ -135,40 +144,53 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg)
end
end
if signs[name] then -- update text on signs with signs_lib
local tmeta = minetest.get_meta(tpos)
tmeta:set_string("infotext", text)
tmeta:set_string("text", text)
if use_signs_lib and signs_lib.update_sign then
local on_punch = (minetest.registered_nodes[name] or {}).on_punch
if on_punch then on_punch(tpos, node, nil) end
if signs[name] then -- update text on signs
if use_signs_lib then -- with signs_lib
if signs_lib.update_sign then
signs_lib.update_sign(tpos, {text = text})
else
return
end
else -- minetest_game default mod
if text:len() > 512 then
minetest.chat_send_player(owner, S("KEYPAD: Text too long.")); return
else
local tmeta = minetest.get_meta(tpos)
tmeta:set_string("infotext", S('"@1"', text))
tmeta:set_string("text", text)
end
end
-- target is keypad, special functions: @, % that output to target keypad text
elseif name == "basic_machines:keypad" then -- special modify of target keypad text and change its target
-- target is keypad, special functions: @, % that output to target keypad's text
elseif name == "basic_machines:keypad" then -- special modify of target keypad's text and change its target
local tmeta = minetest.get_meta(tpos)
if bit == 64 then -- target keypad's text starts with '@' (ascii code 64) -> character replacement
text = text:sub(2); if text == "" then tmeta:set_string("text", ""); return end -- clear target keypad text
text = text:sub(2)
if text == "" then -- clear target keypad's text
tmeta:set_string("text", ""); return
end
-- read words [j] from blocks above keypad:
local j = 0
local function replace()
text = text:gsub("@", function() -- replace every '@' in text with string on blocks above
j = j + 1; return minetest.get_meta({x = pos.x, y = pos.y + j, z = pos.z}):get_string("infotext")
end
text = text:gsub("@", replace) -- replace every '@' in text with string on blocks above
end, 16) -- up to 16 replacements
-- set target keypad's text
tmeta:set_string("text", text)
if text:len() > 4896 then
minetest.chat_send_player(owner, S("KEYPAD: Text too long.")); return
else -- set target keypad's text
tmeta:set_string("text", text)
end
elseif bit == 37 then -- target keypad's text starts with '%' (ascii code 37) -> word extraction
local ttext = minetest.get_meta({x = pos.x, y = pos.y + 1, z = pos.z}):get_string("infotext")
local i = tonumber(text:sub(2, 2)) or 1 -- read the number following the '%'
-- extract i - th word from text
-- extract i-th word from text
local j = 0
for word in ttext:gmatch("%S+") do
j = j + 1; if j == i then text = word; break end
end
-- set target keypad's target's text
-- set target keypad's text
tmeta:set_string("text", text)
else
-- just set text...
@ -184,7 +206,6 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg)
elseif name == "basic_machines:mover" then -- change filter on mover
local tmeta = minetest.get_meta(tpos)
if bit == 64 then -- if text starts with '@' -> clear the filter
tmeta:set_string("prefer", "")
tmeta:get_inventory():set_list("filter", {})
@ -212,7 +233,6 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg)
elseif name == "basic_machines:autocrafter" then
local tmeta = minetest.get_meta(tpos)
if bit == 64 then -- if text starts with '@' -> clear the recipe
basic_machines.change_autocrafter_recipe(tpos, tmeta:get_inventory(), nil)
elseif minetest.registered_items[text] then
@ -232,9 +252,10 @@ basic_machines.use_keypad = function(pos, ttl, reset, reset_msg)
end
else
minetest.get_meta(tpos):set_string("infotext", text:gsub("^ +$", "")) -- else just set text
minetest.get_meta(tpos):set_string("infotext", text:gsub("^ +$", "")) -- just set text
end
-- target activation
else
if count < 2 then
meta:set_string("infotext", S("Keypad operation: @1 cycle left", count))

View File

@ -257,6 +257,10 @@ Mover block refueled. Fuel status @1.=
Mover block. Temperature: @1, Fuel: @2.=
MOVER: Filter defined with unknown node (@1) at @2, @3, @4.=
MOVER: Wrong filter (@1) at @2, @3, @4.=
MOVER: Filter too long.=
KEYPAD: Text too long.=
"@1"=
DETECTOR: Detection filter too long.=
Mover=
object=
inventory=

View File

@ -436,7 +436,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
-- mode
if mode ~= mmode then
if basic_machines.check_mover_filter(mode, pos, meta, prefer) then -- input validation
if prefer:len() > 4896 then
minetest.chat_send_player(name, S("MOVER: Filter too long."))
elseif basic_machines.check_mover_filter(mode, pos, meta, prefer) then -- input validation
if mover_no_large_stacks and basic_machines.check_mover_target(mode, pos, meta) then
prefer = basic_machines.clamp_item_count(prefer)
end
@ -448,7 +450,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
-- filter
if prefer ~= meta:get_string("prefer") then
if basic_machines.check_mover_filter(mode, pos, meta, prefer) then -- input validation
if prefer:len() > 4896 then
minetest.chat_send_player(name, S("MOVER: Filter too long."))
elseif basic_machines.check_mover_filter(mode, pos, meta, prefer) then -- input validation
if mover_no_large_stacks and basic_machines.check_mover_target(mode, pos, meta) then
prefer = basic_machines.clamp_item_count(prefer)
end
@ -521,7 +525,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if mode == mmode then return end
local prefer = fields.prefer or ""
if basic_machines.check_mover_filter(mode, pos, meta, prefer) then -- input validation
if prefer:len() > 4896 then
minetest.chat_send_player(name, S("MOVER: Filter too long."))
elseif basic_machines.check_mover_filter(mode, pos, meta, prefer) then -- input validation
if mover_no_large_stacks and basic_machines.check_mover_target(mode, pos, meta) then
prefer = basic_machines.clamp_item_count(prefer)
end
@ -722,19 +728,24 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if pass ~= "" then
local mpass = meta:get_string("pass")
if pass ~= mpass then
if pass:len() <= 16 then -- don't replace password with hash which is longer - 27 chars
pass = minetest.get_password_hash(pos.x, pass .. pos.y); pass = minetest.get_password_hash(pos.y, pass .. pos.z)
meta:set_string("pass", pass)
else
if pass:len() > 16 then -- don't replace password with hash which is longer - 27 chars
pass = mpass
minetest.chat_send_player(name, S("KEYPAD: Password too long."))
else
pass = minetest.get_password_hash(pos.x, pass .. pos.y); pass = minetest.get_password_hash(pos.y, pass .. pos.z)
meta:set_string("pass", pass)
end
end
end
local text = fields.text or ""
meta:set_string("text", text)
if text:len() > 4896 then
text = meta:get_string("text")
minetest.chat_send_player(name, S("KEYPAD: Text too long."))
else
meta:set_string("text", text)
end
meta:set_int("x0", x0); meta:set_int("y0", y0); meta:set_int("z0", z0)
if pass == "" then
@ -894,7 +905,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
meta:set_string("op", strip_translator_sequence(fields.op, ""))
meta:set_int("r", math.min((tonumber(fields.r) or 1), max_range))
meta:set_string("node", fields.node or "")
local filter = fields.node or ""
if filter:len() > 4896 then
minetest.chat_send_player(name, S("DETECTOR: Detection filter too long."))
else
meta:set_string("node", filter)
end
meta:set_int("NOT", tonumber(fields.NOT) or 0)
meta:set_string("mode", strip_translator_sequence(fields.mode, ""))
meta:set_string("inv1", strip_translator_sequence(fields.inv1, ""))

View File

@ -62,6 +62,8 @@ local mover = {
["default:pine_tree"] = 2,
["default:stone"] = 4,
["default:tree"] = 2,
["gloopblocks:basalt_cooled"] = 3,
["gloopblocks:obsidian_cooled"] = 20,
["gloopblocks:pumice_cooled"] = 2,
["itemframes:frame"] = 999999,
["itemframes:pedestal"] = 999999,
@ -480,6 +482,7 @@ minetest.register_node("basic_machines:mover", {
local meta = minetest.get_meta(pos)
local upgradetype = meta:get_int("upgradetype")
local third_upgradetype = upgradetype == 3
local msg
-- temperature
local t0, t1 = meta:get_int("t"), minetest.get_gametime()
@ -493,7 +496,7 @@ minetest.register_node("basic_machines:mover", {
T = T + 1
elseif T > mover_max_temp or third_upgradetype and T > 0 then
if t1 - t0 > machines_timer then -- reset temperature if more than 5s (by default) elapsed since last activation
T = 0; meta:set_string("infotext", "")
T = 0; msg = ""
else
T = T - 1
end
@ -512,7 +515,7 @@ minetest.register_node("basic_machines:mover", {
local mreverse = meta:get_int("reverse")
local mode_third_upgradetype = third_upgradetype and (mode == "normal" or mode == "dig")
local owner = meta:get_string("owner")
local upgrade, prefer, source_chest, msg
local upgrade, prefer, source_chest
-- positions
local pos1 -- where to take from