mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
Private nodemeta (#5702)
* Private node metadata that isn't sent to the client
This commit is contained in:
parent
6945f807ab
commit
071e114ffa
@ -2895,6 +2895,10 @@ Can be obtained via `minetest.get_meta(pos)`.
|
|||||||
#### Methods
|
#### Methods
|
||||||
* All methods in MetaDataRef
|
* All methods in MetaDataRef
|
||||||
* `get_inventory()`: returns `InvRef`
|
* `get_inventory()`: returns `InvRef`
|
||||||
|
* `mark_as_private(name or {name1, name2, ...})`: Mark specific vars as private
|
||||||
|
This will prevent them from being sent to the client. Note that the "private"
|
||||||
|
status will only be remembered if an associated key-value pair exists, meaning
|
||||||
|
it's best to call this when initializing all other meta (e.g. on_construct).
|
||||||
|
|
||||||
### `ItemStackMetaRef`
|
### `ItemStackMetaRef`
|
||||||
ItemStack metadata: reference extra data and functionality stored in a stack.
|
ItemStack metadata: reference extra data and functionality stored in a stack.
|
||||||
|
@ -1228,6 +1228,8 @@ minetest.register_node("default:chest_locked", {
|
|||||||
meta:set_string("owner", "")
|
meta:set_string("owner", "")
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
inv:set_size("main", 8*4)
|
inv:set_size("main", 8*4)
|
||||||
|
-- this is not really the intended usage but works for testing purposes:
|
||||||
|
meta:mark_as_private("owner")
|
||||||
end,
|
end,
|
||||||
can_dig = function(pos,player)
|
can_dig = function(pos,player)
|
||||||
local meta = minetest.get_meta(pos);
|
local meta = minetest.get_meta(pos);
|
||||||
|
@ -502,10 +502,16 @@ minetest.register_craftitem("experimental:tester_tool_1", {
|
|||||||
on_use = function(itemstack, user, pointed_thing)
|
on_use = function(itemstack, user, pointed_thing)
|
||||||
--print(dump(pointed_thing))
|
--print(dump(pointed_thing))
|
||||||
if pointed_thing.type == "node" then
|
if pointed_thing.type == "node" then
|
||||||
if minetest.get_node(pointed_thing.under).name == "experimental:tester_node_1" then
|
local node = minetest.get_node(pointed_thing.under)
|
||||||
|
if node.name == "experimental:tester_node_1" or node.name == "default:chest" then
|
||||||
local p = pointed_thing.under
|
local p = pointed_thing.under
|
||||||
minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
|
minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
|
||||||
minetest.dig_node(p)
|
if node.name == "experimental:tester_node_1" then
|
||||||
|
minetest.dig_node(p)
|
||||||
|
else
|
||||||
|
minetest.get_meta(p):mark_as_private({"infotext", "formspec"})
|
||||||
|
minetest.chat_send_player(user:get_player_name(), "Verify that chest is unusable now.")
|
||||||
|
end
|
||||||
else
|
else
|
||||||
local p = pointed_thing.above
|
local p = pointed_thing.above
|
||||||
minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
|
minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
|
||||||
|
@ -611,7 +611,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
|
|||||||
Node metadata
|
Node metadata
|
||||||
*/
|
*/
|
||||||
std::ostringstream oss(std::ios_base::binary);
|
std::ostringstream oss(std::ios_base::binary);
|
||||||
m_node_metadata.serialize(oss);
|
m_node_metadata.serialize(oss, version, disk);
|
||||||
compressZlib(oss.str(), os);
|
compressZlib(oss.str(), os);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -669,11 +669,10 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
|
|||||||
u8 flags = readU8(is);
|
u8 flags = readU8(is);
|
||||||
is_underground = (flags & 0x01) ? true : false;
|
is_underground = (flags & 0x01) ? true : false;
|
||||||
m_day_night_differs = (flags & 0x02) ? true : false;
|
m_day_night_differs = (flags & 0x02) ? true : false;
|
||||||
if (version < 27) {
|
if (version < 27)
|
||||||
m_lighting_complete = 0xFFFF;
|
m_lighting_complete = 0xFFFF;
|
||||||
} else {
|
else
|
||||||
m_lighting_complete = readU16(is);
|
m_lighting_complete = readU16(is);
|
||||||
}
|
|
||||||
m_generated = (flags & 0x08) ? false : true;
|
m_generated = (flags & 0x08) ? false : true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util/serialize.h"
|
#include "util/serialize.h"
|
||||||
|
#include "util/basic_macros.h"
|
||||||
#include "constants.h" // MAP_BLOCKSIZE
|
#include "constants.h" // MAP_BLOCKSIZE
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@ -39,28 +40,38 @@ NodeMetadata::~NodeMetadata()
|
|||||||
delete m_inventory;
|
delete m_inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeMetadata::serialize(std::ostream &os) const
|
void NodeMetadata::serialize(std::ostream &os, u8 version, bool disk) const
|
||||||
{
|
{
|
||||||
int num_vars = m_stringvars.size();
|
int num_vars = disk ? m_stringvars.size() : countNonPrivate();
|
||||||
writeU32(os, num_vars);
|
writeU32(os, num_vars);
|
||||||
for (StringMap::const_iterator
|
for (StringMap::const_iterator
|
||||||
it = m_stringvars.begin();
|
it = m_stringvars.begin();
|
||||||
it != m_stringvars.end(); ++it) {
|
it != m_stringvars.end(); ++it) {
|
||||||
|
bool priv = isPrivate(it->first);
|
||||||
|
if (!disk && priv)
|
||||||
|
continue;
|
||||||
|
|
||||||
os << serializeString(it->first);
|
os << serializeString(it->first);
|
||||||
os << serializeLongString(it->second);
|
os << serializeLongString(it->second);
|
||||||
|
if (version >= 2)
|
||||||
|
writeU8(os, (priv) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_inventory->serialize(os);
|
m_inventory->serialize(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeMetadata::deSerialize(std::istream &is)
|
void NodeMetadata::deSerialize(std::istream &is, u8 version)
|
||||||
{
|
{
|
||||||
m_stringvars.clear();
|
clear();
|
||||||
int num_vars = readU32(is);
|
int num_vars = readU32(is);
|
||||||
for(int i=0; i<num_vars; i++){
|
for(int i=0; i<num_vars; i++){
|
||||||
std::string name = deSerializeString(is);
|
std::string name = deSerializeString(is);
|
||||||
std::string var = deSerializeLongString(is);
|
std::string var = deSerializeLongString(is);
|
||||||
m_stringvars[name] = var;
|
m_stringvars[name] = var;
|
||||||
|
if (version >= 2) {
|
||||||
|
if (readU8(is) == 1)
|
||||||
|
markPrivate(name, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_inventory->deSerialize(is);
|
m_inventory->deSerialize(is);
|
||||||
@ -69,6 +80,7 @@ void NodeMetadata::deSerialize(std::istream &is)
|
|||||||
void NodeMetadata::clear()
|
void NodeMetadata::clear()
|
||||||
{
|
{
|
||||||
Metadata::clear();
|
Metadata::clear();
|
||||||
|
m_privatevars.clear();
|
||||||
m_inventory->clear();
|
m_inventory->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,11 +89,34 @@ bool NodeMetadata::empty() const
|
|||||||
return Metadata::empty() && m_inventory->getLists().size() == 0;
|
return Metadata::empty() && m_inventory->getLists().size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NodeMetadata::markPrivate(const std::string &name, bool set)
|
||||||
|
{
|
||||||
|
if (set)
|
||||||
|
m_privatevars.insert(name);
|
||||||
|
else
|
||||||
|
m_privatevars.erase(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
int NodeMetadata::countNonPrivate() const
|
||||||
|
{
|
||||||
|
// m_privatevars can contain names not actually present
|
||||||
|
// DON'T: return m_stringvars.size() - m_privatevars.size();
|
||||||
|
int n = 0;
|
||||||
|
for (StringMap::const_iterator
|
||||||
|
it = m_stringvars.begin();
|
||||||
|
it != m_stringvars.end(); ++it) {
|
||||||
|
if (isPrivate(it->first) == false)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NodeMetadataList
|
NodeMetadataList
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void NodeMetadataList::serialize(std::ostream &os) const
|
void NodeMetadataList::serialize(std::ostream &os, u8 blockver, bool disk) const
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Version 0 is a placeholder for "nothing to see here; go away."
|
Version 0 is a placeholder for "nothing to see here; go away."
|
||||||
@ -93,7 +128,8 @@ void NodeMetadataList::serialize(std::ostream &os) const
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeU8(os, 1); // version
|
u8 version = (blockver > 27) ? 2 : 1;
|
||||||
|
writeU8(os, version);
|
||||||
writeU16(os, count);
|
writeU16(os, count);
|
||||||
|
|
||||||
for(std::map<v3s16, NodeMetadata*>::const_iterator
|
for(std::map<v3s16, NodeMetadata*>::const_iterator
|
||||||
@ -108,7 +144,7 @@ void NodeMetadataList::serialize(std::ostream &os) const
|
|||||||
u16 p16 = p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE + p.Y * MAP_BLOCKSIZE + p.X;
|
u16 p16 = p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE + p.Y * MAP_BLOCKSIZE + p.X;
|
||||||
writeU16(os, p16);
|
writeU16(os, p16);
|
||||||
|
|
||||||
data->serialize(os);
|
data->serialize(os, version, disk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +159,7 @@ void NodeMetadataList::deSerialize(std::istream &is, IItemDefManager *item_def_m
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version != 1) {
|
if (version > 2) {
|
||||||
std::string err_str = std::string(FUNCTION_NAME)
|
std::string err_str = std::string(FUNCTION_NAME)
|
||||||
+ ": version " + itos(version) + " not supported";
|
+ ": version " + itos(version) + " not supported";
|
||||||
infostream << err_str << std::endl;
|
infostream << err_str << std::endl;
|
||||||
@ -132,7 +168,7 @@ void NodeMetadataList::deSerialize(std::istream &is, IItemDefManager *item_def_m
|
|||||||
|
|
||||||
u16 count = readU16(is);
|
u16 count = readU16(is);
|
||||||
|
|
||||||
for (u16 i=0; i < count; i++) {
|
for (u16 i = 0; i < count; i++) {
|
||||||
u16 p16 = readU16(is);
|
u16 p16 = readU16(is);
|
||||||
|
|
||||||
v3s16 p;
|
v3s16 p;
|
||||||
@ -143,15 +179,14 @@ void NodeMetadataList::deSerialize(std::istream &is, IItemDefManager *item_def_m
|
|||||||
p.X = p16;
|
p.X = p16;
|
||||||
|
|
||||||
if (m_data.find(p) != m_data.end()) {
|
if (m_data.find(p) != m_data.end()) {
|
||||||
warningstream<<"NodeMetadataList::deSerialize(): "
|
warningstream << "NodeMetadataList::deSerialize(): "
|
||||||
<<"already set data at position"
|
<< "already set data at position " << PP(p)
|
||||||
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring."
|
<< ": Ignoring." << std::endl;
|
||||||
<<std::endl;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeMetadata *data = new NodeMetadata(item_def_mgr);
|
NodeMetadata *data = new NodeMetadata(item_def_mgr);
|
||||||
data->deSerialize(is);
|
data->deSerialize(is, version);
|
||||||
m_data[p] = data;
|
m_data[p] = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define NODEMETADATA_HEADER
|
#define NODEMETADATA_HEADER
|
||||||
|
|
||||||
#include "metadata.h"
|
#include "metadata.h"
|
||||||
|
#include "util/cpp11_container.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NodeMetadata stores arbitary amounts of data for special blocks.
|
NodeMetadata stores arbitary amounts of data for special blocks.
|
||||||
@ -40,8 +41,8 @@ public:
|
|||||||
NodeMetadata(IItemDefManager *item_def_mgr);
|
NodeMetadata(IItemDefManager *item_def_mgr);
|
||||||
~NodeMetadata();
|
~NodeMetadata();
|
||||||
|
|
||||||
void serialize(std::ostream &os) const;
|
void serialize(std::ostream &os, u8 version, bool disk=true) const;
|
||||||
void deSerialize(std::istream &is);
|
void deSerialize(std::istream &is, u8 version);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
@ -52,8 +53,17 @@ public:
|
|||||||
return m_inventory;
|
return m_inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool isPrivate(const std::string &name) const
|
||||||
|
{
|
||||||
|
return m_privatevars.count(name) != 0;
|
||||||
|
}
|
||||||
|
void markPrivate(const std::string &name, bool set);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int countNonPrivate() const;
|
||||||
|
|
||||||
Inventory *m_inventory;
|
Inventory *m_inventory;
|
||||||
|
UNORDERED_SET<std::string> m_privatevars;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -66,7 +76,7 @@ class NodeMetadataList
|
|||||||
public:
|
public:
|
||||||
~NodeMetadataList();
|
~NodeMetadataList();
|
||||||
|
|
||||||
void serialize(std::ostream &os) const;
|
void serialize(std::ostream &os, u8 blockver, bool disk=true) const;
|
||||||
void deSerialize(std::istream &is, IItemDefManager *item_def_mgr);
|
void deSerialize(std::istream &is, IItemDefManager *item_def_mgr);
|
||||||
|
|
||||||
// Add all keys in this list to the vector keys
|
// Add all keys in this list to the vector keys
|
||||||
|
@ -44,7 +44,7 @@ RollbackNode::RollbackNode(Map *map, v3s16 p, IGameDef *gamedef)
|
|||||||
NodeMetadata *metap = map->getNodeMetadata(p);
|
NodeMetadata *metap = map->getNodeMetadata(p);
|
||||||
if (metap) {
|
if (metap) {
|
||||||
std::ostringstream os(std::ios::binary);
|
std::ostringstream os(std::ios::binary);
|
||||||
metap->serialize(os);
|
metap->serialize(os, 1); // FIXME: version bump??
|
||||||
meta = os.str();
|
meta = os.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::istringstream is(n_old.meta, std::ios::binary);
|
std::istringstream is(n_old.meta, std::ios::binary);
|
||||||
meta->deSerialize(is);
|
meta->deSerialize(is, 1); // FIXME: version bump??
|
||||||
}
|
}
|
||||||
// Inform other things that the meta data has changed
|
// Inform other things that the meta data has changed
|
||||||
v3s16 blockpos = getContainerPos(p, MAP_BLOCKSIZE);
|
v3s16 blockpos = getContainerPos(p, MAP_BLOCKSIZE);
|
||||||
|
@ -94,6 +94,32 @@ int NodeMetaRef::l_get_inventory(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mark_as_private(self, <string> or {<string>, <string>, ...})
|
||||||
|
int NodeMetaRef::l_mark_as_private(lua_State *L)
|
||||||
|
{
|
||||||
|
MAP_LOCK_REQUIRED;
|
||||||
|
|
||||||
|
NodeMetaRef *ref = checkobject(L, 1);
|
||||||
|
NodeMetadata *meta = dynamic_cast<NodeMetadata*>(ref->getmeta(true));
|
||||||
|
assert(meta);
|
||||||
|
|
||||||
|
if (lua_istable(L, 2)) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
while (lua_next(L, 2) != 0) {
|
||||||
|
// key at index -2 and value at index -1
|
||||||
|
luaL_checktype(L, -1, LUA_TSTRING);
|
||||||
|
meta->markPrivate(lua_tostring(L, -1), true);
|
||||||
|
// removes value, keeps key for next iteration
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
} else if (lua_isstring(L, 2)) {
|
||||||
|
meta->markPrivate(lua_tostring(L, 2), true);
|
||||||
|
}
|
||||||
|
ref->reportMetadataChange();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta)
|
void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta)
|
||||||
{
|
{
|
||||||
// fields
|
// fields
|
||||||
@ -229,6 +255,7 @@ const luaL_Reg NodeMetaRef::methodsServer[] = {
|
|||||||
luamethod(MetaDataRef, to_table),
|
luamethod(MetaDataRef, to_table),
|
||||||
luamethod(MetaDataRef, from_table),
|
luamethod(MetaDataRef, from_table),
|
||||||
luamethod(NodeMetaRef, get_inventory),
|
luamethod(NodeMetaRef, get_inventory),
|
||||||
|
luamethod(NodeMetaRef, mark_as_private),
|
||||||
luamethod(MetaDataRef, equals),
|
luamethod(MetaDataRef, equals),
|
||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
@ -73,6 +73,9 @@ private:
|
|||||||
// get_inventory(self)
|
// get_inventory(self)
|
||||||
static int l_get_inventory(lua_State *L);
|
static int l_get_inventory(lua_State *L);
|
||||||
|
|
||||||
|
// mark_as_private(self, <string> or {<string>, <string>, ...})
|
||||||
|
static int l_mark_as_private(lua_State *L);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NodeMetaRef(v3s16 p, ServerEnvironment *env);
|
NodeMetaRef(v3s16 p, ServerEnvironment *env);
|
||||||
NodeMetaRef(Metadata *meta);
|
NodeMetaRef(Metadata *meta);
|
||||||
|
@ -63,13 +63,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
25: Improved node timer format
|
25: Improved node timer format
|
||||||
26: Never written; read the same as 25
|
26: Never written; read the same as 25
|
||||||
27: Added light spreading flags to blocks
|
27: Added light spreading flags to blocks
|
||||||
|
28: Added "private" flag to NodeMetadata
|
||||||
*/
|
*/
|
||||||
// This represents an uninitialized or invalid format
|
// This represents an uninitialized or invalid format
|
||||||
#define SER_FMT_VER_INVALID 255
|
#define SER_FMT_VER_INVALID 255
|
||||||
// Highest supported serialization version
|
// Highest supported serialization version
|
||||||
#define SER_FMT_VER_HIGHEST_READ 27
|
#define SER_FMT_VER_HIGHEST_READ 28
|
||||||
// Saved on disk version
|
// Saved on disk version
|
||||||
#define SER_FMT_VER_HIGHEST_WRITE 27
|
#define SER_FMT_VER_HIGHEST_WRITE 28
|
||||||
// Lowest supported serialization version
|
// Lowest supported serialization version
|
||||||
#define SER_FMT_VER_LOWEST_READ 0
|
#define SER_FMT_VER_LOWEST_READ 0
|
||||||
// Lowest serialization version for writing
|
// Lowest serialization version for writing
|
||||||
|
Loading…
Reference in New Issue
Block a user