BulkSendItems now works on RoF2

This commit is contained in:
KimLS 2015-02-23 17:33:21 -08:00
parent 4e4168852b
commit 8bce7893ed
7 changed files with 722 additions and 104 deletions

View File

@ -46,6 +46,14 @@ bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr<ItemInstance>
return false;
}
uint32 EQEmu::ItemContainer::Size() {
return impl_->items.size();
}
uint32 EQEmu::ItemContainer::Size() const {
return impl_->items.size();
}
bool EQEmu::ItemContainer::Delete(const int slot_id) {
auto iter = impl_->items.find(slot_id);
if(iter == impl_->items.end()) {

View File

@ -35,6 +35,8 @@ namespace EQEmu
std::shared_ptr<ItemInstance> Get(const int slot_id);
bool Put(const int slot_id, std::shared_ptr<ItemInstance> inst);
bool Delete(const int slot_id);
uint32 Size();
uint32 Size() const;
bool Serialize(MemoryBuffer &buf, int container_number);
private:

View File

@ -30,8 +30,12 @@ struct EQEmu::ItemInstance::impl {
uint32 ornament_idfile_;
uint32 ornament_icon_;
uint32 ornament_hero_model_;
uint64 tracking_id_;
char tracking_id_[17];
uint32 serial_id_;
uint32 recast_timestamp_;
uint32 merchant_slot_;
uint32 merchant_count_;
uint32 price_;
ItemContainer contents_;
};
@ -45,8 +49,12 @@ EQEmu::ItemInstance::ItemInstance() {
impl_->ornament_idfile_ = 0;
impl_->ornament_icon_ = 0;
impl_->ornament_hero_model_ = 0;
impl_->serial_id_ = 0;
impl_->recast_timestamp_ = 0;
impl_->tracking_id_ = 0;
impl_->merchant_slot_ = 0;
impl_->merchant_count_ = 0;
impl_->price_ = 0;
memset(impl_->tracking_id_, 0, 17);
}
EQEmu::ItemInstance::ItemInstance(const ItemData* idata) {
@ -59,8 +67,12 @@ EQEmu::ItemInstance::ItemInstance(const ItemData* idata) {
impl_->ornament_idfile_ = 0;
impl_->ornament_icon_ = 0;
impl_->ornament_hero_model_ = 0;
impl_->serial_id_ = 0;
impl_->recast_timestamp_ = 0;
impl_->tracking_id_ = 0;
impl_->merchant_slot_ = 0;
impl_->merchant_count_ = 0;
impl_->price_ = 0;
memset(impl_->tracking_id_, 0, 17);
}
EQEmu::ItemInstance::ItemInstance(const ItemData* idata, int16 charges) {
@ -74,7 +86,11 @@ EQEmu::ItemInstance::ItemInstance(const ItemData* idata, int16 charges) {
impl_->ornament_icon_ = 0;
impl_->ornament_hero_model_ = 0;
impl_->recast_timestamp_ = 0;
impl_->tracking_id_ = 0;
impl_->serial_id_ = 0;
impl_->merchant_slot_ = 0;
impl_->merchant_count_ = 0;
impl_->price_ = 0;
memset(impl_->tracking_id_, 0, 17);
}
EQEmu::ItemInstance::~ItemInstance() {
@ -85,6 +101,10 @@ const ItemData *EQEmu::ItemInstance::GetItem() {
return impl_->modified_item_ ? impl_->modified_item_ : impl_->base_item_;
}
const ItemData *EQEmu::ItemInstance::GetBaseItem() {
return impl_->base_item_;
}
std::shared_ptr<EQEmu::ItemInstance> EQEmu::ItemInstance::Get(const int index) {
if(EQEmu::ValueWithin(index, 0, 255)) {
return impl_->contents_.Get(index);
@ -131,6 +151,22 @@ bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr<ItemInstance> ins
return false;
}
uint32 EQEmu::ItemInstance::GetSubItemCount() {
return impl_->contents_.Size();
}
uint32 EQEmu::ItemInstance::GetSubItemCount() const {
return impl_->contents_.Size();
}
int16 EQEmu::ItemInstance::GetCharges() {
return impl_->charges_;
}
int16 EQEmu::ItemInstance::GetCharges() const {
return impl_->charges_;
}
void EQEmu::ItemInstance::SetCharges(const int16 charges) {
impl_->charges_ = charges;
}
@ -139,6 +175,14 @@ void EQEmu::ItemInstance::SetColor(const uint32 color) {
impl_->color_ = color;
}
bool EQEmu::ItemInstance::GetAttuned() {
return impl_->attuned_;
}
bool EQEmu::ItemInstance::GetAttuned() const {
return impl_->attuned_;
}
void EQEmu::ItemInstance::SetAttuned(const bool attuned) {
impl_->attuned_ = attuned;
}
@ -160,10 +204,87 @@ void EQEmu::ItemInstance::SetOrnamentHeroModel(const uint32 ornament_hero_model)
impl_->ornament_hero_model_ = ornament_hero_model;
}
void EQEmu::ItemInstance::SetTrackingID(const uint64 tracking_id) {
impl_->tracking_id_ = tracking_id;
const char* EQEmu::ItemInstance::GetTrackingID() {
return impl_->tracking_id_;
}
const char* EQEmu::ItemInstance::GetTrackingID() const {
return impl_->tracking_id_;
}
void EQEmu::ItemInstance::SetTrackingID(const char *tracking_id) {
size_t len = strlen(tracking_id);
if(len > 16) {
return;
}
strncpy(impl_->tracking_id_, tracking_id, 16);
}
uint32 EQEmu::ItemInstance::GetRecastTimestamp() {
return impl_->recast_timestamp_;
}
uint32 EQEmu::ItemInstance::GetRecastTimestamp() const {
return impl_->recast_timestamp_;
}
void EQEmu::ItemInstance::SetRecastTimestamp(const uint32 recast_timestamp) {
impl_->recast_timestamp_ = recast_timestamp;
}
uint32 EQEmu::ItemInstance::GetMerchantSlot() {
return impl_->merchant_slot_;
}
uint32 EQEmu::ItemInstance::GetMerchantSlot() const {
return impl_->merchant_slot_;
}
void EQEmu::ItemInstance::SetMerchantSlot(uint32 slot) {
impl_->merchant_slot_ = slot;
}
uint32 EQEmu::ItemInstance::GetMerchantCount() {
return impl_->merchant_count_;
}
uint32 EQEmu::ItemInstance::GetMerchantCount() const {
return impl_->merchant_count_;
}
void EQEmu::ItemInstance::SetMerchantCount(const uint32 cnt) {
impl_->merchant_count_ = cnt;
}
uint32 EQEmu::ItemInstance::GetPrice() {
return impl_->price_;
}
uint32 EQEmu::ItemInstance::GetPrice() const {
return impl_->price_;
}
void EQEmu::ItemInstance::SetPrice(const uint32 p) {
impl_->price_ = p;
}
uint32 EQEmu::ItemInstance::GetSerialNumber() {
return impl_->serial_id_;
}
uint32 EQEmu::ItemInstance::GetSerialNumber() const {
return impl_->serial_id_;
}
void EQEmu::ItemInstance::SetSerialNumber(const uint32 sn) {
impl_->serial_id_ = sn;
}
bool EQEmu::ItemInstance::IsStackable() {
return impl_->base_item_->Stackable;
}
bool EQEmu::ItemInstance::IsStackable() const {
return impl_->base_item_->Stackable;
}

View File

@ -33,18 +33,59 @@ namespace EQEmu
~ItemInstance();
const ItemData *GetItem();
const ItemData *GetBaseItem();
//Container
std::shared_ptr<ItemInstance> Get(const int index);
bool Put(const int index, std::shared_ptr<ItemInstance> inst);
uint32 GetSubItemCount();
uint32 GetSubItemCount() const;
//Persistent State
int16 GetCharges();
int16 GetCharges() const;
void SetCharges(const int16 charges);
void SetColor(const uint32 color);
bool GetAttuned();
bool GetAttuned() const;
void SetAttuned(const bool attuned);
void SetCustomData(const std::string &custom_data);
void SetOrnamentIDFile(const uint32 ornament_idfile);
void SetOrnamentIcon(const uint32 ornament_icon);
void SetOrnamentHeroModel(const uint32 ornament_hero_model);
void SetTrackingID(const uint64 tracking_id);
const char* GetTrackingID();
const char* GetTrackingID() const;
void SetTrackingID(const char *tracking_id);
uint32 GetRecastTimestamp();
uint32 GetRecastTimestamp() const;
void SetRecastTimestamp(const uint32 recast_timestamp);
//Merchant
uint32 GetMerchantSlot();
uint32 GetMerchantSlot() const;
void SetMerchantSlot(const uint32 slot);
uint32 GetMerchantCount();
uint32 GetMerchantCount() const;
void SetMerchantCount(const uint32 cnt);
uint32 GetPrice();
uint32 GetPrice() const;
void SetPrice(const uint32 p);
//Serial Number
uint32 GetSerialNumber();
uint32 GetSerialNumber() const;
void SetSerialNumber(uint32 sn);
//Basic Stats
bool IsStackable();
bool IsStackable() const;
private:
struct impl;
impl *impl_;

View File

@ -28,6 +28,7 @@ namespace RoF2
char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth, ItemPacketType packet_type);
void SerializeItem(EQEmu::MemoryBuffer &packet_data, EQEmu::ItemInstance *inst, int container_id, int slot_id, int bag_id, int aug_id);
// server to client inventory location converters
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType = ItemPacketInvalid);
static inline structs::MainInvItemSlotStruct ServerToRoF2MainInvSlot(uint32 serverSlot);
@ -602,7 +603,6 @@ namespace RoF2
EQApplicationPacket *in = *p;
*p = nullptr;
in->SetReadPosition(0);
size_t entry_size = sizeof(int32) * 2 + sizeof(void*);
size_t entries = in->size / entry_size;
@ -613,7 +613,8 @@ namespace RoF2
return;
}
SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)in->pBuffer;
unsigned char *__emu_buffer = in->pBuffer;
SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)__emu_buffer;
EQEmu::MemoryBuffer packet_data;
packet_data.Write<uint32>(entries);
@ -624,75 +625,16 @@ namespace RoF2
continue;
}
//SerializeItem(packet_data, inst, sis[i].container_id, sis[i].slot_id, -1, -1, ItemPacketCharInventory);
// //SerializeItem((const EQEmu::ItemInstance*)
// //char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0, ItemPacketCharInventory);
SerializeItem(packet_data, inst, sis[i].container_id, sis[i].slot_id, -1, -1);
}
delete in;
in->pBuffer = new uchar[packet_data.Size()];
in->size = packet_data.Size();
memcpy(in->pBuffer, packet_data, in->size);
//if (in->size == 0) {
//
// in->size = 4;
// in->pBuffer = new uchar[in->size];
//
// *((uint32 *)in->pBuffer) = 0;
//
// dest->FastQueuePacket(&in, ack_req);
// return;
//}
//
////store away the emu struct
//unsigned char *__emu_buffer = in->pBuffer;
//
//int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
//
//if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
//
// Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
// opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(InternalSerializedItem_Struct));
//
// delete in;
//
// return;
//}
//
//InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
//
//in->pBuffer = new uchar[4];
//*(uint32 *)in->pBuffer = ItemCount;
//in->size = 4;
//
//for (int r = 0; r < ItemCount; r++, eq++) {
//
// uint32 Length = 0;
//
// char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0, ItemPacketCharInventory);
//
// if (Serialized) {
//
// uchar *OldBuffer = in->pBuffer;
// in->pBuffer = new uchar[in->size + Length];
// memcpy(in->pBuffer, OldBuffer, in->size);
//
// safe_delete_array(OldBuffer);
//
// memcpy(in->pBuffer + in->size, Serialized, Length);
// in->size += Length;
//
// safe_delete_array(Serialized);
// }
// else {
// Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
// }
//}
//
//delete[] __emu_buffer;
//
////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
////Log.Hex(Logs::Netcode, in->pBuffer, in->size);
//
//dest->FastQueuePacket(&in, ack_req);
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ClickObjectAction)
@ -1549,31 +1491,33 @@ namespace RoF2
ENCODE(OP_ItemPacket)
{
//consume the packet
EQApplicationPacket *in = *p;
*p = nullptr;
delete *p;
unsigned char *__emu_buffer = in->pBuffer;
ItemPacket_Struct *old_item_pkt = (ItemPacket_Struct *)__emu_buffer;
InternalSerializedItem_Struct *int_struct = (InternalSerializedItem_Struct *)(old_item_pkt->SerializedItem);
uint32 length;
char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0, old_item_pkt->PacketType);
if (!serialized) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in;
return;
}
in->size = length + 4;
in->pBuffer = new unsigned char[in->size];
ItemPacket_Struct *new_item_pkt = (ItemPacket_Struct *)in->pBuffer;
new_item_pkt->PacketType = old_item_pkt->PacketType;
memcpy(new_item_pkt->SerializedItem, serialized, length);
delete[] __emu_buffer;
safe_delete_array(serialized);
dest->FastQueuePacket(&in, ack_req);
////consume the packet
//EQApplicationPacket *in = *p;
//*p = nullptr;
//
//unsigned char *__emu_buffer = in->pBuffer;
//ItemPacket_Struct *old_item_pkt = (ItemPacket_Struct *)__emu_buffer;
//InternalSerializedItem_Struct *int_struct = (InternalSerializedItem_Struct *)(old_item_pkt->SerializedItem);
//
//uint32 length;
//char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0, old_item_pkt->PacketType);
//
//if (!serialized) {
// Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
// delete in;
// return;
//}
//in->size = length + 4;
//in->pBuffer = new unsigned char[in->size];
//ItemPacket_Struct *new_item_pkt = (ItemPacket_Struct *)in->pBuffer;
//new_item_pkt->PacketType = old_item_pkt->PacketType;
//memcpy(new_item_pkt->SerializedItem, serialized, length);
//
//delete[] __emu_buffer;
//safe_delete_array(serialized);
//dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ItemVerifyReply)
@ -5258,7 +5202,7 @@ namespace RoF2
//sprintf(hdr.unknown000, "06e0002Y1W00");
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%016d", item->ID);
snprintf(hdr.tracking_id, sizeof(hdr.tracking_id), "%016d", item->ID);
hdr.stacksize = stackable ? charges : 1;
hdr.unknown004 = 0;
@ -5794,6 +5738,499 @@ namespace RoF2
return item_serial;
}
void SerializeItem(EQEmu::MemoryBuffer &packet_data, EQEmu::ItemInstance *inst, int container_id, int slot_id, int bag_id, int aug_id) {
int ornamentation_augtype = RuleI(Character, OrnamentationAugmentType);
uint8 null_term = 0;
bool stackable = inst->IsStackable();
uint32 merchant_slot = inst->GetMerchantSlot();
uint32 charges = inst->GetCharges();
const ItemData *item = inst->GetBaseItem();
RoF2::structs::ItemSerializationHeader hdr;
snprintf(hdr.tracking_id, sizeof(hdr.tracking_id), "%016d", inst->GetSerialNumber());
hdr.stacksize = stackable ? charges : 1;
hdr.unknown004 = 0;
hdr.slot_type = (merchant_slot == 0) ? container_id : 9; // 9 is merchant 20 is reclaim items?
hdr.main_slot = (merchant_slot == 0) ? slot_id : merchant_slot;
hdr.sub_slot = (merchant_slot == 0) ? bag_id : 0xffff;
hdr.aug_slot = (merchant_slot == 0) ? aug_id : 0xffff;
hdr.price = inst->GetPrice();
hdr.merchant_slot = (merchant_slot == 0) ? 1 : inst->GetMerchantCount();
//hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
hdr.scaled_value = 0;
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
hdr.unknown028 = 0;
hdr.last_cast_time = inst->GetRecastTimestamp();
hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
hdr.inst_nodrop = inst->GetAttuned() ? 1 : 0;
hdr.unknown044 = 0;
hdr.unknown048 = 0;
hdr.unknown052 = 0;
hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0;
packet_data.Write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader));
if(item->EvolvingLevel > 0) {
RoF2::structs::EvolvingItem evotop;
evotop.unknown001 = 0;
evotop.unknown002 = 0;
evotop.unknown003 = 0;
evotop.unknown004 = 0;
evotop.evoLevel = item->EvolvingLevel;
evotop.progress = 95.512;
evotop.Activated = 1;
evotop.evomaxlevel = 7;
packet_data.Write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem));
}
uint32 orn_icon = 0;
uint32 hero_model = 0;
//if(inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon())
//{
// char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
// //Mainhand
// packet_data.Write(tmp, strlen(tmp));
// packet_data.Write((const char*)&null_term, sizeof(uint8));
// //Offhand
// ss.write(tmp, strlen(tmp));
// ss.write((const char*)&null_term, sizeof(uint8));
// orn_icon = inst->GetOrnamentationIcon();
// hero_model = inst->GetOrnamentHeroModel(InventoryOld::CalcMaterialFromSlot(slot_id_in));
//}
//else
//{
packet_data.Write((const char*)&null_term, sizeof(uint8)); // no main hand Ornamentation
packet_data.Write((const char*)&null_term, sizeof(uint8)); // no off hand Ornamentation
//}
RoF2::structs::ItemSerializationHeaderFinish hdrf;
hdrf.ornamentIcon = orn_icon;
hdrf.unknowna1 = 0xffffffff;
hdrf.ornamentHeroModel = hero_model;
hdrf.unknown063 = 0;
hdrf.Copied = 0;
hdrf.unknowna4 = 0xffffffff;
hdrf.unknowna5 = 0;
hdrf.ItemClass = item->ItemClass;
packet_data.Write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish));
if(strlen(item->Name) > 0)
{
packet_data.Write(item->Name, strlen(item->Name));
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
else
{
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
if(strlen(item->Lore) > 0)
{
packet_data.Write(item->Lore, strlen(item->Lore));
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
else
{
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
if(strlen(item->IDFile) > 0)
{
packet_data.Write(item->IDFile, strlen(item->IDFile));
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
else
{
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
packet_data.Write((const char*)&null_term, sizeof(uint8));
RoF2::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(RoF2::structs::ItemBodyStruct));
ibs.id = item->ID;
ibs.weight = item->Weight;
ibs.norent = item->NoRent;
ibs.nodrop = item->NoDrop;
ibs.attune = item->Attuneable;
ibs.size = item->Size;
ibs.slots = SwapBits21and22(item->Slots);
ibs.price = item->Price;
ibs.icon = item->Icon;
ibs.unknown1 = 1;
ibs.unknown2 = 1;
ibs.BenefitFlag = item->BenefitFlag;
ibs.tradeskills = item->Tradeskills;
ibs.CR = item->CR;
ibs.DR = item->DR;
ibs.PR = item->PR;
ibs.MR = item->MR;
ibs.FR = item->FR;
ibs.SVCorruption = item->SVCorruption;
ibs.AStr = item->AStr;
ibs.ASta = item->ASta;
ibs.AAgi = item->AAgi;
ibs.ADex = item->ADex;
ibs.ACha = item->ACha;
ibs.AInt = item->AInt;
ibs.AWis = item->AWis;
ibs.HP = item->HP;
ibs.Mana = item->Mana;
ibs.Endur = item->Endur;
ibs.AC = item->AC;
ibs.regen = item->Regen;
ibs.mana_regen = item->ManaRegen;
ibs.end_regen = item->EnduranceRegen;
ibs.Classes = item->Classes;
ibs.Races = item->Races;
ibs.Deity = item->Deity;
ibs.SkillModValue = item->SkillModValue;
ibs.SkillModMax = 0xffffffff;
ibs.SkillModType = (int8)(item->SkillModType);
ibs.SkillModExtra = 0;
ibs.BaneDmgRace = item->BaneDmgRace;
ibs.BaneDmgBody = item->BaneDmgBody;
ibs.BaneDmgRaceAmt = item->BaneDmgRaceAmt;
ibs.BaneDmgAmt = item->BaneDmgAmt;
ibs.Magic = item->Magic;
ibs.CastTime_ = item->CastTime_;
ibs.ReqLevel = item->ReqLevel;
if(item->ReqLevel > 100)
ibs.ReqLevel = 100;
ibs.RecLevel = item->RecLevel;
if(item->RecLevel > 100)
ibs.RecLevel = 100;
ibs.RecSkill = item->RecSkill;
ibs.BardType = item->BardType;
ibs.BardValue = item->BardValue;
ibs.Light = item->Light;
ibs.Delay = item->Delay;
ibs.ElemDmgType = item->ElemDmgType;
ibs.ElemDmgAmt = item->ElemDmgAmt;
ibs.Range = item->Range;
ibs.Damage = item->Damage;
ibs.Color = item->Color;
ibs.Prestige = 0;
ibs.ItemType = item->ItemType;
ibs.Material = item->Material;
ibs.MaterialUnknown1 = 0;
ibs.EliteMaterial = item->EliteMaterial;
ibs.HerosForgeModel = item->HerosForgeModel;
ibs.MaterialUnknown2 = 0;
ibs.SellRate = item->SellRate;
ibs.CombatEffects = item->CombatEffects;
ibs.Shielding = item->Shielding;
ibs.StunResist = item->StunResist;
ibs.StrikeThrough = item->StrikeThrough;
ibs.ExtraDmgSkill = item->ExtraDmgSkill;
ibs.ExtraDmgAmt = item->ExtraDmgAmt;
ibs.SpellShield = item->SpellShield;
ibs.Avoidance = item->Avoidance;
ibs.Accuracy = item->Accuracy;
ibs.CharmFileID = item->CharmFileID;
ibs.FactionAmt1 = item->FactionAmt1;
ibs.FactionMod1 = item->FactionMod1;
ibs.FactionAmt2 = item->FactionAmt2;
ibs.FactionMod2 = item->FactionMod2;
ibs.FactionAmt3 = item->FactionAmt3;
ibs.FactionMod3 = item->FactionMod3;
ibs.FactionAmt4 = item->FactionAmt4;
ibs.FactionMod4 = item->FactionMod4;
packet_data.Write((const char*)&ibs, sizeof(RoF2::structs::ItemBodyStruct));
//charm text
if(strlen(item->CharmFile) > 0)
{
packet_data.Write((const char*)item->CharmFile, strlen(item->CharmFile));
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
else
{
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody secondary struct is %i bytes", sizeof(RoF2::structs::ItemSecondaryBodyStruct));
RoF2::structs::ItemSecondaryBodyStruct isbs;
memset(&isbs, 0, sizeof(RoF2::structs::ItemSecondaryBodyStruct));
isbs.augtype = item->AugType;
isbs.augrestrict2 = -1;
isbs.augrestrict = item->AugRestrict;
for(int x = AUG_BEGIN; x < consts::ITEM_COMMON_SIZE; x++)
{
isbs.augslots[x].type = item->AugSlotType[x];
isbs.augslots[x].visible = item->AugSlotVisible[x];
isbs.augslots[x].unknown = item->AugSlotUnk2[x];
}
isbs.ldonpoint_type = item->PointType;
isbs.ldontheme = item->LDoNTheme;
isbs.ldonprice = item->LDoNPrice;
isbs.ldonsellbackrate = item->LDoNSellBackRate;
isbs.ldonsold = item->LDoNSold;
isbs.bagtype = item->BagType;
isbs.bagslots = item->BagSlots;
isbs.bagsize = item->BagSize;
isbs.wreduction = item->BagWR;
isbs.book = item->Book;
isbs.booktype = item->BookType;
packet_data.Write((const char*)&isbs, sizeof(RoF2::structs::ItemSecondaryBodyStruct));
if(strlen(item->Filename) > 0)
{
packet_data.Write((const char*)item->Filename, strlen(item->Filename));
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
else
{
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody tertiary struct is %i bytes", sizeof(RoF2::structs::ItemTertiaryBodyStruct));
RoF2::structs::ItemTertiaryBodyStruct itbs;
memset(&itbs, 0, sizeof(RoF2::structs::ItemTertiaryBodyStruct));
itbs.loregroup = item->LoreGroup;
itbs.artifact = item->ArtifactFlag;
itbs.summonedflag = item->SummonedFlag;
itbs.favor = item->Favor;
itbs.fvnodrop = item->FVNoDrop;
itbs.dotshield = item->DotShielding;
itbs.atk = item->Attack;
itbs.haste = item->Haste;
itbs.damage_shield = item->DamageShield;
itbs.guildfavor = item->GuildFavor;
itbs.augdistil = item->AugDistiller;
itbs.unknown3 = 0xffffffff;
itbs.unknown4 = 0;
itbs.no_pet = item->NoPet;
itbs.unknown5 = 0;
itbs.potion_belt_enabled = item->PotionBelt;
itbs.potion_belt_slots = item->PotionBeltSlots;
itbs.stacksize = stackable ? item->StackSize : 0;
itbs.no_transfer = item->NoTransfer;
itbs.expendablearrow = item->ExpendableArrow;
itbs.unknown8 = 0;
itbs.unknown9 = 0;
itbs.unknown10 = 0;
itbs.unknown11 = 0;
itbs.unknown12 = 0;
itbs.unknown13 = 0;
itbs.unknown14 = 0;
packet_data.Write((const char*)&itbs, sizeof(RoF2::structs::ItemTertiaryBodyStruct));
// Effect Structures Broken down to allow variable length strings for effect names
int32 effect_unknown = 0;
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Click effect struct is %i bytes", sizeof(RoF2::structs::ClickEffectStruct));
RoF2::structs::ClickEffectStruct ices;
memset(&ices, 0, sizeof(RoF2::structs::ClickEffectStruct));
ices.effect = item->Click.Effect;
ices.level2 = item->Click.Level2;
ices.type = item->Click.Type;
ices.level = item->Click.Level;
ices.max_charges = item->MaxCharges;
ices.cast_time = item->CastTime;
ices.recast = item->RecastDelay;
ices.recast_type = item->RecastType;
packet_data.Write((const char*)&ices, sizeof(RoF2::structs::ClickEffectStruct));
if(strlen(item->ClickName) > 0)
{
packet_data.Write((const char*)item->ClickName, strlen(item->ClickName));
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
else
{
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // clickunk7
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody proc effect struct is %i bytes", sizeof(RoF2::structs::ProcEffectStruct));
RoF2::structs::ProcEffectStruct ipes;
memset(&ipes, 0, sizeof(RoF2::structs::ProcEffectStruct));
ipes.effect = item->Proc.Effect;
ipes.level2 = item->Proc.Level2;
ipes.type = item->Proc.Type;
ipes.level = item->Proc.Level;
ipes.procrate = item->ProcRate;
packet_data.Write((const char*)&ipes, sizeof(RoF2::structs::ProcEffectStruct));
if(strlen(item->ProcName) > 0)
{
packet_data.Write((const char*)item->ProcName, strlen(item->ProcName));
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
else
{
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown5
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody worn effect struct is %i bytes", sizeof(RoF2::structs::WornEffectStruct));
RoF2::structs::WornEffectStruct iwes;
memset(&iwes, 0, sizeof(RoF2::structs::WornEffectStruct));
iwes.effect = item->Worn.Effect;
iwes.level2 = item->Worn.Level2;
iwes.type = item->Worn.Type;
iwes.level = item->Worn.Level;
packet_data.Write((const char*)&iwes, sizeof(RoF2::structs::WornEffectStruct));
if(strlen(item->WornName) > 0)
{
packet_data.Write((const char*)item->WornName, strlen(item->WornName));
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
else
{
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6
RoF2::structs::WornEffectStruct ifes;
memset(&ifes, 0, sizeof(RoF2::structs::WornEffectStruct));
ifes.effect = item->Focus.Effect;
ifes.level2 = item->Focus.Level2;
ifes.type = item->Focus.Type;
ifes.level = item->Focus.Level;
packet_data.Write((const char*)&ifes, sizeof(RoF2::structs::WornEffectStruct));
if(strlen(item->FocusName) > 0)
{
packet_data.Write((const char*)item->FocusName, strlen(item->FocusName));
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
else
{
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6
RoF2::structs::WornEffectStruct ises;
memset(&ises, 0, sizeof(RoF2::structs::WornEffectStruct));
ises.effect = item->Scroll.Effect;
ises.level2 = item->Scroll.Level2;
ises.type = item->Scroll.Type;
ises.level = item->Scroll.Level;
packet_data.Write((const char*)&ises, sizeof(RoF2::structs::WornEffectStruct));
if(strlen(item->ScrollName) > 0)
{
packet_data.Write((const char*)item->ScrollName, strlen(item->ScrollName));
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
else
{
packet_data.Write((const char*)&null_term, sizeof(uint8));
}
packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// Bard Effect?
RoF2::structs::WornEffectStruct ibes;
memset(&ibes, 0, sizeof(RoF2::structs::WornEffectStruct));
ibes.effect = item->Bard.Effect;
ibes.level2 = item->Bard.Level2;
ibes.type = item->Bard.Type;
ibes.level = item->Bard.Level;
//ibes.unknown6 = 0xffffffff;
packet_data.Write((const char*)&ibes, sizeof(RoF2::structs::WornEffectStruct));
packet_data.Write((const char*)&null_term, sizeof(uint8));
packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// End of Effects
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Quaternary effect struct is %i bytes", sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
RoF2::structs::ItemQuaternaryBodyStruct iqbs;
memset(&iqbs, 0, sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
iqbs.scriptfileid = item->ScriptFileID;
iqbs.quest_item = item->QuestItemFlag;
iqbs.Power = 0;
iqbs.Purity = item->Purity;
iqbs.unknown16 = 0;
iqbs.BackstabDmg = item->BackstabDmg;
iqbs.DSMitigation = item->DSMitigation;
iqbs.HeroicStr = item->HeroicStr;
iqbs.HeroicInt = item->HeroicInt;
iqbs.HeroicWis = item->HeroicWis;
iqbs.HeroicAgi = item->HeroicAgi;
iqbs.HeroicDex = item->HeroicDex;
iqbs.HeroicSta = item->HeroicSta;
iqbs.HeroicCha = item->HeroicCha;
iqbs.HeroicMR = item->HeroicMR;
iqbs.HeroicFR = item->HeroicFR;
iqbs.HeroicCR = item->HeroicCR;
iqbs.HeroicDR = item->HeroicDR;
iqbs.HeroicPR = item->HeroicPR;
iqbs.HeroicSVCorrup = item->HeroicSVCorrup;
iqbs.HealAmt = item->HealAmt;
iqbs.SpellDmg = item->SpellDmg;
iqbs.clairvoyance = item->Clairvoyance;
//unknown18; //Power Source Capacity or evolve filename?
//evolve_string; // Some String, but being evolution related is just a guess
iqbs.Heirloom = 0;
iqbs.Placeable = 0;
iqbs.unknown28 = -1;
iqbs.unknown30 = -1;
iqbs.NoZone = 0;
iqbs.NoGround = 0;
iqbs.unknown37a = 0; // (guessed position) New to RoF2
iqbs.unknown38 = 0;
iqbs.unknown39 = 1;
iqbs.subitem_count = inst->GetSubItemCount();
packet_data.Write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
for(int x = 0; x < 255; ++x) {
auto sub_inst = inst->Get(x);
if(sub_inst) {
packet_data.Write((const char*)&x, sizeof(uint32));
SerializeItem(packet_data, sub_inst.get(), container_id, slot_id, x, -1);
}
}
}
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType)
{
structs::ItemSlotStruct RoF2Slot;

View File

@ -4407,7 +4407,7 @@ struct RoF2SlotStruct
struct ItemSerializationHeader
{
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
/*000*/ char tracking_id[17]; // New for HoT. Looks like a string.
/*017*/ uint32 stacksize;
/*021*/ uint32 unknown004;
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?

View File

@ -15,6 +15,14 @@
#include "shareddb.h"
#include "string_util.h"
uint32 ItemInstanceSerial = 1;
static inline uint32 GetNextItemInstanceSerial() {
ItemInstanceSerial++;
return ItemInstanceSerial;
}
SharedDatabase::SharedDatabase()
: Database(), skill_caps_mmf(nullptr), items_mmf(nullptr), items_hash(nullptr), faction_mmf(nullptr), faction_hash(nullptr),
loot_table_mmf(nullptr), loot_table_hash(nullptr), loot_drop_mmf(nullptr), loot_drop_hash(nullptr), base_data_mmf(nullptr)
@ -516,7 +524,6 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::Inventory *inv)
uint32 ornament_icon = (uint32)std::stoul(row[9]);
uint32 ornament_idfile = (uint32)std::stoul(row[10]);
uint32 ornament_hero_model = (uint32)std::stoul(row[11]);
uint64 tracking_id = (uint64)std::stoull(row[12]);
inst->SetColor(color);
inst->SetAttuned(attuned ? true : false);
@ -524,7 +531,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::Inventory *inv)
inst->SetOrnamentIcon(ornament_icon);
inst->SetOrnamentIDFile(ornament_idfile);
inst->SetOrnamentHeroModel(ornament_hero_model);
inst->SetTrackingID(tracking_id);
inst->SetTrackingID(row[12]);
auto *item = inst->GetItem();
if(item->RecastDelay) {
@ -1265,7 +1272,9 @@ std::shared_ptr<EQEmu::ItemInstance> SharedDatabase::CreateItem(uint32 item_id,
charges = 1;
}
return std::shared_ptr<EQEmu::ItemInstance>(new EQEmu::ItemInstance(item, charges));
std::shared_ptr<EQEmu::ItemInstance> inst = std::shared_ptr<EQEmu::ItemInstance>(new EQEmu::ItemInstance(item, charges));
inst->SetSerialNumber(GetNextItemInstanceSerial());
return inst;
}
return std::shared_ptr<EQEmu::ItemInstance>(nullptr);