Fix many crashes when placing item on unknown node

Wuzzy 2017-06-29 13:02:53 +02:00
parent 27481afe06
commit 38cf151806
13 changed files with 41 additions and 12 deletions

@ -252,6 +252,9 @@ function mcl_util.generate_on_place_plant_function(condition)
local place_pos local place_pos
local def_under = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] local def_under = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
local def_above = minetest.registered_nodes[minetest.get_node(pointed_thing.above).name] local def_above = minetest.registered_nodes[minetest.get_node(pointed_thing.above).name]
if not def_under or not def_above then
return itemstack
end
if def_under.buildable_to then if def_under.buildable_to then
place_pos = pointed_thing.under place_pos = pointed_thing.under
elseif def_above.buildable_to then elseif def_above.buildable_to then

@ -52,6 +52,7 @@ local on_button_place = function(itemstack, placer, pointed_thing)
local under = pointed_thing.under local under = pointed_thing.under
local node = minetest.get_node(under) local node = minetest.get_node(under)
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
if not def then return end
local groups = def.groups local groups = def.groups
-- Check special rightclick action of pointed node -- Check special rightclick action of pointed node

@ -103,7 +103,7 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name
sound_place("mcl_core:water_source", pos) sound_place("mcl_core:water_source", pos)
elseif item == "bucket:bucket_water" and nn == "mcl_cauldrons:cauldron_3" then elseif item == "bucket:bucket_water" and nn == "mcl_cauldrons:cauldron_3" then
sound_place("mcl_core:water_source", pos) sound_place("mcl_core:water_source", pos)
elseif minetest.registered_nodes[nn].buildable_to then elseif minetest.registered_nodes[nn] and minetest.registered_nodes[nn].buildable_to then
-- buildable; replace the node -- buildable; replace the node
local pns = user:get_player_name() local pns = user:get_player_name()
if minetest.is_protected(pointed_thing.under, pns) then if minetest.is_protected(pointed_thing.under, pns) then
@ -117,7 +117,7 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name
-- not buildable to; place the liquid above -- not buildable to; place the liquid above
-- check if the node above can be replaced -- check if the node above can be replaced
local abovenode = minetest.get_node(pointed_thing.above) local abovenode = minetest.get_node(pointed_thing.above)
if minetest.registered_nodes[abovenode.name].buildable_to then if minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to then
local pn = user:get_player_name() local pn = user:get_player_name()
if minetest.is_protected(pointed_thing.above, pn) then if minetest.is_protected(pointed_thing.above, pn) then
return itemstack return itemstack

@ -78,7 +78,8 @@ function mcl_beds.register_bed(name, def)
end end
local pos local pos
if minetest.registered_items[minetest.get_node(under).name].buildable_to then local undername = minetest.get_node(under).name
if minetest.registered_items[undername] and minetest.registered_items[undername].buildable_to then
pos = under pos = under
else else
pos = pointed_thing.above pos = pointed_thing.above

