mirror of
https://github.com/EQEmu/Server.git
synced 2026-02-16 08:42:25 +00:00
Start up of inventory snapshots
This commit is contained in:
parent
c797fcca87
commit
32dcb634f0
@ -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
|
||||
},
|
||||
|
||||
@ -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<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.charid = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.slotid = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.itemid = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.character_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.charges = row[4] ? static_cast<uint16_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.color = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.augslot1 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.augslot2 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.augslot3 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.augslot4 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.augslot5 = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.augslot6 = row[11] ? static_cast<int32_t>(atoi(row[11])) : 0;
|
||||
e.augment_one = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.augment_two = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.augment_three = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.augment_four = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.augment_five = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.augment_six = row[11] ? static_cast<int32_t>(atoi(row[11])) : 0;
|
||||
e.instnodrop = row[12] ? static_cast<uint8_t>(strtoul(row[12], nullptr, 10)) : 0;
|
||||
e.custom_data = row[13] ? row[13] : "";
|
||||
e.ornamenticon = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
||||
e.ornamentidfile = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
|
||||
e.ornament_icon = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
||||
e.ornament_idfile = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
|
||||
e.ornament_hero_model = row[16] ? static_cast<int32_t>(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<std::string> 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<std::string> 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<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.charid = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.slotid = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.itemid = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.character_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.charges = row[4] ? static_cast<uint16_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.color = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.augslot1 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.augslot2 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.augslot3 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.augslot4 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.augslot5 = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.augslot6 = row[11] ? static_cast<int32_t>(atoi(row[11])) : 0;
|
||||
e.augment_one = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.augment_two = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.augment_three = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.augment_four = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.augment_five = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.augment_six = row[11] ? static_cast<int32_t>(atoi(row[11])) : 0;
|
||||
e.instnodrop = row[12] ? static_cast<uint8_t>(strtoul(row[12], nullptr, 10)) : 0;
|
||||
e.custom_data = row[13] ? row[13] : "";
|
||||
e.ornamenticon = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
||||
e.ornamentidfile = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
|
||||
e.ornament_icon = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
||||
e.ornament_idfile = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
|
||||
e.ornament_hero_model = row[16] ? static_cast<int32_t>(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<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.charid = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.slotid = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.itemid = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.character_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.charges = row[4] ? static_cast<uint16_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.color = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.augslot1 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.augslot2 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.augslot3 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.augslot4 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.augslot5 = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.augslot6 = row[11] ? static_cast<int32_t>(atoi(row[11])) : 0;
|
||||
e.augment_one = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||
e.augment_two = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||
e.augment_three = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||
e.augment_four = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||
e.augment_five = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||
e.augment_six = row[11] ? static_cast<int32_t>(atoi(row[11])) : 0;
|
||||
e.instnodrop = row[12] ? static_cast<uint8_t>(strtoul(row[12], nullptr, 10)) : 0;
|
||||
e.custom_data = row[13] ? row[13] : "";
|
||||
e.ornamenticon = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
||||
e.ornamentidfile = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
|
||||
e.ornament_icon = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
|
||||
e.ornament_idfile = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
|
||||
e.ornament_hero_model = row[16] ? static_cast<int32_t>(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<std::string> 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<std::string> 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) + ")");
|
||||
|
||||
@ -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<int>::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<int>::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<std::pair<uint32, int>> &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<uint32, int>(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<std::pair<int16, uint32>> &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<int16, uint32>(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<InventorySnapshots> 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
|
||||
|
||||
@ -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 <iostream>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../common/global_define.h"
|
||||
|
||||
#include "../common/repositories/inventory_snapshots_repository.h"
|
||||
|
||||
// for windows compile
|
||||
#ifndef _WINDOWS
|
||||
|
||||
225
zone/zonedb.cpp
225
zone/zonedb.cpp
@ -55,8 +55,11 @@
|
||||
#include "../common/repositories/character_evolving_items_repository.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <fmt/format.h>
|
||||
#include <iostream>
|
||||
|
||||
#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<std::pair<uint32, int>> &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<uint32, int>(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<std::pair<int16, uint32>> &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<int16, uint32>(Strings::ToInt(row[0]), Strings::ToUnsignedInt(row[1])));
|
||||
void ZoneDatabase::ListCharacterInvSnapshots(uint32 character_id, std::list<std::pair<uint32, int>> &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<std::pair<int16, uint32>> &parse_list)
|
||||
{
|
||||
InventorySnapshotsRepository::ParseCharacterInvSnapshot(*this, character_id, timestamp, parse_list);
|
||||
}
|
||||
|
||||
void ZoneDatabase::DivergeCharacterInvSnapshotFromInventory(uint32 character_id, uint32 timestamp, std::list<std::pair<int16, uint32>> &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<std::pair<int16, uint32>> &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"
|
||||
")",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user