mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 10:03:45 +01:00
Create the necessary API for /giveme and /give and implement those commands; also sort out the scripts a bit
This commit is contained in:
parent
2a610b011a
commit
103d4793f0
149
data/builtin.lua
149
data/builtin.lua
@ -147,6 +147,155 @@ minetest.register_node("ignore", {
|
||||
air_equivalent = true,
|
||||
})
|
||||
|
||||
--
|
||||
-- stackstring manipulation functions
|
||||
-- example stackstring: 'CraftItem "apple" 4'
|
||||
-- example item: {type="CraftItem", name="apple"}
|
||||
-- example item: {type="ToolItem", name="SteelPick", wear="23272"}
|
||||
--
|
||||
|
||||
function stackstring_take_item(stackstring)
|
||||
if stackstring == nil then
|
||||
return '', nil
|
||||
end
|
||||
local stacktype = nil
|
||||
stacktype = string.match(stackstring,
|
||||
'([%a%d]+Item[%a%d]*)')
|
||||
if stacktype == "NodeItem" or stacktype == "CraftItem" then
|
||||
local itemtype = nil
|
||||
local itemname = nil
|
||||
local itemcount = nil
|
||||
itemtype, itemname, itemcount = string.match(stackstring,
|
||||
'([%a%d]+Item[%a%d]*) "([^"]*)" (%d+)')
|
||||
itemcount = tonumber(itemcount)
|
||||
if itemcount == 0 then
|
||||
return '', nil
|
||||
elseif itemcount == 1 then
|
||||
return '', {type=itemtype, name=itemname}
|
||||
else
|
||||
return itemtype.." \""..itemname.."\" "..(itemcount-1),
|
||||
{type=itemtype, name=itemname}
|
||||
end
|
||||
elseif stacktype == "ToolItem" then
|
||||
local itemtype = nil
|
||||
local itemname = nil
|
||||
local itemwear = nil
|
||||
itemtype, itemname, itemwear = string.match(stackstring,
|
||||
'([%a%d]+Item[%a%d]*) "([^"]*)" (%d+)')
|
||||
itemwear = tonumber(itemwear)
|
||||
return '', {type=itemtype, name=itemname, wear=itemwear}
|
||||
end
|
||||
end
|
||||
|
||||
function stackstring_put_item(stackstring, item)
|
||||
if item == nil then
|
||||
return stackstring, false
|
||||
end
|
||||
stackstring = stackstring or ''
|
||||
local stacktype = nil
|
||||
stacktype = string.match(stackstring,
|
||||
'([%a%d]+Item[%a%d]*)')
|
||||
stacktype = stacktype or ''
|
||||
if stacktype ~= '' and stacktype ~= item.type then
|
||||
return stackstring, false
|
||||
end
|
||||
if item.type == "NodeItem" or item.type == "CraftItem" then
|
||||
local itemtype = nil
|
||||
local itemname = nil
|
||||
local itemcount = nil
|
||||
itemtype, itemname, itemcount = string.match(stackstring,
|
||||
'([%a%d]+Item[%a%d]*) "([^"]*)" (%d+)')
|
||||
itemtype = itemtype or item.type
|
||||
itemname = itemname or item.name
|
||||
if itemcount == nil then
|
||||
itemcount = 0
|
||||
end
|
||||
itemcount = itemcount + 1
|
||||
return itemtype.." \""..itemname.."\" "..itemcount, true
|
||||
elseif item.type == "ToolItem" then
|
||||
if stacktype ~= nil then
|
||||
return stackstring, false
|
||||
end
|
||||
local itemtype = nil
|
||||
local itemname = nil
|
||||
local itemwear = nil
|
||||
itemtype, itemname, itemwear = string.match(stackstring,
|
||||
'([%a%d]+Item[%a%d]*) "([^"]*)" (%d+)')
|
||||
itemwear = tonumber(itemwear)
|
||||
return itemtype.." \""..itemname.."\" "..itemwear, true
|
||||
end
|
||||
return stackstring, false
|
||||
end
|
||||
|
||||
function stackstring_put_stackstring(stackstring, src)
|
||||
while src ~= '' do
|
||||
--print("src="..dump(src))
|
||||
src, item = stackstring_take_item(src)
|
||||
--print("src="..dump(src).." item="..dump(item))
|
||||
local success
|
||||
stackstring, success = stackstring_put_item(stackstring, item)
|
||||
if not success then
|
||||
return stackstring, false
|
||||
end
|
||||
end
|
||||
return stackstring, true
|
||||
end
|
||||
|
||||
function test_stackstring()
|
||||
local stack
|
||||
local item
|
||||
local success
|
||||
|
||||
stack, item = stackstring_take_item('NodeItem "TNT" 3')
|
||||
assert(stack == 'NodeItem "TNT" 2')
|
||||
assert(item.type == 'NodeItem')
|
||||
assert(item.name == 'TNT')
|
||||
|
||||
stack, item = stackstring_take_item('CraftItem "with spaces" 2')
|
||||
assert(stack == 'CraftItem "with spaces" 1')
|
||||
assert(item.type == 'CraftItem')
|
||||
assert(item.name == 'with spaces')
|
||||
|
||||
stack, item = stackstring_take_item('CraftItem "with spaces" 1')
|
||||
assert(stack == '')
|
||||
assert(item.type == 'CraftItem')
|
||||
assert(item.name == 'with spaces')
|
||||
|
||||
stack, item = stackstring_take_item('CraftItem "s8df2kj3" 0')
|
||||
assert(stack == '')
|
||||
assert(item == nil)
|
||||
|
||||
stack, item = stackstring_take_item('ToolItem "With Spaces" 32487')
|
||||
assert(stack == '')
|
||||
assert(item.type == 'ToolItem')
|
||||
assert(item.name == 'With Spaces')
|
||||
assert(item.wear == 32487)
|
||||
|
||||
stack, success = stackstring_put_item('NodeItem "With Spaces" 40',
|
||||
{type='NodeItem', name='With Spaces'})
|
||||
assert(stack == 'NodeItem "With Spaces" 41')
|
||||
assert(success == true)
|
||||
|
||||
stack, success = stackstring_put_item('CraftItem "With Spaces" 40',
|
||||
{type='CraftItem', name='With Spaces'})
|
||||
assert(stack == 'CraftItem "With Spaces" 41')
|
||||
assert(success == true)
|
||||
|
||||
stack, success = stackstring_put_item('ToolItem "With Spaces" 32487',
|
||||
{type='ToolItem', name='With Spaces'})
|
||||
assert(stack == 'ToolItem "With Spaces" 32487')
|
||||
assert(success == false)
|
||||
|
||||
stack, success = stackstring_put_item('NodeItem "With Spaces" 40',
|
||||
{type='ToolItem', name='With Spaces'})
|
||||
assert(stack == 'NodeItem "With Spaces" 40')
|
||||
assert(success == false)
|
||||
|
||||
assert(stackstring_put_stackstring('NodeItem "With Spaces" 2',
|
||||
'NodeItem "With Spaces" 1') == 'NodeItem "With Spaces" 3')
|
||||
end
|
||||
test_stackstring()
|
||||
|
||||
--
|
||||
-- Callback registration
|
||||
--
|
||||
|
@ -26,6 +26,7 @@
|
||||
-- minetest.setting_getbool(name)
|
||||
-- minetest.chat_send_all(text)
|
||||
-- minetest.chat_send_player(name, text)
|
||||
-- minetest.get_player_privs(name)
|
||||
--
|
||||
-- Global objects:
|
||||
-- minetest.env - environment reference
|
||||
@ -52,6 +53,7 @@
|
||||
-- - add_rat(pos)
|
||||
-- - add_firefly(pos)
|
||||
-- - get_meta(pos) -- Get a NodeMetaRef at that position
|
||||
-- - get_player_by_name(name) -- Get an ObjectRef to a player
|
||||
--
|
||||
-- NodeMetaRef
|
||||
-- - get_type()
|
||||
@ -1322,6 +1324,65 @@ function on_punchnode(p, node)
|
||||
end
|
||||
minetest.register_on_punchnode(on_punchnode)
|
||||
|
||||
minetest.register_on_chat_message(function(name, message)
|
||||
print("default on_chat_message: name="..dump(name).." message="..dump(message))
|
||||
local cmd = "/giveme"
|
||||
if message:sub(0, #cmd) == cmd then
|
||||
if not minetest.get_player_privs(name)["give"] then
|
||||
minetest.chat_send_player(name, "you don't have permission to give")
|
||||
return true -- Handled chat message
|
||||
end
|
||||
stackstring = string.match(message, cmd.." (.*)")
|
||||
if stackstring == nil then
|
||||
minetest.chat_send_player(name, 'usage: '..cmd..' stackstring')
|
||||
return true -- Handled chat message
|
||||
end
|
||||
print(cmd..' invoked, stackstring="'..stackstring..'"')
|
||||
player = minetest.env:get_player_by_name(name)
|
||||
added, error_msg = player:add_to_inventory(stackstring)
|
||||
if added then
|
||||
minetest.chat_send_player(name, '"'..stackstring
|
||||
..'" added to inventory.');
|
||||
else
|
||||
minetest.chat_send_player(name, 'Could not give "'..stackstring
|
||||
..'": '..error_msg);
|
||||
end
|
||||
return true -- Handled chat message
|
||||
end
|
||||
local cmd = "/give"
|
||||
if message:sub(0, #cmd) == cmd then
|
||||
print("minetest.get_player_privs(name)="
|
||||
..dump(minetest.get_player_privs(name)))
|
||||
if not minetest.get_player_privs(name)["give"] then
|
||||
minetest.chat_send_player(name, "you don't have permission to give")
|
||||
return true -- Handled chat message
|
||||
end
|
||||
name2, stackstring = string.match(message, cmd.." ([%a%d_-]+) (.*)")
|
||||
if name == nil or stackstring == nil then
|
||||
minetest.chat_send_player(name, 'usage: '..cmd..' name stackstring')
|
||||
return true -- Handled chat message
|
||||
end
|
||||
print(cmd..' invoked, name2="'..name2
|
||||
..'" stackstring="'..stackstring..'"')
|
||||
player = minetest.env:get_player_by_name(name2)
|
||||
if player == nil then
|
||||
minetest.chat_send_player(name, name2..' is not a known player')
|
||||
return true -- Handled chat message
|
||||
end
|
||||
added, error_msg = player:add_to_inventory(stackstring)
|
||||
if added then
|
||||
minetest.chat_send_player(name, '"'..stackstring
|
||||
..'" added to '..name2..'\'s inventory.');
|
||||
minetest.chat_send_player(name2, '"'..stackstring
|
||||
..'" added to inventory.');
|
||||
else
|
||||
minetest.chat_send_player(name, 'Could not give "'..stackstring
|
||||
..'": '..error_msg);
|
||||
end
|
||||
return true -- Handled chat message
|
||||
end
|
||||
end)
|
||||
|
||||
--
|
||||
-- Done, print some random stuff
|
||||
--
|
||||
|
@ -41,148 +41,6 @@ minetest.register_on_placenode(function(pos, newnode, placer)
|
||||
end
|
||||
end)
|
||||
|
||||
function stackstring_take_item(stackstring)
|
||||
if stackstring == nil then
|
||||
return '', nil
|
||||
end
|
||||
local stacktype = nil
|
||||
stacktype = string.match(stackstring,
|
||||
'([%a%d]+Item[%a%d]*)')
|
||||
if stacktype == "NodeItem" or stacktype == "CraftItem" then
|
||||
local itemtype = nil
|
||||
local itemname = nil
|
||||
local itemcount = nil
|
||||
itemtype, itemname, itemcount = string.match(stackstring,
|
||||
'([%a%d]+Item[%a%d]*) "([^"]*)" (%d+)')
|
||||
itemcount = tonumber(itemcount)
|
||||
if itemcount == 0 then
|
||||
return '', nil
|
||||
elseif itemcount == 1 then
|
||||
return '', {type=itemtype, name=itemname}
|
||||
else
|
||||
return itemtype.." \""..itemname.."\" "..(itemcount-1),
|
||||
{type=itemtype, name=itemname}
|
||||
end
|
||||
elseif stacktype == "ToolItem" then
|
||||
local itemtype = nil
|
||||
local itemname = nil
|
||||
local itemwear = nil
|
||||
itemtype, itemname, itemwear = string.match(stackstring,
|
||||
'([%a%d]+Item[%a%d]*) "([^"]*)" (%d+)')
|
||||
itemwear = tonumber(itemwear)
|
||||
return '', {type=itemtype, name=itemname, wear=itemwear}
|
||||
end
|
||||
end
|
||||
|
||||
function stackstring_put_item(stackstring, item)
|
||||
if item == nil then
|
||||
return stackstring, false
|
||||
end
|
||||
stackstring = stackstring or ''
|
||||
local stacktype = nil
|
||||
stacktype = string.match(stackstring,
|
||||
'([%a%d]+Item[%a%d]*)')
|
||||
stacktype = stacktype or ''
|
||||
if stacktype ~= '' and stacktype ~= item.type then
|
||||
return stackstring, false
|
||||
end
|
||||
if item.type == "NodeItem" or item.type == "CraftItem" then
|
||||
local itemtype = nil
|
||||
local itemname = nil
|
||||
local itemcount = nil
|
||||
itemtype, itemname, itemcount = string.match(stackstring,
|
||||
'([%a%d]+Item[%a%d]*) "([^"]*)" (%d+)')
|
||||
itemtype = itemtype or item.type
|
||||
itemname = itemname or item.name
|
||||
if itemcount == nil then
|
||||
itemcount = 0
|
||||
end
|
||||
itemcount = itemcount + 1
|
||||
return itemtype.." \""..itemname.."\" "..itemcount, true
|
||||
elseif item.type == "ToolItem" then
|
||||
if stacktype ~= nil then
|
||||
return stackstring, false
|
||||
end
|
||||
local itemtype = nil
|
||||
local itemname = nil
|
||||
local itemwear = nil
|
||||
itemtype, itemname, itemwear = string.match(stackstring,
|
||||
'([%a%d]+Item[%a%d]*) "([^"]*)" (%d+)')
|
||||
itemwear = tonumber(itemwear)
|
||||
return itemtype.." \""..itemname.."\" "..itemwear, true
|
||||
end
|
||||
return stackstring, false
|
||||
end
|
||||
|
||||
function stackstring_put_stackstring(stackstring, src)
|
||||
while src ~= '' do
|
||||
--print("src="..dump(src))
|
||||
src, item = stackstring_take_item(src)
|
||||
--print("src="..dump(src).." item="..dump(item))
|
||||
local success
|
||||
stackstring, success = stackstring_put_item(stackstring, item)
|
||||
if not success then
|
||||
return stackstring, false
|
||||
end
|
||||
end
|
||||
return stackstring, true
|
||||
end
|
||||
|
||||
function test_stack()
|
||||
local stack
|
||||
local item
|
||||
local success
|
||||
|
||||
stack, item = stackstring_take_item('NodeItem "TNT" 3')
|
||||
assert(stack == 'NodeItem "TNT" 2')
|
||||
assert(item.type == 'NodeItem')
|
||||
assert(item.name == 'TNT')
|
||||
|
||||
stack, item = stackstring_take_item('CraftItem "with spaces" 2')
|
||||
assert(stack == 'CraftItem "with spaces" 1')
|
||||
assert(item.type == 'CraftItem')
|
||||
assert(item.name == 'with spaces')
|
||||
|
||||
stack, item = stackstring_take_item('CraftItem "with spaces" 1')
|
||||
assert(stack == '')
|
||||
assert(item.type == 'CraftItem')
|
||||
assert(item.name == 'with spaces')
|
||||
|
||||
stack, item = stackstring_take_item('CraftItem "s8df2kj3" 0')
|
||||
assert(stack == '')
|
||||
assert(item == nil)
|
||||
|
||||
stack, item = stackstring_take_item('ToolItem "With Spaces" 32487')
|
||||
assert(stack == '')
|
||||
assert(item.type == 'ToolItem')
|
||||
assert(item.name == 'With Spaces')
|
||||
assert(item.wear == 32487)
|
||||
|
||||
stack, success = stackstring_put_item('NodeItem "With Spaces" 40',
|
||||
{type='NodeItem', name='With Spaces'})
|
||||
assert(stack == 'NodeItem "With Spaces" 41')
|
||||
assert(success == true)
|
||||
|
||||
stack, success = stackstring_put_item('CraftItem "With Spaces" 40',
|
||||
{type='CraftItem', name='With Spaces'})
|
||||
assert(stack == 'CraftItem "With Spaces" 41')
|
||||
assert(success == true)
|
||||
|
||||
stack, success = stackstring_put_item('ToolItem "With Spaces" 32487',
|
||||
{type='ToolItem', name='With Spaces'})
|
||||
assert(stack == 'ToolItem "With Spaces" 32487')
|
||||
assert(success == false)
|
||||
|
||||
stack, success = stackstring_put_item('NodeItem "With Spaces" 40',
|
||||
{type='ToolItem', name='With Spaces'})
|
||||
assert(stack == 'NodeItem "With Spaces" 40')
|
||||
assert(success == false)
|
||||
|
||||
assert(stackstring_put_stackstring('NodeItem "With Spaces" 2',
|
||||
'NodeItem "With Spaces" 1') == 'NodeItem "With Spaces" 3')
|
||||
end
|
||||
test_stack()
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"luafurnace"},
|
||||
interval = 1.0,
|
||||
@ -426,7 +284,7 @@ print("setting max_users = " .. dump(minetest.setting_get("max_users")))
|
||||
print("setting asdf = " .. dump(minetest.setting_get("asdf")))
|
||||
|
||||
minetest.register_on_chat_message(function(name, message)
|
||||
print("on_chat_message: name="..dump(name).." message="..dump(message))
|
||||
--[[print("on_chat_message: name="..dump(name).." message="..dump(message))
|
||||
local cmd = "/testcommand"
|
||||
if message:sub(0, #cmd) == cmd then
|
||||
print(cmd.." invoked")
|
||||
@ -437,7 +295,7 @@ minetest.register_on_chat_message(function(name, message)
|
||||
print("script-overridden help command")
|
||||
minetest.chat_send_all("script-overridden help command")
|
||||
return true
|
||||
end
|
||||
end]]
|
||||
end)
|
||||
|
||||
-- Grow papyrus on TNT every 10 seconds
|
||||
|
24
src/auth.cpp
24
src/auth.cpp
@ -25,6 +25,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "strfnd.h"
|
||||
#include "debug.h"
|
||||
|
||||
std::set<std::string> privsToSet(u64 privs)
|
||||
{
|
||||
std::set<std::string> s;
|
||||
if(privs & PRIV_BUILD)
|
||||
s.insert("build");
|
||||
if(privs & PRIV_TELEPORT)
|
||||
s.insert("teleport");
|
||||
if(privs & PRIV_SETTIME)
|
||||
s.insert("settime");
|
||||
if(privs & PRIV_PRIVS)
|
||||
s.insert("privs");
|
||||
if(privs & PRIV_SHOUT)
|
||||
s.insert("shout");
|
||||
if(privs & PRIV_BAN)
|
||||
s.insert("ban");
|
||||
if(privs & PRIV_GIVE)
|
||||
s.insert("give");
|
||||
return s;
|
||||
}
|
||||
|
||||
// Convert a privileges value into a human-readable string,
|
||||
// with each component separated by a comma.
|
||||
std::string privsToString(u64 privs)
|
||||
@ -42,6 +62,8 @@ std::string privsToString(u64 privs)
|
||||
os<<"shout,";
|
||||
if(privs & PRIV_BAN)
|
||||
os<<"ban,";
|
||||
if(privs & PRIV_GIVE)
|
||||
os<<"give,";
|
||||
if(os.tellp())
|
||||
{
|
||||
// Drop the trailing comma. (Why on earth can't
|
||||
@ -74,6 +96,8 @@ u64 stringToPrivs(std::string str)
|
||||
privs |= PRIV_SHOUT;
|
||||
else if(s == "ban")
|
||||
privs |= PRIV_BAN;
|
||||
else if(s == "give")
|
||||
privs |= PRIV_GIVE;
|
||||
else
|
||||
return PRIV_INVALID;
|
||||
}
|
||||
|
@ -20,10 +20,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef AUTH_HEADER
|
||||
#define AUTH_HEADER
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <jthread.h>
|
||||
#include <jmutex.h>
|
||||
#include "common_irrlicht.h"
|
||||
#include "irrlichttypes.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
// Player privileges. These form a bitmask stored in the privs field
|
||||
@ -39,6 +40,7 @@ const u64 PRIV_SERVER = 16; // Can manage the server (e.g. shutodwn
|
||||
const u64 PRIV_SHOUT = 32; // Can broadcast chat messages to all
|
||||
// players
|
||||
const u64 PRIV_BAN = 64; // Can ban players
|
||||
const u64 PRIV_GIVE = 128; // Can give stuff
|
||||
|
||||
// Default privileges - these can be overriden for new players using the
|
||||
// config option "default_privs" - however, this value still applies for
|
||||
@ -47,6 +49,8 @@ const u64 PRIV_DEFAULT = PRIV_BUILD|PRIV_SHOUT;
|
||||
const u64 PRIV_ALL = 0x7FFFFFFFFFFFFFFFULL;
|
||||
const u64 PRIV_INVALID = 0x8000000000000000ULL;
|
||||
|
||||
std::set<std::string> privsToSet(u64 privs);
|
||||
|
||||
// Convert a privileges value into a human-readable string,
|
||||
// with each component separated by a comma.
|
||||
std::string privsToString(u64 privs);
|
||||
|
@ -1023,6 +1023,30 @@ static int l_chat_send_player(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get_player_privs(name, text)
|
||||
static int l_get_player_privs(lua_State *L)
|
||||
{
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
// Get server from registry
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
|
||||
Server *server = (Server*)lua_touserdata(L, -1);
|
||||
// Do it
|
||||
lua_newtable(L);
|
||||
int table = lua_gettop(L);
|
||||
u64 privs_i = server->getPlayerAuthPrivs(name);
|
||||
// Special case for the "name" setting (local player / server owner)
|
||||
if(name == g_settings->get("name"))
|
||||
privs_i = PRIV_ALL;
|
||||
std::set<std::string> privs_s = privsToSet(privs_i);
|
||||
for(std::set<std::string>::const_iterator
|
||||
i = privs_s.begin(); i != privs_s.end(); i++){
|
||||
lua_pushboolean(L, true);
|
||||
lua_setfield(L, table, i->c_str());
|
||||
}
|
||||
lua_pushvalue(L, table);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg minetest_f [] = {
|
||||
{"register_nodedef_defaults", l_register_nodedef_defaults},
|
||||
{"register_entity", l_register_entity},
|
||||
@ -1035,6 +1059,7 @@ static const struct luaL_Reg minetest_f [] = {
|
||||
{"setting_getbool", l_setting_getbool},
|
||||
{"chat_send_all", l_chat_send_all},
|
||||
{"chat_send_player", l_chat_send_player},
|
||||
{"get_player_privs", l_get_player_privs},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@ -1502,236 +1527,6 @@ const luaL_reg NodeMetaRef::methods[] = {
|
||||
{0,0}
|
||||
};
|
||||
|
||||
/*
|
||||
EnvRef
|
||||
*/
|
||||
|
||||
class EnvRef
|
||||
{
|
||||
private:
|
||||
ServerEnvironment *m_env;
|
||||
|
||||
static const char className[];
|
||||
static const luaL_reg methods[];
|
||||
|
||||
static EnvRef *checkobject(lua_State *L, int narg)
|
||||
{
|
||||
luaL_checktype(L, narg, LUA_TUSERDATA);
|
||||
void *ud = luaL_checkudata(L, narg, className);
|
||||
if(!ud) luaL_typerror(L, narg, className);
|
||||
return *(EnvRef**)ud; // unbox pointer
|
||||
}
|
||||
|
||||
// Exported functions
|
||||
|
||||
// EnvRef:add_node(pos, node)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_add_node(lua_State *L)
|
||||
{
|
||||
//infostream<<"EnvRef::l_add_node()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3s16 pos = readpos(L, 2);
|
||||
// content
|
||||
MapNode n = readnode(L, 3, env->getGameDef()->ndef());
|
||||
// Do it
|
||||
bool succeeded = env->getMap().addNodeWithEvent(pos, n);
|
||||
lua_pushboolean(L, succeeded);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// EnvRef:remove_node(pos)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_remove_node(lua_State *L)
|
||||
{
|
||||
//infostream<<"EnvRef::l_remove_node()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3s16 pos = readpos(L, 2);
|
||||
// Do it
|
||||
bool succeeded = env->getMap().removeNodeWithEvent(pos);
|
||||
lua_pushboolean(L, succeeded);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// EnvRef:get_node(pos)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_get_node(lua_State *L)
|
||||
{
|
||||
//infostream<<"EnvRef::l_get_node()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3s16 pos = readpos(L, 2);
|
||||
// Do it
|
||||
MapNode n = env->getMap().getNodeNoEx(pos);
|
||||
// Return node
|
||||
pushnode(L, n, env->getGameDef()->ndef());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// EnvRef:add_luaentity(pos, entityname)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_add_luaentity(lua_State *L)
|
||||
{
|
||||
//infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3f pos = readFloatPos(L, 2);
|
||||
// content
|
||||
const char *name = lua_tostring(L, 3);
|
||||
// Do it
|
||||
ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
|
||||
env->addActiveObject(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EnvRef:add_item(pos, inventorystring)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_add_item(lua_State *L)
|
||||
{
|
||||
infostream<<"EnvRef::l_add_item()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3f pos = readFloatPos(L, 2);
|
||||
// inventorystring
|
||||
const char *inventorystring = lua_tostring(L, 3);
|
||||
// Do it
|
||||
ServerActiveObject *obj = new ItemSAO(env, pos, inventorystring);
|
||||
env->addActiveObject(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EnvRef:add_rat(pos)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_add_rat(lua_State *L)
|
||||
{
|
||||
infostream<<"EnvRef::l_add_rat()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3f pos = readFloatPos(L, 2);
|
||||
// Do it
|
||||
ServerActiveObject *obj = new RatSAO(env, pos);
|
||||
env->addActiveObject(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EnvRef:add_firefly(pos)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_add_firefly(lua_State *L)
|
||||
{
|
||||
infostream<<"EnvRef::l_add_firefly()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3f pos = readFloatPos(L, 2);
|
||||
// Do it
|
||||
ServerActiveObject *obj = new FireflySAO(env, pos);
|
||||
env->addActiveObject(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EnvRef:get_meta(pos)
|
||||
static int l_get_meta(lua_State *L)
|
||||
{
|
||||
//infostream<<"EnvRef::l_get_meta()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// Do it
|
||||
v3s16 p = readpos(L, 2);
|
||||
NodeMetaRef::create(L, p, env);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gc_object(lua_State *L) {
|
||||
EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
|
||||
delete o;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
EnvRef(ServerEnvironment *env):
|
||||
m_env(env)
|
||||
{
|
||||
infostream<<"EnvRef created"<<std::endl;
|
||||
}
|
||||
|
||||
~EnvRef()
|
||||
{
|
||||
infostream<<"EnvRef destructing"<<std::endl;
|
||||
}
|
||||
|
||||
// Creates an EnvRef and leaves it on top of stack
|
||||
// Not callable from Lua; all references are created on the C side.
|
||||
static void create(lua_State *L, ServerEnvironment *env)
|
||||
{
|
||||
EnvRef *o = new EnvRef(env);
|
||||
//infostream<<"EnvRef::create: o="<<o<<std::endl;
|
||||
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||
luaL_getmetatable(L, className);
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
static void set_null(lua_State *L)
|
||||
{
|
||||
EnvRef *o = checkobject(L, -1);
|
||||
o->m_env = NULL;
|
||||
}
|
||||
|
||||
static void Register(lua_State *L)
|
||||
{
|
||||
lua_newtable(L);
|
||||
int methodtable = lua_gettop(L);
|
||||
luaL_newmetatable(L, className);
|
||||
int metatable = lua_gettop(L);
|
||||
|
||||
lua_pushliteral(L, "__metatable");
|
||||
lua_pushvalue(L, methodtable);
|
||||
lua_settable(L, metatable); // hide metatable from Lua getmetatable()
|
||||
|
||||
lua_pushliteral(L, "__index");
|
||||
lua_pushvalue(L, methodtable);
|
||||
lua_settable(L, metatable);
|
||||
|
||||
lua_pushliteral(L, "__gc");
|
||||
lua_pushcfunction(L, gc_object);
|
||||
lua_settable(L, metatable);
|
||||
|
||||
lua_pop(L, 1); // drop metatable
|
||||
|
||||
luaL_openlib(L, 0, methods, 0); // fill methodtable
|
||||
lua_pop(L, 1); // drop methodtable
|
||||
|
||||
// Cannot be created from Lua
|
||||
//lua_register(L, className, create_object);
|
||||
}
|
||||
};
|
||||
const char EnvRef::className[] = "EnvRef";
|
||||
const luaL_reg EnvRef::methods[] = {
|
||||
method(EnvRef, add_node),
|
||||
method(EnvRef, remove_node),
|
||||
method(EnvRef, get_node),
|
||||
method(EnvRef, add_luaentity),
|
||||
method(EnvRef, add_item),
|
||||
method(EnvRef, add_rat),
|
||||
method(EnvRef, add_firefly),
|
||||
method(EnvRef, get_meta),
|
||||
{0,0}
|
||||
};
|
||||
|
||||
/*
|
||||
ObjectRef
|
||||
*/
|
||||
@ -1886,7 +1681,7 @@ private:
|
||||
}
|
||||
|
||||
// add_to_inventory(self, itemstring)
|
||||
// returns: true if item was added, false otherwise
|
||||
// returns: true if item was added, (false, "reason") otherwise
|
||||
static int l_add_to_inventory(lua_State *L)
|
||||
{
|
||||
ObjectRef *ref = checkobject(L, 1);
|
||||
@ -1902,12 +1697,23 @@ private:
|
||||
ServerEnvironment *env = co->getEnv();
|
||||
assert(env);
|
||||
IGameDef *gamedef = env->getGameDef();
|
||||
try{
|
||||
InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
|
||||
infostream<<"item="<<env<<std::endl;
|
||||
bool fits = co->addToInventory(item);
|
||||
if(item->getCount() == 0)
|
||||
item->setCount(1);
|
||||
bool added = co->addToInventory(item);
|
||||
// Return
|
||||
lua_pushboolean(L, fits);
|
||||
return 1;
|
||||
lua_pushboolean(L, added);
|
||||
if(!added)
|
||||
lua_pushstring(L, "does not fit");
|
||||
return 2;
|
||||
} catch(SerializationError &e){
|
||||
// Return
|
||||
lua_pushboolean(L, false);
|
||||
lua_pushstring(L, (std::string("Invalid item: ")
|
||||
+ e.what()).c_str());
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
// add_to_inventory_later(self, itemstring)
|
||||
@ -2093,6 +1899,256 @@ static void objectref_get_or_create(lua_State *L,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
EnvRef
|
||||
*/
|
||||
|
||||
class EnvRef
|
||||
{
|
||||
private:
|
||||
ServerEnvironment *m_env;
|
||||
|
||||
static const char className[];
|
||||
static const luaL_reg methods[];
|
||||
|
||||
static EnvRef *checkobject(lua_State *L, int narg)
|
||||
{
|
||||
luaL_checktype(L, narg, LUA_TUSERDATA);
|
||||
void *ud = luaL_checkudata(L, narg, className);
|
||||
if(!ud) luaL_typerror(L, narg, className);
|
||||
return *(EnvRef**)ud; // unbox pointer
|
||||
}
|
||||
|
||||
// Exported functions
|
||||
|
||||
// EnvRef:add_node(pos, node)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_add_node(lua_State *L)
|
||||
{
|
||||
//infostream<<"EnvRef::l_add_node()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3s16 pos = readpos(L, 2);
|
||||
// content
|
||||
MapNode n = readnode(L, 3, env->getGameDef()->ndef());
|
||||
// Do it
|
||||
bool succeeded = env->getMap().addNodeWithEvent(pos, n);
|
||||
lua_pushboolean(L, succeeded);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// EnvRef:remove_node(pos)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_remove_node(lua_State *L)
|
||||
{
|
||||
//infostream<<"EnvRef::l_remove_node()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3s16 pos = readpos(L, 2);
|
||||
// Do it
|
||||
bool succeeded = env->getMap().removeNodeWithEvent(pos);
|
||||
lua_pushboolean(L, succeeded);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// EnvRef:get_node(pos)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_get_node(lua_State *L)
|
||||
{
|
||||
//infostream<<"EnvRef::l_get_node()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3s16 pos = readpos(L, 2);
|
||||
// Do it
|
||||
MapNode n = env->getMap().getNodeNoEx(pos);
|
||||
// Return node
|
||||
pushnode(L, n, env->getGameDef()->ndef());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// EnvRef:add_luaentity(pos, entityname)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_add_luaentity(lua_State *L)
|
||||
{
|
||||
//infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3f pos = readFloatPos(L, 2);
|
||||
// content
|
||||
const char *name = lua_tostring(L, 3);
|
||||
// Do it
|
||||
ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
|
||||
env->addActiveObject(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EnvRef:add_item(pos, inventorystring)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_add_item(lua_State *L)
|
||||
{
|
||||
infostream<<"EnvRef::l_add_item()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3f pos = readFloatPos(L, 2);
|
||||
// inventorystring
|
||||
const char *inventorystring = lua_tostring(L, 3);
|
||||
// Do it
|
||||
ServerActiveObject *obj = new ItemSAO(env, pos, inventorystring);
|
||||
env->addActiveObject(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EnvRef:add_rat(pos)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_add_rat(lua_State *L)
|
||||
{
|
||||
infostream<<"EnvRef::l_add_rat()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3f pos = readFloatPos(L, 2);
|
||||
// Do it
|
||||
ServerActiveObject *obj = new RatSAO(env, pos);
|
||||
env->addActiveObject(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EnvRef:add_firefly(pos)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
static int l_add_firefly(lua_State *L)
|
||||
{
|
||||
infostream<<"EnvRef::l_add_firefly()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3f pos = readFloatPos(L, 2);
|
||||
// Do it
|
||||
ServerActiveObject *obj = new FireflySAO(env, pos);
|
||||
env->addActiveObject(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EnvRef:get_meta(pos)
|
||||
static int l_get_meta(lua_State *L)
|
||||
{
|
||||
//infostream<<"EnvRef::l_get_meta()"<<std::endl;
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// Do it
|
||||
v3s16 p = readpos(L, 2);
|
||||
NodeMetaRef::create(L, p, env);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// EnvRef:get_player_by_name(name)
|
||||
static int l_get_player_by_name(lua_State *L)
|
||||
{
|
||||
EnvRef *o = checkobject(L, 1);
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// Do it
|
||||
const char *name = lua_tostring(L, 2);
|
||||
ServerRemotePlayer *player =
|
||||
static_cast<ServerRemotePlayer*>(env->getPlayer(name));
|
||||
if(player == NULL){
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
// Put player on stack
|
||||
objectref_get_or_create(L, player);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gc_object(lua_State *L) {
|
||||
EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
|
||||
delete o;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
EnvRef(ServerEnvironment *env):
|
||||
m_env(env)
|
||||
{
|
||||
infostream<<"EnvRef created"<<std::endl;
|
||||
}
|
||||
|
||||
~EnvRef()
|
||||
{
|
||||
infostream<<"EnvRef destructing"<<std::endl;
|
||||
}
|
||||
|
||||
// Creates an EnvRef and leaves it on top of stack
|
||||
// Not callable from Lua; all references are created on the C side.
|
||||
static void create(lua_State *L, ServerEnvironment *env)
|
||||
{
|
||||
EnvRef *o = new EnvRef(env);
|
||||
//infostream<<"EnvRef::create: o="<<o<<std::endl;
|
||||
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||
luaL_getmetatable(L, className);
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
static void set_null(lua_State *L)
|
||||
{
|
||||
EnvRef *o = checkobject(L, -1);
|
||||
o->m_env = NULL;
|
||||
}
|
||||
|
||||
static void Register(lua_State *L)
|
||||
{
|
||||
lua_newtable(L);
|
||||
int methodtable = lua_gettop(L);
|
||||
luaL_newmetatable(L, className);
|
||||
int metatable = lua_gettop(L);
|
||||
|
||||
lua_pushliteral(L, "__metatable");
|
||||
lua_pushvalue(L, methodtable);
|
||||
lua_settable(L, metatable); // hide metatable from Lua getmetatable()
|
||||
|
||||
lua_pushliteral(L, "__index");
|
||||
lua_pushvalue(L, methodtable);
|
||||
lua_settable(L, metatable);
|
||||
|
||||
lua_pushliteral(L, "__gc");
|
||||
lua_pushcfunction(L, gc_object);
|
||||
lua_settable(L, metatable);
|
||||
|
||||
lua_pop(L, 1); // drop metatable
|
||||
|
||||
luaL_openlib(L, 0, methods, 0); // fill methodtable
|
||||
lua_pop(L, 1); // drop methodtable
|
||||
|
||||
// Cannot be created from Lua
|
||||
//lua_register(L, className, create_object);
|
||||
}
|
||||
};
|
||||
const char EnvRef::className[] = "EnvRef";
|
||||
const luaL_reg EnvRef::methods[] = {
|
||||
method(EnvRef, add_node),
|
||||
method(EnvRef, remove_node),
|
||||
method(EnvRef, get_node),
|
||||
method(EnvRef, add_luaentity),
|
||||
method(EnvRef, add_item),
|
||||
method(EnvRef, add_rat),
|
||||
method(EnvRef, add_firefly),
|
||||
method(EnvRef, get_meta),
|
||||
method(EnvRef, get_player_by_name),
|
||||
{0,0}
|
||||
};
|
||||
|
||||
/*
|
||||
Main export function
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user