Saving and loading of guids for items, still needs a lot of work, esp with corpses. No auditing yet

This commit is contained in:
KimLS 2023-03-06 23:59:07 -08:00
parent 593127fb7e
commit d6bdaa5c6e
8 changed files with 74 additions and 46 deletions

View File

@ -24,16 +24,16 @@
#include "rulesys.h"
#include "shareddb.h"
#include "strings.h"
#include "util/uuid.h"
//#include "../common/light_source.h"
#include <limits.h>
//#include <iostream>
int32 NextItemInstSerialNumber = 1;
uint32 NextItemInstSerialNumber = 1;
static inline int32 GetNextItemInstSerialNumber() {
static inline uint32 GetNextItemInstSerialNumber() {
// The Bazaar relies on each item a client has up for Trade having a unique
// identifier. This 'SerialNumber' is sent in Serialized item packets and
@ -45,7 +45,7 @@ static inline int32 GetNextItemInstSerialNumber() {
// NextItemInstSerialNumber is the next one to hand out.
//
// It is very unlikely to reach 2,147,483,647. Maybe we should call abort(), rather than wrapping back to 1.
if(NextItemInstSerialNumber >= INT_MAX)
if(NextItemInstSerialNumber >= UINT_MAX)
NextItemInstSerialNumber = 1;
else
NextItemInstSerialNumber++;
@ -56,13 +56,21 @@ static inline int32 GetNextItemInstSerialNumber() {
//
// class EQ::ItemInstance
//
EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
EQ::ItemInstance::ItemInstance(const ItemData* item, const std::string& guid, int16 charges) {
m_use_type = ItemInstNormal;
if(item) {
m_item = new ItemData(*item);
} else {
m_item = nullptr;
}
if (guid.empty()) {
m_guid = EQ::Util::UUID::Generate().ToString();
}
else {
m_guid = guid;
}
m_charges = charges;
m_price = 0;
m_attuned = false;
@ -72,7 +80,7 @@ EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
else
m_color = 0;
m_merchantcount = 1;
m_SerialNumber = GetNextItemInstSerialNumber();
m_serial_number = GetNextItemInstSerialNumber();
m_exp = 0;
m_evolveLvl = 0;
@ -85,9 +93,10 @@ EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
m_ornament_hero_model = 0;
m_recast_timestamp = 0;
m_new_id_file = 0;
m_currentslot = 0;
}
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges) {
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, const std::string& guid, int16 charges) {
m_use_type = ItemInstNormal;
m_item = db->GetItem(item_id);
if(m_item) {
@ -97,6 +106,13 @@ EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges
m_item = nullptr;
}
if (guid.empty()) {
m_guid = EQ::Util::UUID::Generate().ToString();
}
else {
m_guid = guid;
}
m_charges = charges;
m_price = 0;
m_merchantslot = 0;
@ -106,7 +122,7 @@ EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges
else
m_color = 0;
m_merchantcount = 1;
m_SerialNumber = GetNextItemInstSerialNumber();
m_serial_number = GetNextItemInstSerialNumber();
m_exp = 0;
m_evolveLvl = 0;
@ -119,17 +135,20 @@ EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges
m_ornament_hero_model = 0;
m_recast_timestamp = 0;
m_new_id_file = 0;
m_currentslot = 0;
}
EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
m_use_type = use_type;
m_guid = EQ::Util::UUID::Generate().ToString();
m_item = nullptr;
m_charges = 0;
m_price = 0;
m_attuned = false;
m_merchantslot = 0;
m_color = 0;
m_serial_number = 0;
m_exp = 0;
m_evolveLvl = 0;
m_activated = false;
@ -141,6 +160,8 @@ EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
m_ornament_hero_model = 0;
m_recast_timestamp = 0;
m_new_id_file = 0;
m_currentslot = 0;
m_merchantcount = 0;
}
// Make a copy of an EQ::ItemInstance object
@ -152,6 +173,7 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
else
m_item = nullptr;
m_guid = copy.m_guid;
m_charges=copy.m_charges;
m_price=copy.m_price;
m_color=copy.m_color;
@ -176,7 +198,7 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
for (iter = copy.m_custom_data.begin(); iter != copy.m_custom_data.end(); ++iter) {
m_custom_data[iter->first] = iter->second;
}
m_SerialNumber = copy.m_SerialNumber;
m_serial_number = copy.m_serial_number;
m_custom_data = copy.m_custom_data;
m_timers = copy.m_timers;

View File

@ -69,9 +69,9 @@ namespace EQ
/////////////////////////
// Constructors/Destructor
ItemInstance(const ItemData* item = nullptr, int16 charges = 0);
ItemInstance(const ItemData* item, const std::string& guid, int16 charges);
ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges = 0);
ItemInstance(SharedDatabase *db, uint32 item_id, const std::string &guid, int16 charges);
ItemInstance(ItemInstTypes use_type);
@ -79,6 +79,8 @@ namespace EQ
~ItemInstance();
inline std::string GetGuid() const { return m_guid; }
// Query item type
bool IsType(item::ItemClass item_class) const;
@ -225,11 +227,8 @@ namespace EQ
std::string Serialize(int16 slot_id) const { InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(InternalSerializedItem_Struct)); return ser; }
void Serialize(OutBuffer& ob, int16 slot_id) const { InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
inline int32 GetSerialNumber() const { return m_SerialNumber; }
inline void SetSerialNumber(int32 id) { m_SerialNumber = id; }
inline std::string GetGUID() const { return m_guid; }
inline void SetGUID(const std::string &guid) { m_guid = guid; }
inline int32 GetSerialNumber() const { return m_serial_number; }
inline void SetSerialNumber(int32 id) { m_serial_number = id; }
std::map<std::string, ::Timer>& GetTimers() { return m_timers; }
void SetTimer(std::string name, uint32 time);
@ -306,6 +305,7 @@ namespace EQ
void _PutItem(uint8 index, ItemInstance* inst) { m_contents[index] = inst; }
std::string m_guid;
ItemInstTypes m_use_type; // Usage type for item
const ItemData* m_item; // Ptr to item data
int16 m_charges; // # of charges for chargeable items
@ -315,8 +315,7 @@ namespace EQ
int16 m_currentslot;
bool m_attuned;
int32 m_merchantcount; //number avaliable on the merchant, -1=unlimited
int32 m_SerialNumber; // Unique identifier for this instance of an item. Needed for Bazaar.
std::string m_guid;
uint32 m_serial_number; // Unique identifier for this instance of an item. Needed for Bazaar.
uint32 m_exp;
int8 m_evolveLvl;
bool m_activated;

View File

@ -295,11 +295,11 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const EQ::ItemInstance*
// Update/Insert item
const std::string query = StringFormat("REPLACE INTO inventory "
"(charid, slotid, itemid, charges, instnodrop, custom_data, color, "
"(guid, charid, slotid, itemid, charges, instnodrop, custom_data, color, "
"augslot1, augslot2, augslot3, augslot4, augslot5, augslot6, ornamenticon, ornamentidfile, ornament_hero_model) "
"VALUES( %lu, %lu, %lu, %lu, %lu, '%s', %lu, "
"VALUES( '%s', %lu, %lu, %lu, %lu, %lu, '%s', %lu, "
"%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu)",
static_cast<unsigned long>(char_id), static_cast<unsigned long>(slot_id), static_cast<unsigned long>(inst->GetItem()->ID),
inst->GetGuid().c_str(), static_cast<unsigned long>(char_id), static_cast<unsigned long>(slot_id), static_cast<unsigned long>(inst->GetItem()->ID),
static_cast<unsigned long>(charges), static_cast<unsigned long>(inst->IsAttuned() ? 1 : 0),
inst->GetCustomDataString().c_str(), static_cast<unsigned long>(inst->GetColor()),
static_cast<unsigned long>(augslot[0]), static_cast<unsigned long>(augslot[1]), static_cast<unsigned long>(augslot[2]),
@ -343,11 +343,11 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const EQ::ItemInstance
charges = 0x7FFF;
const std::string query = StringFormat("REPLACE INTO sharedbank "
"(acctid, slotid, itemid, charges, custom_data, "
"(guid, acctid, slotid, itemid, charges, custom_data, "
"augslot1, augslot2, augslot3, augslot4, augslot5, augslot6) "
"VALUES( %lu, %lu, %lu, %lu, '%s', "
"VALUES( '%s', %lu, %lu, %lu, %lu, '%s', "
"%lu, %lu, %lu, %lu, %lu, %lu)",
static_cast<unsigned long>(account_id), static_cast<unsigned long>(slot_id), static_cast<unsigned long>(inst->GetItem()->ID),
inst->GetGuid().c_str(), static_cast<unsigned long>(account_id), static_cast<unsigned long>(slot_id), static_cast<unsigned long>(inst->GetItem()->ID),
static_cast<unsigned long>(charges), inst->GetCustomDataString().c_str(), static_cast<unsigned long>(augslot[0]),
static_cast<unsigned long>(augslot[1]), static_cast<unsigned long>(augslot[2]), static_cast<unsigned long>(augslot[3]), static_cast<unsigned long>(augslot[4]),
static_cast<unsigned long>(augslot[5]));
@ -481,7 +481,7 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, EQ::InventoryPro
if(!myitem)
continue;
const EQ::ItemInstance* myinst = CreateBaseItem(myitem, charges);
const EQ::ItemInstance* myinst = CreateBaseItem(myitem, "", charges);
if(slot < 0)
slot = inv->FindFreeSlot(0, 0);
@ -502,14 +502,14 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is
if (is_charid)
query = StringFormat("SELECT sb.slotid, sb.itemid, sb.charges, "
"sb.augslot1, sb.augslot2, sb.augslot3, "
"sb.augslot4, sb.augslot5, sb.augslot6, sb.custom_data "
"sb.augslot4, sb.augslot5, sb.augslot6, sb.custom_data, sb.guid "
"FROM sharedbank sb INNER JOIN character_data ch "
"ON ch.account_id=sb.acctid WHERE ch.id = %i ORDER BY sb.slotid",
id);
else
query = StringFormat("SELECT slotid, itemid, charges, "
"augslot1, augslot2, augslot3, "
"augslot4, augslot5, augslot6, custom_data "
"augslot4, augslot5, augslot6, custom_data, guid "
"FROM sharedbank WHERE acctid=%i ORDER BY slotid",
id);
auto results = QueryDatabase(query);
@ -538,7 +538,9 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is
continue;
}
EQ::ItemInstance *inst = CreateBaseItem(item, charges);
std::string guid = row[10];
EQ::ItemInstance *inst = CreateBaseItem(item, guid, charges);
if (inst && item->IsClassCommon()) {
for (int i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) {
if (aug[i])
@ -598,7 +600,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv)
// Retrieve character inventory
const std::string query =
StringFormat("SELECT slotid, itemid, charges, color, augslot1, augslot2, augslot3, augslot4, augslot5, "
"augslot6, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model FROM "
"augslot6, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model, guid FROM "
"inventory WHERE charid = %i ORDER BY slotid",
char_id);
auto results = QueryDatabase(query);
@ -672,7 +674,8 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv)
continue;
}
EQ::ItemInstance *inst = CreateBaseItem(item, charges);
std::string guid = row[15];
EQ::ItemInstance *inst = CreateBaseItem(item, guid, charges);
if (inst == nullptr)
continue;
@ -781,7 +784,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQ::InventoryPr
const std::string query =
StringFormat("SELECT slotid, itemid, charges, color, augslot1, "
"augslot2, augslot3, augslot4, augslot5, augslot6, instnodrop, custom_data, ornamenticon, "
"ornamentidfile, ornament_hero_model "
"ornamentidfile, ornament_hero_model, guid "
"FROM inventory INNER JOIN character_data ch "
"ON ch.id = charid WHERE ch.name = '%s' AND ch.account_id = %i ORDER BY slotid",
name, account_id);
@ -816,7 +819,9 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQ::InventoryPr
if (!item)
continue;
EQ::ItemInstance *inst = CreateBaseItem(item, charges);
std::string guid = row[15];
EQ::ItemInstance *inst = CreateBaseItem(item, guid, charges);
if (inst == nullptr)
continue;
@ -1550,7 +1555,7 @@ EQ::ItemInstance* SharedDatabase::CreateItem(
const EQ::ItemData* item = GetItem(item_id);
if (item) {
inst = CreateBaseItem(item, charges);
inst = CreateBaseItem(item, "", charges);
if (!inst) {
LogError("Error: valid item data returned a null reference for EQ::ItemInstance creation in SharedDatabase::CreateItem()");
@ -1585,7 +1590,7 @@ EQ::ItemInstance* SharedDatabase::CreateItem(
) {
EQ::ItemInstance* inst = nullptr;
if (item) {
inst = CreateBaseItem(item, charges);
inst = CreateBaseItem(item, "", charges);
if (!inst) {
LogError("Error: valid item data returned a null reference for EQ::ItemInstance creation in SharedDatabase::CreateItem()");
@ -1605,7 +1610,7 @@ EQ::ItemInstance* SharedDatabase::CreateItem(
return inst;
}
EQ::ItemInstance* SharedDatabase::CreateBaseItem(const EQ::ItemData* item, int16 charges) {
EQ::ItemInstance* SharedDatabase::CreateBaseItem(const EQ::ItemData* item, const std::string& guid, int16 charges) {
EQ::ItemInstance* inst = nullptr;
if (item) {
// if maxcharges is -1 that means it is an unlimited use item.
@ -1616,7 +1621,7 @@ EQ::ItemInstance* SharedDatabase::CreateBaseItem(const EQ::ItemData* item, int16
if(charges <= 0 && item->Stackable)
charges = 1;
inst = new EQ::ItemInstance(item, charges);
inst = new EQ::ItemInstance(item, guid, charges);
if (inst == nullptr) {
LogError("Error: valid item data returned a null reference for EQ::ItemInstance creation in SharedDatabase::CreateBaseItem()");

View File

@ -139,7 +139,7 @@ public:
uint32 aug6 = 0,
bool attuned = 0
);
EQ::ItemInstance *CreateBaseItem(const EQ::ItemData *item, int16 charges = 0);
EQ::ItemInstance *CreateBaseItem(const EQ::ItemData *item, const std::string &guid, int16 charges);
void GetItemsCount(int32 &item_count, uint32 &max_id);
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);

View File

@ -876,7 +876,8 @@ bool WorldDatabase::GetCharSelInventory(uint32 account_id, char *name, EQ::Inven
" custom_data,"
" ornamenticon,"
" ornamentidfile,"
" ornament_hero_model "
" ornament_hero_model, ",
" guid "
"FROM"
" inventory "
"INNER JOIN"
@ -932,12 +933,13 @@ bool WorldDatabase::GetCharSelInventory(uint32 account_id, char *name, EQ::Inven
uint32 ornament_icon = (uint32)Strings::ToUnsignedInt(row[12]);
uint32 ornament_idfile = (uint32)Strings::ToUnsignedInt(row[13]);
uint32 ornament_hero_model = (uint32)Strings::ToUnsignedInt(row[14]);
std::string guid = row[15];
const EQ::ItemData *item = content_db.GetItem(item_id);
if (!item)
continue;
EQ::ItemInstance *inst = content_db.CreateBaseItem(item, charges);
EQ::ItemInstance *inst = content_db.CreateBaseItem(item, guid, charges);
if (inst == nullptr)
continue;

View File

@ -2218,7 +2218,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
//do attack animation regardless of whether or not we can hit below
int16 charges = 0;
EQ::ItemInstance weapon_inst(weapon, charges);
EQ::ItemInstance weapon_inst(weapon, "", charges);
my_hit.skill = AttackAnimation(Hand, &weapon_inst, my_hit.skill);
//basically "if not immune" then do the attack

View File

@ -4743,7 +4743,7 @@ uint16 EntityList::CreateGroundObject(uint32 itemid, const glm::vec4& position,
if (!is)
return 0;
auto i = new EQ::ItemInstance(is, is->MaxCharges);
auto i = new EQ::ItemInstance(is, "", is->MaxCharges);
if (!i)
return 0;

View File

@ -2901,7 +2901,7 @@ void Client::DisenchantSummonedBags(bool client_update)
if (!new_id) { continue; }
auto new_item = database.GetItem(new_id);
if (!new_item) { continue; }
auto new_inst = database.CreateBaseItem(new_item);
auto new_inst = database.CreateBaseItem(new_item, "", 0);
if (!new_inst) { continue; }
if (CopyBagContents(new_inst, inst)) {
@ -2925,7 +2925,7 @@ void Client::DisenchantSummonedBags(bool client_update)
if (!new_id) { continue; }
auto new_item = database.GetItem(new_id);
if (!new_item) { continue; }
auto new_inst = database.CreateBaseItem(new_item);
auto new_inst = database.CreateBaseItem(new_item, "", 0);
if (!new_inst) { continue; }
if (CopyBagContents(new_inst, inst)) {
@ -2946,7 +2946,7 @@ void Client::DisenchantSummonedBags(bool client_update)
if (!new_id) { continue; }
auto new_item = database.GetItem(new_id);
if (!new_item) { continue; }
auto new_inst = database.CreateBaseItem(new_item);
auto new_inst = database.CreateBaseItem(new_item, "", 0);
if (!new_inst) { continue; }
if (CopyBagContents(new_inst, inst)) {
@ -2967,7 +2967,7 @@ void Client::DisenchantSummonedBags(bool client_update)
if (!new_id) { break; }
auto new_item = database.GetItem(new_id);
if (!new_item) { break; }
auto new_inst = database.CreateBaseItem(new_item);
auto new_inst = database.CreateBaseItem(new_item, "", 0);
if (!new_inst) { break; }
if (CopyBagContents(new_inst, inst)) {