From 215861dd86cfada50d70a52ede0ffbfe343a894c Mon Sep 17 00:00:00 2001 From: KimLS Date: Wed, 25 Feb 2015 19:36:10 -0800 Subject: [PATCH] Added serialization differentiation --- common/CMakeLists.txt | 7 +- common/inventory.cpp | 7 +- common/inventory_database_controller.cpp | 0 common/inventory_database_controller.h | 24 - common/item_container.cpp | 66 +- common/item_container.h | 17 +- .../item_container_default_serialization.cpp | 17 + common/item_container_default_serialization.h | 35 ++ .../item_container_personal_serialization.cpp | 19 + .../item_container_personal_serialization.h | 35 ++ .../item_container_serialization_strategy.h | 37 ++ common/item_instance.cpp | 12 +- common/item_instance.h | 7 +- common/patches/rof2.cpp | 581 +----------------- 14 files changed, 236 insertions(+), 628 deletions(-) delete mode 100644 common/inventory_database_controller.cpp delete mode 100644 common/inventory_database_controller.h create mode 100644 common/item_container_default_serialization.cpp create mode 100644 common/item_container_default_serialization.h create mode 100644 common/item_container_personal_serialization.cpp create mode 100644 common/item_container_personal_serialization.h create mode 100644 common/item_container_serialization_strategy.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 243553bff..9d8dea551 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -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 diff --git a/common/inventory.cpp b/common/inventory.cpp index 72b6bc59d..9cd897bed 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -18,6 +18,7 @@ #include "inventory.h" #include "data_verification.h" +#include "item_container_personal_serialization.h" #include struct EQEmu::Inventory::impl @@ -58,7 +59,11 @@ std::shared_ptr EQEmu::Inventory::Get(const InventorySlot & bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr inst) { if(impl_->containers_.count(slot.type_) == 0) { - impl_->containers_.insert(std::pair(slot.type_, ItemContainer())); + if(slot.type_ == 0) { + impl_->containers_.insert(std::pair(slot.type_, ItemContainer(new ItemContainerPersonalSerialization()))); + } else { + impl_->containers_.insert(std::pair(slot.type_, ItemContainer())); + } } //Verify item can be put into the slot requested diff --git a/common/inventory_database_controller.cpp b/common/inventory_database_controller.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/common/inventory_database_controller.h b/common/inventory_database_controller.h deleted file mode 100644 index d3337dd75..000000000 --- a/common/inventory_database_controller.h +++ /dev/null @@ -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 diff --git a/common/item_container.cpp b/common/item_container.cpp index 92823fc20..6f708051a 100644 --- a/common/item_container.cpp +++ b/common/item_container.cpp @@ -1,21 +1,30 @@ #include "item_container.h" -#include +#include "item_container_default_serialization.h" #include struct EQEmu::ItemContainer::impl { - std::map> items; + std::map> 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::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 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 } 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(container_number); - buf.Write(iter.first); - buf.Write(iter.second.get()); - } + return false; +} - return true; -} \ No newline at end of file +EQEmu::ItemContainer::ItemContainerIter EQEmu::ItemContainer::Begin() { + return impl_->items_.begin(); +} + +EQEmu::ItemContainer::ItemContainerIter EQEmu::ItemContainer::End() { + return impl_->items_.end(); +} diff --git a/common/item_container.h b/common/item_container.h index cc650a19b..bde5d3c0d 100644 --- a/common/item_container.h +++ b/common/item_container.h @@ -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 +#include namespace EQEmu { + class ItemContainerSerializationStrategy; class ItemContainer { public: + typedef std::map>::const_iterator ItemContainerIter; + ItemContainer(); + ItemContainer(ItemContainerSerializationStrategy *strategy); ~ItemContainer(); ItemContainer(ItemContainer &&other); + ItemContainer& operator=(ItemContainer &&other); std::shared_ptr Get(const int slot_id); bool Put(const int slot_id, std::shared_ptr 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 diff --git a/common/item_container_default_serialization.cpp b/common/item_container_default_serialization.cpp new file mode 100644 index 000000000..4bcec1e17 --- /dev/null +++ b/common/item_container_default_serialization.cpp @@ -0,0 +1,17 @@ +#include "item_container_default_serialization.h" + +bool EQEmu::ItemContainerDefaultSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items) { + if(items.size() == 0) { + return false; + } + + bool ret = false; + for(auto &iter : items) { + buf.Write(container_number); + buf.Write(iter.first); + buf.Write(iter.second.get()); + ret = true; + } + + return ret; +} diff --git a/common/item_container_default_serialization.h b/common/item_container_default_serialization.h new file mode 100644 index 000000000..3626eded6 --- /dev/null +++ b/common/item_container_default_serialization.h @@ -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>& items); + }; +} // EQEmu + +#endif diff --git a/common/item_container_personal_serialization.cpp b/common/item_container_personal_serialization.cpp new file mode 100644 index 000000000..eefd8423a --- /dev/null +++ b/common/item_container_personal_serialization.cpp @@ -0,0 +1,19 @@ +#include "item_container_personal_serialization.h" + +bool EQEmu::ItemContainerPersonalSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items) { + if(items.size() == 0) { + return false; + } + + bool ret = false; + for(auto &iter : items) { + if(iter.first < 33) { + buf.Write(container_number); + buf.Write(iter.first); + buf.Write(iter.second.get()); + ret = true; + } + } + + return ret; +} diff --git a/common/item_container_personal_serialization.h b/common/item_container_personal_serialization.h new file mode 100644 index 000000000..0b41d5dc6 --- /dev/null +++ b/common/item_container_personal_serialization.h @@ -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>& items); + }; +} // EQEmu + +#endif diff --git a/common/item_container_serialization_strategy.h b/common/item_container_serialization_strategy.h new file mode 100644 index 000000000..e8fb61bee --- /dev/null +++ b/common/item_container_serialization_strategy.h @@ -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 + +namespace EQEmu +{ + class ItemContainerSerializationStrategy + { + public: + ItemContainerSerializationStrategy() { } + virtual ~ItemContainerSerializationStrategy() { } + virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items) = 0; + }; +} // EQEmu + +#endif diff --git a/common/item_instance.cpp b/common/item_instance.cpp index c95c8e72d..4b442dfc2 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -151,14 +151,6 @@ bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr 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_); +} diff --git a/common/item_instance.h b/common/item_instance.h index 595bff390..72bcc3c16 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -24,6 +24,7 @@ namespace EQEmu { + class ItemContainer; class ItemInstance { public: @@ -38,8 +39,6 @@ namespace EQEmu //Container std::shared_ptr Get(const int index); bool Put(const int index, std::shared_ptr 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_; diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index c3a1fd0f4..ea0c11b45 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -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]; // - // - // 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: - // 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)); } }