From 32dcb634f004df7d2f094dacd42aa34293f27e51 Mon Sep 17 00:00:00 2001 From: Mitch Freeman <65987027+neckkola@users.noreply.github.com> Date: Sun, 6 Apr 2025 10:15:11 -0300 Subject: [PATCH] Start up of inventory snapshots --- common/database/database_update_manifest.cpp | 16 + .../base_inventory_snapshots_repository.h | 284 +++++++++--------- .../inventory_snapshots_repository.h | 153 +++++++++- zone/client.cpp | 8 +- zone/zonedb.cpp | 225 +++----------- 5 files changed, 359 insertions(+), 327 deletions(-) diff --git a/common/database/database_update_manifest.cpp b/common/database/database_update_manifest.cpp index fb0632201..976168c44 100644 --- a/common/database/database_update_manifest.cpp +++ b/common/database/database_update_manifest.cpp @@ -7204,6 +7204,22 @@ ALTER TABLE `character_parcels` ALTER TABLE `character_parcels_containers` ADD COLUMN `item_unique_id` VARCHAR(16) NULL DEFAULT NULL AFTER `item_id`; +ALTER TABLE `inventory_snapshots` + CHANGE COLUMN `charid` `character_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `time_index`, + CHANGE COLUMN `slotid` `slot_id` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0' AFTER `character_id`, + CHANGE COLUMN `itemid` `item_id` INT(11) UNSIGNED NULL DEFAULT '0' AFTER `slot_id`, + CHANGE COLUMN `augslot1` `augment_one` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0' AFTER `color`, + CHANGE COLUMN `augslot2` `augment_two` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0' AFTER `augment_one`, + CHANGE COLUMN `augslot3` `augment_three` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0' AFTER `augment_two`, + CHANGE COLUMN `augslot4` `augment_four` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0' AFTER `augment_three`, + CHANGE COLUMN `augslot5` `augment_five` MEDIUMINT(7) UNSIGNED NULL DEFAULT '0' AFTER `augment_four`, + CHANGE COLUMN `augslot6` `augment_six` MEDIUMINT(7) NOT NULL DEFAULT '0' AFTER `augment_five`, + CHANGE COLUMN `ornamenticon` `ornament_icon` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `custom_data`, + CHANGE COLUMN `ornamentidfile` `ornament_idfile` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `ornament_icon`, + ADD COLUMN `item_unique_id` VARCHAR(16) NULL DEFAULT NULL AFTER `ornament_hero_model`; + DROP PRIMARY KEY, + ADD PRIMARY KEY (`time_index`, `character_id`, `slot_id`) USING BTREE; + )", .content_schema_update = false }, diff --git a/common/repositories/base/base_inventory_snapshots_repository.h b/common/repositories/base/base_inventory_snapshots_repository.h index 0b6863727..0088a8784 100644 --- a/common/repositories/base/base_inventory_snapshots_repository.h +++ b/common/repositories/base/base_inventory_snapshots_repository.h @@ -20,22 +20,23 @@ class BaseInventorySnapshotsRepository { public: struct InventorySnapshots { uint32_t time_index; - uint32_t charid; - uint32_t slotid; - uint32_t itemid; + uint32_t character_id; + uint32_t slot_id; + uint32_t item_id; uint16_t charges; uint32_t color; - uint32_t augslot1; - uint32_t augslot2; - uint32_t augslot3; - uint32_t augslot4; - uint32_t augslot5; - int32_t augslot6; + uint32_t augment_one; + uint32_t augment_two; + uint32_t augment_three; + uint32_t augment_four; + uint32_t augment_five; + int32_t augment_six; uint8_t instnodrop; std::string custom_data; - uint32_t ornamenticon; - uint32_t ornamentidfile; + uint32_t ornament_icon; + uint32_t ornament_idfile; int32_t ornament_hero_model; + std::string item_unique_id; uint64_t guid; }; @@ -48,22 +49,23 @@ public: { return { "time_index", - "charid", - "slotid", - "itemid", + "character_id", + "slot_id", + "item_id", "charges", "color", - "augslot1", - "augslot2", - "augslot3", - "augslot4", - "augslot5", - "augslot6", + "augment_one", + "augment_two", + "augment_three", + "augment_four", + "augment_five", + "augment_six", "instnodrop", "custom_data", - "ornamenticon", - "ornamentidfile", + "ornament_icon", + "ornament_idfile", "ornament_hero_model", + "item_unique_id", "guid", }; } @@ -72,22 +74,23 @@ public: { return { "time_index", - "charid", - "slotid", - "itemid", + "character_id", + "slot_id", + "item_id", "charges", "color", - "augslot1", - "augslot2", - "augslot3", - "augslot4", - "augslot5", - "augslot6", + "augment_one", + "augment_two", + "augment_three", + "augment_four", + "augment_five", + "augment_six", "instnodrop", "custom_data", - "ornamenticon", - "ornamentidfile", + "ornament_icon", + "ornament_idfile", "ornament_hero_model", + "item_unique_id", "guid", }; } @@ -130,22 +133,23 @@ public: InventorySnapshots e{}; e.time_index = 0; - e.charid = 0; - e.slotid = 0; - e.itemid = 0; + e.character_id = 0; + e.slot_id = 0; + e.item_id = 0; e.charges = 0; e.color = 0; - e.augslot1 = 0; - e.augslot2 = 0; - e.augslot3 = 0; - e.augslot4 = 0; - e.augslot5 = 0; - e.augslot6 = 0; + e.augment_one = 0; + e.augment_two = 0; + e.augment_three = 0; + e.augment_four = 0; + e.augment_five = 0; + e.augment_six = 0; e.instnodrop = 0; e.custom_data = ""; - e.ornamenticon = 0; - e.ornamentidfile = 0; + e.ornament_icon = 0; + e.ornament_idfile = 0; e.ornament_hero_model = 0; + e.item_unique_id = ""; e.guid = 0; return e; @@ -184,23 +188,24 @@ public: InventorySnapshots e{}; e.time_index = row[0] ? static_cast(strtoul(row[0], nullptr, 10)) : 0; - e.charid = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; - e.slotid = row[2] ? static_cast(strtoul(row[2], nullptr, 10)) : 0; - e.itemid = row[3] ? static_cast(strtoul(row[3], nullptr, 10)) : 0; + e.character_id = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; + e.slot_id = row[2] ? static_cast(strtoul(row[2], nullptr, 10)) : 0; + e.item_id = row[3] ? static_cast(strtoul(row[3], nullptr, 10)) : 0; e.charges = row[4] ? static_cast(strtoul(row[4], nullptr, 10)) : 0; e.color = row[5] ? static_cast(strtoul(row[5], nullptr, 10)) : 0; - e.augslot1 = row[6] ? static_cast(strtoul(row[6], nullptr, 10)) : 0; - e.augslot2 = row[7] ? static_cast(strtoul(row[7], nullptr, 10)) : 0; - e.augslot3 = row[8] ? static_cast(strtoul(row[8], nullptr, 10)) : 0; - e.augslot4 = row[9] ? static_cast(strtoul(row[9], nullptr, 10)) : 0; - e.augslot5 = row[10] ? static_cast(strtoul(row[10], nullptr, 10)) : 0; - e.augslot6 = row[11] ? static_cast(atoi(row[11])) : 0; + e.augment_one = row[6] ? static_cast(strtoul(row[6], nullptr, 10)) : 0; + e.augment_two = row[7] ? static_cast(strtoul(row[7], nullptr, 10)) : 0; + e.augment_three = row[8] ? static_cast(strtoul(row[8], nullptr, 10)) : 0; + e.augment_four = row[9] ? static_cast(strtoul(row[9], nullptr, 10)) : 0; + e.augment_five = row[10] ? static_cast(strtoul(row[10], nullptr, 10)) : 0; + e.augment_six = row[11] ? static_cast(atoi(row[11])) : 0; e.instnodrop = row[12] ? static_cast(strtoul(row[12], nullptr, 10)) : 0; e.custom_data = row[13] ? row[13] : ""; - e.ornamenticon = row[14] ? static_cast(strtoul(row[14], nullptr, 10)) : 0; - e.ornamentidfile = row[15] ? static_cast(strtoul(row[15], nullptr, 10)) : 0; + e.ornament_icon = row[14] ? static_cast(strtoul(row[14], nullptr, 10)) : 0; + e.ornament_idfile = row[15] ? static_cast(strtoul(row[15], nullptr, 10)) : 0; e.ornament_hero_model = row[16] ? static_cast(atoi(row[16])) : 0; - e.guid = row[17] ? strtoull(row[17], nullptr, 10) : 0; + e.item_unique_id = row[17] ? row[17] : ""; + e.guid = row[18] ? strtoull(row[18], nullptr, 10) : 0; return e; } @@ -235,23 +240,24 @@ public: auto columns = Columns(); v.push_back(columns[0] + " = " + std::to_string(e.time_index)); - v.push_back(columns[1] + " = " + std::to_string(e.charid)); - v.push_back(columns[2] + " = " + std::to_string(e.slotid)); - v.push_back(columns[3] + " = " + std::to_string(e.itemid)); + v.push_back(columns[1] + " = " + std::to_string(e.character_id)); + v.push_back(columns[2] + " = " + std::to_string(e.slot_id)); + v.push_back(columns[3] + " = " + std::to_string(e.item_id)); v.push_back(columns[4] + " = " + std::to_string(e.charges)); v.push_back(columns[5] + " = " + std::to_string(e.color)); - v.push_back(columns[6] + " = " + std::to_string(e.augslot1)); - v.push_back(columns[7] + " = " + std::to_string(e.augslot2)); - v.push_back(columns[8] + " = " + std::to_string(e.augslot3)); - v.push_back(columns[9] + " = " + std::to_string(e.augslot4)); - v.push_back(columns[10] + " = " + std::to_string(e.augslot5)); - v.push_back(columns[11] + " = " + std::to_string(e.augslot6)); + v.push_back(columns[6] + " = " + std::to_string(e.augment_one)); + v.push_back(columns[7] + " = " + std::to_string(e.augment_two)); + v.push_back(columns[8] + " = " + std::to_string(e.augment_three)); + v.push_back(columns[9] + " = " + std::to_string(e.augment_four)); + v.push_back(columns[10] + " = " + std::to_string(e.augment_five)); + v.push_back(columns[11] + " = " + std::to_string(e.augment_six)); v.push_back(columns[12] + " = " + std::to_string(e.instnodrop)); v.push_back(columns[13] + " = '" + Strings::Escape(e.custom_data) + "'"); - v.push_back(columns[14] + " = " + std::to_string(e.ornamenticon)); - v.push_back(columns[15] + " = " + std::to_string(e.ornamentidfile)); + v.push_back(columns[14] + " = " + std::to_string(e.ornament_icon)); + v.push_back(columns[15] + " = " + std::to_string(e.ornament_idfile)); v.push_back(columns[16] + " = " + std::to_string(e.ornament_hero_model)); - v.push_back(columns[17] + " = " + std::to_string(e.guid)); + v.push_back(columns[17] + " = '" + Strings::Escape(e.item_unique_id) + "'"); + v.push_back(columns[18] + " = " + std::to_string(e.guid)); auto results = db.QueryDatabase( fmt::format( @@ -274,22 +280,23 @@ public: std::vector v; v.push_back(std::to_string(e.time_index)); - v.push_back(std::to_string(e.charid)); - v.push_back(std::to_string(e.slotid)); - v.push_back(std::to_string(e.itemid)); + v.push_back(std::to_string(e.character_id)); + v.push_back(std::to_string(e.slot_id)); + v.push_back(std::to_string(e.item_id)); v.push_back(std::to_string(e.charges)); v.push_back(std::to_string(e.color)); - v.push_back(std::to_string(e.augslot1)); - v.push_back(std::to_string(e.augslot2)); - v.push_back(std::to_string(e.augslot3)); - v.push_back(std::to_string(e.augslot4)); - v.push_back(std::to_string(e.augslot5)); - v.push_back(std::to_string(e.augslot6)); + v.push_back(std::to_string(e.augment_one)); + v.push_back(std::to_string(e.augment_two)); + v.push_back(std::to_string(e.augment_three)); + v.push_back(std::to_string(e.augment_four)); + v.push_back(std::to_string(e.augment_five)); + v.push_back(std::to_string(e.augment_six)); v.push_back(std::to_string(e.instnodrop)); v.push_back("'" + Strings::Escape(e.custom_data) + "'"); - v.push_back(std::to_string(e.ornamenticon)); - v.push_back(std::to_string(e.ornamentidfile)); + v.push_back(std::to_string(e.ornament_icon)); + v.push_back(std::to_string(e.ornament_idfile)); v.push_back(std::to_string(e.ornament_hero_model)); + v.push_back("'" + Strings::Escape(e.item_unique_id) + "'"); v.push_back(std::to_string(e.guid)); auto results = db.QueryDatabase( @@ -321,22 +328,23 @@ public: std::vector v; v.push_back(std::to_string(e.time_index)); - v.push_back(std::to_string(e.charid)); - v.push_back(std::to_string(e.slotid)); - v.push_back(std::to_string(e.itemid)); + v.push_back(std::to_string(e.character_id)); + v.push_back(std::to_string(e.slot_id)); + v.push_back(std::to_string(e.item_id)); v.push_back(std::to_string(e.charges)); v.push_back(std::to_string(e.color)); - v.push_back(std::to_string(e.augslot1)); - v.push_back(std::to_string(e.augslot2)); - v.push_back(std::to_string(e.augslot3)); - v.push_back(std::to_string(e.augslot4)); - v.push_back(std::to_string(e.augslot5)); - v.push_back(std::to_string(e.augslot6)); + v.push_back(std::to_string(e.augment_one)); + v.push_back(std::to_string(e.augment_two)); + v.push_back(std::to_string(e.augment_three)); + v.push_back(std::to_string(e.augment_four)); + v.push_back(std::to_string(e.augment_five)); + v.push_back(std::to_string(e.augment_six)); v.push_back(std::to_string(e.instnodrop)); v.push_back("'" + Strings::Escape(e.custom_data) + "'"); - v.push_back(std::to_string(e.ornamenticon)); - v.push_back(std::to_string(e.ornamentidfile)); + v.push_back(std::to_string(e.ornament_icon)); + v.push_back(std::to_string(e.ornament_idfile)); v.push_back(std::to_string(e.ornament_hero_model)); + v.push_back("'" + Strings::Escape(e.item_unique_id) + "'"); v.push_back(std::to_string(e.guid)); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); @@ -372,23 +380,24 @@ public: InventorySnapshots e{}; e.time_index = row[0] ? static_cast(strtoul(row[0], nullptr, 10)) : 0; - e.charid = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; - e.slotid = row[2] ? static_cast(strtoul(row[2], nullptr, 10)) : 0; - e.itemid = row[3] ? static_cast(strtoul(row[3], nullptr, 10)) : 0; + e.character_id = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; + e.slot_id = row[2] ? static_cast(strtoul(row[2], nullptr, 10)) : 0; + e.item_id = row[3] ? static_cast(strtoul(row[3], nullptr, 10)) : 0; e.charges = row[4] ? static_cast(strtoul(row[4], nullptr, 10)) : 0; e.color = row[5] ? static_cast(strtoul(row[5], nullptr, 10)) : 0; - e.augslot1 = row[6] ? static_cast(strtoul(row[6], nullptr, 10)) : 0; - e.augslot2 = row[7] ? static_cast(strtoul(row[7], nullptr, 10)) : 0; - e.augslot3 = row[8] ? static_cast(strtoul(row[8], nullptr, 10)) : 0; - e.augslot4 = row[9] ? static_cast(strtoul(row[9], nullptr, 10)) : 0; - e.augslot5 = row[10] ? static_cast(strtoul(row[10], nullptr, 10)) : 0; - e.augslot6 = row[11] ? static_cast(atoi(row[11])) : 0; + e.augment_one = row[6] ? static_cast(strtoul(row[6], nullptr, 10)) : 0; + e.augment_two = row[7] ? static_cast(strtoul(row[7], nullptr, 10)) : 0; + e.augment_three = row[8] ? static_cast(strtoul(row[8], nullptr, 10)) : 0; + e.augment_four = row[9] ? static_cast(strtoul(row[9], nullptr, 10)) : 0; + e.augment_five = row[10] ? static_cast(strtoul(row[10], nullptr, 10)) : 0; + e.augment_six = row[11] ? static_cast(atoi(row[11])) : 0; e.instnodrop = row[12] ? static_cast(strtoul(row[12], nullptr, 10)) : 0; e.custom_data = row[13] ? row[13] : ""; - e.ornamenticon = row[14] ? static_cast(strtoul(row[14], nullptr, 10)) : 0; - e.ornamentidfile = row[15] ? static_cast(strtoul(row[15], nullptr, 10)) : 0; + e.ornament_icon = row[14] ? static_cast(strtoul(row[14], nullptr, 10)) : 0; + e.ornament_idfile = row[15] ? static_cast(strtoul(row[15], nullptr, 10)) : 0; e.ornament_hero_model = row[16] ? static_cast(atoi(row[16])) : 0; - e.guid = row[17] ? strtoull(row[17], nullptr, 10) : 0; + e.item_unique_id = row[17] ? row[17] : ""; + e.guid = row[18] ? strtoull(row[18], nullptr, 10) : 0; all_entries.push_back(e); } @@ -414,23 +423,24 @@ public: InventorySnapshots e{}; e.time_index = row[0] ? static_cast(strtoul(row[0], nullptr, 10)) : 0; - e.charid = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; - e.slotid = row[2] ? static_cast(strtoul(row[2], nullptr, 10)) : 0; - e.itemid = row[3] ? static_cast(strtoul(row[3], nullptr, 10)) : 0; + e.character_id = row[1] ? static_cast(strtoul(row[1], nullptr, 10)) : 0; + e.slot_id = row[2] ? static_cast(strtoul(row[2], nullptr, 10)) : 0; + e.item_id = row[3] ? static_cast(strtoul(row[3], nullptr, 10)) : 0; e.charges = row[4] ? static_cast(strtoul(row[4], nullptr, 10)) : 0; e.color = row[5] ? static_cast(strtoul(row[5], nullptr, 10)) : 0; - e.augslot1 = row[6] ? static_cast(strtoul(row[6], nullptr, 10)) : 0; - e.augslot2 = row[7] ? static_cast(strtoul(row[7], nullptr, 10)) : 0; - e.augslot3 = row[8] ? static_cast(strtoul(row[8], nullptr, 10)) : 0; - e.augslot4 = row[9] ? static_cast(strtoul(row[9], nullptr, 10)) : 0; - e.augslot5 = row[10] ? static_cast(strtoul(row[10], nullptr, 10)) : 0; - e.augslot6 = row[11] ? static_cast(atoi(row[11])) : 0; + e.augment_one = row[6] ? static_cast(strtoul(row[6], nullptr, 10)) : 0; + e.augment_two = row[7] ? static_cast(strtoul(row[7], nullptr, 10)) : 0; + e.augment_three = row[8] ? static_cast(strtoul(row[8], nullptr, 10)) : 0; + e.augment_four = row[9] ? static_cast(strtoul(row[9], nullptr, 10)) : 0; + e.augment_five = row[10] ? static_cast(strtoul(row[10], nullptr, 10)) : 0; + e.augment_six = row[11] ? static_cast(atoi(row[11])) : 0; e.instnodrop = row[12] ? static_cast(strtoul(row[12], nullptr, 10)) : 0; e.custom_data = row[13] ? row[13] : ""; - e.ornamenticon = row[14] ? static_cast(strtoul(row[14], nullptr, 10)) : 0; - e.ornamentidfile = row[15] ? static_cast(strtoul(row[15], nullptr, 10)) : 0; + e.ornament_icon = row[14] ? static_cast(strtoul(row[14], nullptr, 10)) : 0; + e.ornament_idfile = row[15] ? static_cast(strtoul(row[15], nullptr, 10)) : 0; e.ornament_hero_model = row[16] ? static_cast(atoi(row[16])) : 0; - e.guid = row[17] ? strtoull(row[17], nullptr, 10) : 0; + e.item_unique_id = row[17] ? row[17] : ""; + e.guid = row[18] ? strtoull(row[18], nullptr, 10) : 0; all_entries.push_back(e); } @@ -506,22 +516,23 @@ public: std::vector v; v.push_back(std::to_string(e.time_index)); - v.push_back(std::to_string(e.charid)); - v.push_back(std::to_string(e.slotid)); - v.push_back(std::to_string(e.itemid)); + v.push_back(std::to_string(e.character_id)); + v.push_back(std::to_string(e.slot_id)); + v.push_back(std::to_string(e.item_id)); v.push_back(std::to_string(e.charges)); v.push_back(std::to_string(e.color)); - v.push_back(std::to_string(e.augslot1)); - v.push_back(std::to_string(e.augslot2)); - v.push_back(std::to_string(e.augslot3)); - v.push_back(std::to_string(e.augslot4)); - v.push_back(std::to_string(e.augslot5)); - v.push_back(std::to_string(e.augslot6)); + v.push_back(std::to_string(e.augment_one)); + v.push_back(std::to_string(e.augment_two)); + v.push_back(std::to_string(e.augment_three)); + v.push_back(std::to_string(e.augment_four)); + v.push_back(std::to_string(e.augment_five)); + v.push_back(std::to_string(e.augment_six)); v.push_back(std::to_string(e.instnodrop)); v.push_back("'" + Strings::Escape(e.custom_data) + "'"); - v.push_back(std::to_string(e.ornamenticon)); - v.push_back(std::to_string(e.ornamentidfile)); + v.push_back(std::to_string(e.ornament_icon)); + v.push_back(std::to_string(e.ornament_idfile)); v.push_back(std::to_string(e.ornament_hero_model)); + v.push_back("'" + Strings::Escape(e.item_unique_id) + "'"); v.push_back(std::to_string(e.guid)); auto results = db.QueryDatabase( @@ -546,22 +557,23 @@ public: std::vector v; v.push_back(std::to_string(e.time_index)); - v.push_back(std::to_string(e.charid)); - v.push_back(std::to_string(e.slotid)); - v.push_back(std::to_string(e.itemid)); + v.push_back(std::to_string(e.character_id)); + v.push_back(std::to_string(e.slot_id)); + v.push_back(std::to_string(e.item_id)); v.push_back(std::to_string(e.charges)); v.push_back(std::to_string(e.color)); - v.push_back(std::to_string(e.augslot1)); - v.push_back(std::to_string(e.augslot2)); - v.push_back(std::to_string(e.augslot3)); - v.push_back(std::to_string(e.augslot4)); - v.push_back(std::to_string(e.augslot5)); - v.push_back(std::to_string(e.augslot6)); + v.push_back(std::to_string(e.augment_one)); + v.push_back(std::to_string(e.augment_two)); + v.push_back(std::to_string(e.augment_three)); + v.push_back(std::to_string(e.augment_four)); + v.push_back(std::to_string(e.augment_five)); + v.push_back(std::to_string(e.augment_six)); v.push_back(std::to_string(e.instnodrop)); v.push_back("'" + Strings::Escape(e.custom_data) + "'"); - v.push_back(std::to_string(e.ornamenticon)); - v.push_back(std::to_string(e.ornamentidfile)); + v.push_back(std::to_string(e.ornament_icon)); + v.push_back(std::to_string(e.ornament_idfile)); v.push_back(std::to_string(e.ornament_hero_model)); + v.push_back("'" + Strings::Escape(e.item_unique_id) + "'"); v.push_back(std::to_string(e.guid)); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); diff --git a/common/repositories/inventory_snapshots_repository.h b/common/repositories/inventory_snapshots_repository.h index 0fb1f815c..71406c9b5 100644 --- a/common/repositories/inventory_snapshots_repository.h +++ b/common/repositories/inventory_snapshots_repository.h @@ -4,6 +4,7 @@ #include "../database.h" #include "../strings.h" #include "base/base_inventory_snapshots_repository.h" +#include "inventory_repository.h" class InventorySnapshotsRepository: public BaseInventorySnapshotsRepository { public: @@ -46,16 +47,15 @@ public: // Custom extended repository methods here static int64 CountInventorySnapshots(Database& db) { - const std::string& query = "SELECT COUNT(*) FROM (SELECT * FROM `inventory_snapshots` a GROUP BY `charid`, `time_index`) b"; + const std::string &query = + "SELECT COUNT(*) FROM (SELECT * FROM `inventory_snapshots` a GROUP BY `character_id`, `time_index`) b"; auto results = db.QueryDatabase(query); - if (!results.Success() || !results.RowCount()) { return -1; } - auto row = results.begin(); - + auto row = results.begin(); const int64 count = Strings::ToBigInt(row[0]); if (count > std::numeric_limits::max()) { @@ -68,6 +68,151 @@ public: return count; } + + static int64 CountCharacterInvSnapshots(Database& db, uint32 character_id) + { + const std::string &query = fmt::format( + "SELECT COUNT(*) FROM (SELECT * FROM `inventory_snapshots` a WHERE " + "`character_id` = '{}' GROUP BY `time_index`) b", + character_id + ); + + auto results = db.QueryDatabase(query); + if (!results.Success() || !results.RowCount()) { + return -1; + } + + auto &row = results.begin(); + const int64 count = Strings::ToBigInt(row[0]); + + if (count > std::numeric_limits::max()) { + return -2; + } + + if (count < 0) { + return -3; + } + + return count; + } + + static void ClearCharacterInvSnapshots(Database &db, uint32 character_id, bool from_now) + { + uint32 del_time = time(nullptr); + if (!from_now) { + del_time -= RuleI(Character, InvSnapshotHistoryD) * 86400; + } + + DeleteWhere(db, fmt::format("`character_id` = '{}' AND `time_index` = '{}'", character_id, del_time)); + } + + static void ListCharacterInvSnapshots(Database &db, uint32 character_id, std::list> &is_list) + { + const std::string &query = fmt::format( + "SELECT `time_index`, COUNT(*) FROM `inventory_snapshots` WHERE " + "`character_id` = '{}' GROUP BY `time_index` ORDER BY `time_index` DESC", + character_id + ); + auto results = db.QueryDatabase(query); + + if (!results.Success()) + return; + + for (auto row: results) { + is_list.emplace_back(std::pair(Strings::ToUnsignedInt(row[0]), Strings::ToInt(row[1]))); + } + } + + static bool ValidateCharacterInvSnapshotTimestamp(Database &db, uint32 character_id, uint32 timestamp) + { + if (!character_id || !timestamp) { + return false; + } + + const std::string &query = fmt::format( + "SELECT * FROM `inventory_snapshots` WHERE `character_id` = '{}' " + "AND `time_index` = '{}' LIMIT 1", + character_id, + timestamp + ); + auto results = db.QueryDatabase(query); + + if (!results.Success() || results.RowCount() == 0) { + return false; + } + + return true; + } + + static void ParseCharacterInvSnapshot( + Database &db, + uint32 character_id, + uint32 timestamp, + std::list> &parse_list) + { + const std::string &query = fmt::format( + "SELECT `slot_id`, `item_id` FROM `inventory_snapshots` " + "WHERE `character_id` = '{}' AND `time_index` = '{}' ORDER BY `slot_id`", + character_id, + timestamp + ); + auto results = db.QueryDatabase(query); + + if (!results.Success()) { + return; + } + + for (auto row: results) { + parse_list.emplace_back(std::pair(Strings::ToInt(row[0]), Strings::ToUnsignedInt(row[1]))); + } + } + + static void TransformToInv(InventorySnapshots &out, const InventoryRepository::Inventory &in, uint32 time_index) + { + out.character_id = in.character_id; + out.item_id = in.item_id; + out.item_unique_id = in.item_unique_id; + out.augment_one = in.augment_one; + out.augment_two = in.augment_two; + out.augment_three = in.augment_three; + out.augment_four = in.augment_four; + out.augment_five = in.augment_five; + out.augment_six = in.augment_six; + out.charges = in.charges; + out.color = in.color; + out.custom_data = in.custom_data; + out.instnodrop = in.instnodrop; + out.ornament_hero_model = in.ornament_hero_model; + out.ornament_icon = in.ornament_icon; + out.ornament_idfile = in.ornament_idfile; + out.guid = in.guid; + out.slot_id = in.slot_id; + out.time_index = time_index; + } + + static bool SaveCharacterInvSnapshot(Database &db, uint32 character_id) + { + uint32 time_index = time(nullptr); + std::vector queue{}; + + auto inventory = InventoryRepository::GetWhere(db, fmt::format("`character_id` = '{}'", character_id)); + + for (auto const &i: inventory) { + auto snapshot = NewEntity(); + TransformToInv(snapshot, i, time_index); + queue.push_back(snapshot); + } + + if (!queue.empty()) { + InsertMany(db, queue); + LogInventory("Created inventory snapshot for [{}] with ([{}]) items", character_id, queue.size()); + return true; + } + + LogInventory("Failed to created inventory snapshot for [{}]", character_id); + return false; + } + }; #endif //EQEMU_INVENTORY_SNAPSHOTS_REPOSITORY_H diff --git a/zone/client.cpp b/zone/client.cpp index 19d4fd1f2..fa00b9609 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -15,11 +15,13 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "../common/global_define.h" #include -#include -#include #include +#include +#include +#include "../common/global_define.h" + +#include "../common/repositories/inventory_snapshots_repository.h" // for windows compile #ifndef _WINDOWS diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index d1c65edef..56ccaee42 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -55,8 +55,11 @@ #include "../common/repositories/character_evolving_items_repository.h" #include -#include #include +#include + +#include "../common/repositories/inventory_repository.h" +#include "../common/repositories/inventory_snapshots_repository.h" extern Zone* zone; @@ -1313,202 +1316,56 @@ bool ZoneDatabase::NoRentExpired(const std::string& name) return seconds > 1800; } -bool ZoneDatabase::SaveCharacterInvSnapshot(uint32 character_id) { - uint32 time_index = time(nullptr); - std::string query = StringFormat( - "INSERT " - "INTO" - " `inventory_snapshots` " - "(`time_index`," - " `charid`," - " `slotid`," - " `itemid`," - " `charges`," - " `color`," - " `augslot1`," - " `augslot2`," - " `augslot3`," - " `augslot4`," - " `augslot5`," - " `augslot6`," - " `instnodrop`," - " `custom_data`," - " `ornamenticon`," - " `ornamentidfile`," - " `ornament_hero_model`," - " `guid`" - ") " - "SELECT" - " %u," - " `character_id`," - " `slot_id`," - " `item_id`," - " `charges`," - " `color`," - " `augment_one`," - " `augment_two`," - " `augment_three`," - " `augment_four`," - " `augment_five`," - " `augment_six`," - " `instnodrop`," - " `custom_data`," - " `ornament_icon`," - " `ornament_idfile`," - " `ornament_hero_model`," - " `guid` " - "FROM" - " `inventory` " - "WHERE" - " `character_id` = %u", - time_index, - character_id - ); - auto results = database.QueryDatabase(query); - LogInventory("[{}] ([{}])", character_id, (results.Success() ? "pass" : "fail")); - return results.Success(); -} - -int ZoneDatabase::CountCharacterInvSnapshots(uint32 character_id) { - std::string query = StringFormat( - "SELECT" - " COUNT(*) " - "FROM " - "(" - "SELECT * FROM" - " `inventory_snapshots` a " - "WHERE" - " `charid` = %u " - "GROUP BY" - " `time_index`" - ") b", - character_id - ); - auto results = QueryDatabase(query); - - if (!results.Success()) - return -1; - - auto& row = results.begin(); - - int64 count = Strings::ToBigInt(row[0]); - if (count > 2147483647) - return -2; - if (count < 0) - return -3; - - return count; -} - -void ZoneDatabase::ClearCharacterInvSnapshots(uint32 character_id, bool from_now) { - uint32 del_time = time(nullptr); - if (!from_now) { del_time -= RuleI(Character, InvSnapshotHistoryD) * 86400; } - - std::string query = StringFormat( - "DELETE " - "FROM" - " `inventory_snapshots` " - "WHERE" - " `charid` = %u " - "AND" - " `time_index` <= %lu", - character_id, - (unsigned long)del_time - ); - QueryDatabase(query); -} - -void ZoneDatabase::ListCharacterInvSnapshots(uint32 character_id, std::list> &is_list) { - std::string query = StringFormat( - "SELECT" - " `time_index`," - " COUNT(*) " - "FROM" - " `inventory_snapshots` " - "WHERE" - " `charid` = %u " - "GROUP BY" - " `time_index` " - "ORDER BY" - " `time_index` " - "DESC", - character_id - ); - auto results = QueryDatabase(query); - - if (!results.Success()) - return; - - for (auto row : results) - is_list.emplace_back(std::pair(Strings::ToUnsignedInt(row[0]), Strings::ToInt(row[1]))); -} - -bool ZoneDatabase::ValidateCharacterInvSnapshotTimestamp(uint32 character_id, uint32 timestamp) { - if (!character_id || !timestamp) - return false; - - std::string query = StringFormat( - "SELECT" - " * " - "FROM" - " `inventory_snapshots` " - "WHERE" - " `charid` = %u " - "AND" - " `time_index` = %u " - "LIMIT 1", - character_id, - timestamp - ); - auto results = QueryDatabase(query); - - if (!results.Success() || results.RowCount() == 0) +bool ZoneDatabase::SaveCharacterInvSnapshot(uint32 character_id) +{ + if (!InventorySnapshotsRepository::SaveCharacterInvSnapshot(database, character_id)) { return false; + } return true; } -void ZoneDatabase::ParseCharacterInvSnapshot(uint32 character_id, uint32 timestamp, std::list> &parse_list) { - std::string query = StringFormat( - "SELECT" - " `slotid`," - " `itemid` " - "FROM" - " `inventory_snapshots` " - "WHERE" - " `charid` = %u " - "AND" - " `time_index` = %u " - "ORDER BY" - " `slotid`", - character_id, - timestamp - ); - auto results = QueryDatabase(query); +int ZoneDatabase::CountCharacterInvSnapshots(uint32 character_id) +{ + return InventorySnapshotsRepository::CountCharacterInvSnapshots(*this, character_id); +} - if (!results.Success()) - return; +void ZoneDatabase::ClearCharacterInvSnapshots(uint32 character_id, bool from_now) +{ + InventorySnapshotsRepository::ClearCharacterInvSnapshots(*this, character_id, from_now); +} - for (auto row : results) - parse_list.emplace_back(std::pair(Strings::ToInt(row[0]), Strings::ToUnsignedInt(row[1]))); +void ZoneDatabase::ListCharacterInvSnapshots(uint32 character_id, std::list> &is_list) +{ + InventorySnapshotsRepository::ListCharacterInvSnapshots(*this, character_id, is_list); +} + +bool ZoneDatabase::ValidateCharacterInvSnapshotTimestamp(uint32 character_id, uint32 timestamp) +{ + return InventorySnapshotsRepository::ValidateCharacterInvSnapshotTimestamp(*this, character_id, timestamp); +} + +void ZoneDatabase::ParseCharacterInvSnapshot(uint32 character_id, uint32 timestamp, std::list> &parse_list) +{ + InventorySnapshotsRepository::ParseCharacterInvSnapshot(*this, character_id, timestamp, parse_list); } void ZoneDatabase::DivergeCharacterInvSnapshotFromInventory(uint32 character_id, uint32 timestamp, std::list> &compare_list) { std::string query = StringFormat( "SELECT" - " slotid," - " itemid " + " slot_id," + " item_id " "FROM" " `inventory_snapshots` " "WHERE" " `time_index` = %u " "AND" - " `charid` = %u " + " `character_id` = %u " "AND" - " `slotid` NOT IN " + " `slot_id` NOT IN " "(" "SELECT" - " a.`slotid` " + " a.`slot_id` " "FROM" " `inventory_snapshots` a " "JOIN" @@ -1518,7 +1375,7 @@ void ZoneDatabase::DivergeCharacterInvSnapshotFromInventory(uint32 character_id, "WHERE" " a.`time_index` = %u " "AND" - " a.`charid` = %u " + " a.`character_id` = %u " "AND" " b.`character_id` = %u" ")", @@ -1540,27 +1397,27 @@ void ZoneDatabase::DivergeCharacterInvSnapshotFromInventory(uint32 character_id, void ZoneDatabase::DivergeCharacterInventoryFromInvSnapshot(uint32 character_id, uint32 timestamp, std::list> &compare_list) { std::string query = StringFormat( "SELECT" - " `slotid`," - " `itemid` " + " `slot_id`," + " `item_id` " "FROM" " `inventory` " "WHERE" " `character_id` = %u " "AND" - " `slotid` NOT IN " + " `slot_id` NOT IN " "(" "SELECT" - " a.`slotid` " + " a.`slot_id` " "FROM" " `inventory` a " "JOIN" " `inventory_snapshots` b " "USING" - " (`slotid`, `itemid`) " + " (`slot_id`, `item_id`) " "WHERE" " b.`time_index` = %u " "AND" - " b.`charid` = %u " + " b.`character_id` = %u " "AND" " a.`character_id` = %u" ")",