From 0aa07d02ca3b1adaf9e674c968cebdf4a776c2aa Mon Sep 17 00:00:00 2001 From: mattyx14 Date: Sun, 10 Nov 2024 10:01:09 -0600 Subject: [PATCH] update : https://github.com/opentibiabr/canary/commit/685f4cdd133810c88c7a26b9806dd646a0a5b0fb --- .../convert_monsters_callbacks.py | 116 ++++++++++++++++++ schema.sql | 2 +- src/creatures/combat/combat.cpp | 1 + src/creatures/creature.cpp | 32 +++-- src/creatures/creature.hpp | 7 +- src/creatures/monsters/monster.hpp | 1 - .../monsters/spawns/spawn_monster.cpp | 2 - src/creatures/npcs/spawns/spawn_npc.cpp | 3 - src/creatures/players/player.cpp | 20 +-- src/creatures/players/vip/player_vip.cpp | 1 + src/game/game.cpp | 15 +-- src/game/movement/teleport.cpp | 8 +- src/game/scheduling/dispatcher.cpp | 16 --- src/game/scheduling/dispatcher.hpp | 6 - src/game/scheduling/save_manager.cpp | 1 + src/io/functions/iologindata_load_player.cpp | 3 + src/io/functions/iologindata_load_player.hpp | 4 + src/io/functions/iologindata_save_player.cpp | 1 + src/io/functions/iologindata_save_player.hpp | 1 + src/io/iologindata.cpp | 3 + src/io/iologindata.hpp | 11 +- src/io/iomarket.cpp | 1 + src/items/bed.cpp | 1 + src/items/items_definitions.hpp | 53 ++++---- src/items/tile.cpp | 14 +++ src/items/tile.hpp | 3 + src/items/weapons/weapons.cpp | 2 +- src/items/weapons/weapons.hpp | 1 - src/lua/callbacks/callbacks_definitions.hpp | 4 - src/lua/callbacks/event_callback.cpp | 84 ------------- src/lua/callbacks/event_callback.hpp | 5 - src/lua/creature/events.cpp | 110 ----------------- src/lua/creature/events.hpp | 10 -- .../functions/core/game/game_functions.cpp | 3 +- .../functions/core/game/global_functions.cpp | 1 + .../creatures/combat/combat_functions.cpp | 1 + .../creatures/player/player_functions.cpp | 1 + src/lua/functions/map/house_functions.cpp | 1 + src/lua/scripts/luascript.cpp | 4 + src/map/house/house.cpp | 1 + src/map/map.cpp | 7 ++ src/map/mapcache.cpp | 14 +-- src/protobuf/appearances.proto | 1 + src/server/network/protocol/protocolgame.cpp | 9 +- .../network/protocol/protocolstatus.cpp | 2 +- 45 files changed, 260 insertions(+), 327 deletions(-) create mode 100644 docs/python-scripts/convert_monsters_callbacks.py diff --git a/docs/python-scripts/convert_monsters_callbacks.py b/docs/python-scripts/convert_monsters_callbacks.py new file mode 100644 index 000000000..140b2562d --- /dev/null +++ b/docs/python-scripts/convert_monsters_callbacks.py @@ -0,0 +1,116 @@ +""" +Script for processing Lua files in a project. + +This script is designed to modify `.lua` files in the root directory of the project and all of its subdirectories. +The following modifications are made to each `.lua` file: +1. Remove empty callback functions. +2. Remove the 'onAppear' callback function entirely, including its corresponding `end`. +3. Clean up unnecessary blank lines resulting from the removal of callback functions. + +Usage: +1. Save this script in the `docs/python-scripts` directory of your project. +2. Open a terminal and navigate to the `docs/python-scripts` directory: + cd path/to/your/project/docs/python-scripts +3. Run the script using Python: + python convert_monsters_callbacks.py + +Prerequisites: +- Ensure Python 3 is installed. +- Make sure you have read and write permissions for all `.lua` files in the project directory. + +Output: +- The script will print the root directory being processed. +- At the end, it will output the number of files that were modified. + +Example: +Root path: /path/to/your/project +Script completed. Modified 5 file(s). +""" + +import re +import os + +def get_root_path(): + """Get the root path of the project (two levels above the current script directory).""" + return os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) + +def process_lua_code(code): + """Process the Lua code: remove specific callbacks and clean up empty lines. + + Args: + code (str): The Lua code to be processed. + + Returns: + str: The modified Lua code. + """ + # Remove specific callbacks including 'onAppear' and empty callbacks + code = re.sub(r'\n?mType\.onAppear = function\(.*?\)\n(.*?)\nend\n?', '', code, flags=re.DOTALL) + code = re.sub(r'\n?mType\.\w+ = function\(.*?\) end\n?', '', code) + + # Remove extra blank lines created by the removal of callbacks + code = re.sub(r'\n{3,}', '\n\n', code) # Limit multiple blank lines to just two + + return code + +def process_lua_file(file_path): + """Process a single Lua file by applying the required modifications. + + Args: + file_path (str): The path to the Lua file to be processed. + + Returns: + bool: True if the file was modified and saved, False otherwise. + """ + try: + with open(file_path, 'r', encoding='utf-8') as file: + code = file.read() + except Exception as e: + print(f"Error reading file {file_path}: {e}") + return False + + original_code = code + modified_code = process_lua_code(code) + + if modified_code != original_code: + try: + with open(file_path, 'w', encoding='utf-8') as file: + file.write(modified_code) + return True + except Exception as e: + print(f"Error writing file {file_path}: {e}") + return False + +def process_all_lua_files(root_path): + """Process all Lua files in the root path and its subdirectories. + + Args: + root_path (str): The root directory in which to search for Lua files. + + Returns: + int: The count of modified Lua files. + """ + modified_files_count = 0 + + for dirpath, _, filenames in os.walk(root_path): + for filename in filenames: + if filename.endswith(".lua"): + file_path = os.path.join(dirpath, filename) + if process_lua_file(file_path): + modified_files_count += 1 + + return modified_files_count + +def main(): + """Main function to run the script. + + This function determines the root path of the project, processes all Lua files + found in the root path and subdirectories, and prints the number of files modified. + """ + root_path = get_root_path() + print(f"Root path: {root_path}") + + modified_files_count = process_all_lua_files(root_path) + print(f"Script completed. Modified {modified_files_count} file(s).") + +if __name__ == "__main__": + main() diff --git a/schema.sql b/schema.sql index af2450670..86ea9e1bf 100644 --- a/schema.sql +++ b/schema.sql @@ -70,7 +70,7 @@ CREATE TABLE IF NOT EXISTS `players` ( `posx` int(11) NOT NULL DEFAULT '0', `posy` int(11) NOT NULL DEFAULT '0', `posz` int(11) NOT NULL DEFAULT '0', - `conditions` blob NOT NULL, + `conditions` mediumblob NOT NULL, `cap` int(11) NOT NULL DEFAULT '0', `sex` int(11) NOT NULL DEFAULT '0', `pronoun` int(11) NOT NULL DEFAULT '0', diff --git a/src/creatures/combat/combat.cpp b/src/creatures/combat/combat.cpp index a63f42093..6dcd0f229 100644 --- a/src/creatures/combat/combat.cpp +++ b/src/creatures/combat/combat.cpp @@ -27,6 +27,7 @@ #include "lua/callbacks/events_callbacks.hpp" #include "lua/creature/events.hpp" #include "map/spectators.hpp" +#include "creatures/players/player.hpp" int32_t Combat::getLevelFormula(const std::shared_ptr &player, const std::shared_ptr &wheelSpell, const CombatDamage &damage) const { if (!player) { diff --git a/src/creatures/creature.cpp b/src/creatures/creature.cpp index baf93fb65..8214928dd 100644 --- a/src/creatures/creature.cpp +++ b/src/creatures/creature.cpp @@ -270,18 +270,17 @@ void Creature::addEventWalk(bool firstStep) { return; } - g_dispatcher().context().tryAddEvent([ticks, self = getCreature()]() { + safeCall([this, ticks]() { // Take first step right away, but still queue the next if (ticks == 1) { - g_game().checkCreatureWalk(self->getID()); + g_game().checkCreatureWalk(getID()); } - self->eventWalk = g_dispatcher().scheduleEvent( + eventWalk = g_dispatcher().scheduleEvent( static_cast(ticks), - [creatureId = self->getID()] { g_game().checkCreatureWalk(creatureId); }, "Game::checkCreatureWalk" + [creatureId = getID()] { g_game().checkCreatureWalk(creatureId); }, "Game::checkCreatureWalk" ); - }, - "addEventWalk"); + }); } void Creature::stopEventWalk() { @@ -1082,7 +1081,7 @@ void Creature::getPathSearchParams(const std::shared_ptr &, FindPathPa void Creature::goToFollowCreature_async(std::function &&onComplete) { if (!hasAsyncTaskFlag(Pathfinder) && onComplete) { - g_dispatcher().context().addEvent(std::move(onComplete), "goToFollowCreature_async"); + g_dispatcher().addEvent(std::move(onComplete), "goToFollowCreature_async"); } setAsyncTaskFlag(Pathfinder, true); @@ -1592,6 +1591,10 @@ LightInfo Creature::getCreatureLight() const { return internalLight; } +uint16_t Creature::getSpeed() const { + return std::clamp(baseSpeed + varSpeed, 0, static_cast(std::numeric_limits::max())); +} + void Creature::setSpeed(int32_t varSpeedDelta) { // Prevents creatures from not exceeding the maximum allowed speed if (getSpeed() >= PLAYER_MAX_SPEED) { @@ -2002,3 +2005,18 @@ void Creature::sendAsyncTasks() { }, TaskGroup::WalkParallel); } + +void Creature::safeCall(std::function &&action) const { + if (g_dispatcher().context().isAsync()) { + g_dispatcher().addEvent([weak_self = std::weak_ptr(static_self_cast()), action = std::move(action)] { + if (const auto self = weak_self.lock()) { + if (!self->isInternalRemoved) { + action(); + } + } + }, + g_dispatcher().context().getName()); + } else if (!isInternalRemoved) { + action(); + } +} diff --git a/src/creatures/creature.hpp b/src/creatures/creature.hpp index 46f628188..9cdd70f9f 100644 --- a/src/creatures/creature.hpp +++ b/src/creatures/creature.hpp @@ -194,9 +194,7 @@ class Creature : virtual public Thing, public SharedObject { virtual uint16_t getStepSpeed() const { return getSpeed(); } - uint16_t getSpeed() const { - return static_cast(baseSpeed + varSpeed); - } + uint16_t getSpeed() const; void setSpeed(int32_t varSpeedDelta); void setBaseSpeed(uint16_t newBaseSpeed) { @@ -848,6 +846,9 @@ class Creature : virtual public Thing, public SharedObject { virtual void onExecuteAsyncTasks() {}; + // This method maintains safety in asynchronous calls, avoiding competition between threads. + void safeCall(std::function &&action) const; + private: bool canFollowMaster() const; bool isLostSummon(); diff --git a/src/creatures/monsters/monster.hpp b/src/creatures/monsters/monster.hpp index c52a2a6de..ed9a62815 100644 --- a/src/creatures/monsters/monster.hpp +++ b/src/creatures/monsters/monster.hpp @@ -47,7 +47,6 @@ class Monster final : public Creature { const std::string &getTypeName() const override; const std::string &getNameDescription() const override; void setNameDescription(std::string_view nameDescription); - ; std::string getDescription(int32_t) override; CreatureType_t getType() const override; diff --git a/src/creatures/monsters/spawns/spawn_monster.cpp b/src/creatures/monsters/spawns/spawn_monster.cpp index 7d7bbc84e..3a915d737 100644 --- a/src/creatures/monsters/spawns/spawn_monster.cpp +++ b/src/creatures/monsters/spawns/spawn_monster.cpp @@ -232,9 +232,7 @@ bool SpawnMonster::spawnMonster(uint32_t spawnMonsterId, spawnBlock_t &sb, const spawnedMonsterMap[spawnMonsterId] = monster; sb.lastSpawn = OTSYS_TIME(); - g_events().eventMonsterOnSpawn(monster, sb.pos); monster->onSpawn(); - g_callbacks().executeCallback(EventCallback_t::monsterOnSpawn, &EventCallback::monsterOnSpawn, monster, sb.pos); return true; } diff --git a/src/creatures/npcs/spawns/spawn_npc.cpp b/src/creatures/npcs/spawns/spawn_npc.cpp index bf3b6a1bc..404f6ce58 100644 --- a/src/creatures/npcs/spawns/spawn_npc.cpp +++ b/src/creatures/npcs/spawns/spawn_npc.cpp @@ -202,9 +202,6 @@ bool SpawnNpc::spawnNpc(uint32_t spawnId, const std::shared_ptr &npcTyp spawnedNpcMap.insert(spawned_pair(spawnId, npc)); spawnNpcMap[spawnId].lastSpawnNpc = OTSYS_TIME(); - - g_events().eventNpcOnSpawn(npc, pos); - g_callbacks().executeCallback(EventCallback_t::npcOnSpawn, &EventCallback::npcOnSpawn, npc, pos); return true; } diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index dfdf467aa..0b54f3f0b 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -9,6 +9,7 @@ #include "creatures/players/player.hpp" +#include "account/account.hpp" #include "config/configmanager.hpp" #include "core.hpp" #include "creatures/appearance/mounts/mounts.hpp" @@ -1773,8 +1774,8 @@ std::shared_ptr Player::getDepotLocker(uint32_t depotId) { depotLocker->internalAddThing(marketItem); depotLocker->internalAddThing(inbox); if (createSupplyStash) { - const auto &supplyStash = Item::CreateItem(ITEM_SUPPLY_STASH); - depotLocker->internalAddThing(supplyStash); + const auto &supplyStashPtr = Item::CreateItem(ITEM_SUPPLY_STASH); + depotLocker->internalAddThing(supplyStashPtr); } const auto &depotChest = Item::CreateItemAsContainer(ITEM_DEPOT, static_cast(g_configManager().getNumber(DEPOT_BOXES))); for (uint32_t i = g_configManager().getNumber(DEPOT_BOXES); i > 0; i--) { @@ -3783,14 +3784,9 @@ void Player::addInFightTicks(bool pzlock /*= false*/) { updateImbuementTrackerStats(); - // this method can be called asynchronously. - g_dispatcher().context().tryAddEvent([self = std::weak_ptr(getPlayer())] { - if (const auto &player = self.lock()) { - const auto &condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT, g_configManager().getNumber(PZ_LOCKED), 0); - player->addCondition(condition); - } - }, - "Player::addInFightTicks"); + safeCall([this] { + addCondition(Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT, g_configManager().getNumber(PZ_LOCKED), 0)); + }); } void Player::setDailyReward(uint8_t reward) { @@ -8718,10 +8714,6 @@ bool Player::saySpell(SpeakClasses type, const std::string &text, bool isGhostMo } tmpPlayer->onCreatureSay(static_self_cast(), type, text); - if (static_self_cast() != tmpPlayer) { - g_events().eventCreatureOnHear(tmpPlayer, getPlayer(), text, type); - g_callbacks().executeCallback(EventCallback_t::creatureOnHear, &EventCallback::creatureOnHear, tmpPlayer, getPlayer(), text, type); - } } return true; } diff --git a/src/creatures/players/vip/player_vip.cpp b/src/creatures/players/vip/player_vip.cpp index 195480ca5..8a64aebcf 100644 --- a/src/creatures/players/vip/player_vip.cpp +++ b/src/creatures/players/vip/player_vip.cpp @@ -9,6 +9,7 @@ #include "creatures/players/vip/player_vip.hpp" +#include "account/account.hpp" #include "creatures/players/grouping/groups.hpp" #include "creatures/players/player.hpp" #include "io/iologindata.hpp" diff --git a/src/game/game.cpp b/src/game/game.cpp index 49f8bf21d..af8c56c1d 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -2907,9 +2907,7 @@ ReturnValue Game::internalTeleport(const std::shared_ptr &thing, const Po return ret; } - g_dispatcher().addWalkEvent([=] { - g_game().map.moveCreature(creature, toTile, !pushMove); - }); + map.moveCreature(creature, toTile, !pushMove); return RETURNVALUE_NOERROR; } else if (const auto &item = thing->getItem()) { @@ -6397,10 +6395,6 @@ bool Game::internalCreatureSay(const std::shared_ptr &creature, SpeakC // event method for (const auto &spectator : spectators) { spectator->onCreatureSay(creature, type, text); - if (creature != spectator) { - g_events().eventCreatureOnHear(spectator, creature, text, type); - g_callbacks().executeCallback(EventCallback_t::creatureOnHear, &EventCallback::creatureOnHear, spectator, creature, text, type); - } } return true; } @@ -6440,10 +6434,9 @@ void Game::addCreatureCheck(const std::shared_ptr &creature) { creature->inCheckCreaturesVector.store(true); - g_dispatcher().context().tryAddEvent([creature] { + creature->safeCall([this, creature] { checkCreatureLists[uniform_random(0, EVENT_CREATURECOUNT - 1)].emplace_back(creature); - }, - "addCreatureCheck"); + }); } void Game::removeCreatureCheck(const std::shared_ptr &creature) { @@ -6457,7 +6450,7 @@ void Game::checkCreatures() { metrics::method_latency measure(__METHOD_NAME__); static size_t index = 0; - std::erase_if(checkCreatureLists[index], [this](const std::shared_ptr &creature) { + std::erase_if(checkCreatureLists[index], [this](const std::shared_ptr creature) { if (creature->creatureCheck && creature->isAlive()) { creature->onThink(EVENT_CREATURE_THINK_INTERVAL); creature->onAttacking(EVENT_CREATURE_THINK_INTERVAL); diff --git a/src/game/movement/teleport.cpp b/src/game/movement/teleport.cpp index 935ec4436..368bcf6e4 100644 --- a/src/game/movement/teleport.cpp +++ b/src/game/movement/teleport.cpp @@ -93,11 +93,11 @@ void Teleport::addThing(int32_t, const std::shared_ptr &thing) { g_game().internalCreatureTurn(creature, origPos.x > destPos.x ? DIRECTION_WEST : DIRECTION_EAST); g_dispatcher().addWalkEvent([=] { g_game().map.moveCreature(creature, destTile); + if (effect != CONST_ME_NONE) { + g_game().addMagicEffect(origPos, effect); + g_game().addMagicEffect(destTile->getPosition(), effect); + } }); - if (effect != CONST_ME_NONE) { - g_game().addMagicEffect(origPos, effect); - g_game().addMagicEffect(destTile->getPosition(), effect); - } } else if (const auto &item = thing->getItem()) { if (effect != CONST_ME_NONE) { g_game().addMagicEffect(destTile->getPosition(), effect); diff --git a/src/game/scheduling/dispatcher.cpp b/src/game/scheduling/dispatcher.cpp index e716e9867..cb27cba23 100644 --- a/src/game/scheduling/dispatcher.cpp +++ b/src/game/scheduling/dispatcher.cpp @@ -251,22 +251,6 @@ void Dispatcher::stopEvent(uint64_t eventId) { } } -void DispatcherContext::addEvent(std::function &&f, std::string_view context) const { - g_dispatcher().addEvent(std::move(f), context); -} - -void DispatcherContext::tryAddEvent(std::function &&f, std::string_view context) const { - if (!f) { - return; - } - - if (isAsync()) { - g_dispatcher().addEvent(std::move(f), context); - } else { - f(); - } -} - bool DispatcherContext::isOn() { return OTSYS_TIME() != 0; } diff --git a/src/game/scheduling/dispatcher.hpp b/src/game/scheduling/dispatcher.hpp index 5e84d5d5f..d2c681959 100644 --- a/src/game/scheduling/dispatcher.hpp +++ b/src/game/scheduling/dispatcher.hpp @@ -55,12 +55,6 @@ struct DispatcherContext { return type; } - // postpone the event - void addEvent(std::function &&f, std::string_view context) const; - - // if the context is async, the event will be postponed, if not, it will be executed immediately. - void tryAddEvent(std::function &&f, std::string_view context) const; - private: void reset() { group = TaskGroup::ThreadPool; diff --git a/src/game/scheduling/save_manager.cpp b/src/game/scheduling/save_manager.cpp index 9cccc4052..45cd93921 100644 --- a/src/game/scheduling/save_manager.cpp +++ b/src/game/scheduling/save_manager.cpp @@ -16,6 +16,7 @@ #include "io/iologindata.hpp" #include "kv/kv.hpp" #include "lib/di/container.hpp" +#include "creatures/players/player.hpp" SaveManager::SaveManager(ThreadPool &threadPool, KVStore &kvStore, Logger &logger, Game &game) : threadPool(threadPool), kv(kvStore), logger(logger), game(game) { } diff --git a/src/io/functions/iologindata_load_player.cpp b/src/io/functions/iologindata_load_player.cpp index 477572dfb..7cb08a7b9 100644 --- a/src/io/functions/iologindata_load_player.cpp +++ b/src/io/functions/iologindata_load_player.cpp @@ -9,8 +9,10 @@ #include "io/functions/iologindata_load_player.hpp" +#include "account/account.hpp" #include "config/configmanager.hpp" #include "creatures/combat/condition.hpp" +#include "database/database.hpp" #include "creatures/monsters/monsters.hpp" #include "creatures/players/achievement/player_achievement.hpp" #include "creatures/players/cyclopedia/player_badge.hpp" @@ -29,6 +31,7 @@ #include "items/containers/inbox/inbox.hpp" #include "items/containers/rewards/reward.hpp" #include "items/containers/rewards/rewardchest.hpp" +#include "creatures/players/player.hpp" #include "utils/tools.hpp" void IOLoginDataLoad::loadItems(ItemsMap &itemsMap, const DBResult_ptr &result, const std::shared_ptr &player) { diff --git a/src/io/functions/iologindata_load_player.hpp b/src/io/functions/iologindata_load_player.hpp index 2d1a4305c..ca05bdcb1 100644 --- a/src/io/functions/iologindata_load_player.hpp +++ b/src/io/functions/iologindata_load_player.hpp @@ -11,6 +11,10 @@ #include "io/iologindata.hpp" +class Player; +class DBResult; +using DBResult_ptr = std::shared_ptr; + class IOLoginDataLoad : public IOLoginData { public: static bool loadPlayerBasicInfo(const std::shared_ptr &player, const DBResult_ptr &result); diff --git a/src/io/functions/iologindata_save_player.cpp b/src/io/functions/iologindata_save_player.cpp index b38e6e2b8..613fdac1c 100644 --- a/src/io/functions/iologindata_save_player.cpp +++ b/src/io/functions/iologindata_save_player.cpp @@ -17,6 +17,7 @@ #include "items/containers/depot/depotchest.hpp" #include "items/containers/inbox/inbox.hpp" #include "items/containers/rewards/reward.hpp" +#include "creatures/players/player.hpp" bool IOLoginDataSave::saveItems(const std::shared_ptr &player, const ItemBlockList &itemList, DBInsert &query_insert, PropWriteStream &propWriteStream) { if (!player) { diff --git a/src/io/functions/iologindata_save_player.hpp b/src/io/functions/iologindata_save_player.hpp index abafc2c18..1f871a3b5 100644 --- a/src/io/functions/iologindata_save_player.hpp +++ b/src/io/functions/iologindata_save_player.hpp @@ -12,6 +12,7 @@ #include "io/iologindata.hpp" class PropWriteStream; +class DBInsert; class IOLoginDataSave : public IOLoginData { public: diff --git a/src/io/iologindata.cpp b/src/io/iologindata.cpp index 0249d70a5..c0a6a13f3 100644 --- a/src/io/iologindata.cpp +++ b/src/io/iologindata.cpp @@ -9,12 +9,15 @@ #include "io/iologindata.hpp" +#include "account/account.hpp" #include "config/configmanager.hpp" +#include "database/database.hpp" #include "io/functions/iologindata_load_player.hpp" #include "io/functions/iologindata_save_player.hpp" #include "game/game.hpp" #include "creatures/monsters/monster.hpp" #include "creatures/players/wheel/player_wheel.hpp" +#include "creatures/players/player.hpp" #include "lib/metrics/metrics.hpp" #include "enums/account_type.hpp" #include "enums/account_errors.hpp" diff --git a/src/io/iologindata.hpp b/src/io/iologindata.hpp index 29eac0c81..d379031cd 100644 --- a/src/io/iologindata.hpp +++ b/src/io/iologindata.hpp @@ -9,9 +9,12 @@ #pragma once -#include "account/account.hpp" -#include "creatures/players/player.hpp" -#include "database/database.hpp" +class Player; +class Item; +class DBResult; + +struct VIPEntry; +struct VIPGroupEntry; using ItemBlockList = std::list>>; @@ -21,7 +24,7 @@ class IOLoginData { static uint8_t getAccountType(uint32_t accountId); static bool loadPlayerById(const std::shared_ptr &player, uint32_t id, bool disableIrrelevantInfo = true); static bool loadPlayerByName(const std::shared_ptr &player, const std::string &name, bool disableIrrelevantInfo = true); - static bool loadPlayer(const std::shared_ptr &player, const DBResult_ptr &result, bool disableIrrelevantInfo = false); + static bool loadPlayer(const std::shared_ptr &player, const std::shared_ptr &result, bool disableIrrelevantInfo = false); static bool savePlayer(const std::shared_ptr &player); static uint32_t getGuidByName(const std::string &name); static bool getGuidByNameEx(uint32_t &guid, bool &specialVip, std::string &name); diff --git a/src/io/iomarket.cpp b/src/io/iomarket.cpp index 3332ffab1..ff2f9595d 100644 --- a/src/io/iomarket.cpp +++ b/src/io/iomarket.cpp @@ -16,6 +16,7 @@ #include "game/scheduling/save_manager.hpp" #include "io/iologindata.hpp" #include "items/containers/inbox/inbox.hpp" +#include "creatures/players/player.hpp" uint8_t IOMarket::getTierFromDatabaseTable(const std::string &string) { auto tier = static_cast(std::atoi(string.c_str())); diff --git a/src/items/bed.cpp b/src/items/bed.cpp index 25e95318e..527f052e2 100644 --- a/src/items/bed.cpp +++ b/src/items/bed.cpp @@ -16,6 +16,7 @@ #include "game/scheduling/save_manager.hpp" #include "io/iologindata.hpp" #include "server/network/protocol/protocolgame.hpp" +#include "creatures/players/player.hpp" BedItem::BedItem(uint16_t id) : Item(id) { diff --git a/src/items/items_definitions.hpp b/src/items/items_definitions.hpp index 19d7f30b9..9b6990c0c 100644 --- a/src/items/items_definitions.hpp +++ b/src/items/items_definitions.hpp @@ -140,34 +140,35 @@ enum ItemGroup_t { enum ItemTypes_t { ITEM_TYPE_NONE, - // Odered to make the cast from protobuf::itemCategory to ItemTypes_t easier. + // Ordered to make the cast from protobuf::itemCategory to ItemTypes_t easier. // Do not edit it from Start-End // Start - ITEM_TYPE_ARMOR, - ITEM_TYPE_AMULET, - ITEM_TYPE_BOOTS, - ITEM_TYPE_CONTAINER, - ITEM_TYPE_DECORATION, - ITEM_TYPE_FOOD, - ITEM_TYPE_HELMET, - ITEM_TYPE_LEGS, - ITEM_TYPE_OTHER, - ITEM_TYPE_POTION, - ITEM_TYPE_RING, - ITEM_TYPE_RUNE, - ITEM_TYPE_SHIELD, - ITEM_TYPE_TOOLS, - ITEM_TYPE_VALUABLE, - ITEM_TYPE_AMMO, - ITEM_TYPE_AXE, - ITEM_TYPE_CLUB, - ITEM_TYPE_DISTANCE, - ITEM_TYPE_SWORD, - ITEM_TYPE_WAND, - ITEM_TYPE_PREMIUMSCROLL, - ITEM_TYPE_TIBIACOIN, - ITEM_TYPE_CREATUREPRODUCT, - ITEM_TYPE_QUIVER, + ITEM_TYPE_ARMOR = 1, + ITEM_TYPE_AMULET = 2, + ITEM_TYPE_BOOTS = 3, + ITEM_TYPE_CONTAINER = 4, + ITEM_TYPE_DECORATION = 5, + ITEM_TYPE_FOOD = 6, + ITEM_TYPE_HELMET = 7, + ITEM_TYPE_LEGS = 8, + ITEM_TYPE_OTHER = 9, + ITEM_TYPE_POTION = 10, + ITEM_TYPE_RING = 11, + ITEM_TYPE_RUNE = 12, + ITEM_TYPE_SHIELD = 13, + ITEM_TYPE_TOOLS = 14, + ITEM_TYPE_VALUABLE = 15, + ITEM_TYPE_AMMO = 16, + ITEM_TYPE_AXE = 17, + ITEM_TYPE_CLUB = 18, + ITEM_TYPE_DISTANCE = 19, + ITEM_TYPE_SWORD = 20, + ITEM_TYPE_WAND = 21, + ITEM_TYPE_PREMIUMSCROLL = 22, + ITEM_TYPE_TIBIACOIN = 23, + ITEM_TYPE_CREATUREPRODUCT = 24, + ITEM_TYPE_QUIVER = 25, + ITEM_TYPE_SOULCORES = 26, // End ITEM_TYPE_DEPOT, diff --git a/src/items/tile.cpp b/src/items/tile.cpp index f15e2bd8a..4b7cb0fba 100644 --- a/src/items/tile.cpp +++ b/src/items/tile.cpp @@ -23,6 +23,7 @@ #include "lua/creature/movement.hpp" #include "map/spectators.hpp" #include "utils/tools.hpp" +#include "game/scheduling/dispatcher.hpp" auto real_nullptr_tile = std::make_shared(0xFFFF, 0xFFFF, 0xFF); const std::shared_ptr &Tile::nullptr_tile = real_nullptr_tile; @@ -1942,3 +1943,16 @@ void Tile::clearZones() { zones.erase(zone); } } + +void Tile::safeCall(std::function &&action) const { + if (g_dispatcher().context().isAsync()) { + g_dispatcher().addEvent([weak_self = std::weak_ptr(shared_from_this()), action = std::move(action)] { + if (weak_self.lock()) { + action(); + } + }, + g_dispatcher().context().getName()); + } else { + action(); + } +} diff --git a/src/items/tile.hpp b/src/items/tile.hpp index 4137b6e11..ba3834d99 100644 --- a/src/items/tile.hpp +++ b/src/items/tile.hpp @@ -259,6 +259,9 @@ class Tile : public Cylinder, public SharedObject { } } + // This method maintains safety in asynchronous calls, avoiding competition between threads. + void safeCall(std::function &&action) const; + private: void onAddTileItem(const std::shared_ptr &item); void onUpdateTileItem(const std::shared_ptr &oldItem, const ItemType &oldType, const std::shared_ptr &newItem, const ItemType &newType); diff --git a/src/items/weapons/weapons.cpp b/src/items/weapons/weapons.cpp index 81e59f6a7..f27732f3b 100644 --- a/src/items/weapons/weapons.cpp +++ b/src/items/weapons/weapons.cpp @@ -13,8 +13,8 @@ #include "creatures/combat/combat.hpp" #include "game/game.hpp" #include "lua/creature/events.hpp" - #include "lua/global/lua_variant.hpp" +#include "creatures/players/player.hpp" Weapons::Weapons() = default; Weapons::~Weapons() = default; diff --git a/src/items/weapons/weapons.hpp b/src/items/weapons/weapons.hpp index bbe15e12a..c31813d09 100644 --- a/src/items/weapons/weapons.hpp +++ b/src/items/weapons/weapons.hpp @@ -10,7 +10,6 @@ #pragma once #include "lua/scripts/luascript.hpp" -#include "creatures/players/player.hpp" #include "lua/scripts/scripts.hpp" #include "creatures/combat/combat.hpp" #include "utils/utils_definitions.hpp" diff --git a/src/lua/callbacks/callbacks_definitions.hpp b/src/lua/callbacks/callbacks_definitions.hpp index 6c19cc809..faea6b2d1 100644 --- a/src/lua/callbacks/callbacks_definitions.hpp +++ b/src/lua/callbacks/callbacks_definitions.hpp @@ -23,7 +23,6 @@ enum class EventCallback_t : uint16_t { creatureOnChangeOutfit, creatureOnAreaCombat, creatureOnTargetCombat, - creatureOnHear, creatureOnDrainHealth, creatureOnCombat, // Party @@ -62,9 +61,6 @@ enum class EventCallback_t : uint16_t { // Monster monsterOnDropLoot, monsterPostDropLoot, - monsterOnSpawn, - // Npc - npcOnSpawn, // Zone zoneBeforeCreatureEnter, zoneBeforeCreatureLeave, diff --git a/src/lua/callbacks/event_callback.cpp b/src/lua/callbacks/event_callback.cpp index 3d95543f1..1675cdef4 100644 --- a/src/lua/callbacks/event_callback.cpp +++ b/src/lua/callbacks/event_callback.cpp @@ -154,33 +154,6 @@ ReturnValue EventCallback::creatureOnTargetCombat(const std::shared_ptr &creature, const std::shared_ptr &speaker, const std::string &words, SpeakClasses type) const { - if (!LuaScriptInterface::reserveScriptEnv()) { - g_logger().error("[EventCallback::creatureOnHear - " - "Creature {} speaker {}] " - "Call stack overflow. Too many lua script calls being nested.", - creature->getName(), speaker->getName()); - return; - } - - ScriptEnvironment* scriptEnvironment = LuaScriptInterface::getScriptEnv(); - scriptEnvironment->setScriptId(getScriptId(), getScriptInterface()); - - lua_State* L = getScriptInterface()->getLuaState(); - getScriptInterface()->pushFunction(getScriptId()); - - LuaScriptInterface::pushUserdata(L, creature); - LuaScriptInterface::setCreatureMetatable(L, -1, creature); - - LuaScriptInterface::pushUserdata(L, speaker); - LuaScriptInterface::setCreatureMetatable(L, -1, speaker); - - LuaScriptInterface::pushString(L, words); - lua_pushnumber(L, type); - - getScriptInterface()->callVoidFunction(4); -} - void EventCallback::creatureOnDrainHealth(const std::shared_ptr &creature, const std::shared_ptr &attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary) const { if (!LuaScriptInterface::reserveScriptEnv()) { g_logger().error("[EventCallback::creatureOnDrainHealth - " @@ -1162,63 +1135,6 @@ void EventCallback::monsterPostDropLoot(const std::shared_ptr &monster, return getScriptInterface()->callVoidFunction(2); } -void EventCallback::monsterOnSpawn(const std::shared_ptr &monster, const Position &position) const { - if (!LuaScriptInterface::reserveScriptEnv()) { - g_logger().error("{} - " - "Position {}" - ". Call stack overflow. Too many lua script calls being nested.", - __FUNCTION__, position.toString()); - return; - } - - ScriptEnvironment* scriptEnvironment = LuaScriptInterface::getScriptEnv(); - scriptEnvironment->setScriptId(getScriptId(), getScriptInterface()); - - lua_State* L = getScriptInterface()->getLuaState(); - getScriptInterface()->pushFunction(getScriptId()); - - LuaScriptInterface::pushUserdata(L, monster); - LuaScriptInterface::setMetatable(L, -1, "Monster"); - LuaScriptInterface::pushPosition(L, position); - - if (LuaScriptInterface::protectedCall(L, 2, 1) != 0) { - LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L)); - } else { - lua_pop(L, 1); - } - - LuaScriptInterface::resetScriptEnv(); -} - -// Npc -void EventCallback::npcOnSpawn(const std::shared_ptr &npc, const Position &position) const { - if (!LuaScriptInterface::reserveScriptEnv()) { - g_logger().error("{} - " - "Position {}" - ". Call stack overflow. Too many lua script calls being nested.", - __FUNCTION__, position.toString()); - return; - } - - ScriptEnvironment* scriptEnvironment = LuaScriptInterface::getScriptEnv(); - scriptEnvironment->setScriptId(getScriptId(), getScriptInterface()); - - lua_State* L = getScriptInterface()->getLuaState(); - getScriptInterface()->pushFunction(getScriptId()); - - LuaScriptInterface::pushUserdata(L, npc); - LuaScriptInterface::setMetatable(L, -1, "Npc"); - LuaScriptInterface::pushPosition(L, position); - - if (LuaScriptInterface::protectedCall(L, 2, 1) != 0) { - LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L)); - } else { - lua_pop(L, 1); - } - - LuaScriptInterface::resetScriptEnv(); -} - bool EventCallback::zoneBeforeCreatureEnter(const std::shared_ptr &zone, const std::shared_ptr &creature) const { if (!LuaScriptInterface::reserveScriptEnv()) { g_logger().error("[EventCallback::zoneBeforeCreatureEnter - " diff --git a/src/lua/callbacks/event_callback.hpp b/src/lua/callbacks/event_callback.hpp index fb0eb760a..514c7feaf 100644 --- a/src/lua/callbacks/event_callback.hpp +++ b/src/lua/callbacks/event_callback.hpp @@ -96,7 +96,6 @@ class EventCallback final : public Script { bool creatureOnChangeOutfit(const std::shared_ptr &creature, const Outfit_t &outfit) const; ReturnValue creatureOnAreaCombat(const std::shared_ptr &creature, const std::shared_ptr &tile, bool aggressive) const; ReturnValue creatureOnTargetCombat(const std::shared_ptr &creature, const std::shared_ptr &target) const; - void creatureOnHear(const std::shared_ptr &creature, const std::shared_ptr &speaker, const std::string &words, SpeakClasses type) const; void creatureOnDrainHealth(const std::shared_ptr &creature, const std::shared_ptr &attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary) const; void creatureOnCombat(std::shared_ptr attacker, std::shared_ptr target, CombatDamage &damage) const; @@ -137,10 +136,6 @@ class EventCallback final : public Script { // Monster void monsterOnDropLoot(const std::shared_ptr &monster, const std::shared_ptr &corpse) const; void monsterPostDropLoot(const std::shared_ptr &monster, const std::shared_ptr &corpse) const; - void monsterOnSpawn(const std::shared_ptr &monster, const Position &position) const; - - // Npc - void npcOnSpawn(const std::shared_ptr &npc, const Position &position) const; // Zone bool zoneBeforeCreatureEnter(const std::shared_ptr &zone, const std::shared_ptr &creature) const; diff --git a/src/lua/creature/events.cpp b/src/lua/creature/events.cpp index 57a8ff45d..9e0385810 100644 --- a/src/lua/creature/events.cpp +++ b/src/lua/creature/events.cpp @@ -62,8 +62,6 @@ bool Events::loadFromXml() { info.creatureOnAreaCombat = event; } else if (methodName == "onTargetCombat") { info.creatureOnTargetCombat = event; - } else if (methodName == "onHear") { - info.creatureOnHear = event; } else if (methodName == "onDrainHealth") { info.creatureOnDrainHealth = event; } else { @@ -136,17 +134,9 @@ bool Events::loadFromXml() { } else if (className == "Monster") { if (methodName == "onDropLoot") { info.monsterOnDropLoot = event; - } else if (methodName == "onSpawn") { - info.monsterOnSpawn = event; } else { g_logger().warn("{} - Unknown monster method: {}", __FUNCTION__, methodName); } - } else if (className == "Npc") { - if (methodName == "onSpawn") { - info.monsterOnSpawn = event; - } else { - g_logger().warn("{} - Unknown npc method: {}", __FUNCTION__, methodName); - } } else { g_logger().warn("{} - Unknown class: {}", __FUNCTION__, className); } @@ -154,74 +144,6 @@ bool Events::loadFromXml() { return true; } -// Monster -void Events::eventMonsterOnSpawn(const std::shared_ptr &monster, const Position &position) { - // Monster:onSpawn(position) or Monster.onSpawn(self, position) - if (info.monsterOnSpawn == -1) { - return; - } - - if (!LuaScriptInterface::reserveScriptEnv()) { - g_logger().error("{} - " - "Position {}" - ". Call stack overflow. Too many lua script calls being nested.", - __FUNCTION__, position.toString()); - return; - } - - ScriptEnvironment* env = LuaScriptInterface::getScriptEnv(); - env->setScriptId(info.monsterOnSpawn, &scriptInterface); - - lua_State* L = scriptInterface.getLuaState(); - scriptInterface.pushFunction(info.monsterOnSpawn); - - LuaScriptInterface::pushUserdata(L, monster); - LuaScriptInterface::setMetatable(L, -1, "Monster"); - LuaScriptInterface::pushPosition(L, position); - - if (LuaScriptInterface::protectedCall(L, 2, 1) != 0) { - LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L)); - } else { - lua_pop(L, 1); - } - - LuaScriptInterface::resetScriptEnv(); -} - -// Npc -void Events::eventNpcOnSpawn(const std::shared_ptr &npc, const Position &position) { - // Npc:onSpawn(position) or Npc.onSpawn(self, position) - if (info.npcOnSpawn == -1) { - return; - } - - if (!LuaScriptInterface::reserveScriptEnv()) { - g_logger().error("{} - " - "Position {}" - ". Call stack overflow. Too many lua script calls being nested.", - __FUNCTION__, position.toString()); - return; - } - - ScriptEnvironment* env = LuaScriptInterface::getScriptEnv(); - env->setScriptId(info.npcOnSpawn, &scriptInterface); - - lua_State* L = scriptInterface.getLuaState(); - scriptInterface.pushFunction(info.npcOnSpawn); - - LuaScriptInterface::pushUserdata(L, npc); - LuaScriptInterface::setMetatable(L, -1, "Npc"); - LuaScriptInterface::pushPosition(L, position); - - if (LuaScriptInterface::protectedCall(L, 2, 1) != 0) { - LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L)); - } else { - lua_pop(L, 1); - } - - LuaScriptInterface::resetScriptEnv(); -} - Events &Events::getInstance() { return inject(); } @@ -342,38 +264,6 @@ ReturnValue Events::eventCreatureOnTargetCombat(const std::shared_ptr return returnValue; } -void Events::eventCreatureOnHear(const std::shared_ptr &creature, const std::shared_ptr &speaker, const std::string &words, SpeakClasses type) { - // Creature:onHear(speaker, words, type) - if (info.creatureOnHear == -1) { - return; - } - - if (!LuaScriptInterface::reserveScriptEnv()) { - g_logger().error("[Events::eventCreatureOnHear - " - "Creature {} speaker {}] " - "Call stack overflow. Too many lua script calls being nested.", - creature->getName(), speaker->getName()); - return; - } - - ScriptEnvironment* env = LuaScriptInterface::getScriptEnv(); - env->setScriptId(info.creatureOnHear, &scriptInterface); - - lua_State* L = scriptInterface.getLuaState(); - scriptInterface.pushFunction(info.creatureOnHear); - - LuaScriptInterface::pushUserdata(L, creature); - LuaScriptInterface::setCreatureMetatable(L, -1, creature); - - LuaScriptInterface::pushUserdata(L, speaker); - LuaScriptInterface::setCreatureMetatable(L, -1, speaker); - - LuaScriptInterface::pushString(L, words); - lua_pushnumber(L, type); - - scriptInterface.callVoidFunction(4); -} - void Events::eventCreatureOnDrainHealth(const std::shared_ptr &creature, const std::shared_ptr &attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary) { if (info.creatureOnDrainHealth == -1) { return; diff --git a/src/lua/creature/events.hpp b/src/lua/creature/events.hpp index a74cbaf3c..59d6b2f20 100644 --- a/src/lua/creature/events.hpp +++ b/src/lua/creature/events.hpp @@ -41,7 +41,6 @@ class Events { int32_t creatureOnChangeOutfit = -1; int32_t creatureOnAreaCombat = -1; int32_t creatureOnTargetCombat = -1; - int32_t creatureOnHear = -1; int32_t creatureOnDrainHealth = -1; // Party @@ -78,10 +77,6 @@ class Events { // Monster int32_t monsterOnDropLoot = -1; - int32_t monsterOnSpawn = -1; - - // Npc - int32_t npcOnSpawn = -1; }; public: @@ -99,7 +94,6 @@ class Events { bool eventCreatureOnChangeOutfit(const std::shared_ptr &creature, const Outfit_t &outfit); ReturnValue eventCreatureOnAreaCombat(const std::shared_ptr &creature, const std::shared_ptr &tile, bool aggressive); ReturnValue eventCreatureOnTargetCombat(const std::shared_ptr &creature, const std::shared_ptr &target); - void eventCreatureOnHear(const std::shared_ptr &creature, const std::shared_ptr &speaker, const std::string &words, SpeakClasses type); void eventCreatureOnDrainHealth(const std::shared_ptr &creature, const std::shared_ptr &attacker, CombatType_t &typePrimary, int32_t &damagePrimary, CombatType_t &typeSecondary, int32_t &damageSecondary, TextColor_t &colorPrimary, TextColor_t &colorSecondary); // Party @@ -135,10 +129,6 @@ class Events { // Monster void eventMonsterOnDropLoot(const std::shared_ptr &monster, const std::shared_ptr &corpse); - void eventMonsterOnSpawn(const std::shared_ptr &monster, const Position &position); - - // Monster - void eventNpcOnSpawn(const std::shared_ptr &npc, const Position &position); private: LuaScriptInterface scriptInterface; diff --git a/src/lua/functions/core/game/game_functions.cpp b/src/lua/functions/core/game/game_functions.cpp index 16133833b..f1226d2e2 100644 --- a/src/lua/functions/core/game/game_functions.cpp +++ b/src/lua/functions/core/game/game_functions.cpp @@ -28,6 +28,7 @@ #include "lua/functions/events/event_callback_functions.hpp" #include "lua/scripts/lua_environment.hpp" #include "map/spectators.hpp" +#include "creatures/players/player.hpp" // Game int GameFunctions::luaGameCreateMonsterType(lua_State* L) { @@ -444,8 +445,6 @@ int GameFunctions::luaGameCreateMonster(lua_State* L) { const bool extended = getBoolean(L, 3, false); const bool force = getBoolean(L, 4, false); if (g_game().placeCreature(monster, position, extended, force)) { - g_events().eventMonsterOnSpawn(monster, position); - g_callbacks().executeCallback(EventCallback_t::monsterOnSpawn, &EventCallback::monsterOnSpawn, monster, position); monster->onSpawn(); const auto &mtype = monster->getMonsterType(); if (mtype && mtype->info.raceid > 0 && mtype->info.bosstiaryRace == BosstiaryRarity_t::RARITY_ARCHFOE) { diff --git a/src/lua/functions/core/game/global_functions.cpp b/src/lua/functions/core/game/global_functions.cpp index 14d87e5af..6befdc5eb 100644 --- a/src/lua/functions/core/game/global_functions.cpp +++ b/src/lua/functions/core/game/global_functions.cpp @@ -22,6 +22,7 @@ #include "lua/scripts/lua_environment.hpp" #include "lua/scripts/script_environment.hpp" #include "server/network/protocol/protocolstatus.hpp" +#include "creatures/players/player.hpp" void GlobalFunctions::init(lua_State* L) { lua_register(L, "addEvent", GlobalFunctions::luaAddEvent); diff --git a/src/lua/functions/creatures/combat/combat_functions.cpp b/src/lua/functions/creatures/combat/combat_functions.cpp index 27d3a76ef..e07bce7a7 100644 --- a/src/lua/functions/creatures/combat/combat_functions.cpp +++ b/src/lua/functions/creatures/combat/combat_functions.cpp @@ -14,6 +14,7 @@ #include "game/game.hpp" #include "lua/global/lua_variant.hpp" #include "lua/scripts/lua_environment.hpp" +#include "creatures/players/player.hpp" int CombatFunctions::luaCombatCreate(lua_State* L) { // Combat() diff --git a/src/lua/functions/creatures/player/player_functions.cpp b/src/lua/functions/creatures/player/player_functions.cpp index c4c2faa8c..7ef2be62c 100644 --- a/src/lua/functions/creatures/player/player_functions.cpp +++ b/src/lua/functions/creatures/player/player_functions.cpp @@ -9,6 +9,7 @@ #include "lua/functions/creatures/player/player_functions.hpp" +#include "account/account.hpp" #include "creatures/appearance/mounts/mounts.hpp" #include "creatures/combat/spells.hpp" #include "creatures/creature.hpp" diff --git a/src/lua/functions/map/house_functions.cpp b/src/lua/functions/map/house_functions.cpp index 708b9233a..52ca75258 100644 --- a/src/lua/functions/map/house_functions.cpp +++ b/src/lua/functions/map/house_functions.cpp @@ -15,6 +15,7 @@ #include "game/movement/position.hpp" #include "io/iologindata.hpp" #include "map/house/house.hpp" +#include "creatures/players/player.hpp" int HouseFunctions::luaHouseCreate(lua_State* L) { // House(id) diff --git a/src/lua/scripts/luascript.cpp b/src/lua/scripts/luascript.cpp index aa1b60118..44c2c92b4 100644 --- a/src/lua/scripts/luascript.cpp +++ b/src/lua/scripts/luascript.cpp @@ -237,6 +237,7 @@ bool LuaScriptInterface::closeState() { } std::string LuaScriptInterface::getMetricsScope() const { +#ifdef FEATURE_METRICS metrics::method_latency measure(__METHOD_NAME__); int32_t scriptId; int32_t callbackId; @@ -261,6 +262,9 @@ std::string LuaScriptInterface::getMetricsScope() const { } return fmt::format("{}:{}", name, timerEvent ? "timer" : ""); +#else + return {}; +#endif } bool LuaScriptInterface::callFunction(int params) const { diff --git a/src/map/house/house.cpp b/src/map/house/house.cpp index 334144cfb..f519e9a46 100644 --- a/src/map/house/house.cpp +++ b/src/map/house/house.cpp @@ -18,6 +18,7 @@ #include "items/containers/inbox/inbox.hpp" #include "lib/metrics/metrics.hpp" #include "utils/pugicast.hpp" +#include "creatures/players/player.hpp" House::House(uint32_t houseId) : id(houseId) { } diff --git a/src/map/map.cpp b/src/map/map.cpp index 768ba959d..12770ad8b 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -442,6 +442,13 @@ void Map::moveCreature(const std::shared_ptr &creature, const std::sha } else { events(); } + + if (forceTeleport) { + if (const auto &player = creature->getPlayer()) { + player->sendMagicEffect(oldPos, CONST_ME_TELEPORT); + player->sendMagicEffect(newPos, CONST_ME_TELEPORT); + } + } } bool Map::canThrowObjectTo(const Position &fromPos, const Position &toPos, const SightLines_t lineOfSight /*= SightLine_CheckSightLine*/, const int32_t rangex /*= Map::maxClientViewportX*/, const int32_t rangey /*= Map::maxClientViewportY*/) { diff --git a/src/map/mapcache.cpp b/src/map/mapcache.cpp index 01fd9da63..cf2f27c6e 100644 --- a/src/map/mapcache.cpp +++ b/src/map/mapcache.cpp @@ -146,15 +146,11 @@ std::shared_ptr MapCache::getOrCreateTileFromCache(const std::shared_ptrsetFlag(static_cast(cachedTile->flags)); - // add zone synchronously - g_dispatcher().context().tryAddEvent( - [tile, pos] { - for (const auto &zone : Zone::getZones(pos)) { - tile->addZone(zone); - } - }, - "Zone::getZones" - ); + tile->safeCall([tile, pos] { + for (const auto &zone : Zone::getZones(pos)) { + tile->addZone(zone); + } + }); floor->setTile(x, y, tile); diff --git a/src/protobuf/appearances.proto b/src/protobuf/appearances.proto index ed924febf..1ca8defac 100644 --- a/src/protobuf/appearances.proto +++ b/src/protobuf/appearances.proto @@ -42,6 +42,7 @@ enum ITEM_CATEGORY { ITEM_CATEGORY_TIBIA_COINS = 23; ITEM_CATEGORY_CREATURE_PRODUCTS = 24; ITEM_CATEGORY_QUIVER = 25; + ITEM_CATEGORY_SOULCORES = 26; } enum PLAYER_PROFESSION { diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 99c8a9606..15b435087 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -9,6 +9,7 @@ #include "server/network/protocol/protocolgame.hpp" +#include "account/account.hpp" #include "config/configmanager.hpp" #include "core.hpp" #include "creatures/appearance/mounts/mounts.hpp" @@ -4089,7 +4090,7 @@ void ProtocolGame::sendCyclopediaCharacterInspection() { continue; } - msg.add(imbuementInfo.imbuement->getID()); + msg.add(imbuementInfo.imbuement->getIconID()); itemImbuements++; } @@ -8857,7 +8858,11 @@ void ProtocolGame::parseSendBosstiarySlots() { uint32_t boostedBossId = g_ioBosstiary().getBoostedBossId(); // Sanity checks - std::string boostedBossName = g_ioBosstiary().getBoostedBossName(); + const std::string &boostedBossName = g_ioBosstiary().getBoostedBossName(); + if (boostedBossName.empty()) { + g_logger().error("[{}] The boosted boss name is empty", __FUNCTION__); + return; + } const auto mTypeBoosted = g_monsters().getMonsterType(boostedBossName); auto boostedBossRace = mTypeBoosted ? mTypeBoosted->info.bosstiaryRace : BosstiaryRarity_t::BOSS_INVALID; auto isValidBoostedBoss = boostedBossId == 0 || (boostedBossRace >= BosstiaryRarity_t::RARITY_BANE && boostedBossRace <= BosstiaryRarity_t::RARITY_NEMESIS); diff --git a/src/server/network/protocol/protocolstatus.cpp b/src/server/network/protocol/protocolstatus.cpp index 612c5f7e2..d3c37ec6e 100644 --- a/src/server/network/protocol/protocolstatus.cpp +++ b/src/server/network/protocol/protocolstatus.cpp @@ -18,7 +18,7 @@ std::string ProtocolStatus::SERVER_NAME = "OTX Server"; std::string ProtocolStatus::SERVER_VERSION = "6"; -std::string ProtocolStatus::SERVER_DEVELOPERS = "OpenTibiaBR Organization. Based on: Canary (3.1.2). And data edited by: Mattyx14"; +std::string ProtocolStatus::SERVER_DEVELOPERS = "OpenTibiaBR Organization. Based on: Canary (3.0). And data edited by: Mattyx14"; std::map ProtocolStatus::ipConnectMap; const uint64_t ProtocolStatus::start = OTSYS_TIME(true);