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

fix: overload when setting item decay when player logs in #2927

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
24 changes: 15 additions & 9 deletions src/io/functions/iologindata_load_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,25 +479,24 @@ void IOLoginDataLoad::loadPlayerInventoryItems(std::shared_ptr<Player> player, D

bool oldProtocol = g_configManager().getBoolean(OLD_PROTOCOL, __FUNCTION__) && player->getProtocolVersion() < 1200;
Database &db = Database::getInstance();
std::ostringstream query;
query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_items` WHERE `player_id` = " << player->getGUID() << " ORDER BY `sid` DESC";
auto query = fmt::format("SELECT pid, sid, itemtype, count, attributes FROM player_items WHERE player_id = {} ORDER BY sid DESC", player->getGUID());

ItemsMap inventoryItems;
std::vector<std::pair<uint8_t, std::shared_ptr<Container>>> openContainersList;
std::vector<std::shared_ptr<Item>> itemsToStartDecaying;

try {
if ((result = db.storeQuery(query.str()))) {
if ((result = db.storeQuery(query))) {
loadItems(inventoryItems, result, player);

for (ItemsMap::const_reverse_iterator it = inventoryItems.rbegin(), end = inventoryItems.rend(); it != end; ++it) {
const std::pair<std::shared_ptr<Item>, int32_t> &pair = it->second;
std::shared_ptr<Item> item = pair.first;
const std::shared_ptr<Item> &item = pair.first;
if (!item) {
continue;
}

int32_t pid = pair.second;

if (pid >= CONST_SLOT_FIRST && pid <= CONST_SLOT_LAST) {
player->internalAddThing(pid, item);
item->startDecaying();
Expand All @@ -507,14 +506,15 @@ void IOLoginDataLoad::loadPlayerInventoryItems(std::shared_ptr<Player> player, D
continue;
}

std::shared_ptr<Container> container = it2->second.first->getContainer();
const std::shared_ptr<Container> &container = it2->second.first->getContainer();
if (container) {
container->internalAddThing(item);
item->startDecaying();
// Here, the sub-containers do not yet have a parent, since the main backpack has not yet been added to the player, so we need to postpone
itemsToStartDecaying.emplace_back(item);
}
}

std::shared_ptr<Container> itemContainer = item->getContainer();
const std::shared_ptr<Container> &itemContainer = item->getContainer();
if (itemContainer) {
if (!oldProtocol) {
auto cid = item->getAttribute<int64_t>(ItemAttribute_t::OPENCONTAINER);
Expand All @@ -538,6 +538,11 @@ void IOLoginDataLoad::loadPlayerInventoryItems(std::shared_ptr<Player> player, D
}
}

// Now that all items and containers have been added and parent chain is established, start decay
for (const auto &item : itemsToStartDecaying) {
item->startDecaying();
}

if (!oldProtocol) {
std::ranges::sort(openContainersList.begin(), openContainersList.end(), [](const std::pair<uint8_t, std::shared_ptr<Container>> &left, const std::pair<uint8_t, std::shared_ptr<Container>> &right) {
return left.first < right.first;
Expand All @@ -548,8 +553,9 @@ void IOLoginDataLoad::loadPlayerInventoryItems(std::shared_ptr<Player> player, D
player->onSendContainer(it.second);
}
}

} catch (const std::exception &e) {
g_logger().error("[IOLoginDataLoad::loadPlayerInventoryItems] - Exceção durante o carregamento do inventário: {}", e.what());
g_logger().error("[IOLoginDataLoad::loadPlayerInventoryItems] - Exception during inventory loading: {}", e.what());
}
}

Expand Down
7 changes: 0 additions & 7 deletions src/items/containers/container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -895,13 +895,6 @@ void Container::internalAddThing(uint32_t, std::shared_ptr<Thing> thing) {
updateItemWeight(item->getWeight());
}

void Container::startDecaying() {
g_decay().startDecay(getContainer());
for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) {
g_decay().startDecay(*it);
}
}

void Container::stopDecaying() {
g_decay().stopDecay(getContainer());
for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) {
Expand Down
1 change: 0 additions & 1 deletion src/items/containers/container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ class Container : public Item, public Cylinder {

void internalAddThing(std::shared_ptr<Thing> thing) override final;
void internalAddThing(uint32_t index, std::shared_ptr<Thing> thing) override final;
void startDecaying() override;
void stopDecaying() override;

virtual void removeItem(std::shared_ptr<Thing> thing, bool sendUpdateToClient = false);
Expand Down
15 changes: 12 additions & 3 deletions src/items/decay/decay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Decay &Decay::getInstance() {
return inject<Decay>();
}

void Decay::startDecay(std::shared_ptr<Item> item) {
void Decay::startDecay(const std::shared_ptr<Item> &item) {
if (!item) {
return;
}
Expand All @@ -32,6 +32,8 @@ void Decay::startDecay(std::shared_ptr<Item> item) {
return;
}

g_logger().trace("Try decay item {}", item->getName());

const auto duration = item->getAttribute<int64_t>(ItemAttribute_t::DURATION);
if (duration <= 0 && item->hasAttribute(ItemAttribute_t::DURATION)) {
internalDecayItem(item);
Expand Down Expand Up @@ -63,7 +65,10 @@ void Decay::startDecay(std::shared_ptr<Item> item) {
}
}

void Decay::stopDecay(std::shared_ptr<Item> item) {
void Decay::stopDecay(const std::shared_ptr<Item> &item) {
if (!item) {
return;
}
if (item->hasAttribute(ItemAttribute_t::DECAYSTATE)) {
auto timestamp = item->getAttribute<int64_t>(ItemAttribute_t::DURATION_TIMESTAMP);
if (item->hasAttribute(ItemAttribute_t::DURATION_TIMESTAMP)) {
Expand Down Expand Up @@ -146,7 +151,11 @@ void Decay::checkDecay() {
}
}

void Decay::internalDecayItem(std::shared_ptr<Item> item) {
void Decay::internalDecayItem(const std::shared_ptr<Item> &item) {
if (!item) {
return;
}

const ItemType &it = Item::items[item->getID()];
// Remove the item and halt the decay process if a player triggers a bug where the item's decay ID matches its equip or de-equip transformation ID
if (it.id == it.transformEquipTo || it.id == it.transformDeEquipTo) {
Expand Down
6 changes: 3 additions & 3 deletions src/items/decay/decay.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ class Decay {

static Decay &getInstance();

void startDecay(std::shared_ptr<Item> item);
void stopDecay(std::shared_ptr<Item> item);
void startDecay(const std::shared_ptr<Item> &item);
void stopDecay(const std::shared_ptr<Item> &item);

private:
void checkDecay();
void internalDecayItem(std::shared_ptr<Item> item);
void internalDecayItem(const std::shared_ptr<Item> &item);

uint32_t eventId { 0 };
// order is important, so we use an std::map
Expand Down
4 changes: 3 additions & 1 deletion src/map/mapcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ std::shared_ptr<Item> MapCache::createItem(const std::shared_ptr<BasicItem> &Bas
item->setItemCount(1);
}

item->startDecaying();
if (item->canDecay()) {
item->startDecaying();
}
item->loadedFromMap = true;
item->decayDisabled = Item::items[item->getID()].decayTo != -1;

Expand Down
Loading