Run callbacks based on validated inventory

This commit is contained in:
stujones11 2018-05-23 20:15:09 +01:00
parent 7d30bc25a3
commit 83f3e01efa
2 changed files with 32 additions and 12 deletions

View File

@ -481,20 +481,42 @@ armor.save_armor_inventory = function(self, player)
if not name then if not name then
return return
end end
local armor_list = {}
local armor_list_string = player:get_attribute("3d_armor_inventory")
if armor_list_string then
for i, item in pairs(minetest.deserialize(armor_list_string)) do
armor_list[item] = item ~= "" and i or nil
end
end
-- Workaround for detached inventory swap exploit
local elements = {} local elements = {}
local player_inv = player:get_inventory() local player_inv = player:get_inventory()
for i = 1, 6 do for i = 1, 6 do
local stack = inv:get_stack("armor", i) local stack = inv:get_stack("armor", i)
local element = self:get_element(stack:get_name()) if stack:get_count() > 0 then
if element and not elements[element] then local item = stack:get_name()
elements[element] = true; local element = self:get_element(item)
else if element and not elements[element] then
inv:remove_item("armor", stack) if armor_list[item] then
if player_inv and player_inv:room_for_item("main", stack) then armor_list[item] = nil
player_inv:add_item("main", stack) else
-- Item was not in previous inventory
armor:run_callbacks("on_equip", player, i, stack)
end
elements[element] = true;
else
inv:remove_item("armor", stack)
if player_inv and player_inv:room_for_item("main", stack) then
player_inv:add_item("main", stack)
end
end end
end end
end end
for item, i in pairs(armor_list) do
local stack = ItemStack(item)
-- Previous item is not in current inventory
armor:run_callbacks("on_unequip", player, i, stack)
end
player:set_attribute("3d_armor_inventory", player:set_attribute("3d_armor_inventory",
self:serialize_inventory_list(inv:get_list("armor"))) self:serialize_inventory_list(inv:get_list("armor")))
end end

View File

@ -118,12 +118,10 @@ local function init_player_armor(player)
local armor_inv = minetest.create_detached_inventory(name.."_armor", { local armor_inv = minetest.create_detached_inventory(name.."_armor", {
on_put = function(inv, listname, index, stack, player) on_put = function(inv, listname, index, stack, player)
armor:save_armor_inventory(player) armor:save_armor_inventory(player)
armor:run_callbacks("on_equip", player, index, stack)
armor:set_player_armor(player) armor:set_player_armor(player)
end, end,
on_take = function(inv, listname, index, stack, player) on_take = function(inv, listname, index, stack, player)
armor:save_armor_inventory(player) armor:save_armor_inventory(player)
armor:run_callbacks("on_unequip", player, index, stack)
armor:set_player_armor(player) armor:set_player_armor(player)
end, end,
on_move = function(inv, from_list, from_index, to_list, to_index, count, player) on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
@ -132,11 +130,9 @@ local function init_player_armor(player)
end, end,
allow_put = function(inv, listname, index, put_stack, player) allow_put = function(inv, listname, index, put_stack, player)
local element = armor:get_element(put_stack:get_name()) local element = armor:get_element(put_stack:get_name())
if not element then if not element then
return 0 return 0
end end
for i = 1, 6 do for i = 1, 6 do
local stack = inv:get_stack("armor", i) local stack = inv:get_stack("armor", i)
local def = stack:get_definition() or {} local def = stack:get_definition() or {}
@ -167,7 +163,9 @@ local function init_player_armor(player)
end end
for i=1, 6 do for i=1, 6 do
local stack = armor_inv:get_stack("armor", i) local stack = armor_inv:get_stack("armor", i)
armor:run_callbacks("on_equip", player, i, stack) if stack:get_count() > 0 then
armor:run_callbacks("on_equip", player, i, stack)
end
end end
armor.def[name] = { armor.def[name] = {
init_time = minetest.get_gametime(), init_time = minetest.get_gametime(),