From 6c51b3add747791f7aed6250362b4ae031b0ecc7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Paulo?= <jprzimba@gmail.com>
Date: Mon, 13 Jan 2025 09:37:12 -0300
Subject: [PATCH 1/2] * Fix linux compiling error

---
 src/database/database.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/database/database.cpp b/src/database/database.cpp
index 7c67f275..dc40b55e 100644
--- a/src/database/database.cpp
+++ b/src/database/database.cpp
@@ -138,8 +138,9 @@ void Database::createDatabaseBackup(bool compress) const {
 				for (const auto &file : std::filesystem::directory_iterator(entry)) {
 					if (file.path().extension() == ".gz") {
 						auto fileTime = std::filesystem::last_write_time(file);
-						auto fileTimeSystemClock = std::chrono::clock_cast<std::chrono::system_clock>(fileTime);
-						if (fileTimeSystemClock < sevenDaysAgo) {
+						auto sctp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(fileTime - std::filesystem::file_time_type::clock::now() + std::chrono::system_clock::now());
+
+						if (sctp < sevenDaysAgo) {
 							std::filesystem::remove(file);
 							g_logger().info("Deleted old backup file: {}", file.path().string());
 						}

From bdfaf3c1a5d3759cb95235ef3a45b1599d43143e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Paulo?= <jprzimba@gmail.com>
Date: Mon, 13 Jan 2025 11:26:01 -0300
Subject: [PATCH 2/2] * Fix sell loot

---
 markdowns/CHANGELOG.md     |  2 --
 src/creatures/npcs/npc.cpp | 46 ++++++++++++++------------------------
 2 files changed, 17 insertions(+), 31 deletions(-)

diff --git a/markdowns/CHANGELOG.md b/markdowns/CHANGELOG.md
index 8802e2f1..5c9f257f 100644
--- a/markdowns/CHANGELOG.md
+++ b/markdowns/CHANGELOG.md
@@ -7,7 +7,6 @@
 
 - Protocol 14.05 support. ([Tryller](https://github.com/jprzimba))
 - New protocol 14.05 assets. ([Tryller](https://github.com/jprzimba))
-- Optimized the `onPlayerSellAllLoot` code to prevent prolonged freezes. ([Tryller](https://github.com/jprzimba))
 - Add new configurable featurees in `config.lua`:  `chainSystemVipOnly`, `fieldOwnershipDuration`, `bedsOnlyPremium`, `loginProtectionPeriod`, `chainSystemModifyMagic`, `logPlayersStatements`. ([Tryller](https://github.com/jprzimba))
 - Added a new commands for players: `!randomoutfit`, `!spellwords`. ([Tryller](https://github.com/jprzimba))
 - Moved emote spells to `kv` instead of `storage`. ([Tryller](https://github.com/jprzimba))
@@ -134,7 +133,6 @@
 - Fixed V.I.P List ([Tryller](https://github.com/jprzimba)).
 - Fixed damage reflection not working properly ([Tryller](https://github.com/jprzimba)).
 - Fixed imbuement system when the player adds imbuement or cancels imbuement and the imbuement window is open not updating ([Tryller](https://github.com/jprzimba)).
-- Optimized onPlayerSellAllLoot in npc code to avoid long freeze ([Tryller](https://github.com/jprzimba)).
 - Fixed data/scripts/talkactions/player/refill.lua, now check if player has capacity to receive items. ([Tryller](https://github.com/jprzimba)).
 - Fixed Loot pouch using in the Obtain method ([carlospess0a](https://github.com/carlospess0a)).
 - Fixed destroy field is working inside pz ([carlospess0a](https://github.com/carlospess0a)).
diff --git a/src/creatures/npcs/npc.cpp b/src/creatures/npcs/npc.cpp
index f9060b00..5f4fe994 100644
--- a/src/creatures/npcs/npc.cpp
+++ b/src/creatures/npcs/npc.cpp
@@ -443,57 +443,45 @@ void Npc::onPlayerSellAllLoot(uint32_t playerId, uint16_t itemId, bool ignore, u
 	if (!player) {
 		return;
 	}
-
 	if (itemId == ITEM_GOLD_POUCH) {
 		const auto &container = player->getLootPouch();
 		if (!container) {
 			return;
 		}
-
+		bool hasMore = false;
 		uint64_t toSellCount = 0;
 		phmap::flat_hash_map<uint16_t, uint16_t> toSell;
-		ContainerIterator it = container->iterator();
-
-		while (it.hasNext()) {
-			auto item = *it;
+		for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) {
+			if (toSellCount >= 500) {
+				hasMore = true;
+				break;
+			}
+			const auto &item = *it;
 			if (!item) {
 				continue;
 			}
-
 			toSell[item->getID()] += item->getItemAmount();
 			if (item->isStackable()) {
 				toSellCount++;
 			} else {
 				toSellCount += item->getItemAmount();
 			}
-
-			if (toSellCount >= 100) {
-				break;
-			}
-
-			it.advance();
 		}
-
-		if (toSell.empty()) {
-			std::stringstream ss;
+		for (const auto &[m_itemId, amount] : toSell) {
+			onPlayerSellItem(player, m_itemId, 0, amount, ignore, totalPrice, container);
+		}
+		auto ss = std::stringstream();
+		if (totalPrice == 0) {
 			ss << "You have no items in your loot pouch.";
 			player->sendTextMessage(MESSAGE_FAILURE, ss.str());
 			return;
 		}
-
-		for (auto &[itemId, amount] : toSell) {
-			onPlayerSellItem(player, itemId, 0, amount, ignore, totalPrice, container);
+		if (hasMore) {
+			g_dispatcher().scheduleEvent(
+				SCHEDULER_MINTICKS, [this, playerId = player->getID(), itemId, ignore, totalPrice] { onPlayerSellAllLoot(playerId, itemId, ignore, totalPrice); }, __FUNCTION__
+			);
+			return;
 		}
-
-		const auto &task = player->createPlayerTask(
-			100, [this, playerId, itemId, ignore, totalPrice]() {
-				onPlayerSellAllLoot(playerId, itemId, ignore, totalPrice);
-			},
-			__FUNCTION__
-		);
-		player->setNextActionPushTask(task);
-
-		auto ss = std::stringstream();
 		ss << "You sold all of the items from your loot pouch for ";
 		ss << totalPrice << " gold.";
 		player->sendTextMessage(MESSAGE_LOOK, ss.str());