diff --git a/builtin/game/features.lua b/builtin/game/features.lua index 874d3e885..a27160961 100644 --- a/builtin/game/features.lua +++ b/builtin/game/features.lua @@ -39,6 +39,7 @@ core.features = { dynamic_add_media_filepath = true, lsystem_decoration_type = true, item_meta_range = true, + have_guids = true, } function core.has_feature(arg) diff --git a/doc/lua_api.md b/doc/lua_api.md index cca231c73..a6139d897 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -5432,6 +5432,8 @@ Utilities lsystem_decoration_type = true, -- Overrideable pointing range using the itemstack meta key `"range"` (5.9.0) item_meta_range = true, + -- objects have get_guid method and lua entities alse set_guid method (5.9.0) + have_guids = true, } ``` @@ -7283,6 +7285,8 @@ Global tables as they are only read when spawning. * `minetest.object_refs` * Map of object references, indexed by active object id +* `minetest.objects_by_guid` + * Map of object references, indexed by active object GUID * `minetest.luaentities` * Map of Lua entities, indexed by active object id * `minetest.registered_abms` @@ -7934,6 +7938,9 @@ child will follow movement and rotation of that bone. -- Default: false } ``` +* `get_guid()`: returns a global unique identifier (a string) + * For players a global unique identiticator is a player name. + * For non-player objects, it is unique generated string. #### Lua entity only (no-op for other objects) @@ -7941,6 +7948,10 @@ child will follow movement and rotation of that bone. * The object is removed after returning from Lua. However the `ObjectRef` itself instantly becomes unusable with all further method calls having no effect and returning `nil`. +* `set_guid(guid)`: + * Set a global unique identifier string of entity. + * Is valid to be called only in `on_activate` callback. + * Should be used ONLY for restoring saved guid from staticdata!!! * `set_velocity(vel)` * Sets the velocity * `vel` is a vector, e.g. `{x=0.0, y=2.3, z=1.0}` diff --git a/doc/world_format.md b/doc/world_format.md index b5a2a3cfa..be7571cc9 100644 --- a/doc/world_format.md +++ b/doc/world_format.md @@ -582,6 +582,9 @@ Since protocol version 37: * `u8` `version2` (=1) * `s32` pitch * 1000 * `s32` roll * 1000 +* if version2 >= 2: + * u32 len + * u8[len] guid # Itemstring Format diff --git a/games/devtest/mods/unittests/entity.lua b/games/devtest/mods/unittests/entity.lua index 565dd6adf..394aae0e4 100644 --- a/games/devtest/mods/unittests/entity.lua +++ b/games/devtest/mods/unittests/entity.lua @@ -52,6 +52,22 @@ core.register_entity("unittests:callbacks", { end, }) +core.register_entity("unittests:guid", { + initial_properties = { + static_save = false, + }, + on_activate = function(self, staticdata, dtime_s) + self.object:set_guid("@UNITTEST") + insert_log("on_activate(%d)", #staticdata) + end, + on_deactivate = function(self, removal) + insert_log("on_deactivate(%s)", tostring(removal)) + end, + get_staticdata = function(self) + assert(false) + end, +}) + -- local function check_log(expect) @@ -130,3 +146,26 @@ local function test_entity_attach(player, pos) obj:remove() end unittests.register("test_entity_attach", test_entity_attach, {player=true, map=true}) + +local function test_entity_guid(_, pos) + log = {} + + local obj = core.add_entity(pos, "unittests:callbacks") + check_log({"on_activate(0)"}) + + assert(obj:get_guid()~="") + + obj:remove() + check_log({"on_deactivate(true)"}) + + assert(core.objects_by_guid["@UNITTEST"]==nil) + obj = core.add_entity(pos, "unittests:guid") + check_log({"on_activate(0)"}) + + assert(obj:get_guid()=="@UNITTEST") + assert(core.objects_by_guid["@UNITTEST"]~=nil) + + obj:remove() +end +unittests.register("test_entity_guid", test_entity_guid, {map=true}) + diff --git a/games/devtest/mods/unittests/player.lua b/games/devtest/mods/unittests/player.lua index 70b3b6cae..d496f77ef 100644 --- a/games/devtest/mods/unittests/player.lua +++ b/games/devtest/mods/unittests/player.lua @@ -84,3 +84,10 @@ local function run_player_add_pos_tests(player) end unittests.register("test_player_add_pos", run_player_add_pos_tests, {player=true}) +-- +-- Player get uuid +-- +local function test_player_guid_tests(player) + assert(player:get_guid()==player:get_player_name()) +end +unittests.register("test_player_guid", test_player_guid_tests, {player=true}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bf849493a..fcc2aa697 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -381,6 +381,7 @@ set(common_SRCS face_position_cache.cpp filesys.cpp gettext.cpp + guid.cpp httpfetch.cpp hud.cpp inventory.cpp diff --git a/src/guid.cpp b/src/guid.cpp new file mode 100644 index 000000000..1709adb58 --- /dev/null +++ b/src/guid.cpp @@ -0,0 +1,50 @@ +/* +Minetest +Copyright (C) 2021, DS + +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 "guid.h" +#include + +#include "serverenvironment.h" +#include "util/base64.h" + +GUIdGenerator::GUIdGenerator() : + m_uniform(0, UINT64_MAX) +{ + m_rand_usable = m_rand.entropy() > 0.01; +} + +GUId GUIdGenerator::next(const std::string &prefix) +{ + std::stringstream s_guid; + + u64 a[2]; + if (m_rand_usable) { + a[0] = m_uniform(m_rand); + a[1] = m_uniform(m_rand); + } + else { + a[0] = (static_cast(m_env->getGameTime()) << 32) + m_next; + a[1] = m_uniform(m_rand); + m_next++; + } + s_guid << prefix << base64_encode(std::string_view(reinterpret_cast(a), 16)); + + return s_guid.str(); +} + diff --git a/src/guid.h b/src/guid.h new file mode 100644 index 000000000..e2698f0d5 --- /dev/null +++ b/src/guid.h @@ -0,0 +1,68 @@ +/* +Minetest +Copyright (C) 2021, DS + +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. +*/ + +#pragma once + +#include "irrlichttypes.h" +#include "util/basic_macros.h" +#include +#include + +class ServerEnvironment; + +/** + * A global unique identifier. + * It is global because it stays valid in a world forever. + * It is unique because there are no collisions. + */ +typedef std::string GUId; + +/** + * Generates infinitely many guids. + */ +class GUIdGenerator { +public: + /** + * Creates a new uninitialized generator. + * @param env ServerEnvironment where generator is running + * @param prefix Prefix of generated GUId + * @param next next value getted from loadMeta + */ + GUIdGenerator(); + + ~GUIdGenerator() = default; + DISABLE_CLASS_COPY(GUIdGenerator) + + /** + * Generates the next guid, which it will never return again. + * @return the new guid, or "" if the generator is not yet initialized + */ + GUId next(const std::string &prefix); + +private: + void setServerEnvironment(ServerEnvironment *env) { m_env = env; } + + ServerEnvironment *m_env; + std::random_device m_rand; + std::uniform_int_distribution m_uniform; + bool m_rand_usable; + u32 m_next; + + friend class ServerEnvironment; +}; diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index 7731de7a7..1164e2588 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -433,11 +433,12 @@ void ScriptApiBase::setOriginFromTableRaw(int index, const char *fxn) /* * How ObjectRefs are handled in Lua: * When an active object is created, an ObjectRef is created on the Lua side - * and stored in core.object_refs[id]. + * and stored in core.object_refs[id] and in core.objects_by_guids[[GUID]. * Methods that require an ObjectRef to a certain object retrieve it from that * table instead of creating their own.(*) * When an active object is removed, the existing ObjectRef is invalidated - * using ::set_null() and removed from the core.object_refs table. + * using ::set_null() and removed from the core.object_refs and + * core.object_by_guids tables. * (*) An exception to this are NULL ObjectRefs and anonymous ObjectRefs * for objects without ID. * It's unclear what the latter are needed for and their use is problematic @@ -465,6 +466,27 @@ void ScriptApiBase::addObjectReference(ServerActiveObject *cobj) lua_settable(L, objectstable); } +void ScriptApiBase::addObjectByGuid(ServerActiveObject *cobj) +{ + SCRIPTAPI_PRECHECKHEADER + assert(getType() == ScriptingType::Server); + + // Create object on stack + ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack + int object = lua_gettop(L); + + // Get core.objects_by_guid table + lua_getglobal(L, "core"); + lua_getfield(L, -1, "objects_by_guid"); + luaL_checktype(L, -1, LUA_TTABLE); + int objectstable = lua_gettop(L); + + // objects_by_guid[GUID] = object + lua_pushstring(L, cobj->getGuid().c_str()); // Push GUID + lua_pushvalue(L, object); // Copy object to top of stack + lua_settable(L, objectstable); +} + void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj) { SCRIPTAPI_PRECHECKHEADER @@ -472,6 +494,7 @@ void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj) // Get core.object_refs table lua_getglobal(L, "core"); + int core = lua_gettop(L); lua_getfield(L, -1, "object_refs"); luaL_checktype(L, -1, LUA_TTABLE); int objectstable = lua_gettop(L); @@ -484,7 +507,17 @@ void ScriptApiBase::removeObjectReference(ServerActiveObject *cobj) lua_pop(L, 1); // pop object // Set object_refs[id] = nil - lua_pushnumber(L, cobj->getId()); // Push id + lua_pushnumber(L, cobj->getId()); // Push GUID + lua_pushnil(L); + lua_settable(L, objectstable); + + // Get core.objects_by_guid + lua_getfield(L, core, "objects_by_guid"); + luaL_checktype(L, -1, LUA_TTABLE); + objectstable = lua_gettop(L); + + // Set objects_by_guid[GUID] = nil + lua_pushstring(L, cobj->getGuid().c_str()); // Push GUID lua_pushnil(L); lua_settable(L, objectstable); } diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h index ac74c2e68..9eab805d0 100644 --- a/src/script/cpp_api/s_base.h +++ b/src/script/cpp_api/s_base.h @@ -100,6 +100,7 @@ public: /* object */ void addObjectReference(ServerActiveObject *cobj); + void addObjectByGuid(ServerActiveObject *cobj); void removeObjectReference(ServerActiveObject *cobj); ScriptingType getType() { return m_type; } diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index ad4b7af41..30d5da3cd 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -106,6 +106,21 @@ int ObjectRef::l_remove(lua_State *L) return 0; } +// get_guid() +int ObjectRef::l_get_guid(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkObject(L, 1); + ServerActiveObject *sao = getobject(ref); + if (sao == nullptr) + return 0; + + const std::string &guid = sao->getGuid(); + + lua_pushstring(L, guid.c_str()); + return 1; +} + // get_pos(self) int ObjectRef::l_get_pos(lua_State *L) { @@ -1120,6 +1135,25 @@ int ObjectRef::l_set_sprite(lua_State *L) return 0; } +// set_guid(self, guid) +int ObjectRef::l_set_guid(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkObject(L, 1); + LuaEntitySAO *entitysao = getluaobject(ref); + if (entitysao == nullptr) + return 0; + + std::string guid = readParam(L, 2, ""); + + if (!guid.empty()) + lua_pushboolean(L, entitysao->setGuid(guid)); + else + lua_pushboolean(L, false); + + return 1; +} + // DEPRECATED // get_entity_name(self) int ObjectRef::l_get_entity_name(lua_State *L) @@ -2632,6 +2666,7 @@ const char ObjectRef::className[] = "ObjectRef"; luaL_Reg ObjectRef::methods[] = { // ServerActiveObject luamethod(ObjectRef, remove), + luamethod(ObjectRef, get_guid), luamethod_aliased(ObjectRef, get_pos, getpos), luamethod_aliased(ObjectRef, set_pos, setpos), luamethod(ObjectRef, add_pos), @@ -2679,6 +2714,7 @@ luaL_Reg ObjectRef::methods[] = { luamethod_aliased(ObjectRef, set_texture_mod, settexturemod), luamethod(ObjectRef, get_texture_mod), luamethod_aliased(ObjectRef, set_sprite, setsprite), + luamethod(ObjectRef, set_guid), luamethod(ObjectRef, get_entity_name), luamethod(ObjectRef, get_luaentity), diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 73264db10..ff072040b 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -67,6 +67,9 @@ private: // remove(self) static int l_remove(lua_State *L); + // get_guid() + static int l_get_guid(lua_State *L); + // get_pos(self) static int l_get_pos(lua_State *L); @@ -200,6 +203,9 @@ private: // set_sprite(self, start_frame, num_frames, framelength, select_x_by_camera) static int l_set_sprite(lua_State *L); + + // set_guid(self, guid) + static int l_set_guid(lua_State *L); // DEPRECATED // get_entity_name(self) diff --git a/src/script/scripting_server.cpp b/src/script/scripting_server.cpp index 324850011..933e769d7 100644 --- a/src/script/scripting_server.cpp +++ b/src/script/scripting_server.cpp @@ -76,6 +76,9 @@ ServerScripting::ServerScripting(Server* server): lua_newtable(L); lua_setfield(L, -2, "object_refs"); + lua_newtable(L); + lua_setfield(L, -2, "objects_by_guid"); + lua_newtable(L); lua_setfield(L, -2, "luaentities"); diff --git a/src/server/luaentity_sao.cpp b/src/server/luaentity_sao.cpp index 963fd63dc..caafe3950 100644 --- a/src/server/luaentity_sao.cpp +++ b/src/server/luaentity_sao.cpp @@ -85,6 +85,13 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos, const std::string &d m_rotation = rotation; } +LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos, const std::string &name, + const std::string &state) : + UnitSAO(env, pos), + m_init_name(name), m_init_state(state) +{ +} + LuaEntitySAO::~LuaEntitySAO() { if(m_registered){ @@ -113,6 +120,10 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s) // Activate entity, supplying serialized state m_env->getScriptIface()-> luaentity_Activate(m_id, m_init_state, dtime_s); + // if Activate callback does not set guid, set it. + if (m_guid.empty()) { + getGuid(); + } } else { // It's an unknown object // Use entitystring as infotext for debugging @@ -428,6 +439,22 @@ u16 LuaEntitySAO::getHP() const return m_hp; } +bool LuaEntitySAO::setGuid(std::string &guid) +{ + if (m_guid.empty()) { + m_guid = guid; + return true; + } + return false; +} +GUId LuaEntitySAO::getGuid() +{ + if (m_guid.empty()) { + m_guid = m_env->getGUIdGenerator().next(std::string("@")); + } + return m_guid; +} + void LuaEntitySAO::setVelocity(v3f velocity) { m_velocity = velocity; diff --git a/src/server/luaentity_sao.h b/src/server/luaentity_sao.h index 2080df9c3..9e5b4c7ee 100644 --- a/src/server/luaentity_sao.h +++ b/src/server/luaentity_sao.h @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #pragma once #include "unit_sao.h" +#include "guid.h" class LuaEntitySAO : public UnitSAO { @@ -30,11 +31,7 @@ public: LuaEntitySAO(ServerEnvironment *env, v3f pos, const std::string &data); // Used by the Lua API LuaEntitySAO(ServerEnvironment *env, v3f pos, const std::string &name, - const std::string &state) : - UnitSAO(env, pos), - m_init_name(name), m_init_state(state) - { - } + const std::string &state); ~LuaEntitySAO(); ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_LUAENTITY; } @@ -62,6 +59,8 @@ public: void setHP(s32 hp, const PlayerHPChangeReason &reason); u16 getHP() const; + bool setGuid(std::string &guid); + GUId getGuid() override; /* LuaEntitySAO-specific */ void setVelocity(v3f velocity); @@ -95,6 +94,8 @@ private: std::string m_init_state; bool m_registered = false; + GUId m_guid; + v3f m_velocity; v3f m_acceleration; diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index 0806ffd73..86b73ae27 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -30,6 +30,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t p UnitSAO(env_, v3f(0,0,0)), m_player(player_), m_peer_id_initial(peer_id_), + m_guid(player_->getName()), m_is_singleplayer(is_singleplayer) { SANITY_CHECK(m_peer_id_initial != PEER_ID_INEXISTENT); @@ -417,6 +418,11 @@ void PlayerSAO::setPlayerYaw(const float yaw) UnitSAO::setRotation(rotation); } +GUId PlayerSAO::getGuid() +{ + return m_guid; +} + void PlayerSAO::setFov(const float fov) { if (m_player && fov != m_fov) diff --git a/src/server/player_sao.h b/src/server/player_sao.h index b26304589..a7a8448d2 100644 --- a/src/server/player_sao.h +++ b/src/server/player_sao.h @@ -93,6 +93,7 @@ public: void addPos(const v3f &added_pos) override; void moveTo(v3f pos, bool continuous) override; void setPlayerYaw(const float yaw); + GUId getGuid() override; // Data should not be sent at player initialization void setPlayerYawAndSend(const float yaw); void setLookPitch(const float pitch); @@ -195,6 +196,7 @@ private: RemotePlayer *m_player = nullptr; session_t m_peer_id_initial = 0; ///< only used to initialize RemotePlayer + GUId m_guid; // Cheat prevention LagPool m_dig_pool; diff --git a/src/server/serveractiveobject.h b/src/server/serveractiveobject.h index 4d620b768..9fe97b343 100644 --- a/src/server/serveractiveobject.h +++ b/src/server/serveractiveobject.h @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_bloated.h" #include "activeobject.h" #include "itemgroup.h" +#include "guid.h" #include "util/container.h" @@ -160,6 +161,9 @@ public: virtual u16 getHP() const { return 0; } + // Returns always the same unique string for the same object. + virtual GUId getGuid() = 0; + virtual void setArmorGroups(const ItemGroupList &armor_groups) {} virtual const ItemGroupList &getArmorGroups() const @@ -235,6 +239,11 @@ public: about handling it. */ bool m_static_exists = false; + /* + Set this to true when the staticdata needs to be saved even though it + looks like it did not change. + */ + bool m_force_write_staticdata = false; /* The block from which the object was loaded from, and in which a copy of the static data resides. diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index 8a7b568eb..a8f96ff23 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -448,6 +448,8 @@ ServerEnvironment::ServerEnvironment(std::unique_ptr map, m_active_object_gauge = mb->addGauge( "minetest_env_active_objects", "Number of active objects"); + + m_guid_generator.setServerEnvironment(this); } void ServerEnvironment::init() @@ -1889,6 +1891,8 @@ u16 ServerEnvironment::addActiveObjectRaw(std::unique_ptr ob // Post-initialize object // Note that this can change the value of isStaticAllowed() in case of LuaEntitySAO object->addedToEnvironment(dtime_s); + // After post-initialize, GUID is known + m_script->addObjectByGuid(object); // Activate object if (object->m_static_exists) @@ -2199,7 +2203,9 @@ void ServerEnvironment::deactivateFarObjects(const bool _force_delete) While changes are always saved, blocks are only marked as modified if the object has moved or different staticdata. (see above) */ - bool shall_be_written = (!stays_in_same_block || data_changed); + bool shall_be_written = (!stays_in_same_block || data_changed || + obj->m_force_write_staticdata); + obj->m_force_write_staticdata = false; u32 reason = shall_be_written ? MOD_REASON_STATIC_DATA_CHANGED : MOD_REASON_UNKNOWN; // Delete old static object diff --git a/src/serverenvironment.h b/src/serverenvironment.h index d5d45d0f4..42dc603a4 100644 --- a/src/serverenvironment.h +++ b/src/serverenvironment.h @@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "activeobject.h" #include "environment.h" #include "servermap.h" +#include "guid.h" +#include "map.h" #include "settings.h" #include "server/activeobjectmgr.h" #include "util/numeric.h" @@ -238,6 +240,9 @@ public: float getSendRecommendedInterval() { return m_recommended_send_interval; } + GUIdGenerator & getGUIdGenerator() + { return m_guid_generator; } + // Save players void saveLoadedPlayers(bool force = false); void savePlayer(RemotePlayer *player); @@ -463,6 +468,10 @@ private: server::ActiveObjectMgr m_ao_manager; // on_mapblocks_changed map event receiver OnMapblocksChangedReceiver m_on_mapblocks_changed_receiver; + // Generator for luaentity guids + GUIdGenerator m_guid_generator; + // World path + const std::string m_path_world; // Outgoing network message buffer for active objects std::queue m_active_object_messages; // Some timers diff --git a/src/unittest/mock_serveractiveobject.h b/src/unittest/mock_serveractiveobject.h index 78e3df8af..e74ef0264 100644 --- a/src/unittest/mock_serveractiveobject.h +++ b/src/unittest/mock_serveractiveobject.h @@ -29,4 +29,5 @@ public: virtual bool getCollisionBox(aabb3f *toset) const { return false; } virtual bool getSelectionBox(aabb3f *toset) const { return false; } virtual bool collideWithObjects() const { return false; } + virtual std::string getGuid() {return "";} }; diff --git a/src/unittest/test_moveaction.cpp b/src/unittest/test_moveaction.cpp index 0720ba267..3ed8f184c 100644 --- a/src/unittest/test_moveaction.cpp +++ b/src/unittest/test_moveaction.cpp @@ -31,18 +31,18 @@ public: void runTests(IGameDef *gamedef); - void testMove(ServerActiveObject *obj, IGameDef *gamedef); - void testMoveFillStack(ServerActiveObject *obj, IGameDef *gamedef); - void testMoveSomewhere(ServerActiveObject *obj, IGameDef *gamedef); - void testMoveUnallowed(ServerActiveObject *obj, IGameDef *gamedef); - void testMovePartial(ServerActiveObject *obj, IGameDef *gamedef); + void testMove(MockServerActiveObject *obj, IGameDef *gamedef); + void testMoveFillStack(MockServerActiveObject *obj, IGameDef *gamedef); + void testMoveSomewhere(MockServerActiveObject *obj, IGameDef *gamedef); + void testMoveUnallowed(MockServerActiveObject *obj, IGameDef *gamedef); + void testMovePartial(MockServerActiveObject *obj, IGameDef *gamedef); - void testSwap(ServerActiveObject *obj, IGameDef *gamedef); - void testSwapFromUnallowed(ServerActiveObject *obj, IGameDef *gamedef); - void testSwapToUnallowed(ServerActiveObject *obj, IGameDef *gamedef); + void testSwap(MockServerActiveObject *obj, IGameDef *gamedef); + void testSwapFromUnallowed(MockServerActiveObject *obj, IGameDef *gamedef); + void testSwapToUnallowed(MockServerActiveObject *obj, IGameDef *gamedef); - void testCallbacks(ServerActiveObject *obj, Server *server); - void testCallbacksSwap(ServerActiveObject *obj, Server *server); + void testCallbacks(MockServerActiveObject *obj, Server *server); + void testCallbacksSwap(MockServerActiveObject *obj, Server *server); }; static TestMoveAction g_test_instance; @@ -97,7 +97,7 @@ static void apply_action(const char *s, InventoryManager *inv, ServerActiveObjec delete action; } -void TestMoveAction::testMove(ServerActiveObject *obj, IGameDef *gamedef) +void TestMoveAction::testMove(MockServerActiveObject *obj, IGameDef *gamedef) { MockInventoryManager inv(gamedef); @@ -110,7 +110,7 @@ void TestMoveAction::testMove(ServerActiveObject *obj, IGameDef *gamedef) UASSERT(inv.p2.getList("main")->getItem(0).getItemString() == "default:stone 20"); } -void TestMoveAction::testMoveFillStack(ServerActiveObject *obj, IGameDef *gamedef) +void TestMoveAction::testMoveFillStack(MockServerActiveObject *obj, IGameDef *gamedef) { MockInventoryManager inv(gamedef); @@ -130,7 +130,7 @@ void TestMoveAction::testMoveFillStack(ServerActiveObject *obj, IGameDef *gamede UASSERT(list->getItem(1).getItemString() == "default:stone 200"); } -void TestMoveAction::testMoveSomewhere(ServerActiveObject *obj, IGameDef *gamedef) +void TestMoveAction::testMoveSomewhere(MockServerActiveObject *obj, IGameDef *gamedef) { MockInventoryManager inv(gamedef); @@ -146,7 +146,7 @@ void TestMoveAction::testMoveSomewhere(ServerActiveObject *obj, IGameDef *gamede UASSERT(inv.p2.getList("main")->getItem(2).getItemString() == "default:stone 99"); } -void TestMoveAction::testMoveUnallowed(ServerActiveObject *obj, IGameDef *gamedef) +void TestMoveAction::testMoveUnallowed(MockServerActiveObject *obj, IGameDef *gamedef) { MockInventoryManager inv(gamedef); @@ -159,7 +159,7 @@ void TestMoveAction::testMoveUnallowed(ServerActiveObject *obj, IGameDef *gamede UASSERT(inv.p2.getList("main")->getItem(0).empty()) } -void TestMoveAction::testMovePartial(ServerActiveObject *obj, IGameDef *gamedef) +void TestMoveAction::testMovePartial(MockServerActiveObject *obj, IGameDef *gamedef) { MockInventoryManager inv(gamedef); @@ -173,7 +173,7 @@ void TestMoveAction::testMovePartial(ServerActiveObject *obj, IGameDef *gamedef) UASSERT(inv.p2.getList("main")->getItem(0).getItemString() == "default:takeput_max_5 5"); } -void TestMoveAction::testSwap(ServerActiveObject *obj, IGameDef *gamedef) +void TestMoveAction::testSwap(MockServerActiveObject *obj, IGameDef *gamedef) { MockInventoryManager inv(gamedef); @@ -186,7 +186,7 @@ void TestMoveAction::testSwap(ServerActiveObject *obj, IGameDef *gamedef) UASSERT(inv.p2.getList("main")->getItem(0).getItemString() == "default:stone 50"); } -void TestMoveAction::testSwapFromUnallowed(ServerActiveObject *obj, IGameDef *gamedef) +void TestMoveAction::testSwapFromUnallowed(MockServerActiveObject *obj, IGameDef *gamedef) { MockInventoryManager inv(gamedef); @@ -199,7 +199,7 @@ void TestMoveAction::testSwapFromUnallowed(ServerActiveObject *obj, IGameDef *ga UASSERT(inv.p2.getList("main")->getItem(0).getItemString() == "default:brick 60"); } -void TestMoveAction::testSwapToUnallowed(ServerActiveObject *obj, IGameDef *gamedef) +void TestMoveAction::testSwapToUnallowed(MockServerActiveObject *obj, IGameDef *gamedef) { MockInventoryManager inv(gamedef); @@ -230,7 +230,7 @@ static bool check_function(lua_State *L, bool expect_swap) return ok; } -void TestMoveAction::testCallbacks(ServerActiveObject *obj, Server *server) +void TestMoveAction::testCallbacks(MockServerActiveObject *obj, Server *server) { server->m_inventory_mgr = std::make_unique(server); MockInventoryManager &inv = *(MockInventoryManager *)server->getInventoryMgr(); @@ -246,7 +246,7 @@ void TestMoveAction::testCallbacks(ServerActiveObject *obj, Server *server) server->m_inventory_mgr.reset(); } -void TestMoveAction::testCallbacksSwap(ServerActiveObject *obj, Server *server) +void TestMoveAction::testCallbacksSwap(MockServerActiveObject *obj, Server *server) { server->m_inventory_mgr = std::make_unique(server); MockInventoryManager &inv = *(MockInventoryManager *)server->getInventoryMgr(); diff --git a/src/unittest/test_serveractiveobjectmgr.cpp b/src/unittest/test_serveractiveobjectmgr.cpp index 7f0ca84cb..0ec66d5f2 100644 --- a/src/unittest/test_serveractiveobjectmgr.cpp +++ b/src/unittest/test_serveractiveobjectmgr.cpp @@ -26,7 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "profiler.h" - class TestServerActiveObjectMgr : public TestBase { public: