X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fscript%2Flua_api%2Fl_nodemeta.cpp;h=c446a8f07bceffb709e0057b39906be6c5df7948;hb=bdac12761cd92960c3df83c932aa610f2322215f;hp=511fb38ce298cfa94eb254f7ecf0975a4b297918;hpb=ab433775777c4f5055bcf4d2a1cffc506c4f9961;p=dragonfireclient.git diff --git a/src/script/lua_api/l_nodemeta.cpp b/src/script/lua_api/l_nodemeta.cpp index 511fb38ce..c446a8f07 100644 --- a/src/script/lua_api/l_nodemeta.cpp +++ b/src/script/lua_api/l_nodemeta.cpp @@ -17,14 +17,13 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "cpp_api/scriptapi.h" -#include "common/c_converter.h" -#include "common/c_content.h" -#include "map.h" #include "lua_api/l_nodemeta.h" -#include "common/c_internal.h" +#include "lua_api/l_internal.h" #include "lua_api/l_inventory.h" - +#include "common/c_content.h" +#include "serverenvironment.h" +#include "map.h" +#include "server.h" /* NodeMetaRef @@ -37,31 +36,42 @@ NodeMetaRef* NodeMetaRef::checkobject(lua_State *L, int narg) return *(NodeMetaRef**)ud; // unbox pointer } -NodeMetadata* NodeMetaRef::getmeta(NodeMetaRef *ref, bool auto_create) +Metadata* NodeMetaRef::getmeta(bool auto_create) { - NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p); - if(meta == NULL && auto_create) - { - meta = new NodeMetadata(ref->m_env->getGameDef()); - ref->m_env->getMap().setNodeMetadata(ref->m_p, meta); + 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()); + if (!m_env->getMap().setNodeMetadata(m_p, meta)) { + delete meta; + return NULL; + } } 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); - if(block) + MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos); + if (block) { block->raiseModified(MOD_STATE_WRITE_NEEDED, - "NodeMetaRef::reportMetadataChange"); + MOD_REASON_REPORT_META_CHANGE); + } } // Exported functions @@ -73,196 +83,89 @@ int NodeMetaRef::gc_object(lua_State *L) { return 0; } -// get_string(self, name) -int NodeMetaRef::l_get_string(lua_State *L) -{ - NodeMetaRef *ref = checkobject(L, 1); - std::string name = luaL_checkstring(L, 2); - - NodeMetadata *meta = getmeta(ref, 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) +// get_inventory(self) +int NodeMetaRef::l_get_inventory(lua_State *L) { - 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 = getmeta(ref, !str.empty()); - if(meta == NULL || str == meta->getString(name)) - return 0; - meta->setString(name, str); - reportMetadataChange(ref); - return 0; -} + MAP_LOCK_REQUIRED; -// get_int(self, name) -int NodeMetaRef::l_get_int(lua_State *L) -{ NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); - - NodeMetadata *meta = getmeta(ref, false); - if(meta == NULL){ - lua_pushnumber(L, 0); - return 1; - } - std::string str = meta->getString(name); - lua_pushnumber(L, stoi(str)); + ref->getmeta(true); // try to ensure the metadata exists + InvRef::createNodeMeta(L, ref->m_p); return 1; } -// set_int(self, name, var) -int NodeMetaRef::l_set_int(lua_State *L) +// mark_as_private(self, or {, , ...}) +int NodeMetaRef::l_mark_as_private(lua_State *L) { - 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 = getmeta(ref, true); - if(meta == NULL || str == meta->getString(name)) - return 0; - meta->setString(name, str); - reportMetadataChange(ref); - return 0; -} + MAP_LOCK_REQUIRED; -// get_float(self, name) -int NodeMetaRef::l_get_float(lua_State *L) -{ NodeMetaRef *ref = checkobject(L, 1); - std::string name = lua_tostring(L, 2); + NodeMetadata *meta = dynamic_cast(ref->getmeta(true)); + assert(meta); - NodeMetadata *meta = getmeta(ref, false); - if(meta == NULL){ - lua_pushnumber(L, 0); - return 1; + 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); } - std::string str = meta->getString(name); - lua_pushnumber(L, stof(str)); - return 1; -} + ref->reportMetadataChange(); -// set_float(self, name, var) -int NodeMetaRef::l_set_float(lua_State *L) -{ - 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 = getmeta(ref, 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) +void NodeMetaRef::handleToTable(lua_State *L, Metadata *_meta) { - NodeMetaRef *ref = checkobject(L, 1); - getmeta(ref, true); // try to ensure the metadata exists - InvRef::createNodeMeta(L, ref->m_p); - return 1; -} + // fields + MetaDataRef::handleToTable(L, _meta); -// to_table(self) -int NodeMetaRef::l_to_table(lua_State *L) -{ - NodeMetaRef *ref = checkobject(L, 1); + NodeMetadata *meta = (NodeMetadata*) _meta; - NodeMetadata *meta = getmeta(ref, true); - if(meta == NULL){ - lua_pushnil(L); - return 1; - } - lua_newtable(L); - // fields - lua_newtable(L); - { - std::map fields = meta->getStrings(); - for(std::map::const_iterator - i = fields.begin(); i != fields.end(); i++){ - const std::string &name = i->first; - const std::string &value = i->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"); // inventory lua_newtable(L); Inventory *inv = meta->getInventory(); - if(inv){ - std::vector lists = inv->getLists(); - for(std::vector::const_iterator - i = lists.begin(); i != lists.end(); i++){ - push_inventory_list(inv, (*i)->getName().c_str(), L); + if (inv) { + std::vector lists = inv->getLists(); + for(std::vector::const_iterator + i = lists.begin(); i != lists.end(); ++i) { + push_inventory_list(L, inv, (*i)->getName().c_str()); lua_setfield(L, -2, (*i)->getName().c_str()); } } 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) { - NodeMetaRef *ref = checkobject(L, 1); - int base = 2; + // fields + if (!MetaDataRef::handleFromTable(L, table, _meta)) + return false; - if(lua_isnil(L, base)){ - // No metadata - ref->m_env->getMap().removeNodeMetadata(ref->m_p); - lua_pushboolean(L, true); - return 1; - } + NodeMetadata *meta = (NodeMetadata*) _meta; - // Has metadata; clear old one first - ref->m_env->getMap().removeNodeMetadata(ref->m_p); - // Create new metadata - NodeMetadata *meta = getmeta(ref, true); - // Set fields - lua_getfield(L, base, "fields"); - 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); - std::string value(cs, cl); - meta->setString(name, value); - lua_pop(L, 1); // removes value, keeps key for next iteration - } - // Set inventory + // inventory Inventory *inv = meta->getInventory(); - lua_getfield(L, base, "inventory"); - int inventorytable = lua_gettop(L); - lua_pushnil(L); - while(lua_next(L, inventorytable) != 0){ - // key at index -2 and value at index -1 - std::string name = lua_tostring(L, -2); - read_inventory_list(inv, name.c_str(), L, -1,STACK_TO_SERVER(L)); - lua_pop(L, 1); // removes value, keeps key for next iteration + lua_getfield(L, table, "inventory"); + if (lua_istable(L, -1)) { + int inventorytable = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, inventorytable) != 0) { + // key at index -2 and value at index -1 + std::string name = lua_tostring(L, -2); + read_inventory_list(L, -1, inv, name.c_str(), getServer(L)); + lua_pop(L, 1); // Remove value, keep key for next iteration + } + lua_pop(L, 1); } - reportMetadataChange(ref); - lua_pushboolean(L, true); - return 1; + + return true; } @@ -272,6 +175,12 @@ NodeMetaRef::NodeMetaRef(v3s16 p, ServerEnvironment *env): { } +NodeMetaRef::NodeMetaRef(Metadata *meta): + m_meta(meta), + m_is_local(true) +{ +} + NodeMetaRef::~NodeMetaRef() { } @@ -287,7 +196,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); @@ -298,6 +217,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); @@ -306,27 +229,49 @@ void NodeMetaRef::Register(lua_State *L) lua_pushcfunction(L, gc_object); lua_settable(L, metatable); + lua_pushliteral(L, "__eq"); + lua_pushcfunction(L, l_equals); + 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[] = { - luamethod(NodeMetaRef, get_string), - luamethod(NodeMetaRef, set_string), - luamethod(NodeMetaRef, get_int), - luamethod(NodeMetaRef, set_int), - luamethod(NodeMetaRef, get_float), - luamethod(NodeMetaRef, set_float), + +const luaL_Reg NodeMetaRef::methodsServer[] = { + 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), + luamethod(NodeMetaRef, mark_as_private), + luamethod(MetaDataRef, equals), {0,0} }; -REGISTER_LUA_REF(NodeMetaRef); + +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} +};