summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsfan5 <sfan5@live.de>2017-05-10 15:29:21 +0200
committerLoïc Blot <nerzhul@users.noreply.github.com>2017-05-10 15:29:21 +0200
commit071e114ffa945522a7a9acc3259427166992d5ee (patch)
treeb76be5cdc27e9a8d9b58ff15f80691e012afa702
parent6945f807abd789e0f522351e5e790ff2afced233 (diff)
downloadminetest-071e114ffa945522a7a9acc3259427166992d5ee.tar.gz
minetest-071e114ffa945522a7a9acc3259427166992d5ee.tar.bz2
minetest-071e114ffa945522a7a9acc3259427166992d5ee.zip
Private nodemeta (#5702)
* Private node metadata that isn't sent to the client
-rw-r--r--doc/lua_api.txt4
-rw-r--r--games/minimal/mods/default/init.lua2
-rw-r--r--games/minimal/mods/experimental/init.lua10
-rw-r--r--src/mapblock.cpp7
-rw-r--r--src/nodemetadata.cpp63
-rw-r--r--src/nodemetadata.h16
-rw-r--r--src/rollback_interface.cpp4
-rw-r--r--src/script/lua_api/l_nodemeta.cpp27
-rw-r--r--src/script/lua_api/l_nodemeta.h3
-rw-r--r--src/serialization.h5
10 files changed, 114 insertions, 27 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 901dd3c46..a295d7d0e 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -2895,6 +2895,10 @@ Can be obtained via `minetest.get_meta(pos)`.
#### Methods
* All methods in MetaDataRef
* `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`
ItemStack metadata: reference extra data and functionality stored in a stack.
diff --git a/games/minimal/mods/default/init.lua b/games/minimal/mods/default/init.lua
index 64970f922..7d26f38a0 100644
--- a/games/minimal/mods/default/init.lua
+++ b/games/minimal/mods/default/init.lua
@@ -1228,6 +1228,8 @@ minetest.register_node("default:chest_locked", {
meta:set_string("owner", "")
local inv = meta:get_inventory()
inv:set_size("main", 8*4)
+ -- this is not really the intended usage but works for testing purposes:
+ meta:mark_as_private("owner")
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
diff --git a/games/minimal/mods/experimental/init.lua b/games/minimal/mods/experimental/init.lua
index 5e98e1a80..6e0fb1738 100644
--- a/games/minimal/mods/experimental/init.lua
+++ b/games/minimal/mods/experimental/init.lua
@@ -502,10 +502,16 @@ minetest.register_craftitem("experimental:tester_tool_1", {
on_use = function(itemstack, user, pointed_thing)
--print(dump(pointed_thing))
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
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
local p = pointed_thing.above
minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index 1a0b01f2b..ec10a49bb 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -611,7 +611,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
Node metadata
*/
std::ostringstream oss(std::ios_base::binary);
- m_node_metadata.serialize(oss);
+ m_node_metadata.serialize(oss, version, disk);
compressZlib(oss.str(), os);
/*
@@ -669,11 +669,10 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
u8 flags = readU8(is);
is_underground = (flags & 0x01) ? true : false;
m_day_night_differs = (flags & 0x02) ? true : false;
- if (version < 27) {
+ if (version < 27)
m_lighting_complete = 0xFFFF;
- } else {
+ else
m_lighting_complete = readU16(is);
- }
m_generated = (flags & 0x08) ? false : true;
/*
diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp
index 9b60cf33e..0e8195c34 100644
--- a/src/nodemetadata.cpp
+++ b/src/nodemetadata.cpp
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "inventory.h"
#include "log.h"
#include "util/serialize.h"
+#include "util/basic_macros.h"
#include "constants.h" // MAP_BLOCKSIZE
#include <sstream>
@@ -39,28 +40,38 @@ NodeMetadata::~NodeMetadata()
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);
for (StringMap::const_iterator
it = m_stringvars.begin();
it != m_stringvars.end(); ++it) {
+ bool priv = isPrivate(it->first);
+ if (!disk && priv)
+ continue;
+
os << serializeString(it->first);
os << serializeLongString(it->second);
+ if (version >= 2)
+ writeU8(os, (priv) ? 1 : 0);
}
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);
for(int i=0; i<num_vars; i++){
std::string name = deSerializeString(is);
std::string var = deSerializeLongString(is);
m_stringvars[name] = var;
+ if (version >= 2) {
+ if (readU8(is) == 1)
+ markPrivate(name, true);
+ }
}
m_inventory->deSerialize(is);
@@ -69,6 +80,7 @@ void NodeMetadata::deSerialize(std::istream &is)
void NodeMetadata::clear()
{
Metadata::clear();
+ m_privatevars.clear();
m_inventory->clear();
}
@@ -77,11 +89,34 @@ bool NodeMetadata::empty() const
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
*/
-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."
@@ -93,7 +128,8 @@ void NodeMetadataList::serialize(std::ostream &os) const
return;
}
- writeU8(os, 1); // version
+ u8 version = (blockver > 27) ? 2 : 1;
+ writeU8(os, version);
writeU16(os, count);
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;
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;
}
- if (version != 1) {
+ if (version > 2) {
std::string err_str = std::string(FUNCTION_NAME)
+ ": version " + itos(version) + " not supported";
infostream << err_str << std::endl;
@@ -132,7 +168,7 @@ void NodeMetadataList::deSerialize(std::istream &is, IItemDefManager *item_def_m
u16 count = readU16(is);
- for (u16 i=0; i < count; i++) {
+ for (u16 i = 0; i < count; i++) {
u16 p16 = readU16(is);
v3s16 p;
@@ -143,15 +179,14 @@ void NodeMetadataList::deSerialize(std::istream &is, IItemDefManager *item_def_m
p.X = p16;
if (m_data.find(p) != m_data.end()) {
- warningstream<<"NodeMetadataList::deSerialize(): "
- <<"already set data at position"
- <<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring."
- <<std::endl;
+ warningstream << "NodeMetadataList::deSerialize(): "
+ << "already set data at position " << PP(p)
+ << ": Ignoring." << std::endl;
continue;
}
NodeMetadata *data = new NodeMetadata(item_def_mgr);
- data->deSerialize(is);
+ data->deSerialize(is, version);
m_data[p] = data;
}
}
diff --git a/src/nodemetadata.h b/src/nodemetadata.h
index f46c0fe91..0d72485bc 100644
--- a/src/nodemetadata.h
+++ b/src/nodemetadata.h
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define NODEMETADATA_HEADER
#include "metadata.h"
+#include "util/cpp11_container.h"
/*
NodeMetadata stores arbitary amounts of data for special blocks.
@@ -40,8 +41,8 @@ public:
NodeMetadata(IItemDefManager *item_def_mgr);
~NodeMetadata();
- void serialize(std::ostream &os) const;
- void deSerialize(std::istream &is);
+ void serialize(std::ostream &os, u8 version, bool disk=true) const;
+ void deSerialize(std::istream &is, u8 version);
void clear();
bool empty() const;
@@ -52,8 +53,17 @@ public:
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:
+ int countNonPrivate() const;
+
Inventory *m_inventory;
+ UNORDERED_SET<std::string> m_privatevars;
};
@@ -66,7 +76,7 @@ class NodeMetadataList
public:
~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);
// Add all keys in this list to the vector keys
diff --git a/src/rollback_interface.cpp b/src/rollback_interface.cpp
index 40a33a51d..d02d1cb3e 100644
--- a/src/rollback_interface.cpp
+++ b/src/rollback_interface.cpp
@@ -44,7 +44,7 @@ RollbackNode::RollbackNode(Map *map, v3s16 p, IGameDef *gamedef)
NodeMetadata *metap = map->getNodeMetadata(p);
if (metap) {
std::ostringstream os(std::ios::binary);
- metap->serialize(os);
+ metap->serialize(os, 1); // FIXME: version bump??
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);
- meta->deSerialize(is);
+ meta->deSerialize(is, 1); // FIXME: version bump??
}
// Inform other things that the meta data has changed
v3s16 blockpos = getContainerPos(p, MAP_BLOCKSIZE);
diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp
index 6232112c5..5dfa6d52e 100644
--- a/src/script/lua_api/l_nodemeta.cpp
+++ b/src/script/lua_api/l_nodemeta.cpp
@@ -94,6 +94,32 @@ int NodeMetaRef::l_get_inventory(lua_State *L)
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)
{
// fields
@@ -229,6 +255,7 @@ const luaL_Reg NodeMetaRef::methodsServer[] = {
luamethod(MetaDataRef, to_table),
luamethod(MetaDataRef, from_table),
luamethod(NodeMetaRef, get_inventory),
+ luamethod(NodeMetaRef, mark_as_private),
luamethod(MetaDataRef, equals),
{0,0}
};
diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h
index 2ac028079..dd4260ff9 100644
--- a/src/script/lua_api/l_nodemeta.h
+++ b/src/script/lua_api/l_nodemeta.h
@@ -73,6 +73,9 @@ private:
// get_inventory(self)
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:
NodeMetaRef(v3s16 p, ServerEnvironment *env);
NodeMetaRef(Metadata *meta);
diff --git a/src/serialization.h b/src/serialization.h
index 52c63098e..c91c3241f 100644
--- a/src/serialization.h
+++ b/src/serialization.h
@@ -63,13 +63,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
25: Improved node timer format
26: Never written; read the same as 25
27: Added light spreading flags to blocks
+ 28: Added "private" flag to NodeMetadata
*/
// This represents an uninitialized or invalid format
#define SER_FMT_VER_INVALID 255
// Highest supported serialization version
-#define SER_FMT_VER_HIGHEST_READ 27
+#define SER_FMT_VER_HIGHEST_READ 28
// Saved on disk version
-#define SER_FMT_VER_HIGHEST_WRITE 27
+#define SER_FMT_VER_HIGHEST_WRITE 28
// Lowest supported serialization version
#define SER_FMT_VER_LOWEST_READ 0
// Lowest serialization version for writing