From a620d24ec848d6a7e20a43f462bcbf09ccca683c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9D=95=B5=F0=9D=96=94=F0=9D=96=8D=F0=9D=96=86?= =?UTF-8?q?=F0=9D=96=93=F0=9D=96=93=F0=9D=96=8A=F0=9D=96=98=20=F0=9D=95=B1?= =?UTF-8?q?=F0=9D=96=97=F0=9D=96=8E=F0=9D=96=99=F0=9D=96=9F?= Date: Fri, 29 Sep 2023 18:47:07 +0000 Subject: [PATCH] Fix a number of crashes involving unknown nodes, also fix fishbuckets on_place (#3914) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: #3913 #3915 ~~You can reproduce the crash by placing a fish bucket on top snow above an unknown node. I also noticed that the code always uses pointed_thing.above so I fixed that and also added a function to mcl_utils to figure out where a node should be placed (either above or below). Looks like the rest of the code could also use improvement but at least it does not crash now.~~ Cora fixed a bunch of related crashes in Mineclona so I am replacing my commit and cherry picking all her commits here. https://codeberg.org/mineclonia/mineclonia/pulls/549 Here is the list of fixes from that PR: - Crash when placing snow layer on unknown nodes - Crash when snow layers on unknown nodes are flooded - Crash when placing fishbucket on snow on top of unknown nodes - Crash when placing chorus flower and stem on unknown - Crash when placing mob spawners on unknown - The fishbucket on place to actually replace buildable_to Co-authored-by: cora Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/3914 Reviewed-by: ancientmarinerdev Co-authored-by: 𝕵𝖔𝖍𝖆𝖓𝖓𝖊𝖘 𝕱𝖗𝖎𝖙𝖟 Co-committed-by: 𝕵𝖔𝖍𝖆𝖓𝖓𝖊𝖘 𝕱𝖗𝖎𝖙𝖟 --- mods/ITEMS/mcl_buckets/fishbuckets.lua | 23 ++++++++++++++++------- mods/ITEMS/mcl_core/functions.lua | 6 +++--- mods/ITEMS/mcl_core/nodes_base.lua | 2 +- mods/ITEMS/mcl_end/chorus_plant.lua | 6 ++++-- mods/ITEMS/mcl_mobspawners/init.lua | 3 ++- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/mods/ITEMS/mcl_buckets/fishbuckets.lua b/mods/ITEMS/mcl_buckets/fishbuckets.lua index 185f72486..bc93654da 100644 --- a/mods/ITEMS/mcl_buckets/fishbuckets.lua +++ b/mods/ITEMS/mcl_buckets/fishbuckets.lua @@ -18,13 +18,21 @@ local function on_place_fish(itemstack, placer, pointed_thing) return new_stack end - local pos = pointed_thing.above or pointed_thing.under - if not pos then return end - local n = minetest.get_node_or_nil(pos) - if n.name and minetest.registered_nodes[n.name].buildable_to or n.name == "mcl_portals:portal" then - local fish = itemstack:get_name():gsub(fishbucket_prefix,"") - if fish_names[fish] then - local o = minetest.add_entity(pos, "mobs_mc:" .. fish) + if pointed_thing.type ~= "node" then return end + + local pos = pointed_thing.above + local n = minetest.get_node(pointed_thing.above) + local def = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] + + if ( def and def.buildable_to ) or n.name == "mcl_portals:portal" then + pos = pointed_thing.under + n = minetest.get_node(pointed_thing.under) + end + + local fish = itemstack:get_definition()._mcl_buckets_fish + if fish_names[fish] then + local o = minetest.add_entity(pos, "mobs_mc:" .. fish) + if o and o:get_pos() then local props = itemstack:get_meta():get_string("properties") if props ~= "" then o:set_properties(minetest.deserialize(props)) @@ -60,6 +68,7 @@ for techname, fishname in pairs(fish_names) do stack_max = 1, groups = {bucket = 1, fish_bucket = 1}, liquids_pointable = false, + _mcl_buckets_fish = techname, on_place = on_place_fish, on_secondary_use = on_place_fish, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) diff --git a/mods/ITEMS/mcl_core/functions.lua b/mods/ITEMS/mcl_core/functions.lua index b7623bf11..ad2346dd9 100644 --- a/mods/ITEMS/mcl_core/functions.lua +++ b/mods/ITEMS/mcl_core/functions.lua @@ -1581,7 +1581,7 @@ end -- MUST NOT be called if there is a snow cover node above pos. function mcl_core.clear_snow_dirt(pos, node) local def = minetest.registered_nodes[node.name] - if def._mcl_snowless then + if def and def._mcl_snowless then minetest.swap_node(pos, {name = def._mcl_snowless, param2=node.param2}) end end @@ -1602,7 +1602,7 @@ function mcl_core.on_snowable_construct(pos) -- Make snowed if needed if minetest.get_item_group(anode.name, "snow_cover") == 1 then local def = minetest.registered_nodes[node.name] - if def._mcl_snowed then + if def and def._mcl_snowed then minetest.swap_node(pos, {name = def._mcl_snowed, param2=node.param2}) end end @@ -1623,7 +1623,7 @@ function mcl_core.on_snow_construct(pos) local npos = {x=pos.x, y=pos.y-1, z=pos.z} local node = minetest.get_node(npos) local def = minetest.registered_nodes[node.name] - if def._mcl_snowed then + if def and def._mcl_snowed then minetest.swap_node(npos, {name = def._mcl_snowed, param2=node.param2}) end end diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua index 79cd37d8e..01de997d5 100644 --- a/mods/ITEMS/mcl_core/nodes_base.lua +++ b/mods/ITEMS/mcl_core/nodes_base.lua @@ -1038,7 +1038,7 @@ for i=1,8 do -- Get position where snow would be placed local target - if minetest.registered_nodes[unode.name].buildable_to then + if def and def.buildable_to then target = under else target = above diff --git a/mods/ITEMS/mcl_end/chorus_plant.lua b/mods/ITEMS/mcl_end/chorus_plant.lua index 4dc54db18..7f2064a3e 100644 --- a/mods/ITEMS/mcl_end/chorus_plant.lua +++ b/mods/ITEMS/mcl_end/chorus_plant.lua @@ -155,7 +155,8 @@ minetest.register_node("mcl_end:chorus_flower", { 1) On top of end stone or chorus plant 2) On top of air and horizontally adjacent to exactly 1 chorus plant ]] local pos - if minetest.registered_nodes[node_under.name].buildable_to then + local def = minetest.registered_nodes[node_under.name] + if def and def.buildable_to then pos = pointed_thing.under else pos = pointed_thing.above @@ -283,7 +284,8 @@ minetest.register_node("mcl_end:chorus_plant", { condition is met: - placed on end stone or any chorus node ]] local pos_place, node_check - if minetest.registered_nodes[node_under.name].buildable_to then + local def = minetest.registered_nodes[node_under.name] + if def and def.buildable_to then pos_place = pointed_thing.under node_check = node_above else diff --git a/mods/ITEMS/mcl_mobspawners/init.lua b/mods/ITEMS/mcl_mobspawners/init.lua index c5c2212b6..290980e78 100644 --- a/mods/ITEMS/mcl_mobspawners/init.lua +++ b/mods/ITEMS/mcl_mobspawners/init.lua @@ -301,7 +301,8 @@ minetest.register_node("mcl_mobspawners:spawner", { local new_itemstack, success = minetest.item_place(itemstack, placer, pointed_thing) if success then local placepos - if minetest.registered_nodes[node_under.name].buildable_to then + local def = minetest.registered_nodes[node_under.name] + if def and def.buildable_to then placepos = pointed_thing.under else placepos = pointed_thing.above