@ -1409,6 +1409,9 @@ minetest.register_node("mcl_core:ladder", {
local under = pointed_thing.under local under = pointed_thing.under
local node = minetest.get_node(under) local node = minetest.get_node(under)
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
if not def then
return itemstack
end
local groups = def.groups local groups = def.groups
-- Don't allow to place the ladder at particular nodes -- Don't allow to place the ladder at particular nodes
@ -1483,6 +1486,7 @@ minetest.register_node("mcl_core:vine", {
local under = pointed_thing.under local under = pointed_thing.under
local node = minetest.get_node(under) local node = minetest.get_node(under)
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
if not def then return itemstack end
local groups = def.groups local groups = def.groups
-- Check special rightclick action of pointed node -- Check special rightclick action of pointed node

@ -79,21 +79,23 @@ function mcl_doors:register_door(name, def)
local ptu = pointed_thing.under local ptu = pointed_thing.under
local nu = minetest.get_node(ptu) local nu = minetest.get_node(ptu)
-- Pointed thing's rightclick action takes precedence, unless player holds down the sneak key -- Pointed thing's rightclick action takes precedence, unless player holds down the sneak key
if minetest.registered_nodes[nu.name].on_rightclick and not placer:get_player_control().sneak then if minetest.registered_nodes[nu.name] and minetest.registered_nodes[nu.name].on_rightclick and not placer:get_player_control().sneak then
return minetest.registered_nodes[nu.name].on_rightclick(ptu, nu, placer, itemstack) return minetest.registered_nodes[nu.name].on_rightclick(ptu, nu, placer, itemstack)
end end
local pt local pt
if minetest.registered_nodes[minetest.get_node(ptu).name].buildable_to then if minetest.registered_nodes[nu.name] and minetest.registered_nodes[nu.name].buildable_to then
pt = pointed_thing.under pt = pointed_thing.under
else else
pt = pointed_thing.above pt = pointed_thing.above
end end
local pt2 = {x=pt.x, y=pt.y, z=pt.z} local pt2 = {x=pt.x, y=pt.y, z=pt.z}
pt2.y = pt2.y+1 pt2.y = pt2.y+1
local ptname = minetest.get_node(pt).name
local pt2name = minetest.get_node(pt2).name
if if
(not minetest.registered_nodes[minetest.get_node(pt).name].buildable_to) or (minetest.registered_nodes[ptname] and not minetest.registered_nodes[ptname].buildable_to) or
(not minetest.registered_nodes[minetest.get_node(pt2).name].buildable_to) (minetest.registered_nodes[pt2name] and not minetest.registered_nodes[pt2name].buildable_to)
then then
return itemstack return itemstack
end end

@ -16,7 +16,7 @@ minetest.register_tool("mcl_fire:flint_and_steel", {
local used = false local used = false
if pointed_thing.type == "node" then if pointed_thing.type == "node" then
local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
if nodedef._on_ignite then if nodedef and nodedef._on_ignite then
nodedef._on_ignite(pointed_thing.under, user) nodedef._on_ignite(pointed_thing.under, user)
else else
mcl_fire.set_fire(pointed_thing) mcl_fire.set_fire(pointed_thing)

@ -186,15 +186,24 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im
-- Check for a floor and a space of 1×2×1 -- Check for a floor and a space of 1×2×1
local ptu_node = minetest.get_node(pointed_thing.under) local ptu_node = minetest.get_node(pointed_thing.under)
local bottom local bottom
if not minetest.registered_nodes[ptu_node.name] then
return itemstack
end
if minetest.registered_nodes[ptu_node.name].buildable_to then if minetest.registered_nodes[ptu_node.name].buildable_to then
bottom = pointed_thing.under bottom = pointed_thing.under
else else
bottom = pointed_thing.above bottom = pointed_thing.above
end end
if not minetest.registered_nodes[minetest.get_node(bottom).name] then
return itemstack
end
local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z }
local bottom_buildable = minetest.registered_nodes[minetest.get_node(bottom).name].buildable_to local bottom_buildable = minetest.registered_nodes[minetest.get_node(bottom).name].buildable_to
local top_buildable = minetest.registered_nodes[minetest.get_node(top).name].buildable_to local top_buildable = minetest.registered_nodes[minetest.get_node(top).name].buildable_to
local floorname = minetest.get_node({x=bottom.x, y=bottom.y-1, z=bottom.z}).name local floorname = minetest.get_node({x=bottom.x, y=bottom.y-1, z=bottom.z}).name
if not minetest.registered_nodes[floorname] then
return itemstack
end
local light_night = minetest.get_node_light(bottom, 0.0) local light_night = minetest.get_node_light(bottom, 0.0)
local light_day = minetest.get_node_light(bottom, 0.5) local light_day = minetest.get_node_light(bottom, 0.5)

@ -59,7 +59,7 @@ Hoppers interact with containers the following way:
local uposnode = minetest.get_node(upos) local uposnode = minetest.get_node(upos)
local uposnodedef = minetest.registered_nodes[uposnode.name] local uposnodedef = minetest.registered_nodes[uposnode.name]
if not uposnodedef then return itemstack end
-- Use pointed node's on_rightclick function first, if present -- Use pointed node's on_rightclick function first, if present
if placer and not placer:get_player_control().sneak then if placer and not placer:get_player_control().sneak then
if uposnodedef and uposnodedef.on_rightclick then if uposnodedef and uposnodedef.on_rightclick then
@ -72,6 +72,7 @@ Hoppers interact with containers the following way:
bpos = upos bpos = upos
else else
local aposnodedef = minetest.registered_nodes[minetest.get_node(apos).name] local aposnodedef = minetest.registered_nodes[minetest.get_node(apos).name]
if not aposnodedef then return itemstack end
if aposnodedef.buildable_to then if aposnodedef.buildable_to then
bpos = apos bpos = apos
end end
@ -207,6 +208,7 @@ minetest.register_abm({
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
local abovenode = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}) local abovenode = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z})
if not minetest.registered_items[abovenode.name] then return end
-- Don't bother checking item enties if node above is a container (should save some CPU) -- Don't bother checking item enties if node above is a container (should save some CPU)
if minetest.registered_items[abovenode.name].groups.container then if minetest.registered_items[abovenode.name].groups.container then
return return
@ -281,6 +283,7 @@ minetest.register_abm({
-- Suck an item from the container above into the hopper -- Suck an item from the container above into the hopper
local upnode = minetest.get_node(uppos) local upnode = minetest.get_node(uppos)
if not minetest.registered_nodes[upnode.name] then return end
local g = minetest.registered_nodes[upnode.name].groups.container local g = minetest.registered_nodes[upnode.name].groups.container
if g == 2 or g == 3 then if g == 2 or g == 3 then
-- Typical container inventory -- Typical container inventory
@ -298,6 +301,7 @@ minetest.register_abm({
-- Move an item from the hopper into container below -- Move an item from the hopper into container below
local downnode = minetest.get_node(downpos) local downnode = minetest.get_node(downpos)
if not minetest.registered_nodes[downnode.name] then return end
g = minetest.registered_nodes[downnode.name].groups.container g = minetest.registered_nodes[downnode.name].groups.container
local slot_id = -1 local slot_id = -1
if g == 3 then if g == 3 then
@ -338,9 +342,11 @@ minetest.register_abm({
local above = {x=pos.x,y=pos.y+1,z=pos.z} local above = {x=pos.x,y=pos.y+1,z=pos.z}
local frontnode = minetest.get_node(front) local frontnode = minetest.get_node(front)
if not minetest.registered_nodes[frontnode.name] then return end
-- Suck an item from the container above into the hopper -- Suck an item from the container above into the hopper
local abovenode = minetest.get_node(above) local abovenode = minetest.get_node(above)
if not minetest.registered_nodes[abovenode.name] then return end
local g = minetest.registered_nodes[abovenode.name].groups.container local g = minetest.registered_nodes[abovenode.name].groups.container
if g == 2 or g == 3 then if g == 2 or g == 3 then
-- Typical container inventory -- Typical container inventory

@ -37,7 +37,9 @@ minetest.register_craftitem("mcl_potions:glass_bottle", {
-- Try to fill glass bottle with water -- Try to fill glass bottle with water
local get_water = false local get_water = false
if def.groups and def.groups.water and def.liquidtype == "source" then if not def then
-- Unknown node: no-op
elseif def.groups and def.groups.water and def.liquidtype == "source" then
-- Water source -- Water source
get_water = true get_water = true
-- Or reduce water level of cauldron by 1 -- Or reduce water level of cauldron by 1

@ -158,7 +158,7 @@ function mcl_stairs.register_slab(subname, recipeitem, groups, images, descripti
-- combine two slabs if possible -- combine two slabs if possible
-- Requirements: Same slab material, must be placed on top of lower slab, or on bottom of upper slab -- Requirements: Same slab material, must be placed on top of lower slab, or on bottom of upper slab
if (wield_item == under.name or wield_item == minetest.registered_nodes[under.name]._mcl_other_slab_half) and if (wield_item == under.name or (minetest.registered_nodes[under.name] and wield_item == minetest.registered_nodes[under.name]._mcl_other_slab_half)) and
not ((dir.y >= 0 and minetest.get_item_group(under.name, "slab_top") == 1) or not ((dir.y >= 0 and minetest.get_item_group(under.name, "slab_top") == 1) or
(dir.y <= 0 and minetest.get_item_group(under.name, "slab_top") == 0)) then (dir.y <= 0 and minetest.get_item_group(under.name, "slab_top") == 0)) then

@ -243,7 +243,7 @@ local pearl_on_step = function(self, dtime)
--[[ It may be possible that telepos is walkable due to the algorithm. --[[ It may be possible that telepos is walkable due to the algorithm.
Especially when the ender pearl is faster horizontally than vertical. Especially when the ender pearl is faster horizontally than vertical.
This applies final fixing, just to be sure we're not in a walkable node ]] This applies final fixing, just to be sure we're not in a walkable node ]]
if minetest.registered_nodes[telenode.name].walkable then if not minetest.registered_nodes[telenode.name] or minetest.registered_nodes[telenode.name].walkable then
if v.y < 0 then if v.y < 0 then
telepos.y = telepos.y + 0.5 telepos.y = telepos.y + 0.5
else else

@ -54,6 +54,7 @@ mcl_torches.register_torch = function(substring, description, doc_items_longdesc
local under = pointed_thing.under local under = pointed_thing.under
local node = minetest.get_node(under) local node = minetest.get_node(under)
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
if not def then return itemstack end
-- Call on_rightclick if the pointed node defines it -- Call on_rightclick if the pointed node defines it
if placer and not placer:get_player_control().sneak then if placer and not placer:get_player_control().sneak then