From a11dab913279c361b5fd2d5b242e20e8070323e4 Mon Sep 17 00:00:00 2001 From: Foz Date: Sun, 29 Jan 2017 23:06:53 -0500 Subject: [PATCH 1/2] Prevent a shop from trading tools deceptively. This limits the tools a shop will accept or give to those whose wear is less than or equal to the tool shown in the Owner needs or Owner gives lists. This protects both owners and customers from unfair trades. Owners are protected from receiving worn out tools when a new tool is placed in the needs list. Customers are protected from receiving worn out tools when a new one is placed in the give list. --- shop.lua | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/shop.lua b/shop.lua index 07c39af..03ee37c 100644 --- a/shop.lua +++ b/shop.lua @@ -5,6 +5,30 @@ local exchange_shop = {} +-- Tool wear aware replacement for contains_item. +local function list_contains_item(inv, list, stack) + for i, list_stack in pairs(inv:get_list(list)) do + if list_stack:get_name() == stack:get_name() and + list_stack:get_count() >= stack:get_count() and + list_stack:get_wear() <= stack:get_wear() then + return true, i + end + end + return false, nil +end + +-- Tool wear aware replacement for remove_item. +local function list_remove_item(inv, list, stack) + local contains, index = list_contains_item(inv, list, stack) + if contains then + local list_stack = inv:get_stack(list, index) + local removed_stack = list_stack:take_item(stack:get_count()) + inv:set_stack(list, index, list_stack) + return removed_stack + end + return false +end + local function get_exchange_shop_formspec(number,pos,title) local formspec = "" local name = "nodemeta:"..pos.x..","..pos.y..","..pos.z @@ -200,7 +224,7 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields) -- Check availability of the shop's items if err_msg == "" then for i, item in pairs(cust_og) do - if not shop_inv:contains_item("stock", item) then + if not list_contains_item(shop_inv, "stock", item) then err_msg = "This shop is sold out." break end @@ -220,7 +244,7 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields) -- Check availability of the player's items if err_msg == "" then for i, item in pairs(cust_ow) do - if not player_inv:contains_item("main", item) then + if not list_contains_item(player_inv, "main", item) then err_msg = "You do not have the required items." break end @@ -231,7 +255,7 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields) if err_msg == "" then local fully_exchanged = true for i, item in pairs(cust_ow) do - local stack = player_inv:remove_item("main", item) + local stack = list_remove_item(player_inv, "main", item) if shop_inv:room_for_item("custm", stack) then shop_inv:add_item("custm", stack) else @@ -241,7 +265,7 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields) end end for i, item in pairs(cust_og) do - local stack = shop_inv:remove_item("stock", item) + local stack = list_remove_item(shop_inv, "stock", item) if player_inv:room_for_item("main", stack) then player_inv:add_item("main", stack) else From f5303586ba91a9fa211f555cd08bd6b249998667 Mon Sep 17 00:00:00 2001 From: Foz Date: Mon, 30 Jan 2017 23:15:34 -0500 Subject: [PATCH 2/2] Make suggested changes. - Simplifies return values by returning only a single value for success and nothing for failure. - Stores the inventory list in a local to prevent redundant retrievals. --- shop.lua | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/shop.lua b/shop.lua index 03ee37c..a809b93 100644 --- a/shop.lua +++ b/shop.lua @@ -6,27 +6,26 @@ local exchange_shop = {} -- Tool wear aware replacement for contains_item. -local function list_contains_item(inv, list, stack) - for i, list_stack in pairs(inv:get_list(list)) do +local function list_contains_item(inv, listname, stack) + local list = inv:get_list(listname) + for i, list_stack in pairs(list) do if list_stack:get_name() == stack:get_name() and list_stack:get_count() >= stack:get_count() and list_stack:get_wear() <= stack:get_wear() then - return true, i + return i end end - return false, nil end -- Tool wear aware replacement for remove_item. -local function list_remove_item(inv, list, stack) - local contains, index = list_contains_item(inv, list, stack) - if contains then - local list_stack = inv:get_stack(list, index) +local function list_remove_item(inv, listname, stack) + local index = list_contains_item(inv, listname, stack) + if index then + local list_stack = inv:get_stack(listname, index) local removed_stack = list_stack:take_item(stack:get_count()) - inv:set_stack(list, index, list_stack) + inv:set_stack(listname, index, list_stack) return removed_stack end - return false end local function get_exchange_shop_formspec(number,pos,title)