diff --git a/api.lua b/api.lua index 04213f8..360d7d0 100644 --- a/api.lua +++ b/api.lua @@ -20,39 +20,49 @@ function x_marketplace.isnan(value) return value ~= value end -local function esc(x) - return (x:gsub('%%', '%%%%') - :gsub('^%^', '%%^') - :gsub('%$$', '%%$') - :gsub('%(', '%%(') - :gsub('%)', '%%)') - :gsub('%.', '%%.') - :gsub('%,', '%%,') - :gsub('%;', '%%;') - :gsub('%\\', '%%\\') - :gsub('%[', '%%[') - :gsub('%]', '%%]') - :gsub('%*', '%%*') - :gsub('%+', '%%+') - :gsub('%-', '%%-') - :gsub('%?', '%%?')) -end - --- rounds a number to the nearest decimal places +--- rounds a number to the nearest decimal places +-- @local local function round(val, decimal) - if (decimal) then - return math.floor( (val * 10^decimal) + 0.5) / (10^decimal) - else - return math.floor(val+0.5) - end + if (decimal) then + return math.floor( (val * 10^decimal) + 0.5) / (10^decimal) + else + return math.floor(val+0.5) + end end --- Search items in marketplace object +local function string_endswith(full, part) + return full:find(part, 1, true) == #full - #part + 1 +end + +--- Normalize nodename string without mod prefix and return nodename with mod prefix. This function was borrowed from WorldEdit mod. +-- @param nodename name of the node as a string, can be without the mod prefix +-- @return nil if node doesn't exists or nodename with mode prefix +-- @see https://github.com/Uberi/Minetest-WorldEdit +function x_marketplace.normalize_nodename(nodename) + nodename = nodename:gsub("^%s*(.-)%s*$", "%1") -- strip spaces + if nodename == "" then return nil end + + local fullname = ItemStack({name=nodename}):get_name() -- resolve aliases + if minetest.registered_nodes[fullname] or fullname == "air" then -- full name + return fullname + end + for key, value in pairs(minetest.registered_nodes) do + if string_endswith(key, ":" .. nodename) then -- matches name (w/o mod part) + return key + end + end +end + +--- Search items in marketplace object -- @param string the string -- @return string with found items, if no items found returns boolean false function x_marketplace.store_find(string) local found = "" - local str = esc(string) + local str = normalize_nodename(string) + + if not str then + return false + end for k, v in pairs(x_marketplace.store_list) do if string.find(k, str) then @@ -67,7 +77,7 @@ function x_marketplace.store_find(string) return found end --- Get random items from the store +--- Get random items from the store -- @param number the integer -- @return string with found items function x_marketplace.store_get_random(number) @@ -86,7 +96,7 @@ function x_marketplace.store_get_random(number) return suggest end --- Get players balance of BitGold +--- Get players balance of BitGold -- @param name the string of player name -- @return string the current balance function x_marketplace.get_player_balance(name) @@ -99,7 +109,7 @@ function x_marketplace.get_player_balance(name) return balance end --- Set players balance of BitGold +--- Set players balance of BitGold -- @param name the string of player name -- @param amount the number of what should be added/deducted (if negative) from players balance -- @return string the balance info message, returns false if not enough funds diff --git a/chatcommands.lua b/chatcommands.lua index cfa12f9..34ae4fa 100644 --- a/chatcommands.lua +++ b/chatcommands.lua @@ -206,6 +206,8 @@ minetest.register_chatcommand("mp", { -- sell inventory -- elseif params[1] == "sellinv" then + params[2] = x_marketplace.normalize_nodename(params[2]) + -- item name is missing from param[2] if not params[2] then return false, minetest.colorize(x_marketplace.colors.yellow, "MARKET PLACE: You need to write the item name you want to sell. example: /mp sellinv default:stone. See some suggestion from the store: ")..x_marketplace.store_get_random() @@ -252,7 +254,7 @@ minetest.register_chatcommand("mp", { local new_balance = x_marketplace.set_player_balance(caller, sell_price) if amount == 0 then - return false, minetest.chat_send_player(caller, minetest.colorize(x_marketplace.colors.yellow, "MARKET PLACE: We couldn't buy all your items without going above your maximum balance.")) + return false, minetest.chat_send_player(caller, minetest.colorize(x_marketplace.colors.yellow, "MARKET PLACE: You have nothing to sell in your inventory.")) end if over_max_balance then @@ -275,6 +277,8 @@ minetest.register_chatcommand("mp", { -- buy inventory -- elseif params[1] == "buyinv" then + params[2] = x_marketplace.normalize_nodename(params[2]) + -- item name is missing from param[2] if not params[2] then return false, minetest.colorize(x_marketplace.colors.yellow, "MARKET PLACE: You need to write the item name you want to buy. example: /mp buyinv default:stone, or check out other items in the store: ")..x_marketplace.store_get_random() @@ -337,13 +341,14 @@ minetest.register_chatcommand("mp", { -- elseif params[1] == "buy" then local amount = tonumber(params[3]) + params[2] = x_marketplace.normalize_nodename(params[2]) -- check for param[2] - item name - if not params[2] then return false, minetest.colorize(x_marketplace.colors.red, "MARKET PLACE: You need to write the item name you want to buy. example: /mp buy default:stone 10, or check out other items in the store: ")..x_marketplace.store_get_random() end + -- find sign local player = minetest.get_player_by_name(caller) local find_signs = x_marketplace.find_signs(player:get_pos(), "/mp buy", "x_marketplace:sign_wall_diamond") @@ -353,16 +358,7 @@ minetest.register_chatcommand("mp", { -- item not in store if not x_marketplace.store_list[params[2]] then - local suggestions = x_marketplace.store_find(params[2]) - - -- try suggest item from store, else show random items - if suggestions then - return false, minetest.colorize(x_marketplace.colors.yellow, "MARKET PLACE: This item is not in store, check out other items from the store: \n")..suggestions - - else - -- still not found in the store - pick random - return false, minetest.colorize(x_marketplace.colors.yellow, "MARKET PLACE: This item is not in store, check out other items from the store: ")..x_marketplace.store_get_random() - end + return false, minetest.colorize(x_marketplace.colors.yellow, "MARKET PLACE: This item is not in store, check out other items from the store: ")..x_marketplace.store_get_random() end -- check for param[3] - amount