diff options
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/luaentity_sao.cpp | 30 | ||||
-rw-r--r-- | src/server/luaentity_sao.h | 13 | ||||
-rw-r--r-- | src/server/mods.cpp | 31 | ||||
-rw-r--r-- | src/server/mods.h | 23 | ||||
-rw-r--r-- | src/server/player_sao.cpp | 8 | ||||
-rw-r--r-- | src/server/player_sao.h | 52 |
6 files changed, 96 insertions, 61 deletions
diff --git a/src/server/luaentity_sao.cpp b/src/server/luaentity_sao.cpp index 82f6da231..ab4a9e3f2 100644 --- a/src/server/luaentity_sao.cpp +++ b/src/server/luaentity_sao.cpp @@ -117,13 +117,13 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s) } } -void LuaEntitySAO::dispatchScriptDeactivate() +void LuaEntitySAO::dispatchScriptDeactivate(bool removal) { // Ensure that this is in fact a registered entity, // and that it isn't already gone. // The latter also prevents this from ever being called twice. if (m_registered && !isGone()) - m_env->getScriptIface()->luaentity_Deactivate(m_id); + m_env->getScriptIface()->luaentity_Deactivate(m_id, removal); } void LuaEntitySAO::step(float dtime, bool send_recommended) @@ -290,7 +290,7 @@ void LuaEntitySAO::getStaticData(std::string *result) const os<<serializeString32(m_init_state); } writeU16(os, m_hp); - writeV3F1000(os, m_velocity); + writeV3F1000(os, clampToF1000(m_velocity)); // yaw writeF1000(os, m_rotation.Y); @@ -337,19 +337,9 @@ u32 LuaEntitySAO::punch(v3f dir, if (result.did_punch) { setHP((s32)getHP() - result.damage, PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher)); - - // create message and add to list - sendPunchCommand(); } } - if (getHP() == 0 && !isGone()) { - clearParentAttachment(); - clearChildAttachments(); - m_env->getScriptIface()->luaentity_on_death(m_id, puncher); - markForRemoval(); - } - actionstream << puncher->getDescription() << " (id=" << puncher->getId() << ", hp=" << puncher->getHP() << ") punched " << getDescription() << " (id=" << m_id << ", hp=" << m_hp << @@ -402,6 +392,20 @@ std::string LuaEntitySAO::getDescription() void LuaEntitySAO::setHP(s32 hp, const PlayerHPChangeReason &reason) { m_hp = rangelim(hp, 0, U16_MAX); + + sendPunchCommand(); + + if (m_hp == 0 && !isGone()) { + clearParentAttachment(); + clearChildAttachments(); + if (m_registered) { + ServerActiveObject *killer = nullptr; + if (reason.type == PlayerHPChangeReason::PLAYER_PUNCH) + killer = reason.object; + m_env->getScriptIface()->luaentity_on_death(m_id, killer); + } + markForRemoval(); + } } u16 LuaEntitySAO::getHP() const diff --git a/src/server/luaentity_sao.h b/src/server/luaentity_sao.h index 87b664a8b..1dc72b150 100644 --- a/src/server/luaentity_sao.h +++ b/src/server/luaentity_sao.h @@ -36,23 +36,30 @@ public: { } ~LuaEntitySAO(); + ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_LUAENTITY; } ActiveObjectType getSendType() const { return ACTIVEOBJECT_TYPE_GENERIC; } virtual void addedToEnvironment(u32 dtime_s); void step(float dtime, bool send_recommended); std::string getClientInitializationData(u16 protocol_version); + bool isStaticAllowed() const { return m_prop.static_save; } bool shouldUnload() const { return true; } void getStaticData(std::string *result) const; + u32 punch(v3f dir, const ToolCapabilities *toolcap = nullptr, ServerActiveObject *puncher = nullptr, float time_from_last_punch = 1000000.0f, u16 initial_wear = 0); + void rightClick(ServerActiveObject *clicker); + void setPos(const v3f &pos); void moveTo(v3f pos, bool continuous); float getMinimumSavedMovement(); + std::string getDescription(); + void setHP(s32 hp, const PlayerHPChangeReason &reason); u16 getHP() const; @@ -73,9 +80,9 @@ public: bool collideWithObjects() const; protected: - void dispatchScriptDeactivate(); - virtual void onMarkedForDeactivation() { dispatchScriptDeactivate(); } - virtual void onMarkedForRemoval() { dispatchScriptDeactivate(); } + void dispatchScriptDeactivate(bool removal); + virtual void onMarkedForDeactivation() { dispatchScriptDeactivate(false); } + virtual void onMarkedForRemoval() { dispatchScriptDeactivate(true); } private: std::string getPropertyPacket(); diff --git a/src/server/mods.cpp b/src/server/mods.cpp index 609d8c346..f302d4240 100644 --- a/src/server/mods.cpp +++ b/src/server/mods.cpp @@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "scripting_server.h" #include "content/subgames.h" #include "porting.h" -#include "util/metricsbackend.h" /** * Manage server mods @@ -35,18 +34,19 @@ with this program; if not, write to the Free Software Foundation, Inc., * Creates a ServerModManager which targets worldpath * @param worldpath */ -ServerModManager::ServerModManager(const std::string &worldpath) : - ModConfiguration(worldpath) +ServerModManager::ServerModManager(const std::string &worldpath): + configuration() { SubgameSpec gamespec = findWorldSubgame(worldpath); // Add all game mods and all world mods - addModsInPath(gamespec.gamemods_path); - addModsInPath(worldpath + DIR_DELIM + "worldmods"); + configuration.addGameMods(gamespec); + configuration.addModsInPath(worldpath + DIR_DELIM + "worldmods", "worldmods"); // Load normal mods std::string worldmt = worldpath + DIR_DELIM + "world.mt"; - addModsFromConfig(worldmt, gamespec.addon_mods_paths); + configuration.addModsFromConfig(worldmt, gamespec.addon_mods_paths); + configuration.checkConflictsAndDeps(); } // clang-format off @@ -55,12 +55,13 @@ void ServerModManager::loadMods(ServerScripting *script) { // Print mods infostream << "Server: Loading mods: "; - for (const ModSpec &mod : m_sorted_mods) { + for (const ModSpec &mod : configuration.getMods()) { infostream << mod.name << " "; } + infostream << std::endl; // Load and run "mod" scripts - for (const ModSpec &mod : m_sorted_mods) { + for (const ModSpec &mod : configuration.getMods()) { mod.checkAndLog(); std::string script_path = mod.path + DIR_DELIM + "init.lua"; @@ -77,24 +78,26 @@ void ServerModManager::loadMods(ServerScripting *script) // clang-format on const ModSpec *ServerModManager::getModSpec(const std::string &modname) const { - std::vector<ModSpec>::const_iterator it; - for (it = m_sorted_mods.begin(); it != m_sorted_mods.end(); ++it) { - const ModSpec &mod = *it; + for (const auto &mod : configuration.getMods()) { if (mod.name == modname) return &mod; } - return NULL; + + return nullptr; } void ServerModManager::getModNames(std::vector<std::string> &modlist) const { - for (const ModSpec &spec : m_sorted_mods) + for (const ModSpec &spec : configuration.getMods()) modlist.push_back(spec.name); } void ServerModManager::getModsMediaPaths(std::vector<std::string> &paths) const { - for (auto it = m_sorted_mods.crbegin(); it != m_sorted_mods.crend(); it++) { + // Iterate mods in reverse load order: Media loading expects higher priority media files first + // and mods loading later should be able to override media of already loaded mods + const auto &mods = configuration.getMods(); + for (auto it = mods.crbegin(); it != mods.crend(); it++) { const ModSpec &spec = *it; fs::GetRecursiveDirs(paths, spec.path + DIR_DELIM + "textures"); fs::GetRecursiveDirs(paths, spec.path + DIR_DELIM + "sounds"); diff --git a/src/server/mods.h b/src/server/mods.h index 8954bbf72..1d1b42d0f 100644 --- a/src/server/mods.h +++ b/src/server/mods.h @@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #pragma once -#include "content/mods.h" +#include "content/mod_configuration.h" #include <memory> class MetricsBackend; @@ -31,8 +31,10 @@ class ServerScripting; * * All new calls to this class must be tested in test_servermodmanager.cpp */ -class ServerModManager : public ModConfiguration +class ServerModManager { + ModConfiguration configuration; + public: /** * Creates a ServerModManager which targets worldpath @@ -42,6 +44,23 @@ public: void loadMods(ServerScripting *script); const ModSpec *getModSpec(const std::string &modname) const; void getModNames(std::vector<std::string> &modlist) const; + + inline const std::vector<ModSpec> &getMods() const { + return configuration.getMods(); + } + + inline const std::vector<ModSpec> &getUnsatisfiedMods() const { + return configuration.getUnsatisfiedMods(); + } + + inline bool isConsistent() const { + return configuration.isConsistent(); + } + + inline void printUnsatisfiedModsError() const { + return configuration.printUnsatisfiedModsError(); + } + /** * Recursively gets all paths of mod folders that can contain media files. * diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index d076d5783..a58a0397f 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -319,7 +319,7 @@ std::string PlayerSAO::generateUpdatePhysicsOverrideCommand() const return os.str(); } -void PlayerSAO::setBasePosition(const v3f &position) +void PlayerSAO::setBasePosition(v3f position) { if (m_player && position != m_base_position) m_player->setDirty(true); @@ -344,7 +344,7 @@ void PlayerSAO::setPos(const v3f &pos) setBasePosition(pos); // Movement caused by this command is always valid - m_last_good_position = pos; + m_last_good_position = getBasePosition(); m_move_pool.empty(); m_time_from_last_teleport = 0.0; m_env->getGameDef()->SendMovePlayer(m_peer_id); @@ -357,7 +357,7 @@ void PlayerSAO::moveTo(v3f pos, bool continuous) setBasePosition(pos); // Movement caused by this command is always valid - m_last_good_position = pos; + m_last_good_position = getBasePosition(); m_move_pool.empty(); m_time_from_last_teleport = 0.0; m_env->getGameDef()->SendMovePlayer(m_peer_id); @@ -489,7 +489,7 @@ void PlayerSAO::setHP(s32 target_hp, const PlayerHPChangeReason &reason, bool fr m_hp = hp; m_env->getGameDef()->HandlePlayerHPChange(this, reason); } else if (from_client) - m_env->getGameDef()->SendPlayerHP(this); + m_env->getGameDef()->SendPlayerHP(this, true); } void PlayerSAO::setBreath(const u16 breath, bool send) diff --git a/src/server/player_sao.h b/src/server/player_sao.h index 96d8f7189..5f48cae67 100644 --- a/src/server/player_sao.h +++ b/src/server/player_sao.h @@ -72,24 +72,24 @@ public: PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t peer_id_, bool is_singleplayer); - ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_PLAYER; } - ActiveObjectType getSendType() const { return ACTIVEOBJECT_TYPE_GENERIC; } - std::string getDescription(); + ActiveObjectType getType() const override { return ACTIVEOBJECT_TYPE_PLAYER; } + ActiveObjectType getSendType() const override { return ACTIVEOBJECT_TYPE_GENERIC; } + std::string getDescription() override; /* Active object <-> environment interface */ - void addedToEnvironment(u32 dtime_s); - void removingFromEnvironment(); - bool isStaticAllowed() const { return false; } - bool shouldUnload() const { return false; } - std::string getClientInitializationData(u16 protocol_version); - void getStaticData(std::string *result) const; - void step(float dtime, bool send_recommended); - void setBasePosition(const v3f &position); - void setPos(const v3f &pos); - void moveTo(v3f pos, bool continuous); + void addedToEnvironment(u32 dtime_s) override; + void removingFromEnvironment() override; + bool isStaticAllowed() const override { return false; } + bool shouldUnload() const override { return false; } + std::string getClientInitializationData(u16 protocol_version) override; + void getStaticData(std::string *result) const override; + void step(float dtime, bool send_recommended) override; + void setBasePosition(v3f position); + void setPos(const v3f &pos) override; + void moveTo(v3f pos, bool continuous) override; void setPlayerYaw(const float yaw); // Data should not be sent at player initialization void setPlayerYawAndSend(const float yaw); @@ -110,8 +110,8 @@ public: */ u32 punch(v3f dir, const ToolCapabilities *toolcap, ServerActiveObject *puncher, - float time_from_last_punch, u16 initial_wear = 0); - void rightClick(ServerActiveObject *clicker); + float time_from_last_punch, u16 initial_wear = 0) override; + void rightClick(ServerActiveObject *clicker) override; void setHP(s32 hp, const PlayerHPChangeReason &reason) override { return setHP(hp, reason, false); @@ -124,13 +124,13 @@ public: /* Inventory interface */ - Inventory *getInventory() const; - InventoryLocation getInventoryLocation() const; - void setInventoryModified() {} - std::string getWieldList() const { return "main"; } - u16 getWieldIndex() const; - ItemStack getWieldedItem(ItemStack *selected, ItemStack *hand = nullptr) const; - bool setWieldedItem(const ItemStack &item); + Inventory *getInventory() const override; + InventoryLocation getInventoryLocation() const override; + void setInventoryModified() override {} + std::string getWieldList() const override { return "main"; } + u16 getWieldIndex() const override; + ItemStack getWieldedItem(ItemStack *selected, ItemStack *hand = nullptr) const override; + bool setWieldedItem(const ItemStack &item) override; /* PlayerSAO-specific @@ -171,9 +171,9 @@ public: m_is_singleplayer = is_singleplayer; } - bool getCollisionBox(aabb3f *toset) const; - bool getSelectionBox(aabb3f *toset) const; - bool collideWithObjects() const { return true; } + bool getCollisionBox(aabb3f *toset) const override; + bool getSelectionBox(aabb3f *toset) const override; + bool collideWithObjects() const override { return true; } void finalize(RemotePlayer *player, const std::set<std::string> &privs); @@ -235,6 +235,7 @@ struct PlayerHPChangeReason enum Type : u8 { SET_HP, + SET_HP_MAX, // internal type to allow distinguishing hp reset and damage (for effects) PLAYER_PUNCH, FALL, NODE_DAMAGE, @@ -277,6 +278,7 @@ struct PlayerHPChangeReason { switch (type) { case PlayerHPChangeReason::SET_HP: + case PlayerHPChangeReason::SET_HP_MAX: return "set_hp"; case PlayerHPChangeReason::PLAYER_PUNCH: return "punch"; |