Skip to content

Commit

Permalink
fix: reward collect crash (#1602)
Browse files Browse the repository at this point in the history
The crash occurred in very difficult scenarios, when the object's parent had been removed (for example, due to the decay of the boss's original body), which caused the reward container to lose the parent, but still remain in memory. From now on, we will set a new parent (the reward chest and the tile).

Fixes #994
Fixes #1147
  • Loading branch information
dudantas authored Sep 15, 2023
1 parent 4b7e268 commit 2d1aa9e
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 8 deletions.
18 changes: 15 additions & 3 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2695,9 +2695,9 @@ ReturnValue Game::internalCollectLootItems(Player* player, Item* item, ObjectCat
ReturnValue Game::collectRewardChestItems(Player* player, uint32_t maxMoveItems /* = 0*/) {
// Check if have item on player reward chest
RewardChest* rewardChest = player->getRewardChest();
if (!rewardChest || rewardChest->empty()) {
g_logger().debug("Reward chest is wrong or empty");
return RETURNVALUE_NOTPOSSIBLE;
if (rewardChest->empty()) {
g_logger().debug("Reward chest is empty");
return RETURNVALUE_REWARDCHESTISEMPTY;
}

auto rewardItemsVector = player->getRewardsFromContainer(rewardChest->getContainer());
Expand Down Expand Up @@ -9821,6 +9821,18 @@ void Game::playerRewardChestCollect(uint32_t playerId, const Position &pos, uint
return;
}

// Updates the parent of the reward chest and reward containers to avoid memory usage after cleaning
RewardChest* playerRewardChest = player->getRewardChest();
if (playerRewardChest->empty()) {
player->sendCancelMessage(RETURNVALUE_REWARDCHESTISEMPTY);
return;
}

playerRewardChest->setParent(item->getContainer()->getParent()->getTile());
for (const auto &[mapRewardId, reward] : player->rewardMap) {
reward->setParent(playerRewardChest);
}

std::lock_guard<std::mutex> lock(player->quickLootMutex);

ReturnValue returnValue = collectRewardChestItems(player, maxMoveItems);
Expand Down
10 changes: 5 additions & 5 deletions src/lua/creature/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,17 +310,17 @@ ReturnValue Actions::internalUseItem(Player* player, const Position &pos, uint8_

// reward chest
if (container->getRewardChest() != nullptr && container->getParent()) {
RewardChest* myRewardChest = player->getRewardChest();
if (myRewardChest->size() == 0) {
RewardChest* playerRewardChest = player->getRewardChest();
if (playerRewardChest->empty()) {
return RETURNVALUE_REWARDCHESTISEMPTY;
}

myRewardChest->setParent(container->getParent()->getTile());
playerRewardChest->setParent(container->getParent()->getTile());
for (const auto &[mapRewardId, reward] : player->rewardMap) {
reward->setParent(myRewardChest);
reward->setParent(playerRewardChest);
}

openContainer = myRewardChest;
openContainer = playerRewardChest;
}

auto rewardId = container->getAttribute<time_t>(ItemAttribute_t::DATE);
Expand Down

0 comments on commit 2d1aa9e

Please sign in to comment.