Update server_shop mod to v1.6...
https://github.com/AntumMT/mod-server_shop/releases/tag/v1.6master
parent
a92ce7233d
commit
f8064312de
|
@ -32,7 +32,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
|
|||
* commerce/
|
||||
* [atm][] ([GPL][lic.gpl3.0]) -- version: [1.0.4][ver.atm] *2021-04-21* ([patched][patch.atm])
|
||||
* [currency][] ([LGPL][lic.lgpl3.0] / [CC BY-SA][lic.ccbysa4.0]) -- version: [2021-01-30][ver.currency]
|
||||
* [server_shop][] ([MIT][lic.server_shop]) -- version: [1.5][ver.server_shop] *2021-08-15*
|
||||
* [server_shop][] ([MIT][lic.server_shop]) -- version: [1.6][ver.server_shop] *2021-08-18*
|
||||
* core/
|
||||
* [antum][] ([MIT][lic.antum]) -- version: [69b39a4 Git][ver.antum] *2017-08-30*
|
||||
* [minetest_game][] ([LGPL][lic.lgpl2.1] / [CC BY-SA][lic.ccbysa3.0]) -- version: [9270188 Git][ver.minetest_game] *2021-07-08*
|
||||
|
@ -672,7 +672,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
|
|||
[ver.quartz]: https://github.com/minetest-mods/quartz/tree/72ec06f
|
||||
[ver.rainbow_ore]: https://github.com/FsxShader2012/rainbow_ore/tree/830ac09
|
||||
[ver.sand_monster]: https://github.com/AntumMT/mod-mob_sand_monster/tree/3dd5954
|
||||
[ver.server_shop]: https://github.com/AntumMT/mod-server_shop/releases/tag/v1.5
|
||||
[ver.server_shop]: https://github.com/AntumMT/mod-server_shop/releases/tag/v1.6
|
||||
[ver.sfinv]: https://github.com/rubenwardy/sfinv/tree/556f70e
|
||||
[ver.sfinv_buttons]: http://repo.or.cz/minetest_sfinv_buttons.git/tree/ebb1f7c
|
||||
[ver.signs_lib]: https://gitlab.com/VanessaE/signs_lib/tree/2021-03-04-2
|
||||
|
|
|
@ -10,7 +10,7 @@ No craft recipe is given as this for administrators, currently a shop can only b
|
|||
|
||||
### Usage:
|
||||
|
||||
#### Registering Shops:
|
||||
#### Registering Shops via API:
|
||||
|
||||
There are two types of shops, seller & buyer. A seller shop can be registered with `server_shop.register_seller(id, name, products)`. A buyer with `server_shop.register_buyer(id, name, products)`. `id` is a string identifier associated with the shop list. `name` is a human-readable string that will be displayed as the shop's title. `products` is the shop list definition. Shop lists are defined in a table of tuples in `{itemname, value}` format. `itemname` is the technical string name of an item (e.g. `default:wood`). `value` is the number representation of what the item is worth.
|
||||
|
||||
|
@ -26,6 +26,8 @@ server_shop.register_buyer("julie", "Julie's Shop", {
|
|||
})
|
||||
```
|
||||
|
||||
#### Registering Shops via Configuration:
|
||||
|
||||
Shops can optionally be configured in `<world_path>/server_shops.json` file. To register a shop, set `type` to "sell" or "buy". `id` is a string identifier for the shop. `name` is the string displayed in the formspec & when a player points at the node. `products` is an array of products sold at the shop in format "name,value".
|
||||
|
||||
*Example:*
|
||||
|
@ -50,6 +52,33 @@ Shops can optionally be configured in `<world_path>/server_shops.json` file. To
|
|||
]
|
||||
```
|
||||
|
||||
#### Registering Shops via Chat Command:
|
||||
|
||||
The `server_shop` chat command is available to administrators with the `server` privilege. This is used for administering shops & updating configuration.
|
||||
|
||||
Usage:
|
||||
```
|
||||
/server_shop <command> [<params>]
|
||||
|
||||
# Commands:
|
||||
|
||||
/server_shop reload
|
||||
- reloads data from configuration file
|
||||
|
||||
/server_shop register <id> <type> <name> [product1=value,product2=value,...]
|
||||
- registers a shop & updates configuration file
|
||||
- parameters:
|
||||
- id: shop identifier
|
||||
- type: can be "buy" or "sell"
|
||||
- name: displayed shop name ("_" is replaced with " ")
|
||||
- product list: comma-separated list in format "item=value"
|
||||
|
||||
/server_shop unregister <id>
|
||||
- unregisters a shop & updates configuration file
|
||||
- parameters:
|
||||
- id: shop identifier
|
||||
```
|
||||
|
||||
#### Registering Currencies:
|
||||
|
||||
Currencies can be registered with `server_shop.register_currency`:
|
||||
|
@ -106,9 +135,11 @@ For buyer shops, the product list shows what items can be sold to this shop & ho
|
|||
### Dependencies:
|
||||
|
||||
- Required:
|
||||
- none
|
||||
- simple_models
|
||||
- wdata
|
||||
- Optional:
|
||||
- [currency][mod.currency]
|
||||
- sounds
|
||||
|
||||
### Links:
|
||||
|
||||
|
|
|
@ -6,19 +6,15 @@ TODO:
|
|||
- optimize how refunds are given (e.g. if there is no room for 50s, but room for 1s, then give out 1s instead)
|
||||
- Aestethics:
|
||||
- make colorable with unifieddyes
|
||||
- add sounds
|
||||
- fix stepping sound for "large" node
|
||||
- Misc.:
|
||||
- make usable with "folks" mod
|
||||
- set shop name from formspec instead of registration so shops with different names can use same content
|
||||
- add player shops
|
||||
- fix so unknown items don't mess up shop (may become a problem when shops are registered live)
|
||||
- add chat command to reload shops file in world directory
|
||||
- allow shops to be configured live
|
||||
- register chat command "/server_shop" to register live
|
||||
- "/server_shop register <buyer>|<seller> <id>"
|
||||
- "/server_shop unregister <buyer>|<seller> <id>"
|
||||
- "/server_shop add <buyer>|<seller> <id> <item> <price>"
|
||||
- "/server_shop remove <buyer>|<seller> <id> <item>
|
||||
- "/server_shop reload"
|
||||
- use a spinner to select custom amount (example in terraform: https://github.com/x2048/terraform/blob/4b36d36/init.lua#L316 )
|
||||
- support groups in buyer shops
|
||||
|
|
|
@ -111,6 +111,10 @@ ss.register = function(id, name, products, buyer)
|
|||
products = name.products
|
||||
buyer = name.buyer
|
||||
name = name.name
|
||||
|
||||
if name.type then
|
||||
buyer = name.type == "buy"
|
||||
end
|
||||
end
|
||||
|
||||
if type(id) ~= "string" then
|
||||
|
@ -253,3 +257,213 @@ ss.is_shop_owner = function(pos, player)
|
|||
local meta = core.get_meta(pos)
|
||||
return player:get_player_name() == meta:get_string("owner")
|
||||
end
|
||||
|
||||
local shops_file = core.get_worldpath() .. "/server_shops.json"
|
||||
|
||||
local function shop_file_error(msg)
|
||||
ss.log("error", shops_file .. ": " .. msg)
|
||||
end
|
||||
|
||||
--- Loads configuration from world path.
|
||||
--
|
||||
-- Configuration file is <world\_path>/server\_shops.json
|
||||
--
|
||||
-- @function server_shop.file_load
|
||||
ss.file_load = function()
|
||||
local shops_data = wdata.read("server_shops") or {}
|
||||
|
||||
for _, shop in ipairs(shops_data) do
|
||||
if shop.type == "currency" then
|
||||
ss.log("warning", "using \"currency\" key in server_shops.json is deprecated, please use \"currencies\"")
|
||||
|
||||
if type(shop.value) ~= "number" or shop.value <= 0 then
|
||||
shop_file_error("invalid or undeclared currency \"value\"; must be a number greater than 0")
|
||||
end
|
||||
|
||||
ss.register_currency(shop.name, shop.value)
|
||||
elseif shop.type == "currencies" then
|
||||
if not shop.currencies then shop.currencies = shop.value end -- allow "value" to be used instead of "currencies"
|
||||
for k, v in pairs(shop.currencies) do
|
||||
ss.register_currency(k, v)
|
||||
end
|
||||
elseif shop.type == "suffix" then
|
||||
if type(shop.value) ~= "string" or shop.value:trim() == "" then
|
||||
shop_file_error("invalid or undeclared suffix \"value\"; must be non-empty string")
|
||||
else
|
||||
ss.currency_suffix = shop.value
|
||||
end
|
||||
elseif shop.type == "sell" or shop.type == "buy" then
|
||||
if type(shop.id) ~= "string" or shop.id:trim() == "" then
|
||||
shop_file_error("invalid or undeclared \"id\"; must be non-empty string")
|
||||
elseif type(shop.name) ~= "string" or shop.name:trim() == "" then
|
||||
shop_file_error("invalid or undeclared \"name\"; must be non-empty string")
|
||||
elseif type(shop.products) ~= "table" then
|
||||
shop_file_error("invalid or undeclared \"products\" list; must be non-empty table")
|
||||
else
|
||||
if not shop.products then shop.products = {} end
|
||||
if #shop.products == 0 then
|
||||
ss.log("warning", shops_file .. ": empty shop list for shop id \"" .. shop.id .. "\"")
|
||||
end
|
||||
|
||||
if shop.type == "sell" then
|
||||
server_shop.register_seller(shop.id, shop.name, shop.products)
|
||||
else
|
||||
server_shop.register_buyer(shop.id, shop.name, shop.products)
|
||||
end
|
||||
end
|
||||
elseif not shop.type then
|
||||
ss.log("error", shops_file .. ": mandatory \"type\" parameter not set")
|
||||
else
|
||||
ss.log("error", shops_file .. ": Unrecognized type: " .. shop.type)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Permanently registers a shop.
|
||||
--
|
||||
-- @function server_shop.file_register
|
||||
-- @tparam string id Shop identifier.
|
||||
-- @tparam ShopDef def Shop definition.
|
||||
ss.file_register = function(id, def)
|
||||
local shops_data = wdata.read("server_shops") or {}
|
||||
|
||||
local existing = {}
|
||||
for idx=1, #shops_data do
|
||||
local entry = shops_data[idx]
|
||||
if (entry.type == "sell" or entry.type == "buy") and id == entry.id then
|
||||
table.insert(existing, 1, idx)
|
||||
end
|
||||
end
|
||||
|
||||
for _, idx in ipairs(existing) do
|
||||
table.remove(shops_data, idx)
|
||||
end
|
||||
|
||||
def.id = id
|
||||
table.insert(shops_data, def)
|
||||
|
||||
wdata.write("server_shops", shops_data)
|
||||
end
|
||||
|
||||
--- Permanently adds a product to a shop.
|
||||
--
|
||||
-- @function server_shop.file_add_product
|
||||
-- @tparam string id Shop identifier.
|
||||
-- @tparam string name Item technical name.
|
||||
-- @tparam int value Item value.
|
||||
-- @tparam[opt] int idx Shop index for item placement.
|
||||
ss.file_add_product = function(id, name, value, idx)
|
||||
local shops_data = wdata.read("server_shops") or {}
|
||||
|
||||
local target_shop
|
||||
for idx=1, #shops_data do
|
||||
local entry = shops_data[idx]
|
||||
if entry.type == "sell" or entry.type == "buy" then
|
||||
if id == entry.id then
|
||||
target_shop = entry
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not target_shop then
|
||||
ss.log("error", "cannot add item to non-registered shop ID: " .. id)
|
||||
return false
|
||||
end
|
||||
|
||||
-- FIXME: check for duplicates
|
||||
|
||||
if not idx or idx > #target_shop.products then
|
||||
table.insert(target_shop.products, {name, value})
|
||||
else
|
||||
table.insert(target_shop.products, idx, {name, value})
|
||||
end
|
||||
|
||||
ss.register(id, target_shop)
|
||||
wdata.write("server_shops", shops_data)
|
||||
end
|
||||
|
||||
--- Unregisters a shop & updates configuration.
|
||||
--
|
||||
-- @function server_shop.file_unregister
|
||||
-- @tparam string id Shop identifier.
|
||||
-- @treturn bool
|
||||
ss.file_unregister = function(id)
|
||||
local shops_data = wdata.read("server_shops") or {}
|
||||
|
||||
local unregister_idx
|
||||
for idx=1, #shops_data do
|
||||
local entry = shops_data[idx]
|
||||
if entry.type == "sell" or entry.type == "buy" then
|
||||
if id == entry.id then
|
||||
unregister_idx = idx
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not unregister_idx then
|
||||
ss.log("warning", "cannot unregister unknown shop ID: " .. id)
|
||||
return false
|
||||
end
|
||||
|
||||
table.remove(shops_data, unregister_idx)
|
||||
ss.unregister(id)
|
||||
wdata.write("server_shops", shops_data)
|
||||
return true
|
||||
end
|
||||
|
||||
--- Prunes unknown items & updates aliases in shops.
|
||||
--
|
||||
-- @function server_shop.prune_shops
|
||||
ss.prune_shops = function()
|
||||
-- show warning if no currencies are registered
|
||||
if not ss.currency_is_registered() then
|
||||
ss.log("warning", "no currencies registered")
|
||||
else
|
||||
local have_ones = false
|
||||
for k, v in pairs(ss.get_currencies()) do
|
||||
have_ones = v == 1
|
||||
if have_ones then break end
|
||||
end
|
||||
|
||||
if not have_ones then
|
||||
ss.log("warning", "no currency registered with value 1, players may not be refunded all of their money")
|
||||
end
|
||||
end
|
||||
|
||||
-- prune unregistered items
|
||||
for id, def in pairs(ss.get_shops()) do
|
||||
local pruned = false
|
||||
for idx = #def.products, 1, -1 do
|
||||
local pname = def.products[idx][1]
|
||||
local value = def.products[idx][2]
|
||||
if not core.registered_items[pname] then
|
||||
ss.log("warning", "removing unregistered item \"" .. pname
|
||||
.. "\" from seller shop id \"" .. id .. "\"")
|
||||
table.remove(def.products, idx)
|
||||
pruned = true
|
||||
elseif not value then
|
||||
ss.log("warning", "removing item \"" .. pname
|
||||
.. "\" without value from seller shop id \"" .. id .. "\"")
|
||||
table.remove(def.products, idx)
|
||||
pruned = true
|
||||
end
|
||||
|
||||
-- check aliases
|
||||
local alias_of = core.registered_aliases[pname]
|
||||
if alias_of then
|
||||
ss.log("action", "replacing alias \"" .. pname .. "\" with \"" .. alias_of
|
||||
.. "\" in seller shop id \"" .. id .. "\"")
|
||||
table.remove(def.products, idx)
|
||||
table.insert(def.products, idx, {alias_of, value})
|
||||
pruned = true
|
||||
end
|
||||
end
|
||||
|
||||
if pruned then
|
||||
ss.unregister(id)
|
||||
ss.register(id, def)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
|
||||
v1.6
|
||||
----
|
||||
- model moved to simple_models mod
|
||||
- added node sounds
|
||||
- uses wdata for reading/writing shops config
|
||||
- added "server_shop" chat command:
|
||||
- reload: reloads shops configuration
|
||||
- register: registers new shop & updates configuration
|
||||
- unregister: unregister shop id & updates configuration
|
||||
|
||||
|
||||
v1.5
|
||||
----
|
||||
- added "textdomain" line to localization template
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
|
||||
--- Server Shops Chat Commands
|
||||
--
|
||||
-- @topic commands
|
||||
|
||||
|
||||
local ss = server_shop
|
||||
local S = core.get_translator(ss.modname)
|
||||
|
||||
|
||||
local command_list = {"reload", "register", "unregister"}
|
||||
local commands = {
|
||||
reload = "",
|
||||
register = "<"..S("ID")..">".." <sell/buy> ".."<"..S("name")..">"
|
||||
.." ["..S("product1=value,product2=value,...").."]",
|
||||
unregister = "<"..S("ID")..">",
|
||||
}
|
||||
|
||||
local format_usage = function(cmd)
|
||||
local usage = S("Usage:").."\n /"..ss.modname.." "..cmd
|
||||
local params = commands[cmd]
|
||||
if params and params ~= "" then
|
||||
usage = usage.." "..params
|
||||
end
|
||||
|
||||
return usage
|
||||
end
|
||||
|
||||
|
||||
--- Manages shops & config.
|
||||
--
|
||||
-- @chatcmd server_shop
|
||||
-- @param command Command to execute.
|
||||
-- @param[opt] params Parameters associated with command.
|
||||
-- @usage
|
||||
-- /server_shop <command> [<params>]
|
||||
--
|
||||
-- Commands:
|
||||
-- - reload
|
||||
-- - Reloads shops configuration.
|
||||
-- - register
|
||||
-- - Registers new shop & updates configuration.
|
||||
-- - parameters: <id> <sell/buy> <name> [product1=value,product2=value,...]
|
||||
-- - unregister
|
||||
-- - Unregisters shop & updates configuration.
|
||||
-- - parameters: <id>
|
||||
core.register_chatcommand(ss.modname, {
|
||||
description = S("Manage shops configuration."),
|
||||
privs = {server=true},
|
||||
params = "<"..S("command").."> ["..S("params").."]",
|
||||
func = function(name, param)
|
||||
local params = param:split(" ")
|
||||
local cmd = params[1]
|
||||
table.remove(params, 1)
|
||||
|
||||
if not cmd then
|
||||
return false, S("Must provide a command: @1", table.concat(command_list, ", "))
|
||||
end
|
||||
|
||||
if cmd == "reload" then
|
||||
if #params > 0 then
|
||||
return false, S('"@1" command takes no parameters.', cmd).."\n\n"..format_usage(cmd)
|
||||
end
|
||||
|
||||
ss.file_load()
|
||||
ss.prune_shops()
|
||||
return true, S("Shops configuration loaded.")
|
||||
elseif cmd == "register" then
|
||||
if #params > 4 then
|
||||
return false, S("Too many parameters.").."\n\n"..format_usage(cmd)
|
||||
end
|
||||
|
||||
local shop_id = params[1]
|
||||
local shop_type = params[2]
|
||||
local shop_name = params[3]
|
||||
local shop_products = params[4]
|
||||
|
||||
if not shop_id then
|
||||
return false, S("Must provide ID.").."\n\n"..format_usage(cmd)
|
||||
elseif not shop_type then
|
||||
return false, S("Must provide type.").."\n\n"..format_usage(cmd)
|
||||
elseif not shop_name then
|
||||
return false, S("Must provide name.").."\n\n"..format_usage(cmd)
|
||||
end
|
||||
|
||||
if shop_type ~= "sell" and shop_type ~= "buy" then
|
||||
return false, S('Shop type must be "@1" or "@2".', "sell", "buy").."\n\n"..format_usage(cmd)
|
||||
end
|
||||
|
||||
shop_name = shop_name:gsub("_", " ")
|
||||
|
||||
local products = {}
|
||||
if shop_products then
|
||||
shop_products = shop_products:split(",")
|
||||
for _, p in ipairs(shop_products) do
|
||||
local item = p:split("=")
|
||||
local item_name = item[1]
|
||||
local item_value = tonumber(item[2])
|
||||
|
||||
if not core.registered_items[item_name] then
|
||||
return false, S('"@1" is not a recognized item.', item_name).."\n\n"..format_usage(cmd)
|
||||
elseif not item_value then
|
||||
return false, S("Item value must be a number.").."\n\n"..format_usage(cmd)
|
||||
end
|
||||
|
||||
table.insert(products, {item_name, item_value})
|
||||
end
|
||||
end
|
||||
|
||||
ss.file_register(shop_id, {
|
||||
type = shop_type,
|
||||
name = shop_name,
|
||||
products = products,
|
||||
})
|
||||
ss.file_load()
|
||||
ss.prune_shops()
|
||||
|
||||
return true, S("Registered shop with ID: @1", shop_id)
|
||||
elseif cmd == "unregister" then
|
||||
if #params > 1 then
|
||||
return false, S("Too many parameters.").."\n\n"..format_usage(cmd)
|
||||
end
|
||||
|
||||
local shop_id = params[1]
|
||||
if not shop_id then
|
||||
return false, S("Must provide ID.").."\n\n"..format_usage(cmd)
|
||||
end
|
||||
|
||||
if not ss.file_unregister(shop_id) then
|
||||
return false, S("Cannot unregister shop with ID: @1", shop_id)
|
||||
end
|
||||
|
||||
return true, S("Unregistered shop with ID: @1", shop_id)
|
||||
end
|
||||
|
||||
return false, S("Unknown command: @1", cmd)
|
||||
end,
|
||||
})
|
|
@ -154,7 +154,7 @@ end
|
|||
--
|
||||
-- @function server_shop.get_formspec
|
||||
-- @tparam vector pos Shop node coordinates.
|
||||
-- @tparam player ObjectRef Player to whom the formspec is shown.
|
||||
-- @tparam ObjectRef player Player to whom the formspec is shown.
|
||||
-- @tparam[opt] bool buyer `true` if the shop in question is a buyer shop (default: false).
|
||||
-- @treturn string Formspec formatted string.
|
||||
ss.get_formspec = function(id, player, buyer)
|
||||
|
@ -274,7 +274,7 @@ end
|
|||
--
|
||||
-- @function server_shop.show_formspec
|
||||
-- @tparam vector pos Shop node coordinates.
|
||||
-- @tparam player ObjectRef Player to whom the formspec is shown.
|
||||
-- @tparam ObjectRef player Player to whom the formspec is shown.
|
||||
-- @tparam[opt] bool buyer (deprecated)
|
||||
ss.show_formspec = function(pos, player, buyer)
|
||||
if buyer ~= nil then
|
||||
|
|
|
@ -25,132 +25,13 @@ local scripts = {
|
|||
"deposit",
|
||||
"formspec",
|
||||
"node",
|
||||
"command",
|
||||
}
|
||||
|
||||
for _, script in ipairs(scripts) do
|
||||
dofile(ss.modpath .. "/" .. script .. ".lua")
|
||||
end
|
||||
|
||||
-- load configured shops from world directory
|
||||
local shops_file = core.get_worldpath() .. "/server_shops.json"
|
||||
|
||||
local function shop_file_error(msg)
|
||||
error(shops_file .. ": " .. msg)
|
||||
end
|
||||
|
||||
local fopen = io.open(shops_file, "r")
|
||||
if fopen ~= nil then
|
||||
local content = fopen:read("*a")
|
||||
io.close(fopen)
|
||||
|
||||
local json = core.parse_json(content)
|
||||
if json then
|
||||
for _, shop in ipairs(json) do
|
||||
if shop.type == "currency" then
|
||||
ss.log("warning", "using \"currency\" key in server_shops.json is deprecated, please use \"currencies\"")
|
||||
|
||||
if type(shop.value) ~= "number" or shop.value <= 0 then
|
||||
shop_file_error("invalid or undeclared currency \"value\"; must be a number greater than 0")
|
||||
end
|
||||
|
||||
ss.register_currency(shop.name, shop.value)
|
||||
elseif shop.type == "currencies" then
|
||||
if not shop.currencies then shop.currencies = shop.value end -- allow "value" to be used instead of "currencies"
|
||||
for k, v in pairs(shop.currencies) do
|
||||
ss.register_currency(k, v)
|
||||
end
|
||||
elseif shop.type == "suffix" then
|
||||
if type(shop.value) ~= "string" or shop.value:trim() == "" then
|
||||
shop_file_error("invalid or undeclared suffix \"value\"; must be non-empty string")
|
||||
else
|
||||
ss.currency_suffix = shop.value
|
||||
end
|
||||
elseif shop.type == "sell" or shop.type == "buy" then
|
||||
if type(shop.id) ~= "string" or shop.id:trim() == "" then
|
||||
shop_file_error("invalid or undeclared \"id\"; must be non-empty string")
|
||||
elseif type(shop.name) ~= "string" or shop.name:trim() == "" then
|
||||
shop_file_error("invalid or undeclared \"name\"; must be non-empty string")
|
||||
elseif type(shop.products) ~= "table" then
|
||||
shop_file_error("invalid or undeclared \"products\" list; must be non-empty table")
|
||||
else
|
||||
if not shop.products then shop.products = {} end
|
||||
if #shop.products == 0 then
|
||||
ss.log("warning", shops_file .. ": empty shop list for shop id \"" .. shop.id .. "\"")
|
||||
end
|
||||
|
||||
if shop.type == "sell" then
|
||||
server_shop.register_seller(shop.id, shop.name, shop.products)
|
||||
else
|
||||
server_shop.register_buyer(shop.id, shop.name, shop.products)
|
||||
end
|
||||
end
|
||||
elseif not shop.type then
|
||||
error(shops_file .. ": mandatory \"type\" parameter not set")
|
||||
else
|
||||
error(shops_file .. ": Unrecognized type: " .. shop.type)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- create file if doesn't exist
|
||||
fopen = io.open(shops_file, "w")
|
||||
if fopen == nil then
|
||||
server_shop.log("error", "Could not create " .. shops_file .. ", directory exists")
|
||||
else
|
||||
io.close(fopen)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
core.register_on_mods_loaded(function()
|
||||
-- show warning if no currencies are registered
|
||||
if not ss.currency_is_registered() then
|
||||
ss.log("warning", "no currencies registered")
|
||||
else
|
||||
local have_ones = false
|
||||
for k, v in pairs(ss.get_currencies()) do
|
||||
have_ones = v == 1
|
||||
if have_ones then break end
|
||||
end
|
||||
|
||||
if not have_ones then
|
||||
ss.log("warning", "no currency registered with value 1, players may not be refunded all of their money")
|
||||
end
|
||||
end
|
||||
|
||||
-- prune unregistered items
|
||||
for id, def in pairs(ss.get_shops()) do
|
||||
local pruned = false
|
||||
for idx = #def.products, 1, -1 do
|
||||
local pname = def.products[idx][1]
|
||||
local value = def.products[idx][2]
|
||||
if not core.registered_items[pname] then
|
||||
ss.log("warning", "removing unregistered item \"" .. pname
|
||||
.. "\" from seller shop id \"" .. id .. "\"")
|
||||
table.remove(def.products, idx)
|
||||
pruned = true
|
||||
elseif not value then
|
||||
-- FIXME: this should be done in registration method
|
||||
ss.log("warning", "removing item \"" .. pname
|
||||
.. "\" without value from seller shop id \"" .. id .. "\"")
|
||||
table.remove(def.products, idx)
|
||||
pruned = true
|
||||
end
|
||||
|
||||
-- check aliases
|
||||
local alias_of = core.registered_aliases[pname]
|
||||
if alias_of then
|
||||
ss.log("action", "replacing alias \"" .. pname .. "\" with \"" .. alias_of
|
||||
.. "\" in seller shop id \"" .. id .. "\"")
|
||||
table.remove(def.products, idx)
|
||||
table.insert(def.products, idx, {alias_of, value})
|
||||
pruned = true
|
||||
end
|
||||
end
|
||||
|
||||
if pruned then
|
||||
ss.unregister(id)
|
||||
ss.register(id, def)
|
||||
end
|
||||
end
|
||||
end)
|
||||
ss.file_load()
|
||||
core.register_on_mods_loaded(ss.prune_shops)
|
||||
|
|
|
@ -15,3 +15,32 @@ You haven't deposited enough money.=No has depositado suficiente dinero.
|
|||
You purchased @1 @2 for @3 @4.=Compraste @1 @2 por @3 @4.
|
||||
You sold @1 @2 for @3 @4.=Vendiste @1 @2 por @3 @4.
|
||||
WARNING: @1 @2 was dropped on the ground.=AVISO: @1 @2 se cayó en la tierra.
|
||||
|
||||
# chat commands
|
||||
Manage shops configuration.=Administrar configuración de tiendas.
|
||||
Usage:=Uso:
|
||||
command=orden
|
||||
params=parámetros
|
||||
Must provide a command: @1=Debe producir un orden: @1
|
||||
"@1" command takes no parameters.=Orden "@1" no requiere parametros.
|
||||
Too many parameters.=Demasiado parámetros.
|
||||
Unknown command: @1=Orden desconocido: @1
|
||||
Must provide ID.=Se requiere ID.
|
||||
|
||||
# reload command
|
||||
Shops configuration loaded.=Configuración de tiendas cargada.
|
||||
|
||||
# register command
|
||||
ID=
|
||||
name=nombre
|
||||
product1@=value,product2@=value,...=producto1@=valor,producto2@=valor,...
|
||||
Must provide type.=Se requiere tipo.
|
||||
Must provide name.=Se requiere nombre.
|
||||
Shop type must be "@1" or "@2".=Tipo de tienda debe ser "@1" o "@2".
|
||||
"@1" is not a recognized item.="@1" no es objeto conocido.
|
||||
Item value must be a number.=Valor de objeto debe ser número.
|
||||
Registered shop with ID: @1=Agregó al registro tienda con ID: @1
|
||||
|
||||
# unregister command
|
||||
Cannot unregister shop with ID: @1=No puede quitar del registro tienda con ID: @1
|
||||
Unregistered shop with ID: @1=Se quitó del registro tienda con ID: @1
|
||||
|
|
|
@ -15,3 +15,32 @@ You haven't deposited enough money.=
|
|||
You purchased @1 @2 for @3 @4.=
|
||||
You sold @1 @2 for @3 @4.=
|
||||
WARNING: @1 @2 was dropped on the ground.=
|
||||
|
||||
# chat commands
|
||||
Manage shops configuration.=
|
||||
Usage:=
|
||||
command=
|
||||
params=
|
||||
Must provide a command: @1=
|
||||
"@1" command takes no parameters.=
|
||||
Too many parameters.=
|
||||
Unknown command: @1=
|
||||
Must provide ID.=
|
||||
|
||||
# reload command
|
||||
Shops configuration loaded.=
|
||||
|
||||
# register command
|
||||
ID=
|
||||
name=
|
||||
product1@=value,product2@=value,...=
|
||||
Must provide type.=
|
||||
Must provide name.=
|
||||
Shop type must be "@1" or "@2".=
|
||||
"@1" is not a recognized item.=
|
||||
Item value must be a number.=
|
||||
Registered shop with ID: @1=
|
||||
|
||||
# unregister command
|
||||
Cannot unregister shop with ID: @1=
|
||||
Unregistered shop with ID: @1=
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
name = server_shop
|
||||
title = Server Shop
|
||||
description = Shops intended to be set up by server administrators.
|
||||
version = 1.5
|
||||
version = 1.6
|
||||
author = Jordan Irwin (AntumDeluge)
|
||||
min_minetest_version = 5.0
|
||||
optional_depends = currency
|
||||
depends = simple_models, wdata
|
||||
optional_depends = currency, sounds
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
# Blender v2.93.2 OBJ File: 'server_shop_2.blend'
|
||||
# www.blender.org
|
||||
mtllib server_shop.mtl
|
||||
o Cube
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 1.500000 -0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v -0.500000 1.500000 -0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v 0.500000 1.500000 0.500000
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 1.500000 0.500000
|
||||
vt 0.500000 0.250043
|
||||
vt 0.500000 0.000087
|
||||
vt 0.749957 0.000087
|
||||
vt 0.749957 0.250043
|
||||
vt 0.749957 0.749978
|
||||
vt 0.749957 0.250065
|
||||
vt 0.999914 0.250065
|
||||
vt 0.999914 0.749978
|
||||
vt 0.000087 0.749978
|
||||
vt 0.000087 0.250065
|
||||
vt 0.250043 0.250065
|
||||
vt 0.250043 0.749978
|
||||
vt 0.500000 0.999957
|
||||
vt 0.500000 0.750000
|
||||
vt 0.749957 0.999957
|
||||
vt 0.500000 0.250065
|
||||
vn -0.0000 -1.0000 -0.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 -0.0000 1.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn -0.0000 0.0000 -1.0000
|
||||
vn 1.0000 -0.0000 -0.0000
|
||||
usemtl Material
|
||||
s off
|
||||
f 1/1/1 5/2/1 7/3/1 3/4/1
|
||||
f 4/5/2 3/6/2 7/7/2 8/8/2
|
||||
f 8/9/3 7/10/3 5/11/3 6/12/3
|
||||
f 6/13/4 2/14/4 4/5/4 8/15/4
|
||||
f 2/14/5 1/16/5 3/6/5 4/5/5
|
||||
f 6/12/6 5/11/6 1/16/6 2/14/6
|
|
@ -8,11 +8,17 @@ local ss = server_shop
|
|||
local S = core.get_translator(ss.modname)
|
||||
|
||||
|
||||
local node_sound
|
||||
if core.global_exists("sounds") then
|
||||
node_sound = sounds.node_stone()
|
||||
end
|
||||
|
||||
local def = {
|
||||
base = {
|
||||
description = S("Shop"),
|
||||
groups = {oddly_breakable_by_hand=1},
|
||||
paramtype2 = "facedir",
|
||||
sounds = node_sound,
|
||||
after_place_node = function(pos, placer)
|
||||
-- set node owner
|
||||
core.get_meta(pos):set_string("owner", placer:get_player_name())
|
||||
|
@ -54,7 +60,7 @@ local def = {
|
|||
-- @img server_shop_front.png
|
||||
large = {
|
||||
drawtype = "mesh",
|
||||
mesh = "server_shop.obj",
|
||||
mesh = "node_1x2x1.obj",
|
||||
tiles = {"server_shop_mesh.png",},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
|
|
Loading…
Reference in New Issue