feat(give): Add functionality to give items and packages to players/factions

This commit introduces the ability to give items and packages to players or factions. It includes commands for giving various items from packages, emptying inventories, equipping players with items, and more. The changes also include enhancements to handle player names within owned factions or by administrators effectively.
This commit is contained in:
Yves-Marie Haussonne 2024-10-03 16:04:01 +02:00
parent 6d2aaf6cef
commit efb3481b18
13 changed files with 917 additions and 21 deletions

3
.gitignore vendored
View File

@ -4,4 +4,5 @@
!mod.conf
!.gitignore
!settingtypes.txt
dist
dist
locale/*.tr.old

View File

@ -66,6 +66,20 @@ COPY <<-EOF /var/lib/minetest/.minetest/world/map_meta.txt
[end_of_params]
EOF
COPY <<-EOF /var/lib/minetest/.minetest/world/factions/manage_give.conf
{
"packages": {
"ichi": [
"default:dirt 100",
"default:pick_steel 1 30000"
],
"nidan": [
"default:stone 30"
]
}
}
EOF
COPY <<-EOF /etc/minetest/minetest.conf.base
test_harness_run_tests=true
max_forceloaded_blocks=9999

258
give.lua Normal file
View File

@ -0,0 +1,258 @@
local conf_path = minetest.get_worldpath() .. "/factions/manage_give.conf"
local registered_packages, conf_packages = {}, {}
local S = minetest.get_translator("playerfactions_ext")
local function filter_registered_stacks(stack_list)
local copy, index, item_stack = {}, next(stack_list)
while index do
if minetest.registered_items[item_stack:get_name()] then table.insert(copy, item_stack) end
index, item_stack = next(stack_list, index)
end
return copy
end
setmetatable(registered_packages, {
__index = function(parent_table, package_name)
if conf_packages[package_name] then
local registered_stacks = filter_registered_stacks(conf_packages[package_name])
parent_table[package_name] = registered_stacks
return registered_stacks
else
return nil
end
end
})
local function insert_split_stack(stack_list, item_stack)
local count = item_stack:get_count()
local max = item_stack:get_stack_max()
while count > 0 do
local copy = ItemStack(item_stack)
if count > max then
copy:set_count(max)
count = count - max
else
copy:set_count(count)
count = 0
end
table.insert(stack_list, copy)
end
end
local function authorized_package_names(name)
local package_names = {}
if minetest.check_player_privs(name, "playerfactions_give") or minetest.check_player_privs(name, factions.priv) then
for package_name, _ in pairs(conf_packages) do
package_names[package_name] = true
end
else
for priv in pairs(minetest.get_player_privs(name)) do
local package_name = string.match(priv, "playerfactions_give_" .. "(%S+)")
if package_name and registered_packages[package_name] then
package_names[package_name] = true
end
end
end
return package_names
end
local function authorize_item(name, item_name)
if minetest.registered_items[item_name] then
if minetest.check_player_privs(name, "playerfactions_give") then return true end
for authorized_package in pairs(authorized_package_names(name)) do
for _, stack in ipairs(registered_packages[authorized_package]) do
if stack:get_name() == item_name then return true end
end
end
end
return false
end
local function authorize_package(name, package_name)
return (minetest.check_player_privs(name, factions.priv) or minetest.check_player_privs(name, "playerfactions_give")
or minetest.check_player_privs(name, "playerfactions_give_" .. package_name))
and registered_packages[package_name]
end
local function provision_stacks(name, query)
local item_stack, stack_list = ItemStack(query), {}
if authorize_item(name, item_stack:get_name()) then
insert_split_stack(stack_list, item_stack)
return stack_list
end
if authorize_package(name, query) then return registered_packages[query] end
return nil, S("Item or package @1 not found or not allowed.", query)
end
local function iterate_inventory_action(player_names, action)
local names_by_outcome, player, inventory, outcome = {}
if not next(player_names) then return S("No player was affected.") end
for player_name in pairs(player_names) do
player = minetest.get_player_by_name(player_name)
if player then
inventory = player:get_inventory()
outcome = inventory and action(inventory) or S("inventory error")
else
outcome = S("disconnected")
end
factions_ext.register_outcome(names_by_outcome, player_name, outcome)
end
return factions_ext.summarize_iteration(names_by_outcome)
end
local function gen_give_stack_list(stack_list)
return function(inventory)
if not next(stack_list) then return S("Nothing to receive") end
local some_success, some_failure = false, false
for _, item_stack in ipairs(stack_list) do
local leftover = inventory:add_item("main", item_stack)
if leftover:is_empty() then
some_success = true
elseif leftover:get_count() == item_stack:get_count() then
some_failure = true
else
some_success, some_failure = true, true
end
end
return (some_success and (some_failure and S("Some items received") or S("All items received")) or S("None of the items received"))
end
end
local function clear_inventory(inventory)
local was_empty = true
for list_name, _ in pairs(inventory:get_lists()) do
if not inventory:is_empty(list_name) then was_empty = false end
inventory:set_list(list_name, {})
end
return was_empty and S("Inventory already empty") or S("Inventory emptied")
end
local function gen_equip(stack_list)
return function(inventory)
return clear_inventory(inventory) .. ", " .. gen_give_stack_list(stack_list)(inventory)
end
end
factions_ext.register_privilege("playerfactions_give", {description = S("unrestricted use of factions give sub commands") , give_to_singleplayer = false})
local conf_data = (factions_ext.open_file(conf_path, false) or { packages = {} })["packages"]
if type(conf_data) == "table" then
for package_name, package in pairs(conf_data) do
if type(package) == "table" then
if not conf_packages[package_name] then
conf_packages[package_name] = {}
for index, itemstring in ipairs(package) do
if type(itemstring) == "string" then
insert_split_stack(conf_packages[package_name], ItemStack(itemstring))
else
conf_packages[package_name] = nil
minetest.log("warning", "factions -!- invalid item: "
.. package_name .. " [" .. tostring(index) .. "]. Package dismissed")
break
end
end
if conf_packages[package_name] then
factions_ext.register_privilege(
"playerfactions_give_" .. package_name,
{
description = S("Holder has access to contents of @1", package_name),
give_to_singleplayer = false
})
factions_ext.register_privilege(
"playerfactions_grant_give_" .. package_name,
{
description = S("Holder may grant access to contents of @1", package_name),
give_to_singleplayer = false
})
end
else
minetest.log("warning", "factions -!- package already registered: " .. package_name .. ".")
end
else
minetest.log("warning", "factions -!- invalid package: " .. package_name .. ".")
end
end
else
minetest.log("warning", "factions -!- could not load registered packages from " .. conf_path .. ".")
end
local give_description = S("This is an extension of the basic /give command.\
<amount>: 1-65535, defaults to 1 is optional, only affects stackable nodes, has no effect otherwise (e.g. tools)\
<wear>: 0-65535, defaults to 0 (intact), requires amount to be specified, only affects tools.\
Configuration file (<world directory>@1) example: \
{ \"packages\": {\"my_package\": [ \"default:brick 100\", \"default:pick_steel 1 30000\" ] } }", conf_path)
factions_ext.register_subcommand("give", {
params = "<player|faction [and_me]> <identifier [<amount>[ <wear>]]|package>",
description = give_description,
func = function(name, action, parsed_params, params)
local player_names, extra = factions_ext.process_names(name, params, "give")
if not player_names then return false, extra end
local stack_list, summary = provision_stacks(name, extra)
if not stack_list then return false, summary end
local give_stack_list = gen_give_stack_list(stack_list)
return true, iterate_inventory_action(player_names, give_stack_list)
end
})
factions_ext.register_subcommand("giveme", {
params = "<identifier [<amount>[ <wear>]]|package>",
description = S("This is an extension of the basic /give command. See /help factions (give) for contents syntax"),
func = function(name, action, parsed_params, params)
local stack_list, summary = provision_stacks(name, params)
if not stack_list then return false, summary end
local give_stack_list = gen_give_stack_list(stack_list)
return true, iterate_inventory_action({[name] = true}, give_stack_list)
end
})
factions_ext.register_subcommand("empty_inventory", {
params = "<player|faction [and_me]>",
description = S("Empty inventory of designated player(s)"),
func = function(name, action, parsed_params, params)
local player_names, extra = factions_ext.process_names(name, params, "empty_inventory")
if not player_names then return false, extra end
return true, iterate_inventory_action(player_names, clear_inventory)
end
})
factions_ext.register_subcommand("equip", {
params = "<player|faction [and_me]> <identifier [<amount>[ <wear>]]|package>",
description = S("same as give, but replaces player inventory instead of adding to it (see /help factions give)"),
func = function(name, action, parsed_params, params)
local player_names, extra = factions_ext.process_names(name, params, "empty_inventory")
if not player_names then return false, extra end
local stack_list, summary = provision_stacks(name, extra)
if not stack_list then return false, summary end
local equip = gen_equip(stack_list)
return true, iterate_inventory_action(player_names, equip)
end
})
factions_ext.register_subcommand("packages", {
params = "[<package>]",
description = S("List available packages (if no argument is given) or the contents of designated package"),
func = function(name, action, parsed_params, param)
local package_name = string.match(param, "%s*(%S+)")
local summary
if package_name then
if authorize_package(name, package_name) then -- list package contents
summary = S("Package @1 contains:", package_name)
for _, item_stack in ipairs(registered_packages[package_name]) do
summary = summary .. " [" .. item_stack:get_name() .. " " .. item_stack:get_count() .. "]"
end
else
return false, S("Package @1 is not available.", package_name)
end
else --list packages
summary = S("Available packages:")
for authorized_package_name in pairs(authorized_package_names(name)) do
summary = summary .. " " .. authorized_package_name
end
end
return true, summary
end
})

View File

@ -13,7 +13,7 @@ local registered_playerfaction_command = minetest.registered_chatcommands["facti
local factions_handle_command = registered_playerfaction_command.func
local factions_wrapper_func = function(name, action, parsed_params, param)
return factions_handle_command(name, param)
return factions_handle_command(name, action.." "..param)
end
--
@ -130,7 +130,7 @@ local function handle_command(name, param)
return false, S("You need @1 for subcommand @2", priv_list, action)
end
return command_handler_def.func(name, action, params, param)
return command_handler_def.func(name, action, params, factions_ext.remove_prefix(param, action))
end
@ -157,7 +157,8 @@ end
for _, name in ipairs({
"utils",
"teleport"
"teleport",
"give"
}) do
dofile(minetest.get_modpath("playerfactions_ext") .. "/" .. name .. ".lua")
end

View File

@ -1,4 +1,25 @@
# textdomain: playerfactions_ext
Item or package @1 not found or not allowed.=Objet ou paquet @1 n'est pas trouvé
No player was affected.=Aucun joueur n'a été modifié.
inventory error=Erreur dans l'inventaire
disconnected=Deconnecté
Nothing to receive=Rien à recevoir
Some items received=Quelques items ont été reçus
All items received=Tous les objets ont été reçus
None of the items received=Aucun des objets reçu
Inventory already empty=Inventaire déjà vidé
Inventory emptied=Inventaire vidé
unrestricted use of factions give sub commands=Usage non limité de la sous-commande "give" de factions
Holder has access to contents of @1=Les propiétaires peuvent donner accès au contenu de @1
Holder may grant access to contents of @1=Les propriétaires peuvent donner accès au contenu de @1
This is an extension of the basic /give command.\@n<amount>: 1-65535, defaults to 1 is optional, only affects stackable nodes, has no effect otherwise (e.g. tools)\@n<wear>: 0-65535, defaults to 0 (intact), requires amount to be specified, only affects tools.\@nConfiguration file (<world directory>@1) example: \@n{ "packages": {"my_package": [ "default:brick 100", "default:pick_steel 1 30000" ] } }=Ceci est une extension de la commande basique /give.\@n<amount>: 1-65535, optionnelle, default 1, n'as d'effet que sur les nodes empilables, n'a pas d'autre effet (e.g. tools)\@n<wear>: 0-65535, defaults 0 (intacte), quantités à spécifier, ne s'applique qu'aux outils.\@nFichier de configuration= (<world directory>@1) exemple: \@n{ "packages": {"my_package": [ "default:brick 100", "default:pick_steel 1 30000" ] } }
This is an extension of the basic /give command. See /help factions (give) for contents syntax=Ceci est une extension de la commande basique /give. Voir /help factions pour la syntaxe de contenu
Empty inventory of designated player(s)=Vide l'inventaire du(es) joueur(s) désigné(s)
same as give, but replaces player inventory instead of adding to it (see /help factions give)=Même usage que pour "give", mais remplace l'inventaire du joueur à la place de l'augmenter (voir /help factions give)
List available packages (if no argument is given) or the contents of designated package=Liste les paquests disponibles (si aucun argument) ou le contenu du paquest nommé.
Package @1 contains:=Le paquet @1 contient :
Package @1 is not available.=Le paquet @1 n'est pas disponible
Available packages:=Paquets disponibles :
Subcommand @1 not implemented=Sous-commande @1 non implémentée
Create a new faction=Crée une nouvelle faction
List available factions=Liste les factions disponibles
@ -24,3 +45,9 @@ No ground destination found.=Pas de sol trouvé à la destination.
Could not find destination.=Destrination non trouvée
Effect on players:=Effet sur les joueurs :
and @1 more.=et @1 de plus.
@1 not a member of any faction you own.=
Could not find player or faction named @1, no factions=Ne trouve pas le joueur ou la faction @1, pas de faction
Could not find player or faction named @1=Ne trouve pas le joueur ou la faction @1
You do not own faction @1.=La faction @1 n'est pas la votre.
@1 is not a member of any faction you own.=@1 n'est pas un membre d'une de vos factions.
Invalid parameters (see /help factions @1)=Paramètre invalide (voir /help factions @1)

View File

@ -1,4 +1,25 @@
# textdomain: playerfactions_ext
Item or package @1 not found or not allowed.=
No player was affected.=
inventory error=
disconnected=
Nothing to receive=
Some items received=
All items received=
None of the items received=
Inventory already empty=
Inventory emptied=
unrestricted use of factions give sub commands=
Holder has access to contents of @1=
Holder may grant access to contents of @1=
This is an extension of the basic /give command.\@n<amount>: 1-65535, defaults to 1 is optional, only affects stackable nodes, has no effect otherwise (e.g. tools)\@n<wear>: 0-65535, defaults to 0 (intact), requires amount to be specified, only affects tools.\@nConfiguration file (<world directory>@1) example: \@n{ "packages": {"my_package": [ "default:brick 100", "default:pick_steel 1 30000" ] } }=
This is an extension of the basic /give command. See /help factions (give) for contents syntax=
Empty inventory of designated player(s)=
same as give, but replaces player inventory instead of adding to it (see /help factions give)=
List available packages (if no argument is given) or the contents of designated package=
Package @1 contains:=
Package @1 is not available.=
Available packages:=
Subcommand @1 not implemented=
Create a new faction=
List available factions=
@ -22,5 +43,11 @@ Invalid parameters (see /help factions)=
Invalid destination.=
No ground destination found.=
Could not find destination.=
Effect on players :=
and @1 more.=
Effect on players:=
and @1 more.=
@1 not a member of any faction you own.=
Could not find player or faction named @1, no factions=
Could not find player or faction named @1=
You do not own faction @1.=
@1 is not a member of any faction you own.=
Invalid parameters (see /help factions @1)=

8
manage_give.conf.example Normal file
View File

@ -0,0 +1,8 @@
{
"packages": {
"my_package": [
"default:dirt 100",
"default:pick_steel 1 30000"
]
}
}

View File

@ -108,8 +108,6 @@ factions_ext.register_subcommand("teleport", {
description = S("Teleport a player or faction to given coordinates or player.@nIf no destination is given, then destination is your position"),
privs = { playerfactions_teleport = true },
func = function(name, action, params_list, params)
-- remove "teleport " form params
params = string.gsub(params, "%s*teleport%s*", "")
local target, next_params = string.match(params, "(%S+)%s*(.*)")
if not target then return false, S("Invalid parameters (see /help factions)") end
local names_list, reason = factions_ext.provision_player_names(name, target)

View File

@ -30,7 +30,7 @@ factions_ext.register_test("Handler override", function()
assert(log.name == "User")
assert(log.action == "list")
assert(log.param == "list item1 item2")
assert(log.param == "item1 item2")
message_handler("User", "/factions bar")
@ -40,3 +40,9 @@ factions_ext.register_test("Handler override", function()
factions_ext.subcommands_registry = old_registry
end)
factions_ext.register_test("Remove prefix", function()
assert(factions_ext.remove_prefix(" foo bar", "foo") == "bar")
assert(factions_ext.remove_prefix(" foo bar", "world") == " foo bar")
assert(factions_ext.remove_prefix(" foo foo bar", "foo") == "foo bar")
end)

478
test/give.lua Normal file
View File

@ -0,0 +1,478 @@
factions_ext.register_test("Package def tests")
factions_ext.register_test("Check privs registrations", function()
for _, priv in ipairs({
"playerfactions_give",
"playerfactions_give_ichi",
"playerfactions_give_nidan",
"playerfactions_grant_give_ichi",
"playerfactions_grant_give_nidan"}) do
assert(minetest.registered_privileges[priv] ~= nil)
end
end)
factions_ext.register_test("Packages conf", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { [factions.priv]= true })
local package_command = factions_ext.subcommands_registry['packages']
local res, msg = package_command.func("test", "packages", {}, "")
assert(res)
assert(string.match(msg, "ichi"))
assert(string.match(msg, "nidan"))
end)
factions_ext.register_test("Packages conf priv", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_give"]= true })
local package_command = factions_ext.subcommands_registry['packages']
local res, msg = package_command.func("test", "packages", {}, "")
assert(res)
assert(string.match(msg, "ichi"))
assert(string.match(msg, "nidan"))
end)
factions_ext.register_test("Packages conf priv specific", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_give_ichi"]= true })
local package_command = factions_ext.subcommands_registry['packages']
local res, msg = package_command.func("test", "packages", {}, "")
assert(res)
assert(string.match(msg, "ichi"))
assert(not string.match(msg, "nidan"))
end)
factions_ext.register_test("Packages conf priv specific other", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_give_nidan"]= true })
local package_command = factions_ext.subcommands_registry['packages']
local res, msg = package_command.func("test", "packages", {}, "")
assert(res)
assert(not string.match(msg, "ichi"))
assert(string.match(msg, "nidan"))
end)
factions_ext.register_test("Give tests")
factions_ext.register_test("Give package to players", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_admin"]= true })
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
local player1 = minetest.get_player_by_name("player1")
local player2 = minetest.get_player_by_name("player2")
assert(player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['give'].func("test", "give", nil, "testfaction ichi")
if not res then minetest.debug("GIVE res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
for _,p in ipairs({player1, player2}) do
for _,item in ipairs({"default:dirt", "default:pick_steel"}) do
assert(p:get_inventory():contains_item("main", item))
end
end
end, { players= { "player1", "player2" }})
factions_ext.register_test("Give package to players faction owner", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_admin"]= true })
minetest.set_player_privs("player1", { ["playerfactions_give_ichi"]= true })
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
local player1 = minetest.get_player_by_name("player1")
local player2 = minetest.get_player_by_name("player2")
assert(player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['give'].func("player1", "give", nil, "testfaction ichi")
if not res then minetest.debug("GIVE res : ", res, msg) end
assert(res)
assert(player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
for _,p in ipairs({player2}) do
for _,item in ipairs({"default:dirt", "default:pick_steel"}) do
assert(p:get_inventory():contains_item("main", item))
end
end
end, { players= { "player1", "player2" }})
factions_ext.register_test("Give package to players faction owner and_me", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_admin"]= true })
minetest.set_player_privs("player1", { ["playerfactions_give_ichi"]= true })
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
local player1 = minetest.get_player_by_name("player1")
local player2 = minetest.get_player_by_name("player2")
assert(player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['give'].func("player1", "give", nil, "testfaction and_me ichi")
if not res then minetest.debug("GIVE res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
for _,p in ipairs({player1, player2}) do
for _,item in ipairs({"default:dirt", "default:pick_steel"}) do
assert(p:get_inventory():contains_item("main", item))
end
end
end, { players= { "player1", "player2" }})
factions_ext.register_test("Give item to players", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_admin"]= true })
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
local player1 = minetest.get_player_by_name("player1")
local player2 = minetest.get_player_by_name("player2")
assert(player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['give'].func("test", "give", nil, "testfaction default:stone 30")
if not res then minetest.debug("GIVE res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
for _,p in ipairs({player1, player2}) do
assert(p:get_inventory():contains_item("main", ItemStack("default:stone 30"), true))
end
end, { players= { "player1", "player2" }})
factions_ext.register_test("empty inventory faction", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_admin"]= true })
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
local player1 = minetest.get_player_by_name("player1")
local player2 = minetest.get_player_by_name("player2")
assert(player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['give'].func("test", "give", nil, "testfaction ichi")
if not res then minetest.debug("GIVE res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
res, msg = factions_ext.subcommands_registry['empty_inventory'].func("test", "empty_inventory", nil, "testfaction")
if not res then minetest.debug("EMPTY_INVENTORY res : ", res, msg) end
assert(res)
assert(player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
end, { players= { "player1", "player2" }})
factions_ext.register_test("empty inventory player", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_admin"]= true })
local player1 = minetest.get_player_by_name("player1")
assert(player1:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['give'].func("test", "give", nil, "testfaction ichi")
if not res then minetest.debug("GIVE res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
res, msg = factions_ext.subcommands_registry['empty_inventory'].func("test", "empty_inventory", nil, "player1")
if not res then minetest.debug("EMPTY_INVENTORY res : ", res, msg) end
assert(res)
assert(player1:get_inventory():is_empty("main"))
end, { players= { "player1", "player2" }})
factions_ext.register_test("empty inventory faction member", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_admin"]= true })
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
local player1 = minetest.get_player_by_name("player1")
local player2 = minetest.get_player_by_name("player2")
assert(player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['give'].func("test", "give", nil, "testfaction ichi")
if not res then minetest.debug("GIVE res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
res, msg = factions_ext.subcommands_registry['empty_inventory'].func("test", "empty_inventory", nil, "player1")
if not res then minetest.debug("EMPTY_INVENTORY res : ", res, msg) end
assert(res)
assert(player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
end, { players= { "player1", "player2" }})
factions_ext.register_test("empty inventory faction owner", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_admin"]= true })
minetest.set_player_privs("player1", { ["playerfactions_give_ichi"]= true })
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
local player1 = minetest.get_player_by_name("player1")
local player2 = minetest.get_player_by_name("player2")
assert(player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['give'].func("player1", "give", nil, "testfaction and_me ichi")
if not res then minetest.debug("GIVE res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
res, msg = factions_ext.subcommands_registry['empty_inventory'].func("player1", "empty_inventory", nil, "player2")
if not res then minetest.debug("EMPTY_INVENTORY res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
end, { players= { "player1", "player2" }})
factions_ext.register_test("empty inventory faction owner himself", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_admin"]= true })
minetest.set_player_privs("player1", { ["playerfactions_give_ichi"]= true })
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
local player1 = minetest.get_player_by_name("player1")
local player2 = minetest.get_player_by_name("player2")
assert(player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['give'].func("player1", "give", nil, "testfaction and_me ichi")
if not res then minetest.debug("GIVE res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
res, msg = factions_ext.subcommands_registry['empty_inventory'].func("player1", "empty_inventory", nil, "player1")
if not res then minetest.debug("EMPTY_INVENTORY res : ", res, msg) end
assert(res)
assert(player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
end, { players= { "player1", "player2" }})
factions_ext.register_test("empty inventory faction owner faction", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_admin"]= true })
minetest.set_player_privs("player1", { ["playerfactions_give_ichi"]= true })
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
local player1 = minetest.get_player_by_name("player1")
local player2 = minetest.get_player_by_name("player2")
assert(player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['give'].func("player1", "give", nil, "testfaction and_me ichi")
if not res then minetest.debug("GIVE res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
res, msg = factions_ext.subcommands_registry['empty_inventory'].func("player1", "empty_inventory", nil, "testfaction")
if not res then minetest.debug("EMPTY_INVENTORY res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main")) -- !!!!!!!!!!! expected ???
assert(player2:get_inventory():is_empty("main"))
end, { players= { "player1", "player2" }})
factions_ext.register_test("Equip players", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_admin"]= true })
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
local player1 = minetest.get_player_by_name("player1")
local player2 = minetest.get_player_by_name("player2")
assert(player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['give'].func("test", "give", nil, "testfaction default:stone 30")
if not res then minetest.debug("GIVE res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
for _,p in ipairs({player1, player2}) do
assert(p:get_inventory():contains_item("main", ItemStack("default:stone 30"), true))
end
res, msg = factions_ext.subcommands_registry['equip'].func("test", "equip", nil, "testfaction ichi")
if not res then minetest.debug("EQUIP res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
for _,p in ipairs({player1, player2}) do
assert(not p:get_inventory():contains_item("main", ItemStack("default:stone")))
for _,item in ipairs({"default:dirt", "default:pick_steel"}) do
assert(p:get_inventory():contains_item("main", item))
end
end
end, { players= { "player1", "player2" }})
factions_ext.register_test("Equip players item", function()
minetest.set_player_password("test", minetest.get_password_hash("test", "pwrd"))
minetest.set_player_privs("test", { ["playerfactions_admin"]= true })
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
local player1 = minetest.get_player_by_name("player1")
local player2 = minetest.get_player_by_name("player2")
assert(player1:get_inventory():is_empty("main"))
assert(player2:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['give'].func("test", "give", nil, "testfaction default:stone 30")
if not res then minetest.debug("GIVE res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
for _,p in ipairs({player1, player2}) do
assert(not p:get_inventory():contains_item("main", ItemStack("default:dirt")))
assert(p:get_inventory():contains_item("main", ItemStack("default:stone 30"), true))
end
res, msg = factions_ext.subcommands_registry['equip'].func("test", "equip", nil, "testfaction default:dirt")
if not res then minetest.debug("EQUIP res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(not player2:get_inventory():is_empty("main"))
for _,p in ipairs({player1, player2}) do
assert(p:get_inventory():contains_item("main", ItemStack("default:dirt")))
assert(not p:get_inventory():contains_item("main", ItemStack("default:stone")))
end
end, { players= { "player1", "player2" }})
factions_ext.register_test("Giveme package", function()
minetest.set_player_privs("player1", { ["playerfactions_admin"]= true })
local player1 = minetest.get_player_by_name("player1")
assert(player1:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['giveme'].func("player1", "giveme", nil, "ichi")
if not res then minetest.debug("GIVEME res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
for _,item in ipairs({"default:dirt", "default:pick_steel"}) do
assert(player1:get_inventory():contains_item("main", item))
end
end, { players= { "player1", "player2" }})
factions_ext.register_test("Giveme item", function()
minetest.set_player_privs("player1", { ["playerfactions_admin"]= true })
local player1 = minetest.get_player_by_name("player1")
assert(player1:get_inventory():is_empty("main"))
local res, msg = factions_ext.subcommands_registry['giveme'].func("player1", "giveme", nil, "default:stone 30")
if not res then minetest.debug("GIVEME res : ", res, msg) end
assert(res)
assert(not player1:get_inventory():is_empty("main"))
assert(player1:get_inventory():contains_item("main", ItemStack("default:stone 30"), true))
end, { players= { "player1", "player2" }})

View File

@ -4,7 +4,8 @@ factions_ext.register_test = test_harness.get_test_registrator("playerfactions_e
for _, name in ipairs({
"base",
"teleport"
"teleport",
"give"
}) do
dofile(minetest.get_modpath("playerfactions_ext") .. "/test/" .. name .. ".lua")
end

View File

@ -4,8 +4,8 @@ factions_ext.register_test("teleport ok", function()
-- create faction
local owned_factions = factions.get_owned_factions("player1")
assert(not owned_factions or #owned_factions == 0)
factions_ext.subcommands_registry['create'].func("player1", nil, nil, "create testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", nil, nil, "join testfaction foobar")
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
owned_factions = factions.get_owned_factions("player1")
assert(#owned_factions == 1)
@ -16,7 +16,7 @@ factions_ext.register_test("teleport ok", function()
privs.playerfactions_teleport = true
minetest.set_player_privs("player1", privs)
local res, msg = factions_ext.subcommands_registry['teleport'].func("player1", nil, nil, "teleport testfaction 100,100,100")
local res, msg = factions_ext.subcommands_registry['teleport'].func("player1", "teleport", nil, "testfaction 100,100,100")
assert(res)
assert(vector.distance(vector.new(100,100,100), player1:get_pos()) < 2)
@ -24,14 +24,14 @@ factions_ext.register_test("teleport ok", function()
assert(vector.distance(player1:get_pos(), player2:get_pos()) < 2)
-- disband
factions_ext.subcommands_registry['disband'].func("player1", nil, nil, "disband foobar testfaction")
factions_ext.subcommands_registry['disband'].func("player1", "disband", nil, "foobar testfaction")
end, { players= {"player1", "player2"}})
factions_ext.register_test("teleport ko not owner", function()
factions_ext.subcommands_registry['create'].func("player1", nil, nil, "create testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", nil, nil, "join testfaction foobar")
factions_ext.subcommands_registry['create'].func("player1", "create", nil, "testfaction foobar")
factions_ext.subcommands_registry['join'].func("player2", "join", nil, "testfaction foobar")
local player1 = minetest.get_player_by_name("player1")
local player2 = minetest.get_player_by_name("player2")
@ -42,17 +42,17 @@ factions_ext.register_test("teleport ko not owner", function()
local privs = minetest.get_player_privs("player1")
privs.playerfactions_teleport = true
minetest.set_player_privs("player1", privs)
local privs = minetest.get_player_privs("player2")
privs = minetest.get_player_privs("player2")
privs.playerfactions_teleport = true
minetest.set_player_privs("player2", privs)
local res, msg = factions_ext.subcommands_registry['teleport'].func("player2", nil, nil, "teleport testfaction 100,100,100")
local res, msg = factions_ext.subcommands_registry['teleport'].func("player2", "teleport", nil, "testfaction 100,100,100")
assert(not res)
assert(vector.distance(player1_pos, player1:get_pos()) < 2)
assert(vector.distance(player2_pos, player2:get_pos()) < 2)
factions_ext.subcommands_registry['disband'].func("player1", nil, nil, "disband foobar testfaction")
factions_ext.subcommands_registry['disband'].func("player1", "disband", nil, "foobar testfaction")
end, { players= {"player1", "player2"}})

View File

@ -23,7 +23,7 @@ factions_ext.summarize_iteration = function (names_by_outcome)
end
-- Will block unless recipients belong to owned faction or caller is unej_admin or playerfactions_admin
-- Will block unless recipients belong to owned faction or caller is playerfactions_admin
factions_ext.provision_player_names = function(name, query)
if minetest.player_exists(query) then
if name == query or minetest.check_player_privs(name, factions.priv) then
@ -32,7 +32,7 @@ factions_ext.provision_player_names = function(name, query)
for _, faction in pairs(factions.get_administered_factions(name) or {}) do
if factions.player_is_in_faction(faction, query) then return { [query] = true } end
end
return nil, S("@1 is query)not a member of any faction you own.", query)
return nil, S("@1 not a member of any faction you own.", query)
end
local facts = factions.get_facts()
if not facts then return nil, S("Could not find player or faction named @1, no factions", query) end
@ -51,3 +51,80 @@ factions_ext.register_outcome = function(names_by_outcome, name, outcome)
names_by_outcome[outcome] = { name }
end
end
-- Will block unless recipients belong to owned faction or caller is playerfactions_admin
factions_ext.provision_player_names = function(name, query)
if minetest.player_exists(query) then
if name == query or minetest.check_player_privs(name, factions.priv) then
return { [query] = true }
end
for _, faction in pairs(factions.get_administered_factions(name) or {}) do
if factions.player_is_in_faction(faction, query) then return { [query] = true } end
end
return nil, S("@1 is not a member of any faction you own.", query)
end
local facts = factions.get_facts()
if not facts then return nil, S("Could not find player or faction named @1, no factions", query) end
local query_faction = facts[query]
if not query_faction then return nil, S("Could not find player or faction named @1", query) end
if minetest.check_player_privs(name, factions.priv) or query_faction.owner == name then
return query_faction.members
end
return nil, S("You do not own faction @1.",query)
end
-- Returns true, extra parameters on success or false, reason on failure
factions_ext.process_names = function(name, params, command_name)
local targets, next_params = string.match(params, "([%S]+)[%s]*(.*)")
if not targets then return false, S("Invalid parameters (see /help factions @1)", command_name) end
local player_names, reason = factions_ext.provision_player_names(name, targets)
if not player_names then return false, reason end
local and_me, extra_params = string.match(next_params, "(and_me)[%s]*(.*)")
if and_me then
next_params = extra_params
elseif targets ~= name then
player_names[name] = nil
end
return player_names, next_params
end
factions_ext.open_file = function(path, warn)
warn = (warn==nil) or warn
local file = io.open(path,"r")
if not file then
if warn then
minetest.log("warning","factions -!- failed opening " .. path .. ".")
end
return false
end
local content = file:read("*all")
file:close()
local data = minetest.parse_json(content)
if not data then
minetest.log("error","factions -!- Failed to convert json to table " .. path .. "\nCheck that this file is a json file.")
return false
end
return data
end
-- follow keys in nested subtables of json data
factions_ext.table_nested_value = function(data, ...)
for _, key in ipairs{...} do data = (data or {})[key] end
return data
end
factions_ext.write_file = function(path, data)
local file = io.open(path,"w+")
if not file then
return false
end
file:write(minetest.write_json(data,true))
file:close()
return true
end
factions_ext.remove_prefix = function(str, prefix)
return string.gsub(str, "^%s*"..prefix.."%s*", "", 1)
end