mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-27 18:52:27 +00:00
Inventory snapshots complete
This commit is contained in:
parent
af49a4bd10
commit
69cfa3cdbe
@ -167,27 +167,51 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TransformToInv(InventorySnapshots &out, const InventoryRepository::Inventory &in, uint32 time_index)
|
static void DivergeCharacterInvSnapshotFromInventory(
|
||||||
|
Database &db,
|
||||||
|
uint32 character_id,
|
||||||
|
uint32 timestamp,
|
||||||
|
std::list<std::pair<int16, uint32>> &compare_list)
|
||||||
{
|
{
|
||||||
out.character_id = in.character_id;
|
const std::string &query = fmt::format(
|
||||||
out.item_id = in.item_id;
|
"SELECT slot_id, item_id FROM `inventory_snapshots` "
|
||||||
out.item_unique_id = in.item_unique_id;
|
"WHERE `time_index` = '{0}' AND `character_id` = '{1}' AND `slot_id` NOT IN ("
|
||||||
out.augment_one = in.augment_one;
|
"SELECT a.`slot_id` FROM `inventory_snapshots` a JOIN `inventory` b USING (`slot_id`, `item_id`) "
|
||||||
out.augment_two = in.augment_two;
|
"WHERE a.`time_index` = '{0}' AND a.`character_id` = '{1}' AND b.`character_id` = '{1}')",
|
||||||
out.augment_three = in.augment_three;
|
timestamp,
|
||||||
out.augment_four = in.augment_four;
|
character_id
|
||||||
out.augment_five = in.augment_five;
|
);
|
||||||
out.augment_six = in.augment_six;
|
auto results = db.QueryDatabase(query);
|
||||||
out.charges = in.charges;
|
|
||||||
out.color = in.color;
|
if (!results.Success()) {
|
||||||
out.custom_data = in.custom_data;
|
return;
|
||||||
out.instnodrop = in.instnodrop;
|
}
|
||||||
out.ornament_hero_model = in.ornament_hero_model;
|
|
||||||
out.ornament_icon = in.ornament_icon;
|
for (auto row: results) {
|
||||||
out.ornament_idfile = in.ornament_idfile;
|
compare_list.emplace_back(std::pair<int16, uint32>(Strings::ToInt(row[0]), Strings::ToUnsignedInt(row[1])));
|
||||||
out.guid = in.guid;
|
}
|
||||||
out.slot_id = in.slot_id;
|
}
|
||||||
out.time_index = time_index;
|
|
||||||
|
static void DivergeCharacterInventoryFromInvSnapshot(
|
||||||
|
Database &db, uint32 character_id, uint32 timestamp, std::list<std::pair<int16, uint32>> &compare_list)
|
||||||
|
{
|
||||||
|
const std::string &query = fmt::format(
|
||||||
|
"SELECT `slot_id`, `item_id` FROM `inventory` WHERE "
|
||||||
|
"`character_id` = '{0}' AND `slot_id` NOT IN ("
|
||||||
|
"SELECT a.`slot_id` FROM `inventory` a JOIN `inventory_snapshots` b USING (`slot_id`, `item_id`) "
|
||||||
|
"WHERE b.`time_index` = '{1}' AND b.`character_id` = '{0}' AND a.`character_id` = '{0}')",
|
||||||
|
character_id,
|
||||||
|
timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto row: results) {
|
||||||
|
compare_list.emplace_back(std::pair<int16, uint32>(Strings::ToInt(row[0]), Strings::ToUnsignedInt(row[1])));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SaveCharacterInvSnapshot(Database &db, uint32 character_id)
|
static bool SaveCharacterInvSnapshot(Database &db, uint32 character_id)
|
||||||
@ -196,23 +220,104 @@ public:
|
|||||||
std::vector<InventorySnapshots> queue{};
|
std::vector<InventorySnapshots> queue{};
|
||||||
|
|
||||||
auto inventory = InventoryRepository::GetWhere(db, fmt::format("`character_id` = '{}'", character_id));
|
auto inventory = InventoryRepository::GetWhere(db, fmt::format("`character_id` = '{}'", character_id));
|
||||||
|
if (inventory.empty()) {
|
||||||
|
LogError("Character ID [{}] inventory is empty. Snapshot not created", character_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto const &i: inventory) {
|
for (auto const &i: inventory) {
|
||||||
auto snapshot = NewEntity();
|
auto snapshot = NewEntity();
|
||||||
TransformToInv(snapshot, i, time_index);
|
snapshot.character_id = i.character_id;
|
||||||
|
snapshot.item_id = i.item_id;
|
||||||
|
snapshot.item_unique_id = i.item_unique_id;
|
||||||
|
snapshot.augment_one = i.augment_one;
|
||||||
|
snapshot.augment_two = i.augment_two;
|
||||||
|
snapshot.augment_three = i.augment_three;
|
||||||
|
snapshot.augment_four = i.augment_four;
|
||||||
|
snapshot.augment_five = i.augment_five;
|
||||||
|
snapshot.augment_six = i.augment_six;
|
||||||
|
snapshot.charges = i.charges;
|
||||||
|
snapshot.color = i.color;
|
||||||
|
snapshot.custom_data = i.custom_data;
|
||||||
|
snapshot.instnodrop = i.instnodrop;
|
||||||
|
snapshot.ornament_hero_model = i.ornament_hero_model;
|
||||||
|
snapshot.ornament_icon = i.ornament_icon;
|
||||||
|
snapshot.ornament_idfile = i.ornament_idfile;
|
||||||
|
snapshot.guid = i.guid;
|
||||||
|
snapshot.slot_id = i.slot_id;
|
||||||
|
snapshot.time_index = time_index;
|
||||||
queue.push_back(snapshot);
|
queue.push_back(snapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!queue.empty()) {
|
if (queue.empty()) {
|
||||||
InsertMany(db, queue);
|
LogError("Character ID [{}] inventory is empty. Snapshot not created", character_id);
|
||||||
LogInventory("Created inventory snapshot for [{}] with ([{}]) items", character_id, queue.size());
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInventory("Failed to created inventory snapshot for [{}]", character_id);
|
if (!InsertMany(db, queue)) {
|
||||||
return false;
|
LogError("Failed to created inventory snapshot for [{}]", character_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogInventory("Created inventory snapshot for [{}] with ([{}]) items", character_id, queue.size());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool RestoreCharacterInvSnapshot(Database &db, uint32 character_id, uint32 timestamp)
|
||||||
|
{
|
||||||
|
InventoryRepository::DeleteWhere(db, fmt::format("`character_id` = '{}'", character_id));
|
||||||
|
|
||||||
|
auto snapshot = GetWhere(db, fmt::format("`character_id` = '{}' AND `time_index` = '{}'", character_id, timestamp));
|
||||||
|
if (snapshot.empty()) {
|
||||||
|
LogError("The snapshot requested could not be found. Restore failed for character id [{}] @ [{}] failed",
|
||||||
|
character_id,
|
||||||
|
timestamp
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<InventoryRepository::Inventory> queue{};
|
||||||
|
for (auto const &i: snapshot) {
|
||||||
|
auto inventory_entry = InventoryRepository::NewEntity();
|
||||||
|
inventory_entry.character_id = i.character_id;
|
||||||
|
inventory_entry.item_id = i.item_id;
|
||||||
|
inventory_entry.item_unique_id = i.item_unique_id;
|
||||||
|
inventory_entry.augment_one = i.augment_one;
|
||||||
|
inventory_entry.augment_two = i.augment_two;
|
||||||
|
inventory_entry.augment_three = i.augment_three;
|
||||||
|
inventory_entry.augment_four = i.augment_four;
|
||||||
|
inventory_entry.augment_five = i.augment_five;
|
||||||
|
inventory_entry.augment_six = i.augment_six;
|
||||||
|
inventory_entry.charges = i.charges;
|
||||||
|
inventory_entry.color = i.color;
|
||||||
|
inventory_entry.custom_data = i.custom_data;
|
||||||
|
inventory_entry.instnodrop = i.instnodrop;
|
||||||
|
inventory_entry.ornament_hero_model = i.ornament_hero_model;
|
||||||
|
inventory_entry.ornament_icon = i.ornament_icon;
|
||||||
|
inventory_entry.ornament_idfile = i.ornament_idfile;
|
||||||
|
inventory_entry.guid = i.guid;
|
||||||
|
inventory_entry.slot_id = i.slot_id;
|
||||||
|
queue.push_back(inventory_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queue.empty()) {
|
||||||
|
LogError("The snapshot is empty. Restore failed for character id [{}] @ [{}] failed", character_id, timestamp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!InventoryRepository::InsertMany(db, queue)) {
|
||||||
|
LogError("A database error occurred. Restore failed for character id [{}] @ [{}] failed", character_id, timestamp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogInventory(
|
||||||
|
"Restore complete for character id [{}] with snapshot @ [{}] with [{}] entries",
|
||||||
|
character_id,
|
||||||
|
timestamp,
|
||||||
|
queue.size()
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_INVENTORY_SNAPSHOTS_REPOSITORY_H
|
#endif //EQEMU_INVENTORY_SNAPSHOTS_REPOSITORY_H
|
||||||
|
|||||||
155
zone/zonedb.cpp
155
zone/zonedb.cpp
@ -1350,89 +1350,14 @@ void ZoneDatabase::ParseCharacterInvSnapshot(uint32 character_id, uint32 timesta
|
|||||||
InventorySnapshotsRepository::ParseCharacterInvSnapshot(*this, character_id, timestamp, 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) {
|
void ZoneDatabase::DivergeCharacterInvSnapshotFromInventory(uint32 character_id, uint32 timestamp, std::list<std::pair<int16, uint32>> &compare_list)
|
||||||
std::string query = StringFormat(
|
{
|
||||||
"SELECT"
|
InventorySnapshotsRepository::DivergeCharacterInvSnapshotFromInventory(*this, character_id, timestamp, compare_list);
|
||||||
" slot_id,"
|
|
||||||
" item_id "
|
|
||||||
"FROM"
|
|
||||||
" `inventory_snapshots` "
|
|
||||||
"WHERE"
|
|
||||||
" `time_index` = %u "
|
|
||||||
"AND"
|
|
||||||
" `character_id` = %u "
|
|
||||||
"AND"
|
|
||||||
" `slot_id` NOT IN "
|
|
||||||
"("
|
|
||||||
"SELECT"
|
|
||||||
" a.`slot_id` "
|
|
||||||
"FROM"
|
|
||||||
" `inventory_snapshots` a "
|
|
||||||
"JOIN"
|
|
||||||
" `inventory` b "
|
|
||||||
"USING"
|
|
||||||
" (`slot_id`, `item_id`) "
|
|
||||||
"WHERE"
|
|
||||||
" a.`time_index` = %u "
|
|
||||||
"AND"
|
|
||||||
" a.`character_id` = %u "
|
|
||||||
"AND"
|
|
||||||
" b.`character_id` = %u"
|
|
||||||
")",
|
|
||||||
timestamp,
|
|
||||||
character_id,
|
|
||||||
timestamp,
|
|
||||||
character_id,
|
|
||||||
character_id
|
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
|
|
||||||
if (!results.Success())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (auto row : results)
|
|
||||||
compare_list.emplace_back(std::pair<int16, uint32>(Strings::ToInt(row[0]), Strings::ToUnsignedInt(row[1])));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneDatabase::DivergeCharacterInventoryFromInvSnapshot(uint32 character_id, uint32 timestamp, std::list<std::pair<int16, uint32>> &compare_list) {
|
void ZoneDatabase::DivergeCharacterInventoryFromInvSnapshot(uint32 character_id, uint32 timestamp, std::list<std::pair<int16, uint32>> &compare_list)
|
||||||
std::string query = StringFormat(
|
{
|
||||||
"SELECT"
|
InventorySnapshotsRepository::DivergeCharacterInventoryFromInvSnapshot(*this, character_id, timestamp, compare_list);
|
||||||
" `slot_id`,"
|
|
||||||
" `item_id` "
|
|
||||||
"FROM"
|
|
||||||
" `inventory` "
|
|
||||||
"WHERE"
|
|
||||||
" `character_id` = %u "
|
|
||||||
"AND"
|
|
||||||
" `slot_id` NOT IN "
|
|
||||||
"("
|
|
||||||
"SELECT"
|
|
||||||
" a.`slot_id` "
|
|
||||||
"FROM"
|
|
||||||
" `inventory` a "
|
|
||||||
"JOIN"
|
|
||||||
" `inventory_snapshots` b "
|
|
||||||
"USING"
|
|
||||||
" (`slot_id`, `item_id`) "
|
|
||||||
"WHERE"
|
|
||||||
" b.`time_index` = %u "
|
|
||||||
"AND"
|
|
||||||
" b.`character_id` = %u "
|
|
||||||
"AND"
|
|
||||||
" a.`character_id` = %u"
|
|
||||||
")",
|
|
||||||
character_id,
|
|
||||||
timestamp,
|
|
||||||
character_id,
|
|
||||||
character_id
|
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
|
|
||||||
if (!results.Success())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (auto row : results)
|
|
||||||
compare_list.emplace_back(std::pair<int16, uint32>(Strings::ToInt(row[0]), Strings::ToUnsignedInt(row[1])));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::RestoreCharacterInvSnapshot(uint32 character_id, uint32 timestamp) {
|
bool ZoneDatabase::RestoreCharacterInvSnapshot(uint32 character_id, uint32 timestamp) {
|
||||||
@ -1443,73 +1368,7 @@ bool ZoneDatabase::RestoreCharacterInvSnapshot(uint32 character_id, uint32 times
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string query = StringFormat(
|
return InventorySnapshotsRepository::RestoreCharacterInvSnapshot(database, character_id, timestamp);
|
||||||
"DELETE "
|
|
||||||
"FROM"
|
|
||||||
" `inventory` "
|
|
||||||
"WHERE"
|
|
||||||
" `character_id` = %u",
|
|
||||||
character_id
|
|
||||||
);
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
query = StringFormat(
|
|
||||||
"INSERT "
|
|
||||||
"INTO"
|
|
||||||
" `inventory` "
|
|
||||||
"(`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` "
|
|
||||||
") "
|
|
||||||
"SELECT"
|
|
||||||
" `charid`,"
|
|
||||||
" `slotid`,"
|
|
||||||
" `itemid`,"
|
|
||||||
" `charges`,"
|
|
||||||
" `color`,"
|
|
||||||
" `augslot1`,"
|
|
||||||
" `augslot2`,"
|
|
||||||
" `augslot3`,"
|
|
||||||
" `augslot4`,"
|
|
||||||
" `augslot5`,"
|
|
||||||
" `augslot6`,"
|
|
||||||
" `instnodrop`,"
|
|
||||||
" `custom_data`,"
|
|
||||||
" `ornamenticon`,"
|
|
||||||
" `ornamentidfile`,"
|
|
||||||
" `ornament_hero_model`, "
|
|
||||||
" `guid` "
|
|
||||||
"FROM"
|
|
||||||
" `inventory_snapshots` "
|
|
||||||
"WHERE"
|
|
||||||
" `charid` = %u "
|
|
||||||
"AND"
|
|
||||||
" `time_index` = %u",
|
|
||||||
character_id,
|
|
||||||
timestamp
|
|
||||||
);
|
|
||||||
results = database.QueryDatabase(query);
|
|
||||||
|
|
||||||
LogInventory("[{}] snapshot for [{}] @ [{}]",
|
|
||||||
(results.Success() ? "restored" : "failed to restore"), character_id, timestamp);
|
|
||||||
|
|
||||||
return results.Success();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load /*= false*/)
|
const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load /*= false*/)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user