From 04f6cab87ce95d278c4a61c396cc383314bede0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ja=C5=82ocha?= Date: Sat, 21 Dec 2024 20:46:36 +0100 Subject: [PATCH] Use shared_ptr for Inbox (#4880) --- src/game.cpp | 20 ++++++++++++-------- src/game.h | 2 +- src/house.cpp | 6 +++--- src/inbox.h | 3 +++ src/iomarket.cpp | 4 ++-- src/luascript.cpp | 6 +++--- src/mailbox.cpp | 6 +++--- src/player.cpp | 12 +++--------- src/player.h | 11 +++++++++-- src/protocolgame.cpp | 2 +- 10 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index e1f143310b..a53f7b0fd5 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -5321,7 +5321,8 @@ void Game::playerCancelMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 while (tmpAmount > 0) { int32_t stackCount = std::min(ITEM_STACK_SIZE, tmpAmount); Item* item = Item::CreateItem(it.id, stackCount); - if (internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { + if (internalAddItem(player->getInbox().get(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != + RETURNVALUE_NOERROR) { delete item; break; } @@ -5338,7 +5339,8 @@ void Game::playerCancelMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 for (uint16_t i = 0; i < offer.amount; ++i) { Item* item = Item::CreateItem(it.id, subType); - if (internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { + if (internalAddItem(player->getInbox().get(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != + RETURNVALUE_NOERROR) { delete item; break; } @@ -5429,7 +5431,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 while (tmpAmount > 0) { uint16_t stackCount = std::min(ITEM_STACK_SIZE, tmpAmount); Item* item = Item::CreateItem(it.id, stackCount); - if (internalAddItem(buyerPlayer->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != + if (internalAddItem(buyerPlayer->getInbox().get(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { delete item; break; @@ -5447,7 +5449,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 for (uint16_t i = 0; i < amount; ++i) { Item* item = Item::CreateItem(it.id, subType); - if (internalAddItem(buyerPlayer->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != + if (internalAddItem(buyerPlayer->getInbox().get(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { delete item; break; @@ -5476,7 +5478,8 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 while (tmpAmount > 0) { uint16_t stackCount = std::min(ITEM_STACK_SIZE, tmpAmount); Item* item = Item::CreateItem(it.id, stackCount); - if (internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { + if (internalAddItem(player->getInbox().get(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != + RETURNVALUE_NOERROR) { delete item; break; } @@ -5493,7 +5496,8 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16 for (uint16_t i = 0; i < amount; ++i) { Item* item = Item::CreateItem(it.id, subType); - if (internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { + if (internalAddItem(player->getInbox().get(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != + RETURNVALUE_NOERROR) { delete item; break; } @@ -5554,10 +5558,10 @@ void Game::parsePlayerNetworkMessage(uint32_t playerId, uint8_t recvByte, Networ tfs::events::player::onNetworkMessage(player, recvByte, msg); } -std::vector Game::getMarketItemList(uint16_t wareId, uint16_t sufficientCount, const Player& player) +std::vector Game::getMarketItemList(uint16_t wareId, uint16_t sufficientCount, Player& player) { uint16_t count = 0; - std::list containers{player.getInbox()}; + std::list containers{player.getInbox().get()}; for (const auto& chest : player.depotChests) { if (!chest.second->empty()) { diff --git a/src/game.h b/src/game.h index 79af08a274..1ad03f1454 100644 --- a/src/game.h +++ b/src/game.h @@ -394,7 +394,7 @@ class Game void parsePlayerExtendedOpcode(uint32_t playerId, uint8_t opcode, const std::string& buffer); void parsePlayerNetworkMessage(uint32_t playerId, uint8_t recvByte, NetworkMessage* msg); - std::vector getMarketItemList(uint16_t wareId, uint16_t sufficientCount, const Player& player); + std::vector getMarketItemList(uint16_t wareId, uint16_t sufficientCount, Player& player); void cleanup(); void shutdown(); diff --git a/src/house.cpp b/src/house.cpp index 46d203d019..e9dc2e3917 100644 --- a/src/house.cpp +++ b/src/house.cpp @@ -229,8 +229,8 @@ bool House::transferToDepot(Player* player) const } for (Item* item : moveItemList) { - g_game.internalMoveItem(item->getParent(), player->getInbox(), INDEX_WHEREEVER, item, item->getItemCount(), - nullptr, FLAG_NOLIMIT); + g_game.internalMoveItem(item->getParent(), player->getInbox().get(), INDEX_WHEREEVER, item, + item->getItemCount(), nullptr, FLAG_NOLIMIT); } return true; } @@ -686,7 +686,7 @@ void Houses::payHouses(RentPeriod_t rentPeriod) const letter->setText(fmt::format( "Warning! \nThe {:s} rent of {:d} gold for your house \"{:s}\" is payable. Have it within {:d} days or you will lose this house.", period, house->getRent(), house->getName(), daysLeft)); - g_game.internalAddItem(player.getInbox(), letter, INDEX_WHEREEVER, FLAG_NOLIMIT); + g_game.internalAddItem(player.getInbox().get(), letter, INDEX_WHEREEVER, FLAG_NOLIMIT); house->setPayRentWarnings(house->getPayRentWarnings() + 1); } else { house->setOwner(0, true, &player); diff --git a/src/inbox.h b/src/inbox.h index dc21a379e6..aaeaece3a5 100644 --- a/src/inbox.h +++ b/src/inbox.h @@ -6,6 +6,9 @@ #include "container.h" +class Inbox; +using Inbox_ptr = std::shared_ptr; + class Inbox final : public Container { public: diff --git a/src/iomarket.cpp b/src/iomarket.cpp index 79cb5fb5f0..5ab25ab78f 100644 --- a/src/iomarket.cpp +++ b/src/iomarket.cpp @@ -132,7 +132,7 @@ void IOMarket::processExpiredOffers(DBResult_ptr result, bool) while (tmpAmount > 0) { uint16_t stackCount = std::min(ITEM_STACK_SIZE, tmpAmount); Item* item = Item::CreateItem(itemType.id, stackCount); - if (g_game.internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != + if (g_game.internalAddItem(player->getInbox().get(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { delete item; break; @@ -150,7 +150,7 @@ void IOMarket::processExpiredOffers(DBResult_ptr result, bool) for (uint16_t i = 0; i < amount; ++i) { Item* item = Item::CreateItem(itemType.id, subType); - if (g_game.internalAddItem(player->getInbox(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != + if (g_game.internalAddItem(player->getInbox().get(), item, INDEX_WHEREEVER, FLAG_NOLIMIT) != RETURNVALUE_NOERROR) { delete item; break; diff --git a/src/luascript.cpp b/src/luascript.cpp index e50774e163..593dced57a 100644 --- a/src/luascript.cpp +++ b/src/luascript.cpp @@ -9106,10 +9106,10 @@ int LuaScriptInterface::luaPlayerGetInbox(lua_State* L) return 1; } - Inbox* inbox = player->getInbox(); + const auto& inbox = player->getInbox(); if (inbox) { - tfs::lua::pushUserdata(L, inbox); - tfs::lua::setItemMetatable(L, -1, inbox); + pushSharedPtr(L, inbox); + tfs::lua::setItemMetatable(L, -1, inbox.get()); } else { tfs::lua::pushBoolean(L, false); } diff --git a/src/mailbox.cpp b/src/mailbox.cpp index dd10e40ab7..54422da818 100644 --- a/src/mailbox.cpp +++ b/src/mailbox.cpp @@ -82,8 +82,8 @@ bool Mailbox::sendItem(Item* item) const Player* player = g_game.getPlayerByName(receiver); if (player) { - if (g_game.internalMoveItem(item->getParent(), player->getInbox(), INDEX_WHEREEVER, item, item->getItemCount(), - nullptr, FLAG_NOLIMIT) == RETURNVALUE_NOERROR) { + if (g_game.internalMoveItem(item->getParent(), player->getInbox().get(), INDEX_WHEREEVER, item, + item->getItemCount(), nullptr, FLAG_NOLIMIT) == RETURNVALUE_NOERROR) { g_game.transformItem(item, item->getID() + 1); player->onReceiveMail(); return true; @@ -94,7 +94,7 @@ bool Mailbox::sendItem(Item* item) const return false; } - if (g_game.internalMoveItem(item->getParent(), tmpPlayer.getInbox(), INDEX_WHEREEVER, item, + if (g_game.internalMoveItem(item->getParent(), tmpPlayer.getInbox().get(), INDEX_WHEREEVER, item, item->getItemCount(), nullptr, FLAG_NOLIMIT) == RETURNVALUE_NOERROR) { g_game.transformItem(item, item->getID() + 1); IOLoginData::savePlayer(&tmpPlayer); diff --git a/src/player.cpp b/src/player.cpp index a996fda432..d9703418f5 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -13,7 +13,6 @@ #include "depotchest.h" #include "events.h" #include "game.h" -#include "inbox.h" #include "iologindata.h" #include "monster.h" #include "movement.h" @@ -43,11 +42,8 @@ Player::Player(ProtocolGame_ptr p) : lastPing(OTSYS_TIME()), lastPong(lastPing), client(std::move(p)), - inbox(new Inbox(ITEM_INBOX)), storeInbox(new StoreInbox(ITEM_STORE_INBOX)) { - inbox->incrementReferenceCounter(); - storeInbox->setParent(this); storeInbox->incrementReferenceCounter(); } @@ -62,11 +58,9 @@ Player::~Player() } if (depotLocker) { - depotLocker->removeInbox(inbox); + depotLocker->removeInbox(inbox.get()); } - inbox->decrementReferenceCounter(); - storeInbox->setParent(nullptr); storeInbox->decrementReferenceCounter(); @@ -840,7 +834,7 @@ DepotLocker& Player::getDepotLocker() if (!depotLocker) { depotLocker = std::make_shared(ITEM_LOCKER); depotLocker->internalAddThing(Item::CreateItem(ITEM_MARKET)); - depotLocker->internalAddThing(inbox); + depotLocker->internalAddThing(getInbox().get()); DepotChest* depotChest = new DepotChest(ITEM_DEPOT, false); // adding in reverse to align them from first to last @@ -3215,7 +3209,7 @@ void Player::postRemoveNotification(Thing* thing, const Cylinder* newParent, int autoCloseContainers(container); } } else if (const Inbox* inboxContainer = dynamic_cast(topContainer)) { - if (inboxContainer == inbox) { + if (inboxContainer == inbox.get()) { onSendContainer(container); } else { autoCloseContainers(container); diff --git a/src/player.h b/src/player.h index 1d84bd3b53..8d0a5c23cd 100644 --- a/src/player.h +++ b/src/player.h @@ -10,6 +10,7 @@ #include "enums.h" #include "groups.h" #include "guild.h" +#include "inbox.h" #include "protocolgame.h" #include "town.h" #include "vocation.h" @@ -182,7 +183,13 @@ class Player final : public Creature, public Cylinder void setLastWalkthroughAttempt(int64_t walkthroughAttempt) { lastWalkthroughAttempt = walkthroughAttempt; } void setLastWalkthroughPosition(Position walkthroughPosition) { lastWalkthroughPosition = walkthroughPosition; } - Inbox* getInbox() const { return inbox; } + Inbox_ptr getInbox() + { + if (!inbox) { + inbox = std::make_shared(ITEM_INBOX); + } + return inbox; + } StoreInbox* getStoreInbox() const { return storeInbox; } @@ -1211,7 +1218,7 @@ class Player final : public Creature, public Cylinder Guild_ptr guild = nullptr; GuildRank_ptr guildRank = nullptr; Group* group = nullptr; - Inbox* inbox; + Inbox_ptr inbox = nullptr; Item* tradeItem = nullptr; Item* inventory[CONST_SLOT_LAST + 1] = {}; Item* writeItem = nullptr; diff --git a/src/protocolgame.cpp b/src/protocolgame.cpp index ee5d981e7f..45e3ad7dd2 100644 --- a/src/protocolgame.cpp +++ b/src/protocolgame.cpp @@ -2100,7 +2100,7 @@ void ProtocolGame::sendMarketEnter() player->setInMarket(true); std::map depotItems; - std::forward_list containerList{player->getInbox()}; + std::forward_list containerList{player->getInbox().get()}; for (const auto& chest : player->depotChests) { if (!chest.second->empty()) {