Skip to content

Commit

Permalink
feat: save async fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
dudantas committed Nov 24, 2024
1 parent fce5e95 commit 6f5310a
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 405 deletions.
14 changes: 13 additions & 1 deletion data-otservbr-global/migrations/47.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
function onUpdateDatabase()
return false -- true = There are others migrations file | false = this is the last migration file
logger.info("Updating database to version 48 (player bosstiary and player kills unique key)")

db.query([[
ALTER TABLE `player_bosstiary`
ADD PRIMARY KEY (`player_id`)
]])

db.query([[
ALTER TABLE `player_kills`
ADD PRIMARY KEY (`player_id`, `target`, `time`);
]])

return true
end
3 changes: 3 additions & 0 deletions data-otservbr-global/migrations/48.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function onUpdateDatabase()
return false -- true = There are others migrations file | false = this is the last migration file
end
3 changes: 2 additions & 1 deletion schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,8 @@ CREATE TABLE IF NOT EXISTS `player_kills` (
`player_id` int(11) NOT NULL,
`time` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
`target` int(11) NOT NULL,
`unavenged` tinyint(1) NOT NULL DEFAULT '0'
`unavenged` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`player_id`, `target`, `time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- Table structure `player_namelocks`
Expand Down
80 changes: 35 additions & 45 deletions src/creatures/players/components/player_forge_history.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,60 +62,50 @@ bool PlayerForgeHistory::save() {
}

auto playerGUID = m_player.getGUID();
auto removedHistoryIds = m_removedHistoryIds;
auto modifiedHistory = m_modifiedHistory;

auto deleteForgeHistoryEntries = [playerGUID, removedHistoryIds]() mutable {
if (!removedHistoryIds.empty()) {
std::string idsToDelete = fmt::format("{}", fmt::join(removedHistoryIds, ", "));
std::string deleteQuery = fmt::format(
"DELETE FROM `forge_history` WHERE `player_id` = {} AND `id` IN ({})",
playerGUID, idsToDelete
);

if (!g_database().executeQuery(deleteQuery)) {
g_logger().error("[{}] failed to delete forge history entries for player with ID: {}", std::source_location::current().function_name(), playerGUID);
return false;
}

removedHistoryIds.clear();
}

return true;
};

auto insertModifiedHistory = [playerGUID, modifiedHistory]() mutable {
DBInsert insertQuery("INSERT INTO `forge_history` (`id`, `player_id`, `action_type`, `description`, `done_at`, `is_success`) VALUES ");
insertQuery.upsert({ "action_type", "description", "done_at", "is_success" });

for (const auto &history : modifiedHistory) {
auto row = fmt::format("{}, {}, {}, {}, {}, {}", history.id, playerGUID, history.actionType, g_database().escapeString(history.description), history.createdAt, history.success ? 1 : 0);
if (!insertQuery.addRow(row)) {
g_logger().warn("[{}] failed to add forge history entry for player with ID: {}", std::source_location::current().function_name(), playerGUID);
return false;
}
g_logger().debug("Added forge history entry date: {}, for player with ID: {}", formatDate(history.createdAt / 1000), playerGUID);
}
Database& db = Database::getInstance();

if (!m_removedHistoryIds.empty()) {
std::string idsToDelete = fmt::format("{}", fmt::join(m_removedHistoryIds, ", "));
std::string deleteQuery = fmt::format(
"DELETE FROM `forge_history` WHERE `player_id` = {} AND `id` IN ({})",
playerGUID, idsToDelete
);

if (!insertQuery.execute()) {
g_logger().error("[{}] failed to execute insertion for forge history entries for player with ID: {}", std::source_location::current().function_name(), playerGUID);
if (!db.executeQuery(deleteQuery)) {
g_logger().error("Failed to delete forge history entries for player with ID: {}", playerGUID);
return false;
}

return true;
};
m_removedHistoryIds.clear();
}

auto forgeHistorySaveTask = [deleteForgeHistoryEntries, insertModifiedHistory]() mutable {
if (!deleteForgeHistoryEntries()) {
return;
}
DBInsert insertQuery("INSERT INTO `forge_history` (`id`, `player_id`, `action_type`, `description`, `done_at`, `is_success`) VALUES ");
insertQuery.upsert({ "action_type", "description", "done_at", "is_success" });

for (const auto& history : m_modifiedHistory) {
auto row = fmt::format("{}, {}, {}, {}, {}, {}",
history.id,
playerGUID,
history.actionType,
db.escapeString(history.description),
history.createdAt,
history.success ? 1 : 0);

if (!insertModifiedHistory()) {
return;
if (!insertQuery.addRow(row)) {
g_logger().warn("Failed to add forge history entry for player with ID: {}", playerGUID);
return false;
}
};

g_saveManager().addTask(forgeHistorySaveTask, "PlayerForgeHistory::save - forgeHistorySaveTask");
g_logger().debug("Added forge history entry date: {}, for player with ID: {}", formatDate(history.createdAt / 1000), playerGUID);
}

if (!insertQuery.execute()) {
g_logger().error("Failed to execute insertion for forge history entries for player with ID: {}", playerGUID);
return false;
}

m_modifiedHistory.clear();

return true;
}
70 changes: 24 additions & 46 deletions src/creatures/players/components/player_stash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,59 +77,37 @@ bool PlayerStash::save() {
}

const auto playerGUID = m_player.getGUID();
auto removedItems = m_removedItems;
auto modifiedItems = m_modifiedItems;

auto deleteStashItems = [playerGUID, removedItems = std::move(removedItems)]() mutable {
if (!removedItems.empty()) {
std::string removedItemIds = fmt::format("{}", fmt::join(removedItems, ", "));
std::string deleteQuery = fmt::format(
"DELETE FROM `player_stash` WHERE `player_id` = {} AND `item_id` IN ({})",
playerGUID, removedItemIds
);

if (!g_database().executeQuery(deleteQuery)) {
g_logger().error("[{}] failed to delete removed items for player: {}", std::source_location::current().function_name(), playerGUID);
return false;
}

removedItems.clear();
}

return true;
};

auto insertModifiedStashItems = [playerGUID, modifiedItems = std::move(modifiedItems)]() mutable {
DBInsert insertQuery("INSERT INTO `player_stash` (`player_id`, `item_id`, `item_count`) VALUES ");
insertQuery.upsert({ "item_count" });

for (const auto &[itemId, itemCount] : modifiedItems) {
auto row = fmt::format("{}, {}, {}", playerGUID, itemId, itemCount);
if (!insertQuery.addRow(row)) {
g_logger().warn("[{}] - Failed to add row for stash item: {}", std::source_location::current().function_name(), itemId);
return false;
}
}

if (!insertQuery.execute()) {
g_logger().error("[{}] - Failed to execute insertion for modified stash items for player: {}", std::source_location::current().function_name(), playerGUID);
if (!m_removedItems.empty()) {
std::string removedItemIds = fmt::format("{}", fmt::join(m_removedItems, ", "));
std::string deleteQuery = fmt::format(
"DELETE FROM `player_stash` WHERE `player_id` = {} AND `item_id` IN ({})",
playerGUID, removedItemIds
);

if (!g_database().executeQuery(deleteQuery)) {
g_logger().error("[PlayerStash::save] - Failed to delete removed items for player: {}", m_player.getName());
return false;
}

return true;
};
m_removedItems.clear();
}

auto stashSaveTask = [deleteStashItems, insertModifiedStashItems]() mutable {
if (!deleteStashItems()) {
return;
}
DBInsert insertQuery("INSERT INTO `player_stash` (`player_id`, `item_id`, `item_count`) VALUES ");
insertQuery.upsert({ "item_count" });

if (!insertModifiedStashItems()) {
return;
for (const auto& [itemId, itemCount] : m_modifiedItems) {
auto row = fmt::format("{}, {}, {}", playerGUID, itemId, itemCount);
if (!insertQuery.addRow(row)) {
g_logger().warn("[PlayerStash::save] - Failed to add row for stash item: {}", itemId);
return false;
}
};
}

if (!insertQuery.execute()) {
g_logger().error("[PlayerStash::save] - Failed to execute insertion for modified stash items for player: {}", m_player.getName());
return false;
}

g_saveManager().addTask(stashSaveTask, "PlayerStash::save - stashSaveTask");
m_modifiedItems.clear();

return true;
Expand Down
72 changes: 27 additions & 45 deletions src/creatures/players/components/player_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,61 +104,43 @@ bool PlayerStorage::save() {
return true;
}

auto playerGUID = m_player.getGUID();
auto playerName = m_player.getName();
auto removedKeys = m_removedKeys;
auto modifiedKeys = m_modifiedKeys;
auto storageMap = m_storageMap;

auto deleteStorageKeys = [playerGUID, playerName, removedKeys]() mutable {
if (!removedKeys.empty()) {
std::string keysList = fmt::format("{}", fmt::join(removedKeys, ", "));
std::string deleteQuery = fmt::format(
"DELETE FROM `player_storage` WHERE `player_id` = {} AND `key` IN ({})",
playerGUID, keysList
);

if (!g_database().executeQuery(deleteQuery)) {
g_logger().error("[{}] failed to delete storage keys for player: {}", std::source_location::current().function_name(), playerName);
return false;
}
if (!m_removedKeys.empty()) {
std::string keysList = fmt::format("{}", fmt::join(m_removedKeys, ", "));
std::string deleteQuery = fmt::format(
"DELETE FROM `player_storage` WHERE `player_id` = {} AND `key` IN ({})",
m_player.getGUID(), keysList
);

if (!g_database().executeQuery(deleteQuery)) {
g_logger().error("[PlayerStorage::save] - Falha ao deletar as chaves de storage para o jogador: {}", m_player.getName());
return false;
}
return true;
};

auto insertModifiedStorageKeys = [this, playerGUID, playerName, modifiedKeys, storageMap]() mutable {
getReservedRange();
if (!modifiedKeys.empty()) {
DBInsert storageQuery("INSERT INTO `player_storage` (`player_id`, `key`, `value`) VALUES ");
storageQuery.upsert({ "value" });

for (const auto &key : modifiedKeys) {
auto row = fmt::format("{}, {}, {}", playerGUID, key, storageMap.at(key));
if (!storageQuery.addRow(row)) {
g_logger().warn("[{}] failed to add row for player storage: {}", std::source_location::current().function_name(), playerName);
return false;
}
}
m_removedKeys.clear();
}

if (!storageQuery.execute()) {
g_logger().error("[{}] failed to execute storage insertion for player: {}", std::source_location::current().function_name(), playerName);
if (!m_modifiedKeys.empty()) {
getReservedRange();
DBInsert storageQuery("INSERT INTO `player_storage` (`player_id`, `key`, `value`) VALUES ");
storageQuery.upsert({ "value" });

auto playerGUID = m_player.getGUID();
for (const auto &key : m_modifiedKeys) {
auto row = fmt::format("{}, {}, {}", playerGUID, key, m_storageMap.at(key));
if (!storageQuery.addRow(row)) {
g_logger().warn("[PlayerStorage::save] - Failed to add row for player storage: {}", m_player.getName());
return false;
}
}
return true;
};

auto saveTask = [deleteStorageKeys, insertModifiedStorageKeys]() mutable {
if (!deleteStorageKeys()) {
return;
if (!storageQuery.execute()) {
g_logger().error("[PlayerStorage::save] - Failed to execute storage insertion for player: {}", m_player.getName());
return false;
}

if (!insertModifiedStorageKeys()) {
return;
}
};
m_modifiedKeys.clear();
}

g_saveManager().addTask(saveTask, "PlayerStorage::save - playerStorageSaveTask");
return true;
}

Expand Down
Loading

0 comments on commit 6f5310a

Please sign in to comment.