Added serialization differentiation

This commit is contained in:
KimLS 2015-02-25 19:36:10 -08:00
parent c62cff1ce7
commit 215861dd86
14 changed files with 236 additions and 628 deletions

View File

@ -31,10 +31,11 @@ SET(common_sources
guild_base.cpp
guilds.cpp
inventory.cpp
inventory_database_controller.cpp
ipc_mutex.cpp
item.cpp
item_container.cpp
item_container_default_serialization.cpp
item_container_personal_serialization.cpp
item_instance.cpp
md5.cpp
memory_buffer.cpp
@ -141,10 +142,12 @@ SET(common_headers
guild_base.h
guilds.h
inventory.h
inventory_database_controller.h
ipc_mutex.h
item.h
item_container.h
item_container_default_serialization.h
item_container_personal_serialization.h
item_container_serialization_strategy.h
item_data.h
item_fieldlist.h
item_instance.h

View File

@ -18,6 +18,7 @@
#include "inventory.h"
#include "data_verification.h"
#include "item_container_personal_serialization.h"
#include <map>
struct EQEmu::Inventory::impl
@ -58,7 +59,11 @@ std::shared_ptr<EQEmu::ItemInstance> EQEmu::Inventory::Get(const InventorySlot &
bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst) {
if(impl_->containers_.count(slot.type_) == 0) {
impl_->containers_.insert(std::pair<int, ItemContainer>(slot.type_, ItemContainer()));
if(slot.type_ == 0) {
impl_->containers_.insert(std::pair<int, ItemContainer>(slot.type_, ItemContainer(new ItemContainerPersonalSerialization())));
} else {
impl_->containers_.insert(std::pair<int, ItemContainer>(slot.type_, ItemContainer()));
}
}
//Verify item can be put into the slot requested

View File

@ -1,24 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_INVENTORY_DATABASE_CONTROLLER_H
#define COMMON_INVENTORY_DATABASE_CONTROLLER_H
#endif

View File

@ -1,21 +1,30 @@
#include "item_container.h"
#include <map>
#include "item_container_default_serialization.h"
#include <utility>
struct EQEmu::ItemContainer::impl
{
std::map<int, std::shared_ptr<ItemInstance>> items;
std::map<int, std::shared_ptr<ItemInstance>> items_;
ItemContainerSerializationStrategy *serialize_strat_;
};
EQEmu::ItemContainer::ItemContainer()
{
impl_ = new impl();
impl_->serialize_strat_ = new ItemContainerDefaultSerialization();
}
EQEmu::ItemContainer::ItemContainer(ItemContainerSerializationStrategy *strategy) {
impl_ = new impl();
impl_->serialize_strat_ = strategy;
}
EQEmu::ItemContainer::~ItemContainer()
{
if(impl_)
if(impl_) {
delete impl_->serialize_strat_;
delete impl_;
}
}
EQEmu::ItemContainer::ItemContainer(ItemContainer &&other) {
@ -23,9 +32,18 @@ EQEmu::ItemContainer::ItemContainer(ItemContainer &&other) {
other.impl_ = nullptr;
}
EQEmu::ItemContainer& EQEmu::ItemContainer::operator=(ItemContainer &&other) {
if(this == &other)
return *this;
impl_ = other.impl_;
other.impl_ = nullptr;
return *this;
}
std::shared_ptr<EQEmu::ItemInstance> EQEmu::ItemContainer::Get(const int slot_id) {
auto iter = impl_->items.find(slot_id);
if(iter != impl_->items.end()) {
auto iter = impl_->items_.find(slot_id);
if(iter != impl_->items_.end()) {
return iter->second;
}
@ -36,10 +54,9 @@ bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr<ItemInstance>
if(!inst)
return false;
auto iter = impl_->items.find(slot_id);
if(iter == impl_->items.end()) {
impl_->items[slot_id] = inst;
//trigger insert in slot_id
auto iter = impl_->items_.find(slot_id);
if(iter == impl_->items_.end()) {
impl_->items_[slot_id] = inst;
return true;
}
@ -47,34 +64,35 @@ bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr<ItemInstance>
}
uint32 EQEmu::ItemContainer::Size() {
return impl_->items.size();
return (uint32)impl_->items_.size();
}
uint32 EQEmu::ItemContainer::Size() const {
return impl_->items.size();
return (uint32)impl_->items_.size();
}
bool EQEmu::ItemContainer::Delete(const int slot_id) {
auto iter = impl_->items.find(slot_id);
if(iter == impl_->items.end()) {
auto iter = impl_->items_.find(slot_id);
if(iter == impl_->items_.end()) {
return false;
} else {
impl_->items.erase(iter);
//trigger delete in slotid
impl_->items_.erase(iter);
return true;
}
}
bool EQEmu::ItemContainer::Serialize(MemoryBuffer &buf, int container_number) {
if(impl_->items.size() == 0) {
return false;
if(impl_->serialize_strat_) {
return impl_->serialize_strat_->Serialize(buf, container_number, impl_->items_);
}
for(auto &iter : impl_->items) {
buf.Write<int32>(container_number);
buf.Write<int32>(iter.first);
buf.Write<void*>(iter.second.get());
}
return false;
}
return true;
}
EQEmu::ItemContainer::ItemContainerIter EQEmu::ItemContainer::Begin() {
return impl_->items_.begin();
}
EQEmu::ItemContainer::ItemContainerIter EQEmu::ItemContainer::End() {
return impl_->items_.end();
}

View File

@ -20,17 +20,24 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define COMMON_ITEM_CONTAINER_H
#include "item_instance.h"
#include "item_container_serialization_strategy.h"
#include "memory_buffer.h"
#include <memory>
#include <map>
namespace EQEmu
{
class ItemContainerSerializationStrategy;
class ItemContainer
{
public:
typedef std::map<int, std::shared_ptr<ItemInstance>>::const_iterator ItemContainerIter;
ItemContainer();
ItemContainer(ItemContainerSerializationStrategy *strategy);
~ItemContainer();
ItemContainer(ItemContainer &&other);
ItemContainer& operator=(ItemContainer &&other);
std::shared_ptr<ItemInstance> Get(const int slot_id);
bool Put(const int slot_id, std::shared_ptr<ItemInstance> inst);
@ -38,13 +45,17 @@ namespace EQEmu
uint32 Size();
uint32 Size() const;
//Low level interface for encode/decode
bool Serialize(MemoryBuffer &buf, int container_number);
ItemContainerIter Begin();
ItemContainerIter End();
protected:
struct impl;
impl *impl_;
private:
ItemContainer(const ItemContainer &other);
ItemContainer& operator=(const ItemContainer &other);
struct impl;
impl *impl_;
};
} // EQEmu

View File

@ -0,0 +1,17 @@
#include "item_container_default_serialization.h"
bool EQEmu::ItemContainerDefaultSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, std::shared_ptr<ItemInstance>>& items) {
if(items.size() == 0) {
return false;
}
bool ret = false;
for(auto &iter : items) {
buf.Write<int32>(container_number);
buf.Write<int32>(iter.first);
buf.Write<void*>(iter.second.get());
ret = true;
}
return ret;
}

View File

@ -0,0 +1,35 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_ITEM_CONTAINER_DEFAULT_SERIALIZATION_H
#define COMMON_ITEM_CONTAINER_DEFAULT_SERIALIZATION_H
#include "item_container_serialization_strategy.h"
namespace EQEmu
{
class ItemContainerDefaultSerialization : public ItemContainerSerializationStrategy
{
public:
ItemContainerDefaultSerialization() { }
virtual ~ItemContainerDefaultSerialization() { }
virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, std::shared_ptr<ItemInstance>>& items);
};
} // EQEmu
#endif

View File

@ -0,0 +1,19 @@
#include "item_container_personal_serialization.h"
bool EQEmu::ItemContainerPersonalSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, std::shared_ptr<ItemInstance>>& items) {
if(items.size() == 0) {
return false;
}
bool ret = false;
for(auto &iter : items) {
if(iter.first < 33) {
buf.Write<int32>(container_number);
buf.Write<int32>(iter.first);
buf.Write<void*>(iter.second.get());
ret = true;
}
}
return ret;
}

View File

@ -0,0 +1,35 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_ITEM_CONTAINER_PERSONAL_SERIALIZATION_H
#define COMMON_ITEM_CONTAINER_PERSONAL_SERIALIZATION_H
#include "item_container_serialization_strategy.h"
namespace EQEmu
{
class ItemContainerPersonalSerialization : public ItemContainerSerializationStrategy
{
public:
ItemContainerPersonalSerialization() { }
virtual ~ItemContainerPersonalSerialization() { }
virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, std::shared_ptr<ItemInstance>>& items);
};
} // EQEmu
#endif

View File

@ -0,0 +1,37 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_ITEM_CONTAINER_SERIALIZATION_STRATEGY_H
#define COMMON_ITEM_CONTAINER_SERIALIZATION_STRATEGY_H
#include "item_container.h"
#include "memory_buffer.h"
#include <map>
namespace EQEmu
{
class ItemContainerSerializationStrategy
{
public:
ItemContainerSerializationStrategy() { }
virtual ~ItemContainerSerializationStrategy() { }
virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map<int, std::shared_ptr<ItemInstance>>& items) = 0;
};
} // EQEmu
#endif

View File

@ -151,14 +151,6 @@ 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_;
}
@ -330,3 +322,7 @@ bool EQEmu::ItemInstance::IsStackable() {
bool EQEmu::ItemInstance::IsStackable() const {
return impl_->base_item_->Stackable;
}
EQEmu::ItemContainer *EQEmu::ItemInstance::GetContainer() {
return &(impl_->contents_);
}

View File

@ -24,6 +24,7 @@
namespace EQEmu
{
class ItemContainer;
class ItemInstance
{
public:
@ -38,8 +39,6 @@ namespace EQEmu
//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();
@ -95,6 +94,10 @@ namespace EQEmu
//Basic Stats
bool IsStackable();
bool IsStackable() const;
//Internal state
//Used for low level operations such as encode/decode
ItemContainer *GetContainer();
private:
struct impl;
impl *impl_;

View File

@ -5193,561 +5193,6 @@ namespace RoF2
return NextItemInstSerialNumber;
}
//char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth, ItemPacketType packet_type)
//{
// int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
// uint8 null_term = 0;
// bool stackable = inst->IsStackable();
// uint32 merchant_slot = inst->GetMerchantSlot();
// uint32 charges = inst->GetCharges();
// if (!stackable && charges > 254)
// charges = 0xFFFFFFFF;
//
// std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
//
// const ItemData *item = inst->GetUnscaledItem();
// //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name);
//
// RoF2::structs::ItemSerializationHeader hdr;
//
// //sprintf(hdr.unknown000, "06e0002Y1W00");
//
// snprintf(hdr.tracking_id, sizeof(hdr.tracking_id), "%016d", item->ID);
//
// hdr.stacksize = stackable ? charges : 1;
// hdr.unknown004 = 0;
//
// structs::ItemSlotStruct slot_id = ServerToRoF2Slot(slot_id_in, packet_type);
//
// hdr.slot_type = (merchant_slot == 0) ? slot_id.SlotType : 9; // 9 is merchant 20 is reclaim items?
// hdr.main_slot = (merchant_slot == 0) ? slot_id.MainSlot : merchant_slot;
// hdr.sub_slot = (merchant_slot == 0) ? slot_id.SubSlot : 0xffff;
// hdr.aug_slot = (merchant_slot == 0) ? slot_id.AugSlot : 0xffff;
// hdr.price = inst->GetPrice();
// hdr.merchant_slot = (merchant_slot == 0) ? 1 : inst->GetMerchantCount();
// hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 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->IsAttuned() ? 1 : 0;
// hdr.unknown044 = 0;
// hdr.unknown048 = 0;
// hdr.unknown052 = 0;
// hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0;
// ss.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;
// ss.write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem));
// }
// //ORNAMENT IDFILE / ICON
// uint32 ornaIcon = 0;
// uint32 heroModel = 0;
//
// if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon())
// {
// char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
// //Mainhand
// ss.write(tmp, strlen(tmp));
// ss.write((const char*)&null_term, sizeof(uint8));
// //Offhand
// ss.write(tmp, strlen(tmp));
// ss.write((const char*)&null_term, sizeof(uint8));
// ornaIcon = inst->GetOrnamentationIcon();
// heroModel = inst->GetOrnamentHeroModel(InventoryOld::CalcMaterialFromSlot(slot_id_in));
// }
// else
// {
// ss.write((const char*)&null_term, sizeof(uint8)); // no main hand Ornamentation
// ss.write((const char*)&null_term, sizeof(uint8)); // no off hand Ornamentation
// }
//
// RoF2::structs::ItemSerializationHeaderFinish hdrf;
// hdrf.ornamentIcon = ornaIcon;
// hdrf.unknowna1 = 0xffffffff;
// hdrf.ornamentHeroModel = heroModel;
// hdrf.unknown063 = 0;
// hdrf.Copied = 0;
// hdrf.unknowna4 = 0xffffffff;
// hdrf.unknowna5 = 0;
// hdrf.ItemClass = item->ItemClass;
//
// ss.write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish));
//
// if (strlen(item->Name) > 0)
// {
// ss.write(item->Name, strlen(item->Name));
// ss.write((const char*)&null_term, sizeof(uint8));
// }
// else
// {
// ss.write((const char*)&null_term, sizeof(uint8));
// }
//
// if (strlen(item->Lore) > 0)
// {
// ss.write(item->Lore, strlen(item->Lore));
// ss.write((const char*)&null_term, sizeof(uint8));
// }
// else
// {
// ss.write((const char*)&null_term, sizeof(uint8));
// }
//
// if (strlen(item->IDFile) > 0)
// {
// ss.write(item->IDFile, strlen(item->IDFile));
// ss.write((const char*)&null_term, sizeof(uint8));
// }
// else
// {
// ss.write((const char*)&null_term, sizeof(uint8));
// }
//
// ss.write((const char*)&null_term, sizeof(uint8));
// //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody struct is %i bytes", sizeof(RoF2::structs::ItemBodyStruct));
// 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;
//
// ss.write((const char*)&ibs, sizeof(RoF2::structs::ItemBodyStruct));
//
// //charm text
// if (strlen(item->CharmFile) > 0)
// {
// ss.write((const char*)item->CharmFile, strlen(item->CharmFile));
// ss.write((const char*)&null_term, sizeof(uint8));
// }
// else
// {
// ss.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;
//
// ss.write((const char*)&isbs, sizeof(RoF2::structs::ItemSecondaryBodyStruct));
//
// if (strlen(item->Filename) > 0)
// {
// ss.write((const char*)item->Filename, strlen(item->Filename));
// ss.write((const char*)&null_term, sizeof(uint8));
// }
// else
// {
// ss.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;
//
// ss.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;
//
// ss.write((const char*)&ices, sizeof(RoF2::structs::ClickEffectStruct));
//
// if (strlen(item->ClickName) > 0)
// {
// ss.write((const char*)item->ClickName, strlen(item->ClickName));
// ss.write((const char*)&null_term, sizeof(uint8));
// }
// else
// {
// ss.write((const char*)&null_term, sizeof(uint8));
// }
//
// ss.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;
//
// ss.write((const char*)&ipes, sizeof(RoF2::structs::ProcEffectStruct));
//
// if (strlen(item->ProcName) > 0)
// {
// ss.write((const char*)item->ProcName, strlen(item->ProcName));
// ss.write((const char*)&null_term, sizeof(uint8));
// }
// else
// {
// ss.write((const char*)&null_term, sizeof(uint8));
// }
//
// ss.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;
//
// ss.write((const char*)&iwes, sizeof(RoF2::structs::WornEffectStruct));
//
// if (strlen(item->WornName) > 0)
// {
// ss.write((const char*)item->WornName, strlen(item->WornName));
// ss.write((const char*)&null_term, sizeof(uint8));
// }
// else
// {
// ss.write((const char*)&null_term, sizeof(uint8));
// }
//
// ss.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;
//
// ss.write((const char*)&ifes, sizeof(RoF2::structs::WornEffectStruct));
//
// if (strlen(item->FocusName) > 0)
// {
// ss.write((const char*)item->FocusName, strlen(item->FocusName));
// ss.write((const char*)&null_term, sizeof(uint8));
// }
// else
// {
// ss.write((const char*)&null_term, sizeof(uint8));
// }
//
// ss.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;
//
// ss.write((const char*)&ises, sizeof(RoF2::structs::WornEffectStruct));
//
// if (strlen(item->ScrollName) > 0)
// {
// ss.write((const char*)item->ScrollName, strlen(item->ScrollName));
// ss.write((const char*)&null_term, sizeof(uint8));
// }
// else
// {
// ss.write((const char*)&null_term, sizeof(uint8));
// }
//
// ss.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;
//
// ss.write((const char*)&ibes, sizeof(RoF2::structs::WornEffectStruct));
//
// /*
// if(strlen(item->BardName) > 0)
// {
// ss.write((const char*)item->BardName, strlen(item->BardName));
// ss.write((const char*)&null_term, sizeof(uint8));
// }
// else */
// ss.write((const char*)&null_term, sizeof(uint8));
//
// ss.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 = 0;
//
// char *SubSerializations[10]; // <watch>
//
// uint32 SubLengths[10];
//
// for (int x = SUB_BEGIN; x < EmuConstants::ITEM_CONTAINER_SIZE; ++x) {
//
// SubSerializations[x] = nullptr;
//
// const ItemInst* subitem = ((const ItemInst*)inst)->GetItem(x);
//
// if (subitem) {
//
// int SubSlotNumber;
//
// iqbs.subitem_count++;
//
// if (slot_id_in >= EmuConstants::GENERAL_BEGIN && slot_id_in <= EmuConstants::GENERAL_END) // (< 30) - no cursor?
// //SubSlotNumber = (((slot_id_in + 3) * 10) + x + 1);
// SubSlotNumber = (((slot_id_in + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + x + 1);
// else if (slot_id_in >= EmuConstants::BANK_BEGIN && slot_id_in <= EmuConstants::BANK_END)
// //SubSlotNumber = (((slot_id_in - 2000) * 10) + 2030 + x + 1);
// SubSlotNumber = (((slot_id_in - EmuConstants::BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE) + EmuConstants::BANK_BAGS_BEGIN + x);
// else if (slot_id_in >= EmuConstants::SHARED_BANK_BEGIN && slot_id_in <= EmuConstants::SHARED_BANK_END)
// //SubSlotNumber = (((slot_id_in - 2500) * 10) + 2530 + x + 1);
// SubSlotNumber = (((slot_id_in - EmuConstants::SHARED_BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE) + EmuConstants::SHARED_BANK_BAGS_BEGIN + x);
// else
// SubSlotNumber = slot_id_in; // ???????
//
// /*
// // TEST CODE: <watch>
// SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x);
// */
//
// SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1, packet_type);
// }
// }
//
// ss.write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
//
// for (int x = SUB_BEGIN; x < EmuConstants::ITEM_CONTAINER_SIZE; ++x) {
//
// if (SubSerializations[x]) {
//
// ss.write((const char*)&x, sizeof(uint32));
//
// ss.write(SubSerializations[x], SubLengths[x]);
//
// safe_delete_array(SubSerializations[x]);
// }
// }
//
// char* item_serial = new char[ss.tellp()];
// memset(item_serial, 0, ss.tellp());
// memcpy(item_serial, ss.str().c_str(), ss.tellp());
//
// *length = ss.tellp();
// 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;
@ -6222,17 +5667,25 @@ namespace RoF2
iqbs.unknown39 = 1;
iqbs.subitem_count = inst->GetSubItemCount();
EQEmu::ItemContainer *container = inst->GetContainer();
if(container) {
iqbs.subitem_count = container->Size();
packet_data.Write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
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);
auto iter = container->Begin();
auto end = container->End();
while(iter != end) {
auto sub_inst = inst->Get(iter->first);
if(sub_inst) {
uint32 bag_slot = iter->first;
packet_data.Write((const char*)&bag_slot, sizeof(uint32));
SerializeItem(packet_data, sub_inst.get(), container_id, slot_id, bag_slot, -1);
}
++iter;
}
} else {
iqbs.subitem_count = 0;
packet_data.Write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
}
}