From b54a712ffa6c9ae2f0250b74d2f65ed51e53ba6b Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Thu, 5 Dec 2024 20:02:07 -0300 Subject: [PATCH] fix: check creatures crash (#3168) --- src/game/game.cpp | 30 ++++++++++++++++-------------- src/game/scheduling/task.hpp | 1 + 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/game/game.cpp b/src/game/game.cpp index e69654a47ad..7a492348649 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -72,7 +72,7 @@ #include -std::vector> checkCreatureLists[EVENT_CREATURECOUNT]; +std::vector> checkCreatureLists[EVENT_CREATURECOUNT]; namespace InternalGame { void sendBlockEffect(BlockType_t blockType, CombatType_t combatType, const Position &targetPos, const std::shared_ptr &source) { @@ -6461,16 +6461,15 @@ void Game::addCreatureCheck(const std::shared_ptr &creature) { creature->creatureCheck.store(true); - if (creature->inCheckCreaturesVector.load()) { + if (creature->inCheckCreaturesVector.exchange(true)) { // already in a vector return; } - creature->inCheckCreaturesVector.store(true); - - creature->safeCall([this, creature] { - checkCreatureLists[uniform_random(0, EVENT_CREATURECOUNT - 1)].emplace_back(creature); - }); + g_dispatcher().addEvent([this, index = uniform_random(0, EVENT_CREATURECOUNT - 1), creature] { + checkCreatureLists[index].emplace_back(creature); + }, + "Game::addCreatureCheck"); } void Game::removeCreatureCheck(const std::shared_ptr &creature) { @@ -6484,15 +6483,18 @@ void Game::checkCreatures() { metrics::method_latency measure(__METRICS_METHOD_NAME__); static size_t index = 0; - 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); - creature->executeConditions(EVENT_CREATURE_THINK_INTERVAL); - return false; + std::erase_if(checkCreatureLists[index], [this](const std::weak_ptr &weak) { + if (const auto creature = weak.lock()) { + if (creature->creatureCheck && creature->isAlive()) { + creature->onThink(EVENT_CREATURE_THINK_INTERVAL); + creature->onAttacking(EVENT_CREATURE_THINK_INTERVAL); + creature->executeConditions(EVENT_CREATURE_THINK_INTERVAL); + return false; + } + + creature->inCheckCreaturesVector = false; } - creature->inCheckCreaturesVector = false; return true; }); diff --git a/src/game/scheduling/task.hpp b/src/game/scheduling/task.hpp index c01dbe2f676..6cd9eef342d 100644 --- a/src/game/scheduling/task.hpp +++ b/src/game/scheduling/task.hpp @@ -75,6 +75,7 @@ class Task { "Game::createInfluencedMonsters", "Game::updateCreatureWalk", "Game::updateForgeableMonsters", + "Game::addCreatureCheck", "GlobalEvents::think", "LuaEnvironment::executeTimerEvent", "Modules::executeOnRecvbyte",