From 13f94ecad5d4fcda08663ee91e45b4a205a1dadb Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Tue, 31 Jan 2017 16:18:45 +0000 Subject: Make NodeMetaRef::getmeta a non-static member --- src/script/lua_api/l_nodemeta.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/script/lua_api/l_nodemeta.h') diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h index e39ac3931..4ce338b18 100644 --- a/src/script/lua_api/l_nodemeta.h +++ b/src/script/lua_api/l_nodemeta.h @@ -52,7 +52,7 @@ private: * @param auto_create when true, try to create metadata information for the node if it has none. * @return pointer to a @c NodeMetadata object or @c NULL in case of error. */ - static NodeMetadata* getmeta(NodeMetaRef *ref, bool auto_create); + virtual NodeMetadata* getmeta(bool auto_create); static void reportMetadataChange(NodeMetaRef *ref); -- cgit v1.2.3 From c2e7b1f57941cb34cb7e3d71dc040fad53a64e3e Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Tue, 31 Jan 2017 16:43:45 +0000 Subject: Derive NodeMetaRef from MetaDataRef --- .gitignore | 2 +- build/android/jni/Android.mk | 1 + src/metadata.cpp | 48 ++++++-- src/metadata.h | 4 +- src/script/lua_api/CMakeLists.txt | 2 +- src/script/lua_api/l_metadata.cpp | 252 ++++++++++++++++++++++++++++++++++++++ src/script/lua_api/l_metadata.h | 71 +++++++++++ src/script/lua_api/l_nodemeta.cpp | 224 +++++---------------------------- src/script/lua_api/l_nodemeta.h | 35 ++---- 9 files changed, 407 insertions(+), 232 deletions(-) create mode 100644 src/script/lua_api/l_metadata.cpp create mode 100644 src/script/lua_api/l_metadata.h (limited to 'src/script/lua_api/l_nodemeta.h') diff --git a/.gitignore b/.gitignore index d7e0daab4..c2600afeb 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,7 @@ locale/ *.a *.ninja .ninja* +*.gch ## Android build files build/android/src/main/assets @@ -86,4 +87,3 @@ build/android/obj build/android/local.properties build/android/.gradle timestamp - diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk index 8f333c3d4..70a3d29c0 100644 --- a/build/android/jni/Android.mk +++ b/build/android/jni/Android.mk @@ -307,6 +307,7 @@ LOCAL_SRC_FILES += \ jni/src/script/lua_api/l_item.cpp \ jni/src/script/lua_api/l_mainmenu.cpp \ jni/src/script/lua_api/l_mapgen.cpp \ + jni/src/script/lua_api/l_metadata.cpp \ jni/src/script/lua_api/l_nodemeta.cpp \ jni/src/script/lua_api/l_nodetimer.cpp \ jni/src/script/lua_api/l_noise.cpp \ diff --git a/src/metadata.cpp b/src/metadata.cpp index 8e04aa2d3..96453d710 100644 --- a/src/metadata.cpp +++ b/src/metadata.cpp @@ -37,12 +37,39 @@ bool Metadata::empty() const return m_stringvars.size() == 0; } -std::string Metadata::getString(const std::string &name, - u16 recursion) const +size_t Metadata::size() const +{ + return m_stringvars.size(); +} + +bool Metadata::contains(const std::string &name) const +{ + return m_stringvars.find(name) != m_stringvars.end(); +} + +bool Metadata::operator==(const Metadata &other) const +{ + if (size() != other.size()) + return false; + + for (StringMap::const_iterator it = m_stringvars.begin(); + it != m_stringvars.end(); ++it) { + if (!other.contains(it->first) || + other.getString(it->first) != it->second) + return false; + } + + return true; +} + +const std::string &Metadata::getString(const std::string &name, + u16 recursion) const { StringMap::const_iterator it = m_stringvars.find(name); - if (it == m_stringvars.end()) - return ""; + if (it == m_stringvars.end()) { + static const std::string empty_string = std::string(""); + return empty_string; + } return resolveString(it->second, recursion); } @@ -56,14 +83,13 @@ void Metadata::setString(const std::string &name, const std::string &var) } } -std::string Metadata::resolveString(const std::string &str, - u16 recursion) const +const std::string &Metadata::resolveString(const std::string &str, + u16 recursion) const { - if (recursion > 1) { - return str; - } - if (str.substr(0, 2) == "${" && str[str.length() - 1] == '}') { + if (recursion <= 1 && + str.substr(0, 2) == "${" && str[str.length() - 1] == '}') { return getString(str.substr(2, str.length() - 3), recursion + 1); + } else { + return str; } - return str; } diff --git a/src/metadata.h b/src/metadata.h index a96bfc408..a629c0615 100644 --- a/src/metadata.h +++ b/src/metadata.h @@ -44,10 +44,10 @@ public: bool empty() const; // Generic key/value store - std::string getString(const std::string &name, u16 recursion = 0) const; + const std::string &getString(const std::string &name, u16 recursion = 0) const; void setString(const std::string &name, const std::string &var); // Support variable names in values - std::string resolveString(const std::string &str, u16 recursion = 0) const; + const std::string &resolveString(const std::string &str, u16 recursion = 0) const; const StringMap &getStrings() const { return m_stringvars; diff --git a/src/script/lua_api/CMakeLists.txt b/src/script/lua_api/CMakeLists.txt index d507dcf70..efccce515 100644 --- a/src/script/lua_api/CMakeLists.txt +++ b/src/script/lua_api/CMakeLists.txt @@ -6,6 +6,7 @@ set(common_SCRIPT_LUA_API_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/l_inventory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_item.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_mapgen.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_metadata.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_nodemeta.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_nodetimer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp @@ -22,4 +23,3 @@ set(common_SCRIPT_LUA_API_SRCS set(client_SCRIPT_LUA_API_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/l_mainmenu.cpp PARENT_SCOPE) - diff --git a/src/script/lua_api/l_metadata.cpp b/src/script/lua_api/l_metadata.cpp new file mode 100644 index 000000000..b54005bac --- /dev/null +++ b/src/script/lua_api/l_metadata.cpp @@ -0,0 +1,252 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_metadata.h" +#include "lua_api/l_internal.h" +#include "common/c_content.h" +#include "serverenvironment.h" +#include "map.h" +#include "server.h" + +// LUALIB_API +void *luaL_checkudata_is_metadataref(lua_State *L, int ud) { + void *p = lua_touserdata(L, ud); + if (p != NULL && // value is a userdata? + lua_getmetatable(L, ud)) { // does it have a metatable? + lua_getfield(L, -1, "metadata_class"); + if (lua_type(L, -1) == LUA_TSTRING) { // does it have a metadata_class field? + return p; + } + } + luaL_typerror(L, ud, "MetaDataRef"); + return NULL; +} + +MetaDataRef* MetaDataRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata_is_metadataref(L, narg); + if (!ud) + luaL_typerror(L, narg, "MetaDataRef"); + + return *(MetaDataRef**)ud; // unbox pointer +} + +// Exported functions + +// get_string(self, name) +int MetaDataRef::l_get_string(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + + Metadata *meta = ref->getmeta(false); + if (meta == NULL) { + lua_pushlstring(L, "", 0); + return 1; + } + + const std::string &str = meta->getString(name); + lua_pushlstring(L, str.c_str(), str.size()); + return 1; +} + +// set_string(self, name, var) +int MetaDataRef::l_set_string(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + size_t len = 0; + const char *s = lua_tolstring(L, 3, &len); + std::string str(s, len); + + Metadata *meta = ref->getmeta(!str.empty()); + if (meta == NULL || str == meta->getString(name)) + return 0; + + meta->setString(name, str); + ref->reportMetadataChange(); + return 0; +} + +// get_int(self, name) +int MetaDataRef::l_get_int(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = lua_tostring(L, 2); + + Metadata *meta = ref->getmeta(false); + if (meta == NULL) { + lua_pushnumber(L, 0); + return 1; + } + + const std::string &str = meta->getString(name); + lua_pushnumber(L, stoi(str)); + return 1; +} + +// set_int(self, name, var) +int MetaDataRef::l_set_int(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = lua_tostring(L, 2); + int a = lua_tointeger(L, 3); + std::string str = itos(a); + + Metadata *meta = ref->getmeta(true); + if (meta == NULL || str == meta->getString(name)) + return 0; + + meta->setString(name, str); + ref->reportMetadataChange(); + return 0; +} + +// get_float(self, name) +int MetaDataRef::l_get_float(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = lua_tostring(L, 2); + + Metadata *meta = ref->getmeta(false); + if (meta == NULL) { + lua_pushnumber(L, 0); + return 1; + } + + const std::string &str = meta->getString(name); + lua_pushnumber(L, stof(str)); + return 1; +} + +// set_float(self, name, var) +int MetaDataRef::l_set_float(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + std::string name = lua_tostring(L, 2); + float a = lua_tonumber(L, 3); + std::string str = ftos(a); + + Metadata *meta = ref->getmeta(true); + if (meta == NULL || str == meta->getString(name)) + return 0; + + meta->setString(name, str); + ref->reportMetadataChange(); + return 0; +} + +// to_table(self) +int MetaDataRef::l_to_table(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + + Metadata *meta = ref->getmeta(true); + if (meta == NULL) { + lua_pushnil(L); + return 1; + } + lua_newtable(L); + + ref->handleToTable(L, meta); + + return 1; +} + +// from_table(self, table) +int MetaDataRef::l_from_table(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + MetaDataRef *ref = checkobject(L, 1); + int base = 2; + + ref->clearMeta(); + + if (!lua_istable(L, base)) { + // No metadata + lua_pushboolean(L, true); + return 1; + } + + // Create new metadata + Metadata *meta = ref->getmeta(true); + if (meta == NULL) { + lua_pushboolean(L, false); + return 1; + } + + bool was_successful = ref->handleFromTable(L, base, meta); + ref->reportMetadataChange(); + lua_pushboolean(L, was_successful); + return 1; +} + +void MetaDataRef::handleToTable(lua_State *L, Metadata *meta) +{ + lua_newtable(L); + { + const StringMap &fields = meta->getStrings(); + for (StringMap::const_iterator + it = fields.begin(); it != fields.end(); ++it) { + const std::string &name = it->first; + const std::string &value = it->second; + lua_pushlstring(L, name.c_str(), name.size()); + lua_pushlstring(L, value.c_str(), value.size()); + lua_settable(L, -3); + } + } + lua_setfield(L, -2, "fields"); +} + +bool MetaDataRef::handleFromTable(lua_State *L, int table, Metadata *meta) +{ + // Set fields + lua_getfield(L, table, "fields"); + if (lua_istable(L, -1)) { + int fieldstable = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, fieldstable) != 0) { + // key at index -2 and value at index -1 + std::string name = lua_tostring(L, -2); + size_t cl; + const char *cs = lua_tolstring(L, -1, &cl); + meta->setString(name, std::string(cs, cl)); + lua_pop(L, 1); // Remove value, keep key for next iteration + } + lua_pop(L, 1); + } + + return true; +} diff --git a/src/script/lua_api/l_metadata.h b/src/script/lua_api/l_metadata.h new file mode 100644 index 000000000..561be6adf --- /dev/null +++ b/src/script/lua_api/l_metadata.h @@ -0,0 +1,71 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#ifndef L_METADATA_H_ +#define L_METADATA_H_ + +#include "lua_api/l_base.h" +#include "irrlichttypes_bloated.h" + +class Metadata; + +/* + NodeMetaRef +*/ + +class MetaDataRef : public ModApiBase { +public: + virtual ~MetaDataRef() {} +protected: + static MetaDataRef *checkobject(lua_State *L, int narg); + + virtual void reportMetadataChange() {} + virtual Metadata* getmeta(bool auto_create) = 0; + virtual void clearMeta() = 0; + + virtual void handleToTable(lua_State *L, Metadata *meta); + virtual bool handleFromTable(lua_State *L, int table, Metadata *meta); + + // Exported functions + + // get_string(self, name) + static int l_get_string(lua_State *L); + + // set_string(self, name, var) + static int l_set_string(lua_State *L); + + // get_int(self, name) + static int l_get_int(lua_State *L); + + // set_int(self, name, var) + static int l_set_int(lua_State *L); + + // get_float(self, name) + static int l_get_float(lua_State *L); + + // set_float(self, name, var) + static int l_set_float(lua_State *L); + + // to_table(self) + static int l_to_table(lua_State *L); + + // from_table(self, table) + static int l_from_table(lua_State *L); +}; + +#endif /* L_NODEMETA_H_ */ diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 8391de03c..4b2b392da 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -36,7 +36,7 @@ NodeMetaRef* NodeMetaRef::checkobject(lua_State *L, int narg) return *(NodeMetaRef**)ud; // unbox pointer } -NodeMetadata* NodeMetaRef::getmeta(bool auto_create) +Metadata* NodeMetaRef::getmeta(bool auto_create) { NodeMetadata *meta = m_env->getMap().getNodeMetadata(m_p); if (meta == NULL && auto_create) { @@ -49,17 +49,22 @@ NodeMetadata* NodeMetaRef::getmeta(bool auto_create) return meta; } -void NodeMetaRef::reportMetadataChange(NodeMetaRef *ref) +void NodeMetaRef::clearMeta() +{ + m_env->getMap().removeNodeMetadata(m_p); +} + +void NodeMetaRef::reportMetadataChange() { // NOTE: This same code is in rollback_interface.cpp // Inform other things that the metadata has changed - v3s16 blockpos = getNodeBlockPos(ref->m_p); + v3s16 blockpos = getNodeBlockPos(m_p); MapEditEvent event; event.type = MEET_BLOCK_NODE_METADATA_CHANGED; event.p = blockpos; - ref->m_env->getMap().dispatchEvent(&event); + m_env->getMap().dispatchEvent(&event); // Set the block to be saved - MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos); + MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos); if (block) { block->raiseModified(MOD_STATE_WRITE_NEEDED, MOD_REASON_REPORT_META_CHANGE); @@ -75,115 +80,6 @@ int NodeMetaRef::gc_object(lua_State *L) { return 0; } -// get_string(self, name) -int NodeMetaRef::l_get_string(lua_State *L) -{ - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - std::string name = luaL_checkstring(L, 2); - - NodeMetadata *meta = ref->getmeta(false); - if(meta == NULL){ - lua_pushlstring(L, "", 0); - return 1; - } - std::string str = meta->getString(name); - lua_pushlstring(L, str.c_str(), str.size()); - return 1; -} - -// set_string(self, name, var) -int NodeMetaRef::l_set_string(lua_State *L) -{ - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - std::string name = luaL_checkstring(L, 2); - size_t len = 0; - const char *s = lua_tolstring(L, 3, &len); - std::string str(s, len); - - NodeMetadata *meta = ref->getmeta(!str.empty()); - if(meta == NULL || str == meta->getString(name)) - return 0; - meta->setString(name, str); - reportMetadataChange(ref); - return 0; -} - -// get_int(self, name) -int NodeMetaRef::l_get_int(lua_State *L) -{ - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - - NodeMetadata *meta = ref->getmeta(false); - if(meta == NULL){ - lua_pushnumber(L, 0); - return 1; - } - std::string str = meta->getString(name); - lua_pushnumber(L, stoi(str)); - return 1; -} - -// set_int(self, name, var) -int NodeMetaRef::l_set_int(lua_State *L) -{ - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - int a = lua_tointeger(L, 3); - std::string str = itos(a); - - NodeMetadata *meta = ref->getmeta(true); - if(meta == NULL || str == meta->getString(name)) - return 0; - meta->setString(name, str); - reportMetadataChange(ref); - return 0; -} - -// get_float(self, name) -int NodeMetaRef::l_get_float(lua_State *L) -{ - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - - NodeMetadata *meta = ref->getmeta(false); - if(meta == NULL){ - lua_pushnumber(L, 0); - return 1; - } - std::string str = meta->getString(name); - lua_pushnumber(L, stof(str)); - return 1; -} - -// set_float(self, name, var) -int NodeMetaRef::l_set_float(lua_State *L) -{ - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - float a = lua_tonumber(L, 3); - std::string str = ftos(a); - - NodeMetadata *meta = ref->getmeta(true); - if(meta == NULL || str == meta->getString(name)) - return 0; - meta->setString(name, str); - reportMetadataChange(ref); - return 0; -} - // get_inventory(self) int NodeMetaRef::l_get_inventory(lua_State *L) { @@ -195,34 +91,12 @@ int NodeMetaRef::l_get_inventory(lua_State *L) return 1; } -// to_table(self) -int NodeMetaRef::l_to_table(lua_State *L) +void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta) { - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - - NodeMetadata *meta = ref->getmeta(true); - if (meta == NULL) { - lua_pushnil(L); - return 1; - } - lua_newtable(L); - // fields - lua_newtable(L); - { - StringMap fields = meta->getStrings(); - for (StringMap::const_iterator - it = fields.begin(); it != fields.end(); ++it) { - const std::string &name = it->first; - const std::string &value = it->second; - lua_pushlstring(L, name.c_str(), name.size()); - lua_pushlstring(L, value.c_str(), value.size()); - lua_settable(L, -3); - } - } - lua_setfield(L, -2, "fields"); + MetaDataRef::handleToTable(L, _meta); + + NodeMetadata *meta = (NodeMetadata*) _meta; // inventory lua_newtable(L); @@ -236,52 +110,20 @@ int NodeMetaRef::l_to_table(lua_State *L) } } lua_setfield(L, -2, "inventory"); - return 1; } // from_table(self, table) -int NodeMetaRef::l_from_table(lua_State *L) +bool NodeMetaRef::handleFromTable(lua_State *L, int table, Metadata *_meta) { - MAP_LOCK_REQUIRED; - - NodeMetaRef *ref = checkobject(L, 1); - int base = 2; - - // clear old metadata first - ref->m_env->getMap().removeNodeMetadata(ref->m_p); - - if (!lua_istable(L, base)) { - // No metadata - lua_pushboolean(L, true); - return 1; - } + // fields + if (!MetaDataRef::handleFromTable(L, table, _meta)) + return false; - // Create new metadata - NodeMetadata *meta = ref->getmeta(true); - if (meta == NULL) { - lua_pushboolean(L, false); - return 1; - } + NodeMetadata *meta = (NodeMetadata*) _meta; - // Set fields - lua_getfield(L, base, "fields"); - if (lua_istable(L, -1)) { - int fieldstable = lua_gettop(L); - lua_pushnil(L); - while (lua_next(L, fieldstable) != 0) { - // key at index -2 and value at index -1 - std::string name = lua_tostring(L, -2); - size_t cl; - const char *cs = lua_tolstring(L, -1, &cl); - meta->setString(name, std::string(cs, cl)); - lua_pop(L, 1); // Remove value, keep key for next iteration - } - lua_pop(L, 1); - } - - // Set inventory + // inventory Inventory *inv = meta->getInventory(); - lua_getfield(L, base, "inventory"); + lua_getfield(L, table, "inventory"); if (lua_istable(L, -1)) { int inventorytable = lua_gettop(L); lua_pushnil(L); @@ -294,9 +136,7 @@ int NodeMetaRef::l_from_table(lua_State *L) lua_pop(L, 1); } - reportMetadataChange(ref); - lua_pushboolean(L, true); - return 1; + return true; } @@ -332,6 +172,10 @@ void NodeMetaRef::Register(lua_State *L) lua_pushvalue(L, methodtable); lua_settable(L, metatable); // hide metatable from Lua getmetatable() + lua_pushliteral(L, "metadata_class"); + lua_pushlstring(L, className, strlen(className)); + lua_settable(L, metatable); + lua_pushliteral(L, "__index"); lua_pushvalue(L, methodtable); lua_settable(L, metatable); @@ -351,14 +195,14 @@ void NodeMetaRef::Register(lua_State *L) const char NodeMetaRef::className[] = "NodeMetaRef"; const luaL_reg NodeMetaRef::methods[] = { - luamethod(NodeMetaRef, get_string), - luamethod(NodeMetaRef, set_string), - luamethod(NodeMetaRef, get_int), - luamethod(NodeMetaRef, set_int), - luamethod(NodeMetaRef, get_float), - luamethod(NodeMetaRef, set_float), + luamethod(MetaDataRef, get_string), + luamethod(MetaDataRef, set_string), + luamethod(MetaDataRef, get_int), + luamethod(MetaDataRef, set_int), + luamethod(MetaDataRef, get_float), + luamethod(MetaDataRef, set_float), + luamethod(MetaDataRef, to_table), + luamethod(MetaDataRef, from_table), luamethod(NodeMetaRef, get_inventory), - luamethod(NodeMetaRef, to_table), - luamethod(NodeMetaRef, from_table), {0,0} }; diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h index 4ce338b18..d03f086c9 100644 --- a/src/script/lua_api/l_nodemeta.h +++ b/src/script/lua_api/l_nodemeta.h @@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define L_NODEMETA_H_ #include "lua_api/l_base.h" +#include "lua_api/l_metadata.h" #include "irrlichttypes_bloated.h" class ServerEnvironment; @@ -29,7 +30,7 @@ class NodeMetadata; NodeMetaRef */ -class NodeMetaRef : public ModApiBase { +class NodeMetaRef : public MetaDataRef { private: v3s16 m_p; ServerEnvironment *m_env; @@ -52,42 +53,22 @@ private: * @param auto_create when true, try to create metadata information for the node if it has none. * @return pointer to a @c NodeMetadata object or @c NULL in case of error. */ - virtual NodeMetadata* getmeta(bool auto_create); + virtual Metadata* getmeta(bool auto_create); + virtual void clearMeta(); - static void reportMetadataChange(NodeMetaRef *ref); + virtual void reportMetadataChange(); + + virtual void handleToTable(lua_State *L, Metadata *_meta); + virtual bool handleFromTable(lua_State *L, int table, Metadata *_meta); // Exported functions // garbage collector static int gc_object(lua_State *L); - // get_string(self, name) - static int l_get_string(lua_State *L); - - // set_string(self, name, var) - static int l_set_string(lua_State *L); - - // get_int(self, name) - static int l_get_int(lua_State *L); - - // set_int(self, name, var) - static int l_set_int(lua_State *L); - - // get_float(self, name) - static int l_get_float(lua_State *L); - - // set_float(self, name, var) - static int l_set_float(lua_State *L); - // get_inventory(self) static int l_get_inventory(lua_State *L); - // to_table(self) - static int l_to_table(lua_State *L); - - // from_table(self, table) - static int l_from_table(lua_State *L); - public: NodeMetaRef(v3s16 p, ServerEnvironment *env); -- cgit v1.2.3 From 000ec260017256016b62bb9936bbda1ff969e252 Mon Sep 17 00:00:00 2001 From: red-001 Date: Tue, 4 Apr 2017 06:41:37 +0100 Subject: [CSM] Add local node meta reference. (#5508) --- doc/client_lua_api.md | 15 ++++++++++- src/script/clientscripting.cpp | 2 ++ src/script/lua_api/l_client.cpp | 13 ++++++++++ src/script/lua_api/l_client.h | 3 +++ src/script/lua_api/l_nodemeta.cpp | 54 +++++++++++++++++++++++++++++++++------ src/script/lua_api/l_nodemeta.h | 12 ++++++++- 6 files changed, 89 insertions(+), 10 deletions(-) (limited to 'src/script/lua_api/l_nodemeta.h') diff --git a/doc/client_lua_api.md b/doc/client_lua_api.md index c9ccbeefa..68156efd3 100644 --- a/doc/client_lua_api.md +++ b/doc/client_lua_api.md @@ -690,6 +690,8 @@ Call these functions only at load time! for unloaded areas. * `minetest.get_node_or_nil(pos)` * Same as `get_node` but returns `nil` for unloaded areas. +* `minetest.get_meta(pos)` + * Get a `NodeMetaRef` at that position ### Player * `minetest.get_wielded_item()` @@ -794,7 +796,18 @@ It can be created via `Settings(filename)`. * write changes to file * `to_table()`: returns `{[key1]=value1,...}` -Definition tables +### NodeMetaRef +Node metadata: reference extra data and functionality stored in a node. +Can be obtained via `minetest.get_meta(pos)`. + +#### Methods +* `get_string(name)` +* `get_int(name)` +* `get_float(name)` +* `to_table()`: returns `nil` or a table with keys: + * `fields`: key-value storage + * `inventory`: `{list1 = {}, ...}}` + ----------------- ### Chat command definition (`register_chatcommand`) diff --git a/src/script/clientscripting.cpp b/src/script/clientscripting.cpp index df30a7253..17c53985d 100644 --- a/src/script/clientscripting.cpp +++ b/src/script/clientscripting.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_sound.h" #include "lua_api/l_util.h" #include "lua_api/l_item.h" +#include "lua_api/l_nodemeta.h" ClientScripting::ClientScripting(Client *client): ScriptApiBase() @@ -68,4 +69,5 @@ void ClientScripting::InitializeModApi(lua_State *L, int top) LuaItemStack::Register(L); StorageRef::Register(L); LuaMinimap::Register(L); + NodeMetaRef::RegisterClient(L); } diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp index 5f9474702..5a0cd5cc3 100644 --- a/src/script/lua_api/l_client.cpp +++ b/src/script/lua_api/l_client.cpp @@ -25,8 +25,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gettext.h" #include "l_internal.h" #include "lua_api/l_item.h" +#include "lua_api/l_nodemeta.h" #include "mainmenumanager.h" #include "util/string.h" +#include "clientenvironment.h" +#include "map.h" extern MainGameCallback *g_gamecallback; @@ -182,6 +185,15 @@ int ModApiClient::l_get_wielded_item(lua_State *L) return 1; } +// get_meta(pos) +int ModApiClient::l_get_meta(lua_State *L) +{ + v3s16 p = read_v3s16(L, 1); + NodeMetadata *meta = getClient(L)->getEnv().getMap().getNodeMetadata(p); + NodeMetaRef::createClient(L, meta); + return 1; +} + void ModApiClient::Initialize(lua_State *L, int top) { API_FCT(get_current_modname); @@ -196,4 +208,5 @@ void ModApiClient::Initialize(lua_State *L, int top) API_FCT(get_node_or_nil); API_FCT(get_wielded_item); API_FCT(disconnect); + API_FCT(get_meta); } diff --git a/src/script/lua_api/l_client.h b/src/script/lua_api/l_client.h index d7f92ac1c..94b154bb4 100644 --- a/src/script/lua_api/l_client.h +++ b/src/script/lua_api/l_client.h @@ -62,6 +62,9 @@ private: // get_wielded_item() static int l_get_wielded_item(lua_State *L); + // get_meta(pos) + static int l_get_meta(lua_State *L); + public: static void Initialize(lua_State *L, int top); }; diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 4b2b392da..4368a8c50 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -38,6 +38,9 @@ NodeMetaRef* NodeMetaRef::checkobject(lua_State *L, int narg) Metadata* NodeMetaRef::getmeta(bool auto_create) { + if (m_is_local) + return m_meta; + NodeMetadata *meta = m_env->getMap().getNodeMetadata(m_p); if (meta == NULL && auto_create) { meta = new NodeMetadata(m_env->getGameDef()->idef()); @@ -142,7 +145,14 @@ bool NodeMetaRef::handleFromTable(lua_State *L, int table, Metadata *_meta) NodeMetaRef::NodeMetaRef(v3s16 p, ServerEnvironment *env): m_p(p), - m_env(env) + m_env(env), + m_is_local(false) +{ +} + +NodeMetaRef::NodeMetaRef(Metadata *meta): + m_meta(meta), + m_is_local(true) { } @@ -161,7 +171,17 @@ void NodeMetaRef::create(lua_State *L, v3s16 p, ServerEnvironment *env) lua_setmetatable(L, -2); } -void NodeMetaRef::Register(lua_State *L) +// Client-sided version of the above +void NodeMetaRef::createClient(lua_State *L, Metadata *meta) +{ + NodeMetaRef *o = new NodeMetaRef(meta); + *(void **)(lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); +} + +const char NodeMetaRef::className[] = "NodeMetaRef"; +void NodeMetaRef::RegisterCommon(lua_State *L) { lua_newtable(L); int methodtable = lua_gettop(L); @@ -185,16 +205,17 @@ void NodeMetaRef::Register(lua_State *L) lua_settable(L, metatable); lua_pop(L, 1); // drop metatable +} - luaL_openlib(L, 0, methods, 0); // fill methodtable +void NodeMetaRef::Register(lua_State *L) +{ + RegisterCommon(L); + luaL_openlib(L, 0, methodsServer, 0); // fill methodtable lua_pop(L, 1); // drop methodtable - - // Cannot be created from Lua - //lua_register(L, className, create_object); } -const char NodeMetaRef::className[] = "NodeMetaRef"; -const luaL_reg NodeMetaRef::methods[] = { + +const luaL_reg NodeMetaRef::methodsServer[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, set_string), luamethod(MetaDataRef, get_int), @@ -206,3 +227,20 @@ const luaL_reg NodeMetaRef::methods[] = { luamethod(NodeMetaRef, get_inventory), {0,0} }; + + +void NodeMetaRef::RegisterClient(lua_State *L) +{ + RegisterCommon(L); + luaL_openlib(L, 0, methodsClient, 0); // fill methodtable + lua_pop(L, 1); // drop methodtable +} + + +const luaL_reg NodeMetaRef::methodsClient[] = { + luamethod(MetaDataRef, get_string), + luamethod(MetaDataRef, get_int), + luamethod(MetaDataRef, get_float), + luamethod(MetaDataRef, to_table), + {0,0} +}; diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h index d03f086c9..6d146416b 100644 --- a/src/script/lua_api/l_nodemeta.h +++ b/src/script/lua_api/l_nodemeta.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_base.h" #include "lua_api/l_metadata.h" #include "irrlichttypes_bloated.h" +#include "nodemetadata.h" class ServerEnvironment; class NodeMetadata; @@ -34,9 +35,12 @@ class NodeMetaRef : public MetaDataRef { private: v3s16 m_p; ServerEnvironment *m_env; + Metadata *m_meta; + bool m_is_local; static const char className[]; - static const luaL_reg methods[]; + static const luaL_reg methodsServer[]; + static const luaL_reg methodsClient[]; static NodeMetaRef *checkobject(lua_State *L, int narg); @@ -71,6 +75,7 @@ private: public: NodeMetaRef(v3s16 p, ServerEnvironment *env); + NodeMetaRef(Metadata *meta); ~NodeMetaRef(); @@ -78,7 +83,12 @@ public: // Not callable from Lua; all references are created on the C side. static void create(lua_State *L, v3s16 p, ServerEnvironment *env); + // Client-sided version of the above + static void createClient(lua_State *L, Metadata *meta); + + static void RegisterCommon(lua_State *L); static void Register(lua_State *L); + static void RegisterClient(lua_State *L); }; #endif /* L_NODEMETA_H_ */ -- cgit v1.2.3 From 41c54830242269de073e4a0c10d1775dfdf6811d Mon Sep 17 00:00:00 2001 From: Loïc Blot Date: Sat, 8 Apr 2017 09:28:37 +0200 Subject: Replace luaL_reg with luaL_Reg as recent LuaJIT dropped the Lua 5.0 compat (#5541) We are bundling Lua5.1 which has same macro --- src/script/lua_api/l_areastore.cpp | 4 ++-- src/script/lua_api/l_areastore.h | 2 +- src/script/lua_api/l_inventory.cpp | 2 +- src/script/lua_api/l_inventory.h | 2 +- src/script/lua_api/l_item.cpp | 2 +- src/script/lua_api/l_item.h | 2 +- src/script/lua_api/l_itemstackmeta.cpp | 2 +- src/script/lua_api/l_itemstackmeta.h | 2 +- src/script/lua_api/l_minimap.cpp | 2 +- src/script/lua_api/l_minimap.h | 2 +- src/script/lua_api/l_nodemeta.cpp | 4 ++-- src/script/lua_api/l_nodemeta.h | 4 ++-- src/script/lua_api/l_nodetimer.cpp | 2 +- src/script/lua_api/l_nodetimer.h | 2 +- src/script/lua_api/l_noise.cpp | 10 +++++----- src/script/lua_api/l_noise.h | 10 +++++----- src/script/lua_api/l_object.cpp | 2 +- src/script/lua_api/l_object.h | 2 +- src/script/lua_api/l_settings.cpp | 2 +- src/script/lua_api/l_settings.h | 2 +- src/script/lua_api/l_storage.cpp | 2 +- src/script/lua_api/l_storage.h | 2 +- src/script/lua_api/l_vmanip.cpp | 2 +- src/script/lua_api/l_vmanip.h | 2 +- 24 files changed, 35 insertions(+), 35 deletions(-) (limited to 'src/script/lua_api/l_nodemeta.h') diff --git a/src/script/lua_api/l_areastore.cpp b/src/script/lua_api/l_areastore.cpp index 09a5c78f9..b81985a7f 100644 --- a/src/script/lua_api/l_areastore.cpp +++ b/src/script/lua_api/l_areastore.cpp @@ -74,7 +74,7 @@ static inline void push_areas(lua_State *L, const std::vector &areas, static int deserialization_helper(lua_State *L, AreaStore *as, std::istream &is) { - try { + try { as->deserialize(is); } catch (const SerializationError &e) { lua_pushboolean(L, false); @@ -380,7 +380,7 @@ void LuaAreaStore::Register(lua_State *L) } const char LuaAreaStore::className[] = "AreaStore"; -const luaL_reg LuaAreaStore::methods[] = { +const luaL_Reg LuaAreaStore::methods[] = { luamethod(LuaAreaStore, get_area), luamethod(LuaAreaStore, get_areas_for_pos), luamethod(LuaAreaStore, get_areas_in_area), diff --git a/src/script/lua_api/l_areastore.h b/src/script/lua_api/l_areastore.h index 7dea08df4..8292e7712 100644 --- a/src/script/lua_api/l_areastore.h +++ b/src/script/lua_api/l_areastore.h @@ -28,7 +28,7 @@ class LuaAreaStore : public ModApiBase { private: static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static int gc_object(lua_State *L); diff --git a/src/script/lua_api/l_inventory.cpp b/src/script/lua_api/l_inventory.cpp index 9a4aa845d..f5e76a7b6 100644 --- a/src/script/lua_api/l_inventory.cpp +++ b/src/script/lua_api/l_inventory.cpp @@ -463,7 +463,7 @@ void InvRef::Register(lua_State *L) } const char InvRef::className[] = "InvRef"; -const luaL_reg InvRef::methods[] = { +const luaL_Reg InvRef::methods[] = { luamethod(InvRef, is_empty), luamethod(InvRef, get_size), luamethod(InvRef, set_size), diff --git a/src/script/lua_api/l_inventory.h b/src/script/lua_api/l_inventory.h index cc5333965..91d41c0d0 100644 --- a/src/script/lua_api/l_inventory.h +++ b/src/script/lua_api/l_inventory.h @@ -36,7 +36,7 @@ private: InventoryLocation m_loc; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static InvRef *checkobject(lua_State *L, int narg); diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp index 7e6f457e1..19b5b0955 100644 --- a/src/script/lua_api/l_item.cpp +++ b/src/script/lua_api/l_item.cpp @@ -462,7 +462,7 @@ void LuaItemStack::Register(lua_State *L) } const char LuaItemStack::className[] = "ItemStack"; -const luaL_reg LuaItemStack::methods[] = { +const luaL_Reg LuaItemStack::methods[] = { luamethod(LuaItemStack, is_empty), luamethod(LuaItemStack, get_name), luamethod(LuaItemStack, set_name), diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h index 1ba5d79e0..b4efaefc8 100644 --- a/src/script/lua_api/l_item.h +++ b/src/script/lua_api/l_item.h @@ -28,7 +28,7 @@ private: ItemStack m_stack; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions diff --git a/src/script/lua_api/l_itemstackmeta.cpp b/src/script/lua_api/l_itemstackmeta.cpp index 304a7cdf3..efdd77b51 100644 --- a/src/script/lua_api/l_itemstackmeta.cpp +++ b/src/script/lua_api/l_itemstackmeta.cpp @@ -102,7 +102,7 @@ void ItemStackMetaRef::Register(lua_State *L) } const char ItemStackMetaRef::className[] = "ItemStackMetaRef"; -const luaL_reg ItemStackMetaRef::methods[] = { +const luaL_Reg ItemStackMetaRef::methods[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, set_string), luamethod(MetaDataRef, get_int), diff --git a/src/script/lua_api/l_itemstackmeta.h b/src/script/lua_api/l_itemstackmeta.h index 6f9b2016c..4ef64a91e 100644 --- a/src/script/lua_api/l_itemstackmeta.h +++ b/src/script/lua_api/l_itemstackmeta.h @@ -31,7 +31,7 @@ private: ItemStack *istack; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static ItemStackMetaRef *checkobject(lua_State *L, int narg); diff --git a/src/script/lua_api/l_minimap.cpp b/src/script/lua_api/l_minimap.cpp index 182894f4f..c68602909 100644 --- a/src/script/lua_api/l_minimap.cpp +++ b/src/script/lua_api/l_minimap.cpp @@ -201,7 +201,7 @@ void LuaMinimap::Register(lua_State *L) } const char LuaMinimap::className[] = "Minimap"; -const luaL_reg LuaMinimap::methods[] = { +const luaL_Reg LuaMinimap::methods[] = { luamethod(LuaMinimap, show), luamethod(LuaMinimap, hide), luamethod(LuaMinimap, get_pos), diff --git a/src/script/lua_api/l_minimap.h b/src/script/lua_api/l_minimap.h index 9a299b4fd..8be72b8e7 100644 --- a/src/script/lua_api/l_minimap.h +++ b/src/script/lua_api/l_minimap.h @@ -28,7 +28,7 @@ class LuaMinimap : public ModApiBase { private: static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // garbage collector static int gc_object(lua_State *L); diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 4368a8c50..55d11fc13 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -215,7 +215,7 @@ void NodeMetaRef::Register(lua_State *L) } -const luaL_reg NodeMetaRef::methodsServer[] = { +const luaL_Reg NodeMetaRef::methodsServer[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, set_string), luamethod(MetaDataRef, get_int), @@ -237,7 +237,7 @@ void NodeMetaRef::RegisterClient(lua_State *L) } -const luaL_reg NodeMetaRef::methodsClient[] = { +const luaL_Reg NodeMetaRef::methodsClient[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, get_int), luamethod(MetaDataRef, get_float), diff --git a/src/script/lua_api/l_nodemeta.h b/src/script/lua_api/l_nodemeta.h index 6d146416b..2ac028079 100644 --- a/src/script/lua_api/l_nodemeta.h +++ b/src/script/lua_api/l_nodemeta.h @@ -39,8 +39,8 @@ private: bool m_is_local; static const char className[]; - static const luaL_reg methodsServer[]; - static const luaL_reg methodsClient[]; + static const luaL_Reg methodsServer[]; + static const luaL_Reg methodsClient[]; static NodeMetaRef *checkobject(lua_State *L, int narg); diff --git a/src/script/lua_api/l_nodetimer.cpp b/src/script/lua_api/l_nodetimer.cpp index ed11cc58e..17b275c46 100644 --- a/src/script/lua_api/l_nodetimer.cpp +++ b/src/script/lua_api/l_nodetimer.cpp @@ -162,7 +162,7 @@ void NodeTimerRef::Register(lua_State *L) } const char NodeTimerRef::className[] = "NodeTimerRef"; -const luaL_reg NodeTimerRef::methods[] = { +const luaL_Reg NodeTimerRef::methods[] = { luamethod(NodeTimerRef, start), luamethod(NodeTimerRef, set), luamethod(NodeTimerRef, stop), diff --git a/src/script/lua_api/l_nodetimer.h b/src/script/lua_api/l_nodetimer.h index 239112037..ae362d8b3 100644 --- a/src/script/lua_api/l_nodetimer.h +++ b/src/script/lua_api/l_nodetimer.h @@ -32,7 +32,7 @@ private: ServerEnvironment *m_env; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static int gc_object(lua_State *L); diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp index e0039371f..e3e76191f 100644 --- a/src/script/lua_api/l_noise.cpp +++ b/src/script/lua_api/l_noise.cpp @@ -135,7 +135,7 @@ void LuaPerlinNoise::Register(lua_State *L) const char LuaPerlinNoise::className[] = "PerlinNoise"; -const luaL_reg LuaPerlinNoise::methods[] = { +const luaL_Reg LuaPerlinNoise::methods[] = { luamethod(LuaPerlinNoise, get2d), luamethod(LuaPerlinNoise, get3d), {0,0} @@ -393,7 +393,7 @@ void LuaPerlinNoiseMap::Register(lua_State *L) const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap"; -const luaL_reg LuaPerlinNoiseMap::methods[] = { +const luaL_Reg LuaPerlinNoiseMap::methods[] = { luamethod(LuaPerlinNoiseMap, get2dMap), luamethod(LuaPerlinNoiseMap, get2dMap_flat), luamethod(LuaPerlinNoiseMap, calc2dMap), @@ -498,7 +498,7 @@ void LuaPseudoRandom::Register(lua_State *L) const char LuaPseudoRandom::className[] = "PseudoRandom"; -const luaL_reg LuaPseudoRandom::methods[] = { +const luaL_Reg LuaPseudoRandom::methods[] = { luamethod(LuaPseudoRandom, next), {0,0} }; @@ -597,7 +597,7 @@ void LuaPcgRandom::Register(lua_State *L) const char LuaPcgRandom::className[] = "PcgRandom"; -const luaL_reg LuaPcgRandom::methods[] = { +const luaL_Reg LuaPcgRandom::methods[] = { luamethod(LuaPcgRandom, next), luamethod(LuaPcgRandom, rand_normal_dist), {0,0} @@ -711,7 +711,7 @@ void LuaSecureRandom::Register(lua_State *L) } const char LuaSecureRandom::className[] = "SecureRandom"; -const luaL_reg LuaSecureRandom::methods[] = { +const luaL_Reg LuaSecureRandom::methods[] = { luamethod(LuaSecureRandom, next_bytes), {0,0} }; diff --git a/src/script/lua_api/l_noise.h b/src/script/lua_api/l_noise.h index 11ec348bf..f252b5ba2 100644 --- a/src/script/lua_api/l_noise.h +++ b/src/script/lua_api/l_noise.h @@ -32,7 +32,7 @@ class LuaPerlinNoise : public ModApiBase private: NoiseParams np; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions @@ -64,7 +64,7 @@ class LuaPerlinNoiseMap : public ModApiBase Noise *noise; bool m_is3d; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions @@ -103,7 +103,7 @@ private: PseudoRandom m_pseudo; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions @@ -134,7 +134,7 @@ private: PcgRandom m_rnd; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // Exported functions @@ -169,7 +169,7 @@ class LuaSecureRandom : public ModApiBase private: static const size_t RAND_BUF_SIZE = 2048; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; u32 m_rand_idx; char m_rand_buf[RAND_BUF_SIZE]; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index d5681b809..f9d2754e7 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1823,7 +1823,7 @@ void ObjectRef::Register(lua_State *L) } const char ObjectRef::className[] = "ObjectRef"; -const luaL_reg ObjectRef::methods[] = { +const luaL_Reg ObjectRef::methods[] = { // ServerActiveObject luamethod(ObjectRef, remove), luamethod_aliased(ObjectRef, get_pos, getpos), diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 2c9aa559a..b6fc35bc2 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -37,7 +37,7 @@ private: ServerActiveObject *m_object; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; public: static ObjectRef *checkobject(lua_State *L, int narg); diff --git a/src/script/lua_api/l_settings.cpp b/src/script/lua_api/l_settings.cpp index d3fe03005..809f7d115 100644 --- a/src/script/lua_api/l_settings.cpp +++ b/src/script/lua_api/l_settings.cpp @@ -214,7 +214,7 @@ LuaSettings* LuaSettings::checkobject(lua_State* L, int narg) } const char LuaSettings::className[] = "Settings"; -const luaL_reg LuaSettings::methods[] = { +const luaL_Reg LuaSettings::methods[] = { luamethod(LuaSettings, get), luamethod(LuaSettings, get_bool), luamethod(LuaSettings, set), diff --git a/src/script/lua_api/l_settings.h b/src/script/lua_api/l_settings.h index d5edd32ce..b90f0a8f2 100644 --- a/src/script/lua_api/l_settings.h +++ b/src/script/lua_api/l_settings.h @@ -28,7 +28,7 @@ class LuaSettings : public ModApiBase { private: static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; // garbage collector static int gc_object(lua_State *L); diff --git a/src/script/lua_api/l_storage.cpp b/src/script/lua_api/l_storage.cpp index 867ab9c8d..59906dda5 100644 --- a/src/script/lua_api/l_storage.cpp +++ b/src/script/lua_api/l_storage.cpp @@ -129,7 +129,7 @@ void StorageRef::clearMeta() } const char StorageRef::className[] = "StorageRef"; -const luaL_reg StorageRef::methods[] = { +const luaL_Reg StorageRef::methods[] = { luamethod(MetaDataRef, get_string), luamethod(MetaDataRef, set_string), luamethod(MetaDataRef, get_int), diff --git a/src/script/lua_api/l_storage.h b/src/script/lua_api/l_storage.h index e09b8b391..ec6f8d941 100644 --- a/src/script/lua_api/l_storage.h +++ b/src/script/lua_api/l_storage.h @@ -41,7 +41,7 @@ private: ModMetadata *m_object; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; virtual Metadata *getmeta(bool auto_create); virtual void clearMeta(); diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp index 5f129d2af..7316fb200 100644 --- a/src/script/lua_api/l_vmanip.cpp +++ b/src/script/lua_api/l_vmanip.cpp @@ -452,7 +452,7 @@ void LuaVoxelManip::Register(lua_State *L) } const char LuaVoxelManip::className[] = "VoxelManip"; -const luaL_reg LuaVoxelManip::methods[] = { +const luaL_Reg LuaVoxelManip::methods[] = { luamethod(LuaVoxelManip, read_from_map), luamethod(LuaVoxelManip, get_data), luamethod(LuaVoxelManip, set_data), diff --git a/src/script/lua_api/l_vmanip.h b/src/script/lua_api/l_vmanip.h index 65fc0d97a..b6a69f36a 100644 --- a/src/script/lua_api/l_vmanip.h +++ b/src/script/lua_api/l_vmanip.h @@ -38,7 +38,7 @@ private: bool is_mapgen_vm; static const char className[]; - static const luaL_reg methods[]; + static const luaL_Reg methods[]; static int gc_object(lua_State *L); -- cgit v1.2.3 From 071e114ffa945522a7a9acc3259427166992d5ee Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 10 May 2017 15:29:21 +0200 Subject: Private nodemeta (#5702) * Private node metadata that isn't sent to the client --- doc/lua_api.txt | 4 ++ games/minimal/mods/default/init.lua | 2 + games/minimal/mods/experimental/init.lua | 10 ++++- src/mapblock.cpp | 7 ++-- src/nodemetadata.cpp | 63 +++++++++++++++++++++++++------- src/nodemetadata.h | 16 ++++++-- src/rollback_interface.cpp | 4 +- src/script/lua_api/l_nodemeta.cpp | 27 ++++++++++++++ src/script/lua_api/l_nodemeta.h | 3 ++ src/serialization.h | 5 ++- 10 files changed, 114 insertions(+), 27 deletions(-) (limited to 'src/script/lua_api/l_nodemeta.h') 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 @@ -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= 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::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" - <<"("<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 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, or {, , ...}) +int NodeMetaRef::l_mark_as_private(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + NodeMetaRef *ref = checkobject(L, 1); + NodeMetadata *meta = dynamic_cast(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, or {, , ...}) + 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 -- cgit v1.2.3