Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed crash when creating specific offers with certain amount from inbox #453

Merged
merged 6 commits into from
Jul 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 32 additions & 25 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7619,7 +7619,8 @@ void Game::playerCreateMarketOffer(uint32_t playerId, uint8_t type, uint16_t ite
}

DepotLocker* depotLocker = player->getDepotLocker(player->getLastDepotId());
if (!depotLocker) {
if (depotLocker == nullptr) {
SPDLOG_ERROR("[Game::playerCreateMarketOffer] - Sell depot chest is nullptr");
return;
}

Expand All @@ -7638,8 +7639,9 @@ void Game::playerCreateMarketOffer(uint32_t playerId, uint8_t type, uint16_t ite
uint16_t stashminus = player->getStashItemCount(it.wareId);
amount = (amount - (amount > stashminus ? stashminus : amount));

std::forward_list<Item *> itemList = getMarketItemList(it.wareId, amount, depotLocker);
if (itemList.empty() && amount > 0) {
std::vector<Item*> itemVector = getMarketItemList(it.wareId, amount, depotLocker);
if (itemVector.empty() && amount > 0) {
SPDLOG_ERROR("[Game::playerCreateMarketOffer] - Sell item list is empty");
return;
}

Expand All @@ -7648,7 +7650,7 @@ void Game::playerCreateMarketOffer(uint32_t playerId, uint8_t type, uint16_t ite
}

uint16_t tmpAmount = amount;
for (Item *item : itemList) {
for (Item *item : itemVector) {
if (!it.stackable) {
internalRemoveItem(item);
continue;
Expand Down Expand Up @@ -7812,7 +7814,8 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
// so the market action is 'buy' as who created the offer is buying.
if (offer.type == MARKETACTION_BUY) {
DepotLocker* depotLocker = player->getDepotLocker(player->getLastDepotId());
if (!depotLocker) {
if (depotLocker == nullptr) {
SPDLOG_ERROR("[Game::playerCreateMarketOffer] - Buy depot chest is nullptr");
return;
}

Expand Down Expand Up @@ -7856,14 +7859,15 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
}

if (removeAmount > 0) {
std::forward_list<Item*> itemList = getMarketItemList(it.wareId, removeAmount, depotLocker);
if (itemList.empty() && removeAmount > 0) {
std::vector<Item*> itemVector = getMarketItemList(it.wareId, amount, depotLocker);
if (itemVector.empty()) {
SPDLOG_ERROR("[Game::playerCreateMarketOffer] - Buy item list is empty");
return;
}

if (it.stackable) {
uint16_t tmpAmount = removeAmount;
for (Item* item : itemList) {
for (Item* item : itemVector) {
if (!item) {
continue;
}
Expand All @@ -7876,7 +7880,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
}
}
} else {
for (Item* item : itemList) {
for (Item* item : itemVector) {
if (!item) {
continue;
}
Expand Down Expand Up @@ -7931,7 +7935,6 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
delete buyerPlayer;
}
} else if (offer.type == MARKETACTION_SELL) {

Player *sellerPlayer = getPlayerByGUID(offer.playerId);
if (!sellerPlayer) {
sellerPlayer = new Player(nullptr);
Expand Down Expand Up @@ -8468,20 +8471,22 @@ void Game::parsePlayerExtendedOpcode(uint32_t playerId, uint8_t opcode, const st
}
}

std::forward_list<Item*> Game::getMarketItemList(uint16_t wareId, uint16_t sufficientCount, DepotLocker* depotLocker)
std::vector<Item*> Game::getMarketItemList(uint16_t wareId, uint16_t sufficientCount, DepotLocker* depotLocker)
{
std::forward_list<Item*> itemList;
uint16_t count = 0;
std::vector<Item*> itemVector;
itemVector.reserve(std::max<size_t>(32, depotLocker->size()));

std::list<Container*> containers {depotLocker};
do {
Container* container = containers.front();
containers.pop_front();
std::vector<Container*> containers{ depotLocker };
containers.reserve(32);

uint16_t count = 0;
size_t i = 0;
do {
Container* container = containers[i];
for (Item* item : container->getItemList()) {
Container* c = item->getContainer();
if (c && !c->empty()) {
containers.push_back(c);
Container* itemContainer = item->getContainer();
if (itemContainer && !itemContainer->empty()) {
containers.push_back(itemContainer);
continue;
}

Expand All @@ -8490,23 +8495,25 @@ std::forward_list<Item*> Game::getMarketItemList(uint16_t wareId, uint16_t suffi
continue;
}

if (c && (!itemType.isContainer() || c->capacity() != itemType.maxItems)) {
if (itemContainer && (!itemType.isContainer() || itemContainer->capacity() != itemType.maxItems)) {
continue;
}

if (!item->hasMarketAttributes()) {
continue;
}

itemList.push_front(item);
itemVector.push_back(item);

count += Item::countByType(item, -1);
if (count >= sufficientCount) {
return itemList;
return itemVector;
}
}
} while (!containers.empty());
return std::forward_list<Item*>();
} while (++i < containers.size());

itemVector.clear();
return itemVector;
}

void Game::forceRemoveCondition(uint32_t creatureId, ConditionType_t conditionType, ConditionId_t conditionId)
Expand Down
2 changes: 1 addition & 1 deletion src/game/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ class Game

void parsePlayerExtendedOpcode(uint32_t playerId, uint8_t opcode, const std::string& buffer);

std::forward_list<Item*> getMarketItemList(uint16_t wareId, uint16_t sufficientCount, DepotLocker* depotLocker);
std::vector<Item*> getMarketItemList(uint16_t wareId, uint16_t sufficientCount, DepotLocker* depotLocker);

static void updatePremium(account::Account& account);

Expand Down