2016-09-17 21:18:36 +02:00
--[[
2020-01-31 05:23:25 +01:00
-- Metadata Tools
2015-04-05 22:13:32 +02:00
--
2020-01-31 05:23:25 +01:00
-- A mod providing write and read access to a nodes' metadata using commands
2022-04-17 05:44:51 +02:00
-- (c) 2015-2016 ßÿ Lymkwi/LeMagnesium/Mg and Paly2; (c) 2017-2022 Poikilos
-- License: [CC0](https://creativecommons.org/share-your-work/public-domain/cc0/)
2016-09-17 21:18:36 +02:00
--
2020-01-31 05:23:25 +01:00
-- Version: Poikilos fork of 1.2.2
2016-09-17 21:18:36 +02:00
--
] ] --
2015-04-05 22:13:32 +02:00
2022-04-28 03:47:24 +02:00
local function isArray ( t )
2022-04-28 03:49:17 +02:00
-- Check if a table only contains sequential values.
-- by kikito
-- [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)
-- answered May 21, 2011 at 7:22
-- edited Mar 2, 2014 at 17:13
-- <https://stackoverflow.com/a/6080274/4541104>
local i = 0
for _ in pairs ( t ) do
i = i + 1
if t [ i ] == nil then return false end
end
return true
2022-04-28 03:47:24 +02:00
end
function yamlSerializeTable ( val , name , depth )
2022-04-28 03:49:17 +02:00
-- Make a table into a string.
-- (c) 2011 Henrik Ilgen, 2022 Poikilos
-- [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)
-- answered May 21 '11 at 12:14 Henrik Ilgen
-- edited May 13, 2019 at 9:10
-- on <https://stackoverflow.com/a/6081639>
-- Only the first argument is required.
-- Get the object back from the string via:
-- a = loadstring(s)()
depth = depth or 0
2022-04-28 03:47:24 +02:00
2022-04-28 03:49:17 +02:00
local tmp = string.rep ( " " , depth )
2022-04-28 03:47:24 +02:00
2022-04-28 03:49:17 +02:00
if name then
if name == " METATOOLS_ARRAY_ELEMENT " then
tmp = tmp .. " - "
else
tmp = tmp .. name .. " : "
end
end
2022-04-28 03:47:24 +02:00
2022-04-28 03:49:17 +02:00
if type ( val ) == " table " then
if isArray ( val ) then
tmp = tmp .. " \n "
for k , v in pairs ( val ) do
tmp = tmp .. yamlSerializeTable ( v , " METATOOLS_ARRAY_ELEMENT " , depth + 1 ) .. " \n "
end
-- tmp = tmp .. string.rep(" ", depth)
else
tmp = tmp .. " \n " -- Newline is after <name>: for tables.
for k , v in pairs ( val ) do
tmp = tmp .. yamlSerializeTable ( v , k , depth + 1 ) .. " \n "
end
-- tmp = tmp .. string.rep(" ", depth)
end
elseif type ( val ) == " number " then
tmp = tmp .. tostring ( val )
elseif type ( val ) == " string " then
tmp = tmp .. string.format ( " %q " , val )
elseif type ( val ) == " boolean " then
tmp = tmp .. ( val and " true " or " false " )
else
tmp = tmp .. " \" [inserializeable datatype: " .. type ( val ) .. " ] \" "
end
return tmp
2022-04-28 03:47:24 +02:00
end
2021-11-29 01:03:22 +01:00
function serializeTable ( val , name , skipnewlines , depth )
2022-04-28 03:49:17 +02:00
-- Make a table into a string.
-- (c) 2011 Henrik Ilgen
-- [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)
-- answered May 21 '11 at 12:14 Henrik Ilgen
-- edited May 13, 2019 at 9:10
-- on <https://stackoverflow.com/a/6081639>
-- Only the first argument is required.
-- Get the object back from the string via:
-- a = loadstring(s)()
skipnewlines = skipnewlines or false
depth = depth or 0
2021-11-29 01:03:22 +01:00
2022-04-28 03:49:17 +02:00
local tmp = string.rep ( " " , depth )
2021-11-29 01:03:22 +01:00
2022-04-28 03:49:17 +02:00
if name then tmp = tmp .. name .. " = " end
2021-11-29 01:03:22 +01:00
2022-04-28 03:49:17 +02:00
if type ( val ) == " table " then
tmp = tmp .. " { " .. ( not skipnewlines and " \n " or " " )
2021-11-29 01:03:22 +01:00
2022-04-28 03:49:17 +02:00
for k , v in pairs ( val ) do
tmp = tmp .. serializeTable ( v , k , skipnewlines , depth + 1 ) .. " , " .. ( not skipnewlines and " \n " or " " )
end
2021-11-29 01:03:22 +01:00
2022-04-28 03:49:17 +02:00
tmp = tmp .. string.rep ( " " , depth ) .. " } "
elseif type ( val ) == " number " then
tmp = tmp .. tostring ( val )
elseif type ( val ) == " string " then
tmp = tmp .. string.format ( " %q " , val )
elseif type ( val ) == " boolean " then
tmp = tmp .. ( val and " true " or " false " )
else
tmp = tmp .. " \" [inserializeable datatype: " .. type ( val ) .. " ] \" "
end
2021-11-29 01:03:22 +01:00
2022-04-28 03:49:17 +02:00
return tmp
2021-11-29 01:03:22 +01:00
end
2020-01-31 05:23:25 +01:00
local function token_indices ( haystack , needle )
local results = { }
for i = 1 , # haystack do
local try = haystack : sub ( i , i + needle : len ( ) - 1 )
if try == needle then
table.insert ( results , i )
end
end
return results
end
local function split_and_keep_token ( s , needle )
local results = { }
local indices = token_indices ( s , needle )
local start = 1
for k , v in pairs ( indices ) do
table.insert ( results , s : sub ( start , v ) )
start = v + 1
end
if start < # s then
table.insert ( results , s : sub ( start ) )
end
return results
end
local function delimit ( table , tab , delimiter )
if not tab then
tab = " "
end
if not table then
return tab .. " nil "
end
if not delimiter then
delimiter = " "
end
local ret = " "
if delimiter ~= " \n " then
ret = tab
end
for k , v in pairs ( table ) do
if delimiter == " \n " then
ret = ret .. tab .. k .. " : " .. v .. " \n "
else
ret = ret .. k .. " : " .. v .. " \n "
end
end
return ret
end
local function delimit_sequence ( table , tab , delimiter )
if not tab then
tab = " "
end
if not table then
return tab .. " nil "
end
if not delimiter then
delimiter = " "
end
local ret = " "
if delimiter ~= " \n " then
ret = tab
end
for k , v in pairs ( table ) do
if delimiter == " \n " then
ret = ret .. tab .. v .. delimiter
else
ret = ret .. v .. delimiter
end
end
return ret
end
local function send_messages_sequence ( username , table , tab )
if not tab then
tab = " "
end
if not table then
minetest.chat_send_player ( username , tab .. " nil " )
return
end
for k , v in pairs ( table ) do
minetest.chat_send_player ( username , tab .. v .. " , " )
end
end
local function inv_to_tables ( inv )
-- see bones mod
results = { }
for i = 1 , inv : get_size ( " main " ) do
local stk = inv : get_stack ( " main " , i )
table.insert ( results , stk : to_table ( ) )
-- to_table shows everything:
-- meta:
-- metadata: ""
-- count:1
-- name:"default:sapling"
-- wear:0
end
return results
end
local function inv_to_table ( inv , blank )
-- see bones mod
2021-04-14 01:06:24 +02:00
local results = { }
2020-01-31 05:23:25 +01:00
for i = 1 , inv : get_size ( " main " ) do
local stk = inv : get_stack ( " main " , i )
local stk_s = stk : to_string ( )
if # stk_s > 0 or blank then
table.insert ( results , stk_s )
end
end
return results
end
2020-01-31 18:48:49 +01:00
local function send_messages ( username , table , tab , blank )
2020-01-31 05:23:25 +01:00
if not tab then
tab = " "
end
if not table then
minetest.chat_send_player ( username , tab .. " nil " )
return
end
for k , v in pairs ( table ) do
2020-01-31 18:48:49 +01:00
if blank or ( ( v ~= nil ) and ( dump ( v ) ~= " " ) and ( dump ( v ) ~= " \" \" " ) ) then
if type ( v ) == " table " then
minetest.chat_send_player ( username , tab .. k .. " : " )
send_messages ( username , v , tab .. " \t " )
elseif k == " formspec " then
minetest.chat_send_player ( username , tab .. k .. " : " )
local chunks = split_and_keep_token ( v , " ] " )
send_messages_sequence ( username , chunks , tab .. " \t " )
else
minetest.chat_send_player ( username , tab .. k .. " : " .. dump ( v ) )
end
2020-01-31 05:23:25 +01:00
end
end
end
2019-06-06 22:27:29 +02:00
local function get_nodedef_field ( nodename , fieldname )
if not minetest.registered_nodes [ nodename ] then
-- print("metatools.get_nodedef_field: no registered node named " .. nodename)
return nil
end
-- print("metatools.get_nodedef_field: checking " .. nodename .. " for " .. fieldname .. " in " .. dump(minetest.registered_nodes[nodename]))
-- print("* result:" .. dump(minetest.registered_nodes[nodename][fieldname]))
return minetest.registered_nodes [ nodename ] [ fieldname ]
end
2016-09-17 21:18:36 +02:00
metatools = { } -- Public namespace
2016-09-20 17:19:28 +02:00
metatools.contexts = { }
2016-09-20 18:28:56 +02:00
metatools.playerlocks = { } -- Selection locks of the players
local version = " 1.2.2 "
2016-09-18 21:31:41 +02:00
local nodelock = { }
2015-04-05 22:13:32 +02:00
2016-09-19 18:54:13 +02:00
local modpath = minetest.get_modpath ( " metatools " )
dofile ( modpath .. " /assertions.lua " )
2019-06-05 20:52:46 +02:00
dofile ( modpath .. " /chatcommands.lua " )
2016-09-19 18:54:13 +02:00
2015-04-05 22:13:32 +02:00
minetest.register_craftitem ( " metatools:stick " , {
description = " Meta stick " ,
inventory_image = " metatools_stick.png " ,
2021-11-29 01:03:22 +01:00
stack_max = 1 ,
2015-04-05 22:13:32 +02:00
on_use = function ( itemstack , user , pointed_thing )
local username = user : get_player_name ( )
2019-06-06 22:27:29 +02:00
local userpos = user : get_pos ( )
2021-11-29 01:03:22 +01:00
if pointed_thing.type == " nothing " then
minetest.chat_send_player (
username ,
" [metatools::stick] You pointed at nothing. "
)
return
2022-04-13 17:56:17 +02:00
elseif pointed_thing.type == " object " then
2021-11-29 01:03:22 +01:00
local pointedObjRef = pointed_thing.ref
-- local objAsStr = minetest.serialize(pointedObjRef)
-- ^ if param is pointed_thing or pointed_thing.ref, minetest.serialize causes "2021-11-14 16:45:39: ERROR[Main]: ServerError: AsyncErr: ServerThread::run Lua: Runtime error from mod 'metatools' in callback item_OnUse(): /home/owner/minetest/bin/../builtin/common/serialize.lua:151: Can't serialize data of type userdata"
2022-04-28 03:47:24 +02:00
-- - even yamlSerializeTable returns [inserializeable datatype:userdata]
2021-11-29 01:03:22 +01:00
-- unrelated note: minetest.serialize(nil) returns "return nil"
-- TODO:
-- Show ObjectRef armor groups (See <https://git.minetest.org/minetest/minetest/src/branch/master/doc/lua_api.txt#L1825>)
-- documentation for ObjectRef: <https://git.minetest.org/minetest/minetest/src/branch/master/doc/lua_api.txt#L1825>
2022-04-28 03:47:24 +02:00
local objAsStr = yamlSerializeTable ( pointedObjRef )
2021-11-29 01:03:22 +01:00
minetest.chat_send_player (
username ,
2022-04-13 21:18:44 +02:00
" [metatools::stick] You pointed at an object ( " .. objAsStr .. " ) "
2021-11-29 01:03:22 +01:00
)
local pointedObjRef = pointed_thing.ref
2022-04-13 21:18:44 +02:00
-- if pointed_thing.ref.get_hp then
2021-11-29 01:03:22 +01:00
minetest.chat_send_player (
username ,
2022-04-13 21:18:44 +02:00
" [metatools::stick] pointed_thing.ref:get_hp(): " .. pointedObjRef : get_hp ( )
2021-11-29 01:03:22 +01:00
)
2022-04-13 21:18:44 +02:00
-- end
2022-04-13 17:56:17 +02:00
-- minetest.log("action", "[metatools] You pointed at an object: " .. objAsStr)
local luaEntity = pointedObjRef : get_luaentity ( )
2022-04-13 21:18:44 +02:00
-- INFO: For player name, use user:get_player_name()
2022-04-13 17:56:17 +02:00
minetest.chat_send_player (
username ,
" [metatools::stick] LuaEntity name: " .. luaEntity.name
)
-- ^ This is the entity name such as namespace:sheep_black where namespace is a mod name.
minetest.chat_send_player (
username ,
2022-04-28 03:47:24 +02:00
" [metatools::stick] LuaEntity: " .. yamlSerializeTable ( luaEntity )
)
local animation = pointedObjRef : get_animation ( )
minetest.chat_send_player (
username ,
" [metatools::stick] LuaEntity.ref:get_animation(): " .. yamlSerializeTable ( animation )
2022-04-13 17:56:17 +02:00
)
2022-04-28 03:47:24 +02:00
-- Hmm, animation.range, animation['range'] are nil
-- (same for other variables),
-- so API documentation is unclear:
-- `get_animation()`: returns `range`, `frame_speed`, `frame_blend` and
2022-04-28 03:49:17 +02:00
-- `frame_loop`.
-- yamlSerializeTable(animation) only gets:
-- y: 65
-- x: 35
2022-04-28 03:47:24 +02:00
-- minetest.chat_send_player(
-- username,
-- yamlSerializeTable(animation.range, " range")
-- )
2022-04-13 17:56:17 +02:00
-- else type is usually "node"
2021-11-29 01:03:22 +01:00
end
2015-04-05 22:13:32 +02:00
local nodepos = pointed_thing.under
2021-11-29 01:03:22 +01:00
-- > * `under` refers to the node position behind the pointed face
-- > * `above` refers to the node position in front of the pointed face.
-- -<https://git.minetest.org/minetest/minetest/src/branch/master/doc/lua_api.txt>
2015-04-18 13:47:21 +02:00
if not nodepos or not minetest.get_node ( nodepos ) then return end
2015-04-05 22:13:32 +02:00
local nodename = minetest.get_node ( nodepos ) . name
2020-01-31 05:23:25 +01:00
local node = minetest.registered_nodes [ nodename ]
local meta = minetest.get_meta ( nodepos )
2015-04-05 22:13:32 +02:00
local metalist = meta : to_table ( )
2019-06-06 22:27:29 +02:00
minetest.chat_send_player (
username ,
" [metatools::stick] You pointed at the ' " .. nodename .. " ': "
)
minetest.chat_send_player (
username ,
" [metatools::stick] pos: "
.. minetest.pos_to_string ( nodepos )
)
-- minetest.chat_send_player(
-- username,
-- "[metatools::stick] drawtype:"
-- .. get_nodedef_field(nodename, "drawtype")
-- )
-- minetest.chat_send_player(
-- username,
-- "[metatools::stick] sunlight_propagates:"
-- .. (get_nodedef_field(nodename, "sunlight_propagates") and 'true' or 'false')
-- )
2021-04-14 01:06:24 +02:00
if # metalist > 0 then
2020-01-31 18:53:07 +01:00
minetest.chat_send_player (
username ,
" [metatools::stick] metadata: "
--.. delimit(meta:to_table()["fields"], "", "\n")
)
2021-04-14 01:06:24 +02:00
send_messages ( username , metalist )
2020-01-31 18:53:07 +01:00
-- send_messages(username, meta:to_table()["fields"])
-- minetest.chat_send_player(
-- username,
-- "[metatools::stick] inventory: "
-- --.. delimit(meta:to_table()["fields"], "", "\n")
-- )
end
2020-01-31 05:23:25 +01:00
if meta [ " get_inventory " ] then
local inventory = meta : get_inventory ( )
if inventory then -- this is never true for some reason
2020-01-31 18:53:07 +01:00
local this_inv_table = inv_to_table ( inventory , true )
if # this_inv_table > 0 then
minetest.chat_send_player ( username , " get_inventory(): " )
2021-04-14 01:13:27 +02:00
send_messages ( username , this_inv_table , " " )
2020-01-31 18:53:07 +01:00
end
2020-01-31 18:48:49 +01:00
-- else
-- minetest.chat_send_player(username, "\tnil")
2020-01-31 05:23:25 +01:00
end
2020-01-31 18:48:49 +01:00
-- else
-- minetest.chat_send_player(username, "get_inventory:nil")
2020-01-31 05:23:25 +01:00
end
2021-11-29 01:03:22 +01:00
-- node is nil at this point if the node is an "unknown node"!
if node and node.frame_contents then
2021-04-14 01:26:27 +02:00
-- frames mod
2021-04-14 01:13:27 +02:00
local frame_contents = node.frame_contents
if frame_contents then
minetest.chat_send_player ( username , " frame_contents: " .. frame_contents )
-- else
-- minetest.chat_send_player(username, "\tnil")
end
-- else
-- minetest.chat_send_player(username, "get_inventory:nil")
end
2021-04-14 01:26:27 +02:00
if meta : get_string ( " item " ) ~= " " then
-- itemframes mod or xdecor:itemframe
local frame_contents = meta : get_string ( " item " )
if frame_contents then
minetest.chat_send_player ( username , " meta item: " .. frame_contents )
-- else
-- minetest.chat_send_player(username, "\tnil")
end
-- else
-- minetest.chat_send_player(username, "get_inventory:nil")
end
2019-06-06 22:27:29 +02:00
local airname = minetest.get_name_from_content_id ( minetest.CONTENT_AIR )
-- local litnode = nil
local litpos = nil
local litdist = nil
local litwhy = " unknown "
local litmsg = " "
local litid = nil
local litwhat = nil
local litindent = " "
local foundPointed = false
local offsets = {
[ 0 ] = { [ " x " ] = 0 , [ " y " ] = 0 , [ " z " ] = 0 } ,
[ 1 ] = { [ " x " ] = 0 , [ " y " ] = 1 , [ " z " ] = 0 } ,
[ 2 ] = { [ " x " ] = 0 , [ " y " ] = - 1 , [ " z " ] = 0 } ,
[ 3 ] = { [ " x " ] = 1 , [ " y " ] = 0 , [ " z " ] = 0 } ,
[ 4 ] = { [ " x " ] = - 1 , [ " y " ] = 0 , [ " z " ] = 0 } ,
[ 5 ] = { [ " x " ] = 0 , [ " y " ] = 0 , [ " z " ] = 1 } ,
[ 6 ] = { [ " x " ] = 0 , [ " y " ] = 0 , [ " z " ] = - 1 } ,
}
-- local touching = {}
for key , value in pairs ( offsets ) do
local trydist = nil
local trywhy = nil
local trypos = vector.new (
nodepos.x + value.x ,
nodepos.y + value.y ,
nodepos.z + value.z
)
-- touching[key] = trypos
local trynode = minetest.get_node ( trypos )
local tryid = nil
local tryname = nil
if ( trynode ) then
tryname = trynode.name
tryid = minetest.get_content_id ( tryname )
2020-01-31 05:23:25 +01:00
-- print("tryname:" .. tryname)
-- print("trynode.name:" .. trynode.name)
2019-06-06 22:27:29 +02:00
-- if (tryid == minetest.CONTENT_AIR) then
if trynode.name == airname then
-- found:
if ( userpos ) then
trydist = vector.distance ( userpos , trypos )
else
-- dummy value for "found" state:
trydist = vector.distance ( nodepos , trypos )
end
trywhy = " air "
else
-- local trygroup = minetest.get_item_group(trynode.name, "air")
-- local drawtype = get_nodedef_field(tryname, "drawtype")
if ( get_nodedef_field ( tryname , " drawtype " ) == " airlike " ) then
trywhy = " airlike "
elseif ( get_nodedef_field ( tryname , " sunlight_propagates " ) == true ) then
trywhy = " sunlight_propagates "
else
trynode = nil
-- print("[metatools::stick] " .. key .. ": "..tryname.." is not airlike, no sunlight_propagates")
end
if ( trynode ) then
-- found:
if ( userpos ) then
trydist = vector.distance ( userpos , trypos )
else
-- dummy value for "found" state:
trydist = vector.distance ( nodepos , trypos )
end
end
-- if trydef.sunlight_propagates
end
else
trywhy = " non-node "
-- (non-node pos should work for the later light check)
-- found:
if ( userpos ) then
trydist = vector.distance ( userpos , trypos )
else
-- dummy value for "found" state:
trydist = vector.distance ( nodepos , trypos )
end
end
if ( trydist ) then
if ( litpos == nil ) or ( trydist < litdist ) then
litdist = trydist
litpos = trypos
litid = tryid -- nil if trywhy == "non-node"
litwhy = trywhy
if ( key > 0 ) then
litwhat = " neighbor: "
litindent = " "
else
foundPointed = true
-- is the pointed node
break -- always use pointed node if lightable
end
end
end
end
local nodelightsource = get_nodedef_field ( nodename , " light_source " )
if ( nodelightsource ) and ( nodelightsource > 0 ) then
if not foundPointed then
litmsg = " # next to pointed light_source= " .. nodelightsource
end
end
-- litnode = minetest.find_node_near(nodepos, 1, minetest.get_name_from_content_id(minetest.CONTENT_AIR))
if ( litpos ) then
if ( litwhat ) then
minetest.chat_send_player (
username ,
" [metatools::stick] nearby lit: # " .. minetest.pos_to_string ( litpos )
)
end
minetest.chat_send_player (
username ,
" [metatools::stick] " .. litindent .. " why lit: " .. litwhy .. litmsg
)
minetest.chat_send_player (
username ,
" [metatools::stick] " .. litindent .. " light: " .. minetest.get_node_light ( litpos )
)
else
minetest.chat_send_player (
username ,
" [metatools::stick] nearby lit: ~ # no air/propogator for determining lighting "
)
end
minetest.log ( " action " , " [metatools] Player " .. username .. " saw metadatas of node at " .. minetest.pos_to_string ( nodepos ) )
2015-04-05 22:13:32 +02:00
end ,
} )
2016-09-20 18:28:56 +02:00
-- Useful callbacks
minetest.register_on_dignode ( function ( pos , node , digger )
local spos = minetest.pos_to_string ( pos )
local ctxid = metatools.get_context_from_pos ( pos )
if ctxid then
if not metatools.get_context_owner ( ctxid ) then
metatools.alert_users ( " Node at " .. spos .. " dug by " .. ( digger : get_player_name ( ) or " a drone " ) .. " : context " .. ctxid .. " closed " )
metatools.close_node ( ctxid )
else
local owner = metatools.get_context_owner ( ctxid )
if owner == digger : get_player_name ( ) then
metatools.alert_users ( owner .. " dug themselves out of node at " .. spos .. " : context " .. ctxid .. " closed " )
metatools.close_node ( ctxid )
else
minetest.chat_send_player ( digger : get_player_name ( ) or " " , " - meta - You are not allowed to dig the present node at " .. spos .. " : someone is operating on it " )
minetest.chat_send_player ( metatools.get_context_owner ( ctxid ) , " - meta - " .. digger : get_player_name ( ) .. " tried to dig the node you are operating on " )
return true
end
end
end
end )
2016-09-17 21:18:36 +02:00
-- Functions
function metatools . get_version ( ) return version end
2016-09-20 18:28:56 +02:00
function metatools . get_context_from_pos ( pos )
for id , ctx in pairs ( metatools.contexts ) do
if minetest.pos_to_string ( ctx.position ) == minetest.pos_to_string ( pos ) then
return id
end
end
end
function metatools . alert_users ( msg )
for name , _ in pairs ( metatools.playerlocks ) do
minetest.chat_send_player ( name , ( " - meta::alert - ALERT: %s " ) : format ( msg ) )
end
end
2016-09-17 21:18:36 +02:00
function metatools . build_param_str ( table , index , separator )
local str = table [ index ]
for newindex = 1 , # table - index do
str = str .. ( separator or ' ' ) .. table [ newindex + index ]
end
return str
end
2016-09-19 18:54:13 +02:00
function metatools . get_player_selection ( name )
2016-09-20 18:28:56 +02:00
return metatools.playerlocks [ name ]
2016-09-19 18:54:13 +02:00
end
function metatools . player_select ( name , ctxid )
2016-09-20 18:28:56 +02:00
metatools.playerlocks [ name ] = ctxid
2016-09-19 18:54:13 +02:00
return true , ( " context %d selected " ) : format ( ctxid )
end
function metatools . player_unselect ( name )
2016-09-20 18:28:56 +02:00
metatools.playerlocks [ name ] = nil
2016-09-19 18:54:13 +02:00
return true , " context unselected "
end
function metatools . switch ( contextid )
2016-09-20 17:19:28 +02:00
local ctx = metatools.contexts [ contextid ]
2016-09-19 18:54:13 +02:00
if ctx.mode == " inventory " then
ctx.mode = " fields "
else
ctx.mode = " inventory "
end
ctx.list = " "
return true , " switched to mode " .. ctx.mode
end
function metatools . get_context_owner ( ctxid )
2016-09-20 18:28:56 +02:00
for name , id in pairs ( metatools.playerlocks ) do
2016-09-19 18:54:13 +02:00
if id == ctxid then
return name
end
end
end
2016-09-18 21:31:41 +02:00
function assign_context ( pos , mode , owner )
local i = 1
2016-09-20 17:19:28 +02:00
while metatools.contexts [ i ] do i = i + 1 end
2016-09-17 21:18:36 +02:00
2016-09-20 17:19:28 +02:00
metatools.contexts [ i ] = {
2016-09-18 21:31:41 +02:00
owner = owner or " " ,
position = pos ,
list = " " ,
mode = mode
}
nodelock [ minetest.pos_to_string ( pos ) ] = owner or " "
return i
2016-09-17 21:18:36 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-18 21:31:41 +02:00
function free_context ( contextid )
2016-09-20 17:19:28 +02:00
nodelock [ minetest.pos_to_string ( metatools.contexts [ contextid ] . position ) ] = nil
metatools.contexts [ contextid ] = nil
2016-09-18 21:31:41 +02:00
return true
end
2015-04-05 22:13:32 +02:00
2016-09-19 18:54:13 +02:00
function dump_normalize ( dmp )
return dump ( dmp ) : gsub ( ' \n ' , ' ' ) : gsub ( ' \t ' , ' ' )
2016-09-18 21:31:41 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-19 18:54:13 +02:00
--function meta_assertion(assert_type, params)
2015-04-05 22:13:32 +02:00
2016-09-19 18:54:13 +02:00
function meta_exec ( struct )
if not struct.scope then
struct.scope = " meta "
end
2015-04-05 22:13:32 +02:00
2016-09-19 18:54:13 +02:00
if not struct.func then
return
end
2015-04-05 22:13:32 +02:00
2016-09-19 18:54:13 +02:00
if struct.required then
-- will call meta_assertion from here
for category , req in pairs ( struct.required ) do
if category == " position " and not assert_pos ( req ) then
return false , ( " - %s - Failure : Invalid position : %s " ) : format ( struct.scope , dump_normalize ( req ) )
2019-06-05 20:52:46 +02:00
2016-09-19 18:54:13 +02:00
elseif category == " contextid " and not assert_contextid ( req ) then
return false , ( " - %s - Failutre : Invalid contextid : %s " ) : format ( struct.scope , dump_normalize ( req ) )
2016-09-18 21:31:41 +02:00
2016-09-19 18:54:13 +02:00
elseif category == " no_nodelock " then
if not assert_pos ( req ) then
return false , ( " - %s - Failure : Invalid pos : %s " ) : format ( struct.scope , dump_normalize ( req ) )
end
local npos = req
if type ( npos ) == " table " then
npos = minetest.pos_to_string ( npos )
end
if nodelock [ npos ] then
return false , ( " - %s - Failure : Nodelock on %s " ) : format ( struct.scope , dump_normalize ( req ) )
end
2016-09-18 21:31:41 +02:00
2016-09-19 18:54:13 +02:00
elseif category == " open_mode " and not assert_mode ( req ) then
return false , ( " - %s - Failure : Invalid mode %s " ) : format ( struct.scope , dump_normalize ( req ) )
2016-09-18 21:31:41 +02:00
2016-09-19 18:54:13 +02:00
elseif category == " ownership " then
if type ( req ) ~= " table " or not req.name then
return false , ( " - %s - Failure : Requirement of ownership invalid or missing a 'name' field " ) : format ( struct.scope )
end
2015-04-05 22:13:32 +02:00
2016-09-19 18:54:13 +02:00
if req.contextid then
if not assert_contextid ( req.contextid ) then
return false , ( " - %s - Failure : Invalid context id %s " ) : format ( struct.scope , req.contextid )
end
if not assert_ownership ( req.contextid , req.name ) then
return false , ( " - %s - Failure : Context %d is not owner by %s " ) : format ( struct.scope , req.contextid , req.name )
end
else
return false , ( " - %s - Failure : No context selected " ) : format ( struct.scope )
end
elseif category == " no_ownership " then
if not assert_contextid ( req ) then
return false , ( " - %s - Failure : Invalid context id %s " ) : format ( struct.scope , dump_normalize ( req ) )
elseif metatools.get_context_owner ( req ) then
return false , ( " - %s - Failure : Node already owned " ) : format ( struct.scope )
end
2016-09-18 21:31:41 +02:00
2016-09-20 18:28:56 +02:00
elseif category == " some_ownership " and ( not req or not metatools.playerlocks [ req ] ) then
2016-09-19 18:54:13 +02:00
return false , ( " - %s - Failure : No context owned at the moment " ) : format ( struct.scope )
elseif category == " specific_open_mode " then
if not req or not req.mode or not req.contextid then
return false , ( " - %s - Failure : Invalid specific open mode requirement " ) : format ( struct.scope )
end
if not assert_contextid ( req.contextid ) then
return false , ( " - %s - Failure : Invalid context id : %s " ) : format ( struct.scope , dump_normalize ( req.contextid ) )
end
2019-06-05 20:52:46 +02:00
2016-09-20 17:19:28 +02:00
if not metatools.contexts [ req.contextid ] . mode == req.mode then
2016-09-19 18:54:13 +02:00
return false , ( " - %s - Failure : Invalid mode, %s is required " ) : format ( struct.scope , dump_normalize ( req.mode ) )
end
end
end
end
local ret , msg = struct.func ( unpack ( struct.params ) )
2016-09-18 21:31:41 +02:00
if ret then
2016-09-20 18:28:56 +02:00
if struct.success then
struct.success ( struct.params , { ret , msg } )
end
2016-09-19 18:54:13 +02:00
return true , ( " - %s - Success : %s " ) : format ( struct.scope , msg )
2016-09-18 21:31:41 +02:00
else
2016-09-19 18:54:13 +02:00
return false , ( " - %s - Failure : %s " ) : format ( struct.scope , msg )
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-18 21:31:41 +02:00
function metatools . contexts_summary ( )
local ctxs = { }
2016-09-20 18:28:56 +02:00
for ctxid , ctx in pairs ( metatools.contexts ) do
2016-09-19 18:54:13 +02:00
table.insert ( ctxs , 1 , {
id = ctxid ,
pos = ctx.position ,
owner = metatools.get_context_owner ( ctxid ) or " nobody " ,
mode = ctx.mode ,
} )
2016-09-18 21:31:41 +02:00
end
return true , ctxs
2016-09-17 21:18:36 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-18 21:31:41 +02:00
function metatools . open_node ( pos , mode , owner )
2016-09-19 18:54:13 +02:00
local id = assign_context ( pos , mode )
if owner then
2016-09-20 18:28:56 +02:00
metatools.playerlocks [ owner ] = id
2016-09-18 21:31:41 +02:00
end
2016-09-19 18:54:13 +02:00
return true , " opened node " .. minetest.get_node ( pos ) . name .. " at " .. minetest.pos_to_string ( pos ) .. " in context ID " .. id
2016-09-17 21:18:36 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-18 21:31:41 +02:00
function metatools . close_node ( contextid ) --, closer)
free_context ( contextid )
return true , " node closed "
2016-09-17 21:18:36 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-18 21:31:41 +02:00
function metatools . show ( contextid )
2016-09-20 18:28:56 +02:00
if not assert_contextid ( contextid ) then
return false , " invalid or missing context id "
end
2016-09-20 17:19:28 +02:00
local ctx = metatools.contexts [ contextid ]
2016-09-18 21:31:41 +02:00
local metabase = minetest.get_meta ( ctx.position ) : to_table ( ) [ ctx.mode ]
if assert_specific_mode ( contextid , " inventory " ) and ctx.list ~= " " then
metabase = metabase [ ctx.list ]
2016-09-17 21:18:36 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-18 21:31:41 +02:00
return true , metabase
2016-09-17 21:18:36 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-18 21:31:41 +02:00
function metatools . list_enter ( contextid , listname )
if not assert_contextid ( contextid ) then
return false , " invalid contexid " .. dump_normalize ( contextid )
end
2015-04-05 22:13:32 +02:00
2016-09-18 21:31:41 +02:00
if not assert_specific_mode ( contextid , " inventory " ) then
return false , " invalid mode, inventory mode required "
2016-09-17 21:18:36 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-18 21:31:41 +02:00
if not listname then
return false , " no list name provided "
2016-09-17 21:18:36 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-20 17:19:28 +02:00
local ctx = metatools.contexts [ contextid ]
2016-09-18 21:31:41 +02:00
if ctx.list ~= " " then
return false , " unable to reach another list until leaving the current one "
2016-09-17 21:18:36 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-18 21:31:41 +02:00
local _ , metabase = metatools.show ( contextid )
if not metabase [ listname ] or type ( metabase [ listname ] ) ~= " table " then
return false , " inexistent or invalid list called " .. dump_normalize ( listname )
end
2016-09-20 17:19:28 +02:00
metatools.contexts [ contextid ] . list = listname
2016-09-18 21:31:41 +02:00
return true , " entered list " .. listname
end
function metatools . list_leave ( contextid )
if not assert_contextid ( contextid ) then
return false , " invalid contextid " .. dump_normalize ( contextid )
end
if not assert_specific_mode ( contextid , " inventory " ) then
return false , " invalid mode, inventory mode required "
end
2016-09-20 17:19:28 +02:00
local ctx = metatools.contexts [ contextid ]
2016-09-18 21:31:41 +02:00
if ctx.list == " " then
return false , " cannot leave, not in a list "
2016-09-17 21:18:36 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-18 21:31:41 +02:00
ctx.list = " "
return true , " left list "
2016-09-17 21:18:36 +02:00
end
2015-04-05 22:13:32 +02:00
2016-09-19 18:54:13 +02:00
function metatools . set ( contextid , varname , varval )
2016-09-18 21:31:41 +02:00
if not varname or varname == " " then
return false , " invalid or empty variable name "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
if not varval then
return false , " missing value, use unset to set variable to nil "
end
2016-09-17 21:18:36 +02:00
2016-09-20 17:19:28 +02:00
local ctx = metatools.contexts [ contextid ]
2016-09-18 21:31:41 +02:00
local meta = minetest.get_meta ( ctx.position )
2016-09-19 18:54:13 +02:00
meta : set_string ( varname , ( " %s " ) : format ( varval ) )
2016-09-18 21:31:41 +02:00
return true , " value of field " .. varname .. " set to " .. varval
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
function metatools . unset ( contextid , varname )
if not varname or varname == " " then
return false , " invalid or empty variable name "
end
2016-09-17 21:18:36 +02:00
2016-09-20 17:19:28 +02:00
minetest.get_meta ( metatools.contexts [ contextid ] . position ) : set_string ( varname , nil )
2016-09-18 21:31:41 +02:00
return true , " field " .. varname .. " unset "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
function metatools . purge ( contextid )
2016-09-20 17:19:28 +02:00
local ctx = metatools.contexts [ contextid ]
2016-09-18 21:31:41 +02:00
local meta = minetest.get_meta ( ctx.position )
if ctx.mode == " inventory " then
local inv = meta : get_inventory ( )
2016-09-19 18:54:13 +02:00
inv : set_lists ( { } )
2016-09-18 21:31:41 +02:00
return true , " inventory purged "
2019-06-05 20:52:46 +02:00
2016-09-18 21:31:41 +02:00
else
meta : from_table ( nil )
return true , " fields purged "
end
end
2016-09-17 21:18:36 +02:00
2016-09-19 19:03:49 +02:00
function metatools . prune ( )
2016-09-20 18:28:56 +02:00
for id , ctx in pairs ( metatools.contexts ) do
2016-09-19 19:03:49 +02:00
if not metatools.get_context_owner ( id ) then
metatools.close_node ( id )
end
end
return true , " contexts pruned "
end
2016-09-18 21:31:41 +02:00
function metatools . list_init ( contextid , listname , size )
if not listname or listname == " " then
return false , " missing or empty list name "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
if not size or not assert_integer ( size ) or tonumber ( size ) < 0 then
2016-09-19 18:54:13 +02:00
return false , " invalid size " .. dump_normalize ( size )
2016-09-17 21:18:36 +02:00
end
2016-09-20 17:19:28 +02:00
local inv = minetest.get_meta ( metatools.contexts [ contextid ] . position ) : get_inventory ( )
2016-09-17 21:18:36 +02:00
inv : set_list ( listname , { } )
inv : set_size ( listname , tonumber ( size ) )
2016-09-18 21:31:41 +02:00
return true , " list " .. listname .. " of size " .. size .. " created "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
function metatools . list_delete ( contextid , listname )
if not assert_contextid ( contextid ) then
return false , " invalid context id " .. dump_normalize ( contextid )
end
2016-09-17 21:18:36 +02:00
2016-09-18 21:31:41 +02:00
if not assert_specific_mode ( contextid , " inventory " ) then
return false , " invalid mode, inventory mode is required "
2016-09-17 21:18:36 +02:00
end
if not listname or listname == " " then
2016-09-18 21:31:41 +02:00
return false , " missing or empty list name "
end
2016-09-20 17:19:28 +02:00
local ctx = metatools.contexts [ contextid ]
2016-09-18 21:31:41 +02:00
if ctx.list == listname then
ctx.list = " "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
local inv = minetest.get_meta ( ctx.position ) : get_inventory ( )
inv : set_list ( listname , { } )
2016-09-17 21:18:36 +02:00
inv : set_size ( listname , 0 )
2016-09-18 21:31:41 +02:00
return true , " list " .. listname .. " deleted "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
function metatools . itemstack_erase ( contextid , index )
if not assert_contextid ( contextid ) then
return false , " invalid context id " .. dump_normalize ( contextid )
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
if not assert_specific_mode ( contextid , " inventory " ) then
return false , " invalid mode, inventory mode required "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
if not assert_integer ( index ) or tonumber ( index ) < 0 then
return false , " invalid index "
2016-09-17 21:18:36 +02:00
end
2016-09-20 17:19:28 +02:00
local ctx = metatools.contexts [ contextid ]
2016-09-18 21:31:41 +02:00
if ctx.list == " " then
return false , " your presence is required in a list "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
local inv = minetest.get_meta ( ctx.position ) : get_inventory ( )
if tonumber ( index ) > inv : get_size ( ctx.list ) then
return false , " index value higher than list size "
end
inv : set_stack ( ctx.list , tonumber ( index ) , nil )
return true , " itemstack at index " .. index .. " erased "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
function metatools . itemstack_write ( contextid , index , data )
if not assert_contextid ( contextid ) then
return false , " invalid context id " .. dump_normalize ( contextid )
end
2016-09-17 21:18:36 +02:00
2016-09-18 21:31:41 +02:00
if not assert_specific_mode ( contextid , " inventory " ) then
return false , " invalid mode, inventory mode required "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
if not assert_integer ( index ) or tonumber ( index ) < 0 then
return false , " invalid index "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
local stack = ItemStack ( data )
if not stack then
return false , " invalid itemstack representation " .. dump_normalize ( data )
2016-09-17 21:18:36 +02:00
end
2016-09-20 17:19:28 +02:00
local ctx = metatools.contexts [ contextid ]
2016-09-18 21:31:41 +02:00
if ctx.list == " " then
return false , " your presence is required in a list "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
local inv = minetest.get_meta ( ctx.position ) : get_inventory ( )
if tonumber ( index ) > inv : get_size ( ctx.list ) then
return false , " index value higher than list size "
end
inv : set_stack ( ctx.list , tonumber ( index ) , stack )
return true , " itemstack at index " .. index .. " written "
end
function metatools . itemstack_add ( contextid , data )
if not assert_contextid ( contextid ) then
return false , " invalid context id " .. dump_normalize ( contextid )
end
if not assert_specific_mode ( contextid , " inventory " ) then
return false , " invalid mode, inventory mode required "
2016-09-17 21:18:36 +02:00
end
2016-09-18 21:31:41 +02:00
local stack = ItemStack ( data )
2016-09-17 21:18:36 +02:00
if not stack then
2016-09-18 21:31:41 +02:00
return false , " invalid itemstack representation " .. dump_normalize ( data )
2016-09-17 21:18:36 +02:00
end
2016-09-20 17:19:28 +02:00
local ctx = metatools.contexts [ contextid ]
2016-09-18 21:31:41 +02:00
if ctx.list == " " then
return false , " your presence is required in a list "
end
2016-09-17 21:18:36 +02:00
2016-09-18 21:31:41 +02:00
local inv = minetest.get_meta ( ctx.position ) : get_inventory ( )
inv : add_item ( ctx.list , stack )
return true , " added " .. data .. " in list " .. ctx.list
end
2016-09-17 21:18:36 +02:00
-- Main chat command
minetest.register_chatcommand ( " meta " , {
privs = { server = true } ,
params = " help | version | open (x,y,z) {mode} | show | enter <name> | leave | set <name> <value> | unset <name> | purge | list <init/delete> <name> <size>| itemstack <write/erase> <index> <data> | close " ,
description = " Metadata manipulation command " ,
func = function ( name , paramstr )
-- name : Ingame name of the manipulating player
-- paramstr : string with all parameters
if paramstr == " " then
return true , " - meta - Consult '/meta help' for a better understanding of the meta command "
end
local params = paramstr : split ( ' ' )
-- meta version
if params [ 1 ] == " version " then
return true , " - meta::version - Metatools version " .. metatools.get_version ( )
-- meta help
elseif params [ 1 ] == " help " then
return true , " - meta::help - Help : \n " ..
" - meta::help - /meta version : Prints out the version \n " ..
" - meta::help - /meta help : This very command \n " ..
2016-09-18 21:31:41 +02:00
" - meta::help - /meta open <(x,y,z) [mode] : Open not at (x,y,z) with mode 'mode' (either 'fields' or 'inventory'; default is 'fields') \n " ..
2016-09-20 18:28:56 +02:00
" - meta::help - /meta select <contextid> : Select the node with context <contextid> for operations \n " ..
" - meta::help - /meta unselect : Unselect the context you are currently in \n " ..
" - meta::help - /meta contexts : Show all open contexts with id, operator, position and open mode \n " ..
2016-09-19 18:54:13 +02:00
" - meta::help - /meta switch : Switch open mode in the current context \n " ..
" - meta::help - /meta close : Close the currently selected node \n " ..
2016-09-19 19:03:49 +02:00
" - meta::help - /meta prune : Close all currently unoperated nodes \n " ..
2016-09-19 18:54:13 +02:00
" - meta::help - /meta show : Show you the fields/lists available \n " ..
" - meta::help - /meta set <name> <value> : Set variable 'name' to 'value', overriding any existing data \n " ..
" - meta::help - /meta unset <name> : Set variable 'name' to nil, ignoring whether it exists or not \n " ..
" - meta::help - /meta purge : Purge all metadata variables or inventory lists (depending on the open mode) \n " ..
2016-09-17 21:18:36 +02:00
" - meta::help - /meta list : List manipulation : \n " ..
2016-09-19 18:54:13 +02:00
" - meta::help - /meta list enter <name> : Enter in list <name> \n " ..
" - meta::help - /meta list leave : Go back to the top level of inventory data \n " ..
" - meta::help - /meta list init <name> <size> : Initialize list 'name' of size 'size', overriding any existing data \n " ..
" - meta::help - /meta list delete <name> : Delete list 'name', ignoring whether it exists or not \n " ..
2016-09-17 21:18:36 +02:00
" - meta::help - /meta itemstack : ItemStack manipulation : \n " ..
2016-09-19 18:54:13 +02:00
" - meta::help - /meta itemstack write <index> <data> : Write an itemstack represented by 'data' at index 'index' of the list you are in \n " ..
" - meta::help - /meta itemstack add <data> : Add items of an itemstack represented by 'data' in the list you are in \n " ..
" - meta::help - /meta itemstack erase <index> : Remove itemstack at index 'index' in the current inventory, regardless of whether it exists or not \n " ..
2016-09-17 21:18:36 +02:00
" - meta::help - End of Help "
2016-09-18 21:31:41 +02:00
-- meta context
elseif params [ 1 ] == " contexts " then
local _ , ctxs = metatools.contexts_summary ( )
local retstr = " "
for _ , summ in pairs ( ctxs ) do
2016-09-19 18:54:13 +02:00
retstr = retstr .. ( " - meta::contexts : %d: [%s] Node at %s owner by %s \n " ) :
format ( summ.id , summ.mode , minetest.pos_to_string ( summ.pos ) , summ.owner )
2016-09-18 21:31:41 +02:00
end
return true , retstr .. ( " - meta::contexts - %d contexts " ) : format ( # ctxs )
2019-06-05 20:52:46 +02:00
2016-09-17 21:18:36 +02:00
-- meta open (x,y,z) [fields|inventory]
elseif params [ 1 ] == " open " then
2015-04-18 13:47:21 +02:00
2016-09-17 21:18:36 +02:00
-- Call the API function
2016-09-19 18:54:13 +02:00
if not params [ 3 ] then
params [ 3 ] = " fields "
end
return meta_exec ( {
scope = " meta::open " ,
func = metatools.open_node ,
params = { minetest.string_to_pos ( params [ 2 ] ) , params [ 3 ] , name } ,
required = {
mode = params [ 3 ] ,
no_nodelock = params [ 2 ] ,
2016-09-20 18:28:56 +02:00
} ,
success = function ( fparams )
metatools.alert_users ( name .. " opened node at " .. minetest.pos_to_string ( fparams [ 1 ] ) )
end
2016-09-19 18:54:13 +02:00
} )
2016-09-17 21:18:36 +02:00
-- meta close
elseif params [ 1 ] == " close " then
-- Call the API function
2016-09-19 18:54:13 +02:00
return meta_exec ( {
scope = " meta::close " ,
func = metatools.close_node ,
params = { metatools.get_player_selection ( name ) } ,
required = {
ownership = {
contextid = metatools.get_player_selection ( name ) ,
name = name
}
2016-09-20 18:28:56 +02:00
} ,
success = function ( fparams )
metatools.alert_users ( name .. " closed node of id " .. fparams [ 1 ] )
end
2016-09-19 18:54:13 +02:00
} )
-- meta select <contextid>
elseif params [ 1 ] == " select " then
return meta_exec ( {
scope = " meta::select " ,
func = metatools.player_select ,
params = { name , tonumber ( params [ 2 ] ) } ,
required = {
no_ownership = tonumber ( params [ 2 ] ) ,
2016-09-20 18:28:56 +02:00
} ,
success = function ( fparams )
metatools.alert_users ( name .. " selected context of id " .. fparams [ 1 ] )
end
2016-09-19 18:54:13 +02:00
} )
-- meta unselect
elseif params [ 1 ] == " unselect " then
return meta_exec ( {
scope = " meta::unselect " ,
func = metatools.player_unselect ,
params = { name } ,
required = {
some_ownership = name ,
2016-09-20 18:28:56 +02:00
} ,
success = function ( fparams )
metatools.alert_users ( name .. " unselected their context " )
end
2016-09-19 18:54:13 +02:00
} )
2016-09-19 19:03:49 +02:00
-- meta prune
elseif params [ 1 ] == " prune " then
return meta_exec ( {
scope = " meta::prune " ,
func = metatools.prune ,
params = { } ,
2016-09-20 18:28:56 +02:00
success = function ( )
metatools.alert_users ( name .. " is pruning contexts! " )
end
2016-09-19 19:03:49 +02:00
} )
2016-09-19 18:54:13 +02:00
-- meta switch
elseif params [ 1 ] == " switch " then
return meta_exec ( {
scope = " meta::switch " ,
func = metatools.switch ,
params = { metatools.get_player_selection ( name ) } ,
required = {
some_ownership = name ,
2016-09-20 18:28:56 +02:00
} ,
success = function ( fparams )
metatools.alert_users ( name .. " switched context (ID= " .. fparams [ 1 ] .. " )'s open mode " )
end
2016-09-19 18:54:13 +02:00
} )
2016-09-17 21:18:36 +02:00
-- meta show
elseif params [ 1 ] == " show " then
2016-09-19 18:54:13 +02:00
return meta_exec ( {
scope = " meta::show " ,
func = function ( )
local status , fieldlist = metatools.show ( metatools.get_player_selection ( name ) )
if not status then
return status , fieldlist
2016-09-18 21:31:41 +02:00
else
2016-09-19 18:54:13 +02:00
local retstr = " Output : \n "
for name , field in pairs ( fieldlist ) do
local rpr
if type ( field ) == " table " then
rpr = ( " -> {...} (size %s) " ) : format ( # field )
elseif type ( field ) == " string " then
rpr = ( " = %s " ) : format ( dump_normalize ( field ) )
elseif type ( field ) == " userdata " then
if field.get_name and field.get_count then
rpr = ( " = ItemStack({name='%s', count=%d, metadata='%s'}) " ) :
format ( field : get_name ( ) , field : get_count ( ) , field : get_metadata ( ) )
else
rpr = ( " = %s " ) : format ( dump_normalize ( field ) )
end
else
rpr = ( " = %s " ) : format ( field )
end
retstr = retstr .. ( " - meta::show - %s %s \n " ) : format ( name , rpr )
end
return true , retstr .. " - meta::show - End of output "
2016-09-18 21:31:41 +02:00
end
2016-09-19 18:54:13 +02:00
end ,
params = { } ,
required = {
some_ownership = name
}
} )
-- meta set <varname> <value>
2016-09-17 21:18:36 +02:00
elseif params [ 1 ] == " set " then
2016-09-19 18:54:13 +02:00
return meta_exec ( {
scope = " meta::set " ,
func = metatools.set ,
params = { metatools.get_player_selection ( name ) , params [ 2 ] , metatools.build_param_str ( params , 3 , ' ' ) } ,
required = {
some_ownership = name ,
specific_open_mode = {
mode = " fields " ,
contextid = metatools.get_player_selection ( name )
}
}
} )
2015-04-18 13:47:21 +02:00
2016-09-17 21:18:36 +02:00
-- meta unset <varname>
elseif params [ 1 ] == " unset " then
2016-09-19 18:54:13 +02:00
return meta_exec ( {
scope = " meta::unset " ,
func = metatools.unset ,
params = { metatools.get_player_selection ( name ) , params [ 2 ] } ,
required = {
some_ownership = name ,
specific_open_mode = {
mode = " fields " ,
contextid = metatools.get_player_selection ( name )
}
}
} )
2019-06-05 20:52:46 +02:00
2016-09-17 21:18:36 +02:00
-- meta purge
elseif params [ 1 ] == " purge " then
2016-09-19 18:54:13 +02:00
return meta_exec ( {
scope = " meta::purge " ,
func = metatools.purge ,
params = { metatools.get_player_selection ( name ) } ,
required = {
some_ownership = name ,
2016-09-20 18:28:56 +02:00
} ,
success = function ( fparams )
metatools.alert_users ( name .. " purged context " .. fparams [ 1 ] )
end
2016-09-19 18:54:13 +02:00
} )
2015-04-18 13:47:21 +02:00
2016-09-17 21:18:36 +02:00
-- meta list...
elseif params [ 1 ] == " list " then
if not params [ 2 ] then
return false , " - meta::list - Subcommand needed, consult '/meta help' for help "
end
2016-09-18 21:31:41 +02:00
-- meta list enter <listname>
if params [ 2 ] == " enter " then
2016-09-19 18:54:13 +02:00
return meta_exec ( {
scope = " meta::list::enter " ,
func = metatools.list_enter ,
params = { metatools.get_player_selection ( name ) , params [ 3 ] } ,
required = {
some_ownership = name ,
specific_open_mode = {
contextid = metatools.get_player_selection ( name ) ,
mode = " inventory " ,
} ,
}
} )
2015-04-18 13:47:21 +02:00
2016-09-18 21:31:41 +02:00
-- meta list leave
elseif params [ 2 ] == " leave " then
2016-09-19 18:54:13 +02:00
return meta_exec ( {
scope = " meta::list::leave " ,
func = metatools.list_leave ,
params = { metatools.get_player_selection ( name ) } ,
required = {
some_ownership = name ,
specific_open_mode = {
contextid = metatools.get_player_selection ( name ) ,
mode = " inventory " ,
}
}
} )
2016-09-18 21:31:41 +02:00
-- meta list init <name> <size>
elseif params [ 2 ] == " init " then
2016-09-19 18:54:13 +02:00
return meta_exec ( {
scope = " meta::list::init " ,
func = metatools.list_init ,
params = { metatools.get_player_selection ( name ) , params [ 3 ] , params [ 4 ] } ,
required = {
some_ownership = name ,
specific_open_mode = {
contextid = metatools.get_player_selection ( name ) ,
mode = " inventory " ,
}
}
} )
2016-09-17 21:18:36 +02:00
-- meta list delete <name>
elseif params [ 2 ] == " delete " then
2016-09-19 18:54:13 +02:00
return meta_exec ( {
scope = " meta::list::delete " ,
func = metatools.list_delete ,
params = { metatools.get_player_selection ( name ) , params [ 3 ] } ,
required = {
some_ownership = name ,
specific_open_mode = {
contextid = metatools.get_player_selection ( name ) ,
mode = " inventory " ,
}
}
} )
2019-06-05 20:52:46 +02:00
2016-09-17 21:18:36 +02:00
else
return false , " - meta::list - Unknown subcommand ' " .. params [ 2 ] .. " ', please consult '/meta help' for help "
end
2015-04-18 13:47:21 +02:00
2016-09-17 21:18:36 +02:00
-- meta itemstack...
elseif params [ 1 ] == " itemstack " then
if not params [ 2 ] then
return false , " - meta::itemstack - Subcommand needde, consult '/meta help' for help "
end
2015-04-18 13:47:21 +02:00
2016-09-17 21:18:36 +02:00
-- meta itemstack erase <index>
if params [ 2 ] == " erase " then
2016-09-19 18:54:13 +02:00
return meta_exec ( {
scope = " meta::itemstack::erase " ,
func = metatools.itemstack_erase ,
params = { metatools.get_player_selection ( name ) , params [ 3 ] } ,
required = {
some_ownership = name ,
specific_open_mode = {
contextid = metatools.get_player_selection ( name ) ,
mode = " inventory " ,
}
}
} )
2015-04-18 13:47:21 +02:00
2016-09-17 21:18:36 +02:00
-- meta itemstack write <index> <itemstack>
elseif params [ 2 ] == " write " then
2016-09-19 18:54:13 +02:00
return meta_exec ( {
scope = " meta::itemstack::write " ,
func = metatools.itemstack_write ,
params = { metatools.get_player_selection ( name ) , params [ 3 ] , metatools.build_param_str ( params , 4 , ' ' ) } ,
required = {
some_ownership = name ,
specific_open_mode = {
contextid = metatools.get_player_selection ( name ) ,
mode = " inventory " ,
}
}
} )
2019-06-05 20:52:46 +02:00
2016-09-18 21:31:41 +02:00
-- meta itemstack add <itemstack>
elseif params [ 2 ] == " add " then
2016-09-19 18:54:13 +02:00
return meta_exec ( {
scope = " meta::itemstack::write " ,
func = metatools.itemstack_add ,
params = { metatools.get_player_selection ( name ) , metatools.build_param_str ( params , 3 , ' ' ) } ,
required = {
some_ownership = name ,
specific_open_mode = {
contextid = metatools.get_player_selection ( name ) ,
mode = " inventory " ,
}
}
} )
2016-09-18 21:31:41 +02:00
else
return false , " - meta::itemstack - Unknown subcommand " .. params [ 2 ]
2015-04-18 13:47:21 +02:00
end
2015-05-12 21:51:18 +02:00
2015-04-05 22:13:32 +02:00
else
2016-09-17 21:18:36 +02:00
return false , " - meta - Unknown command " .. params [ 1 ]
2015-04-05 22:13:32 +02:00
end
2016-09-17 21:18:36 +02:00
end ,
2015-04-05 22:13:32 +02:00
} )