Added EQEmu::OutBuffer() - stringstream-derived class with a few additional methods

This commit is contained in:
Uleat 2016-05-18 22:38:41 -04:00
parent 67c92bf171
commit ffb88e0a8f
10 changed files with 631 additions and 638 deletions

View File

@ -31,9 +31,11 @@ class EvolveInfo; // Stores information about an evolving item family
#include "../common/timer.h" #include "../common/timer.h"
#include "../common/bodytypes.h" #include "../common/bodytypes.h"
#include "string_util.h"
#include <list> #include <list>
#include <map> #include <map>
#include <sstream> //#include <sstream>
namespace ItemField namespace ItemField
@ -413,7 +415,7 @@ public:
uint32 GetKillsNeeded(uint8 currentlevel); uint32 GetKillsNeeded(uint8 currentlevel);
std::string Serialize(int16 slot_id) const { InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(InternalSerializedItem_Struct)); return ser; } std::string Serialize(int16 slot_id) const { InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(InternalSerializedItem_Struct)); return ser; }
void Serialize(std::stringstream& ss, int16 slot_id) const { InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ss.write((const char*)&isi, sizeof(isi)); } void Serialize(EQEmu::OutBuffer& ob, int16 slot_id) const { InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
inline int32 GetSerialNumber() const { return m_SerialNumber; } inline int32 GetSerialNumber() const { return m_SerialNumber; }
inline void SetSerialNumber(int32 id) { m_SerialNumber = id; } inline void SetSerialNumber(int32 id) { m_SerialNumber = id; }

View File

@ -24,7 +24,7 @@ namespace RoF
static OpcodeManager *opcodes = nullptr; static OpcodeManager *opcodes = nullptr;
static Strategy struct_strategy; static Strategy struct_strategy;
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id, uint8 depth); void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth);
// server to client inventory location converters // server to client inventory location converters
static inline structs::InventorySlot_Struct ServerToRoFSlot(uint32 serverSlot); static inline structs::InventorySlot_Struct ServerToRoFSlot(uint32 serverSlot);
@ -557,24 +557,21 @@ namespace RoF
InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer; InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer;
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
ss.write((const char*)&item_count, sizeof(uint32)); ob.write((const char*)&item_count, sizeof(uint32));
for (int index = 0; index < item_count; ++index, ++eq) { for (int index = 0; index < item_count; ++index, ++eq) {
SerializeItem(ss, (const ItemInst*)eq->inst, eq->slot_id, 0); SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
if (ss.tellp() == last_pos) if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id); Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
last_pos = ss.tellp(); last_pos = ob.tellp();
} }
std::string serialized = ss.str(); in->size = ob.size();
in->pBuffer = ob.detach();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
delete[] __emu_buffer; delete[] __emu_buffer;
@ -1492,29 +1489,23 @@ namespace RoF
//store away the emu struct //store away the emu struct
uchar* __emu_buffer = in->pBuffer; uchar* __emu_buffer = in->pBuffer;
//ItemPacket_Struct* old_item_pkt = (ItemPacket_Struct*)__emu_buffer;
//InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(old_item_pkt->SerializedItem);
InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(&__emu_buffer[4]); InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(&__emu_buffer[4]);
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
ss.write((const char*)__emu_buffer, 4); ob.write((const char*)__emu_buffer, 4);
SerializeItem(ss, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0); SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
if (ss.tellp() == last_pos) { if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id); Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in; delete in;
return; return;
} }
std::string serialized = ss.str(); in->size = ob.size();
in->pBuffer = ob.detach();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
//ItemPacket_Struct* new_item_pkt = (ItemPacket_Struct*)in->pBuffer;
//new_item_pkt->PacketType = old_item_pkt->PacketType;
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
delete[] __emu_buffer; delete[] __emu_buffer;
@ -5180,7 +5171,7 @@ namespace RoF
return NextItemInstSerialNumber; return NextItemInstSerialNumber;
} }
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id_in, uint8 depth) void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
{ {
const Item_Struct *item = inst->GetUnscaledItem(); const Item_Struct *item = inst->GetUnscaledItem();
@ -5212,7 +5203,7 @@ namespace RoF
hdr.unknown052 = 0; hdr.unknown052 = 0;
hdr.isEvolving = item->EvolvingItem; hdr.isEvolving = item->EvolvingItem;
ss.write((const char*)&hdr, sizeof(RoF::structs::ItemSerializationHeader)); ob.write((const char*)&hdr, sizeof(RoF::structs::ItemSerializationHeader));
if (item->EvolvingItem > 0) { if (item->EvolvingItem > 0) {
RoF::structs::EvolvingItem evotop; RoF::structs::EvolvingItem evotop;
@ -5226,7 +5217,7 @@ namespace RoF
evotop.Activated = 1; evotop.Activated = 1;
evotop.evomaxlevel = item->EvolvingMax; evotop.evomaxlevel = item->EvolvingMax;
ss.write((const char*)&evotop, sizeof(RoF::structs::EvolvingItem)); ob.write((const char*)&evotop, sizeof(RoF::structs::EvolvingItem));
} }
//ORNAMENT IDFILE / ICON //ORNAMENT IDFILE / ICON
@ -5241,16 +5232,16 @@ namespace RoF
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile()); char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
//Mainhand //Mainhand
ss.write(tmp, strlen(tmp)); ob.write(tmp, strlen(tmp));
ss.write("\0", 1); ob.write("\0", 1);
//Offhand //Offhand
ss.write(tmp, strlen(tmp)); ob.write(tmp, strlen(tmp));
ss.write("\0", 1); ob.write("\0", 1);
} }
else { else {
ss.write("\0", 1); // no main hand Ornamentation ob.write("\0", 1); // no main hand Ornamentation
ss.write("\0", 1); // no off hand Ornamentation ob.write("\0", 1); // no off hand Ornamentation
} }
RoF::structs::ItemSerializationHeaderFinish hdrf; RoF::structs::ItemSerializationHeaderFinish hdrf;
@ -5264,21 +5255,21 @@ namespace RoF
hdrf.unknowna5 = 0; hdrf.unknowna5 = 0;
hdrf.ItemClass = item->ItemClass; hdrf.ItemClass = item->ItemClass;
ss.write((const char*)&hdrf, sizeof(RoF::structs::ItemSerializationHeaderFinish)); ob.write((const char*)&hdrf, sizeof(RoF::structs::ItemSerializationHeaderFinish));
if (strlen(item->Name) > 0) if (strlen(item->Name) > 0)
ss.write(item->Name, strlen(item->Name)); ob.write(item->Name, strlen(item->Name));
ss.write("\0", 1); ob.write("\0", 1);
if (strlen(item->Lore) > 0) if (strlen(item->Lore) > 0)
ss.write(item->Lore, strlen(item->Lore)); ob.write(item->Lore, strlen(item->Lore));
ss.write("\0", 1); ob.write("\0", 1);
if (strlen(item->IDFile) > 0) if (strlen(item->IDFile) > 0)
ss.write(item->IDFile, strlen(item->IDFile)); ob.write(item->IDFile, strlen(item->IDFile));
ss.write("\0", 1); ob.write("\0", 1);
ss.write("\0", 1); ob.write("\0", 1);
RoF::structs::ItemBodyStruct ibs; RoF::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(RoF::structs::ItemBodyStruct)); memset(&ibs, 0, sizeof(RoF::structs::ItemBodyStruct));
@ -5369,12 +5360,12 @@ namespace RoF
ibs.FactionAmt4 = item->FactionAmt4; ibs.FactionAmt4 = item->FactionAmt4;
ibs.FactionMod4 = item->FactionMod4; ibs.FactionMod4 = item->FactionMod4;
ss.write((const char*)&ibs, sizeof(RoF::structs::ItemBodyStruct)); ob.write((const char*)&ibs, sizeof(RoF::structs::ItemBodyStruct));
//charm text //charm text
if (strlen(item->CharmFile) > 0) if (strlen(item->CharmFile) > 0)
ss.write((const char*)item->CharmFile, strlen(item->CharmFile)); ob.write((const char*)item->CharmFile, strlen(item->CharmFile));
ss.write("\0", 1); ob.write("\0", 1);
RoF::structs::ItemSecondaryBodyStruct isbs; RoF::structs::ItemSecondaryBodyStruct isbs;
memset(&isbs, 0, sizeof(RoF::structs::ItemSecondaryBodyStruct)); memset(&isbs, 0, sizeof(RoF::structs::ItemSecondaryBodyStruct));
@ -5403,11 +5394,11 @@ namespace RoF
isbs.book = item->Book; isbs.book = item->Book;
isbs.booktype = item->BookType; isbs.booktype = item->BookType;
ss.write((const char*)&isbs, sizeof(RoF::structs::ItemSecondaryBodyStruct)); ob.write((const char*)&isbs, sizeof(RoF::structs::ItemSecondaryBodyStruct));
if (strlen(item->Filename) > 0) if (strlen(item->Filename) > 0)
ss.write((const char*)item->Filename, strlen(item->Filename)); ob.write((const char*)item->Filename, strlen(item->Filename));
ss.write("\0", 1); ob.write("\0", 1);
RoF::structs::ItemTertiaryBodyStruct itbs; RoF::structs::ItemTertiaryBodyStruct itbs;
memset(&itbs, 0, sizeof(RoF::structs::ItemTertiaryBodyStruct)); memset(&itbs, 0, sizeof(RoF::structs::ItemTertiaryBodyStruct));
@ -5442,7 +5433,7 @@ namespace RoF
itbs.unknown13 = 0; itbs.unknown13 = 0;
itbs.unknown14 = 0; itbs.unknown14 = 0;
ss.write((const char*)&itbs, sizeof(RoF::structs::ItemTertiaryBodyStruct)); ob.write((const char*)&itbs, sizeof(RoF::structs::ItemTertiaryBodyStruct));
// Effect Structures Broken down to allow variable length strings for effect names // Effect Structures Broken down to allow variable length strings for effect names
int32 effect_unknown = 0; int32 effect_unknown = 0;
@ -5459,13 +5450,13 @@ namespace RoF
ices.recast = item->RecastDelay; ices.recast = item->RecastDelay;
ices.recast_type = item->RecastType; ices.recast_type = item->RecastType;
ss.write((const char*)&ices, sizeof(RoF::structs::ClickEffectStruct)); ob.write((const char*)&ices, sizeof(RoF::structs::ClickEffectStruct));
if (strlen(item->ClickName) > 0) if (strlen(item->ClickName) > 0)
ss.write((const char*)item->ClickName, strlen(item->ClickName)); ob.write((const char*)item->ClickName, strlen(item->ClickName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7 ob.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7
RoF::structs::ProcEffectStruct ipes; RoF::structs::ProcEffectStruct ipes;
memset(&ipes, 0, sizeof(RoF::structs::ProcEffectStruct)); memset(&ipes, 0, sizeof(RoF::structs::ProcEffectStruct));
@ -5476,13 +5467,13 @@ namespace RoF
ipes.level = item->Proc.Level; ipes.level = item->Proc.Level;
ipes.procrate = item->ProcRate; ipes.procrate = item->ProcRate;
ss.write((const char*)&ipes, sizeof(RoF::structs::ProcEffectStruct)); ob.write((const char*)&ipes, sizeof(RoF::structs::ProcEffectStruct));
if (strlen(item->ProcName) > 0) if (strlen(item->ProcName) > 0)
ss.write((const char*)item->ProcName, strlen(item->ProcName)); ob.write((const char*)item->ProcName, strlen(item->ProcName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown5 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown5
RoF::structs::WornEffectStruct iwes; RoF::structs::WornEffectStruct iwes;
memset(&iwes, 0, sizeof(RoF::structs::WornEffectStruct)); memset(&iwes, 0, sizeof(RoF::structs::WornEffectStruct));
@ -5492,13 +5483,13 @@ namespace RoF
iwes.type = item->Worn.Type; iwes.type = item->Worn.Type;
iwes.level = item->Worn.Level; iwes.level = item->Worn.Level;
ss.write((const char*)&iwes, sizeof(RoF::structs::WornEffectStruct)); ob.write((const char*)&iwes, sizeof(RoF::structs::WornEffectStruct));
if (strlen(item->WornName) > 0) if (strlen(item->WornName) > 0)
ss.write((const char*)item->WornName, strlen(item->WornName)); ob.write((const char*)item->WornName, strlen(item->WornName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
RoF::structs::WornEffectStruct ifes; RoF::structs::WornEffectStruct ifes;
memset(&ifes, 0, sizeof(RoF::structs::WornEffectStruct)); memset(&ifes, 0, sizeof(RoF::structs::WornEffectStruct));
@ -5508,13 +5499,13 @@ namespace RoF
ifes.type = item->Focus.Type; ifes.type = item->Focus.Type;
ifes.level = item->Focus.Level; ifes.level = item->Focus.Level;
ss.write((const char*)&ifes, sizeof(RoF::structs::WornEffectStruct)); ob.write((const char*)&ifes, sizeof(RoF::structs::WornEffectStruct));
if (strlen(item->FocusName) > 0) if (strlen(item->FocusName) > 0)
ss.write((const char*)item->FocusName, strlen(item->FocusName)); ob.write((const char*)item->FocusName, strlen(item->FocusName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
RoF::structs::WornEffectStruct ises; RoF::structs::WornEffectStruct ises;
memset(&ises, 0, sizeof(RoF::structs::WornEffectStruct)); memset(&ises, 0, sizeof(RoF::structs::WornEffectStruct));
@ -5524,13 +5515,13 @@ namespace RoF
ises.type = item->Scroll.Type; ises.type = item->Scroll.Type;
ises.level = item->Scroll.Level; ises.level = item->Scroll.Level;
ss.write((const char*)&ises, sizeof(RoF::structs::WornEffectStruct)); ob.write((const char*)&ises, sizeof(RoF::structs::WornEffectStruct));
if (strlen(item->ScrollName) > 0) if (strlen(item->ScrollName) > 0)
ss.write((const char*)item->ScrollName, strlen(item->ScrollName)); ob.write((const char*)item->ScrollName, strlen(item->ScrollName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// Bard Effect? // Bard Effect?
RoF::structs::WornEffectStruct ibes; RoF::structs::WornEffectStruct ibes;
@ -5542,7 +5533,7 @@ namespace RoF
ibes.level = 0; ibes.level = 0;
//ibes.unknown6 = 0xffffffff; //ibes.unknown6 = 0xffffffff;
ss.write((const char*)&ibes, sizeof(RoF::structs::WornEffectStruct)); ob.write((const char*)&ibes, sizeof(RoF::structs::WornEffectStruct));
/* /*
if(strlen(item->BardName) > 0) if(strlen(item->BardName) > 0)
@ -5551,9 +5542,9 @@ namespace RoF
ss.write((const char*)&null_term, sizeof(uint8)); ss.write((const char*)&null_term, sizeof(uint8));
} }
else */ else */
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// End of Effects // End of Effects
RoF::structs::ItemQuaternaryBodyStruct iqbs; RoF::structs::ItemQuaternaryBodyStruct iqbs;
@ -5586,12 +5577,12 @@ namespace RoF
iqbs.unknown30 = 0; iqbs.unknown30 = 0;
iqbs.unknown39 = 1; iqbs.unknown39 = 1;
ss.write((const char*)&iqbs, sizeof(RoF::structs::ItemQuaternaryBodyStruct)); ob.write((const char*)&iqbs, sizeof(RoF::structs::ItemQuaternaryBodyStruct));
std::stringstream::pos_type count_pos = ss.tellp(); std::stringstream::pos_type count_pos = ob.tellp();
uint32 subitem_count = 0; uint32 subitem_count = 0;
ss.write((const char*)&subitem_count, sizeof(uint32)); ob.write((const char*)&subitem_count, sizeof(uint32));
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) { for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
ItemInst* sub = inst->GetItem(index); ItemInst* sub = inst->GetItem(index);
@ -5608,20 +5599,14 @@ namespace RoF
else else
SubSlotNumber = slot_id_in; SubSlotNumber = slot_id_in;
ss.write((const char*)&index, sizeof(uint32)); ob.write((const char*)&index, sizeof(uint32));
SerializeItem(ss, sub, SubSlotNumber, (depth + 1)); SerializeItem(ob, sub, SubSlotNumber, (depth + 1));
++subitem_count; ++subitem_count;
} }
if (subitem_count) { if (subitem_count)
std::stringstream::pos_type cur_pos = ss.tellp(); ob.overwrite(count_pos, (const char*)&subitem_count, sizeof(uint32));
ss.seekp(count_pos);
ss.write((const char*)&subitem_count, sizeof(uint32));
ss.seekp(cur_pos);
}
} }
static inline structs::InventorySlot_Struct ServerToRoFSlot(uint32 serverSlot) static inline structs::InventorySlot_Struct ServerToRoFSlot(uint32 serverSlot)

View File

@ -24,7 +24,7 @@ namespace RoF2
static OpcodeManager *opcodes = nullptr; static OpcodeManager *opcodes = nullptr;
static Strategy struct_strategy; static Strategy struct_strategy;
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id, uint8 depth, ItemPacketType packet_type); void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth, ItemPacketType packet_type);
// server to client inventory location converters // server to client inventory location converters
static inline structs::InventorySlot_Struct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType = ItemPacketInvalid); static inline structs::InventorySlot_Struct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType = ItemPacketInvalid);
@ -628,24 +628,21 @@ namespace RoF2
InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer; InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer;
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
ss.write((const char*)&item_count, sizeof(uint32)); ob.write((const char*)&item_count, sizeof(uint32));
for (int index = 0; index < item_count; ++index, ++eq) { for (int index = 0; index < item_count; ++index, ++eq) {
SerializeItem(ss, (const ItemInst*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory); SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
if (ss.tellp() == last_pos) if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id); Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
last_pos = ss.tellp(); last_pos = ob.tellp();
} }
std::string serialized = ss.str(); in->size = ob.size();
in->pBuffer = ob.detach();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
delete[] __emu_buffer; delete[] __emu_buffer;
@ -1563,29 +1560,24 @@ namespace RoF2
//store away the emu struct //store away the emu struct
uchar* __emu_buffer = in->pBuffer; uchar* __emu_buffer = in->pBuffer;
ItemPacket_Struct* old_item_pkt = (ItemPacket_Struct*)__emu_buffer; ItemPacket_Struct* old_item_pkt = (ItemPacket_Struct*)__emu_buffer;
//InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(old_item_pkt->SerializedItem);
InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(&__emu_buffer[4]); InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(&__emu_buffer[4]);
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
ss.write((const char*)__emu_buffer, 4); ob.write((const char*)__emu_buffer, 4);
SerializeItem(ss, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType); SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
if (ss.tellp() == last_pos) { if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id); Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in; delete in;
return; return;
} }
std::string serialized = ss.str(); in->size = ob.size();
in->pBuffer = ob.detach();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
//ItemPacket_Struct* new_item_pkt = (ItemPacket_Struct*)in->pBuffer;
//new_item_pkt->PacketType = old_item_pkt->PacketType;
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
delete[] __emu_buffer; delete[] __emu_buffer;
@ -5451,7 +5443,7 @@ namespace RoF2
return NextItemInstSerialNumber; return NextItemInstSerialNumber;
} }
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id_in, uint8 depth, ItemPacketType packet_type) void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth, ItemPacketType packet_type)
{ {
const Item_Struct *item = inst->GetUnscaledItem(); const Item_Struct *item = inst->GetUnscaledItem();
@ -5483,7 +5475,7 @@ namespace RoF2
hdr.unknown052 = 0; hdr.unknown052 = 0;
hdr.isEvolving = item->EvolvingItem; hdr.isEvolving = item->EvolvingItem;
ss.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader)); ob.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader));
if (item->EvolvingItem > 0) { if (item->EvolvingItem > 0) {
RoF2::structs::EvolvingItem evotop; RoF2::structs::EvolvingItem evotop;
@ -5497,7 +5489,7 @@ namespace RoF2
evotop.Activated = 1; evotop.Activated = 1;
evotop.evomaxlevel = item->EvolvingMax; evotop.evomaxlevel = item->EvolvingMax;
ss.write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem)); ob.write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem));
} }
//ORNAMENT IDFILE / ICON //ORNAMENT IDFILE / ICON
@ -5512,16 +5504,16 @@ namespace RoF2
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile()); char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
//Mainhand //Mainhand
ss.write(tmp, strlen(tmp)); ob.write(tmp, strlen(tmp));
ss.write("\0", 1); ob.write("\0", 1);
//Offhand //Offhand
ss.write(tmp, strlen(tmp)); ob.write(tmp, strlen(tmp));
ss.write("\0", 1); ob.write("\0", 1);
} }
else { else {
ss.write("\0", 1); // no main hand Ornamentation ob.write("\0", 1); // no main hand Ornamentation
ss.write("\0", 1); // no off hand Ornamentation ob.write("\0", 1); // no off hand Ornamentation
} }
RoF2::structs::ItemSerializationHeaderFinish hdrf; RoF2::structs::ItemSerializationHeaderFinish hdrf;
@ -5535,21 +5527,21 @@ namespace RoF2
hdrf.unknowna5 = 0; hdrf.unknowna5 = 0;
hdrf.ItemClass = item->ItemClass; hdrf.ItemClass = item->ItemClass;
ss.write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish)); ob.write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish));
if (strlen(item->Name) > 0) if (strlen(item->Name) > 0)
ss.write(item->Name, strlen(item->Name)); ob.write(item->Name, strlen(item->Name));
ss.write("\0", 1); ob.write("\0", 1);
if (strlen(item->Lore) > 0) if (strlen(item->Lore) > 0)
ss.write(item->Lore, strlen(item->Lore)); ob.write(item->Lore, strlen(item->Lore));
ss.write("\0", 1); ob.write("\0", 1);
if (strlen(item->IDFile) > 0) if (strlen(item->IDFile) > 0)
ss.write(item->IDFile, strlen(item->IDFile)); ob.write(item->IDFile, strlen(item->IDFile));
ss.write("\0", 1); ob.write("\0", 1);
ss.write("\0", 1); ob.write("\0", 1);
RoF2::structs::ItemBodyStruct ibs; RoF2::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(RoF2::structs::ItemBodyStruct)); memset(&ibs, 0, sizeof(RoF2::structs::ItemBodyStruct));
@ -5640,12 +5632,12 @@ namespace RoF2
ibs.FactionAmt4 = item->FactionAmt4; ibs.FactionAmt4 = item->FactionAmt4;
ibs.FactionMod4 = item->FactionMod4; ibs.FactionMod4 = item->FactionMod4;
ss.write((const char*)&ibs, sizeof(RoF2::structs::ItemBodyStruct)); ob.write((const char*)&ibs, sizeof(RoF2::structs::ItemBodyStruct));
//charm text //charm text
if (strlen(item->CharmFile) > 0) if (strlen(item->CharmFile) > 0)
ss.write((const char*)item->CharmFile, strlen(item->CharmFile)); ob.write((const char*)item->CharmFile, strlen(item->CharmFile));
ss.write("\0", 1); ob.write("\0", 1);
RoF2::structs::ItemSecondaryBodyStruct isbs; RoF2::structs::ItemSecondaryBodyStruct isbs;
memset(&isbs, 0, sizeof(RoF2::structs::ItemSecondaryBodyStruct)); memset(&isbs, 0, sizeof(RoF2::structs::ItemSecondaryBodyStruct));
@ -5674,11 +5666,11 @@ namespace RoF2
isbs.book = item->Book; isbs.book = item->Book;
isbs.booktype = item->BookType; isbs.booktype = item->BookType;
ss.write((const char*)&isbs, sizeof(RoF2::structs::ItemSecondaryBodyStruct)); ob.write((const char*)&isbs, sizeof(RoF2::structs::ItemSecondaryBodyStruct));
if (strlen(item->Filename) > 0) if (strlen(item->Filename) > 0)
ss.write((const char*)item->Filename, strlen(item->Filename)); ob.write((const char*)item->Filename, strlen(item->Filename));
ss.write("\0", 1); ob.write("\0", 1);
RoF2::structs::ItemTertiaryBodyStruct itbs; RoF2::structs::ItemTertiaryBodyStruct itbs;
memset(&itbs, 0, sizeof(RoF2::structs::ItemTertiaryBodyStruct)); memset(&itbs, 0, sizeof(RoF2::structs::ItemTertiaryBodyStruct));
@ -5713,7 +5705,7 @@ namespace RoF2
itbs.unknown13 = 0; itbs.unknown13 = 0;
itbs.unknown14 = 0; itbs.unknown14 = 0;
ss.write((const char*)&itbs, sizeof(RoF2::structs::ItemTertiaryBodyStruct)); ob.write((const char*)&itbs, sizeof(RoF2::structs::ItemTertiaryBodyStruct));
// Effect Structures Broken down to allow variable length strings for effect names // Effect Structures Broken down to allow variable length strings for effect names
int32 effect_unknown = 0; int32 effect_unknown = 0;
@ -5730,13 +5722,13 @@ namespace RoF2
ices.recast = item->RecastDelay; ices.recast = item->RecastDelay;
ices.recast_type = item->RecastType; ices.recast_type = item->RecastType;
ss.write((const char*)&ices, sizeof(RoF2::structs::ClickEffectStruct)); ob.write((const char*)&ices, sizeof(RoF2::structs::ClickEffectStruct));
if (strlen(item->ClickName) > 0) if (strlen(item->ClickName) > 0)
ss.write((const char*)item->ClickName, strlen(item->ClickName)); ob.write((const char*)item->ClickName, strlen(item->ClickName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7 ob.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7
RoF2::structs::ProcEffectStruct ipes; RoF2::structs::ProcEffectStruct ipes;
memset(&ipes, 0, sizeof(RoF2::structs::ProcEffectStruct)); memset(&ipes, 0, sizeof(RoF2::structs::ProcEffectStruct));
@ -5747,13 +5739,13 @@ namespace RoF2
ipes.level = item->Proc.Level; ipes.level = item->Proc.Level;
ipes.procrate = item->ProcRate; ipes.procrate = item->ProcRate;
ss.write((const char*)&ipes, sizeof(RoF2::structs::ProcEffectStruct)); ob.write((const char*)&ipes, sizeof(RoF2::structs::ProcEffectStruct));
if (strlen(item->ProcName) > 0) if (strlen(item->ProcName) > 0)
ss.write((const char*)item->ProcName, strlen(item->ProcName)); ob.write((const char*)item->ProcName, strlen(item->ProcName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown5 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown5
RoF2::structs::WornEffectStruct iwes; RoF2::structs::WornEffectStruct iwes;
memset(&iwes, 0, sizeof(RoF2::structs::WornEffectStruct)); memset(&iwes, 0, sizeof(RoF2::structs::WornEffectStruct));
@ -5763,13 +5755,13 @@ namespace RoF2
iwes.type = item->Worn.Type; iwes.type = item->Worn.Type;
iwes.level = item->Worn.Level; iwes.level = item->Worn.Level;
ss.write((const char*)&iwes, sizeof(RoF2::structs::WornEffectStruct)); ob.write((const char*)&iwes, sizeof(RoF2::structs::WornEffectStruct));
if (strlen(item->WornName) > 0) if (strlen(item->WornName) > 0)
ss.write((const char*)item->WornName, strlen(item->WornName)); ob.write((const char*)item->WornName, strlen(item->WornName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
RoF2::structs::WornEffectStruct ifes; RoF2::structs::WornEffectStruct ifes;
memset(&ifes, 0, sizeof(RoF2::structs::WornEffectStruct)); memset(&ifes, 0, sizeof(RoF2::structs::WornEffectStruct));
@ -5779,13 +5771,13 @@ namespace RoF2
ifes.type = item->Focus.Type; ifes.type = item->Focus.Type;
ifes.level = item->Focus.Level; ifes.level = item->Focus.Level;
ss.write((const char*)&ifes, sizeof(RoF2::structs::WornEffectStruct)); ob.write((const char*)&ifes, sizeof(RoF2::structs::WornEffectStruct));
if (strlen(item->FocusName) > 0) if (strlen(item->FocusName) > 0)
ss.write((const char*)item->FocusName, strlen(item->FocusName)); ob.write((const char*)item->FocusName, strlen(item->FocusName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
RoF2::structs::WornEffectStruct ises; RoF2::structs::WornEffectStruct ises;
memset(&ises, 0, sizeof(RoF2::structs::WornEffectStruct)); memset(&ises, 0, sizeof(RoF2::structs::WornEffectStruct));
@ -5795,13 +5787,13 @@ namespace RoF2
ises.type = item->Scroll.Type; ises.type = item->Scroll.Type;
ises.level = item->Scroll.Level; ises.level = item->Scroll.Level;
ss.write((const char*)&ises, sizeof(RoF2::structs::WornEffectStruct)); ob.write((const char*)&ises, sizeof(RoF2::structs::WornEffectStruct));
if (strlen(item->ScrollName) > 0) if (strlen(item->ScrollName) > 0)
ss.write((const char*)item->ScrollName, strlen(item->ScrollName)); ob.write((const char*)item->ScrollName, strlen(item->ScrollName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// Bard Effect? // Bard Effect?
RoF2::structs::WornEffectStruct ibes; RoF2::structs::WornEffectStruct ibes;
@ -5813,18 +5805,18 @@ namespace RoF2
ibes.level = item->Bard.Level; ibes.level = item->Bard.Level;
//ibes.unknown6 = 0xffffffff; //ibes.unknown6 = 0xffffffff;
ss.write((const char*)&ibes, sizeof(RoF2::structs::WornEffectStruct)); ob.write((const char*)&ibes, sizeof(RoF2::structs::WornEffectStruct));
/* /*
if(strlen(item->BardName) > 0) if(strlen(item->BardName) > 0)
{ {
ss.write((const char*)item->BardName, strlen(item->BardName)); ob.write((const char*)item->BardName, strlen(item->BardName));
ss.write((const char*)&null_term, sizeof(uint8)); ob.write((const char*)&null_term, sizeof(uint8));
} }
else */ else */
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// End of Effects // End of Effects
RoF2::structs::ItemQuaternaryBodyStruct iqbs; RoF2::structs::ItemQuaternaryBodyStruct iqbs;
@ -5867,12 +5859,12 @@ namespace RoF2
iqbs.unknown38 = 0; iqbs.unknown38 = 0;
iqbs.unknown39 = 1; iqbs.unknown39 = 1;
ss.write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); ob.write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct));
std::stringstream::pos_type count_pos = ss.tellp(); EQEmu::OutBuffer::pos_type count_pos = ob.tellp();
uint32 subitem_count = 0; uint32 subitem_count = 0;
ss.write((const char*)&subitem_count, sizeof(uint32)); ob.write((const char*)&subitem_count, sizeof(uint32));
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) { for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
ItemInst* sub = inst->GetItem(index); ItemInst* sub = inst->GetItem(index);
@ -5889,20 +5881,14 @@ namespace RoF2
else else
SubSlotNumber = slot_id_in; SubSlotNumber = slot_id_in;
ss.write((const char*)&index, sizeof(uint32)); ob.write((const char*)&index, sizeof(uint32));
SerializeItem(ss, sub, SubSlotNumber, (depth + 1), packet_type); SerializeItem(ob, sub, SubSlotNumber, (depth + 1), packet_type);
++subitem_count; ++subitem_count;
} }
if (subitem_count) { if (subitem_count)
std::stringstream::pos_type cur_pos = ss.tellp(); ob.overwrite(count_pos, (const char*)&subitem_count, sizeof(uint32));
ss.seekp(count_pos);
ss.write((const char*)&subitem_count, sizeof(uint32));
ss.seekp(cur_pos);
}
} }
static inline structs::InventorySlot_Struct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType) static inline structs::InventorySlot_Struct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType)

View File

@ -22,7 +22,7 @@ namespace SoD
static OpcodeManager *opcodes = nullptr; static OpcodeManager *opcodes = nullptr;
static Strategy struct_strategy; static Strategy struct_strategy;
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id, uint8 depth); void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth);
// server to client inventory location converters // server to client inventory location converters
static inline uint32 ServerToSoDSlot(uint32 ServerSlot); static inline uint32 ServerToSoDSlot(uint32 ServerSlot);
@ -361,24 +361,21 @@ namespace SoD
InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer; InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer;
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
ss.write((const char*)&item_count, sizeof(uint32)); ob.write((const char*)&item_count, sizeof(uint32));
for (int index = 0; index < item_count; ++index, ++eq) { for (int index = 0; index < item_count; ++index, ++eq) {
SerializeItem(ss, (const ItemInst*)eq->inst, eq->slot_id, 0); SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
if (ss.tellp() == last_pos) if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id); Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
last_pos = ss.tellp(); last_pos = ob.tellp();
} }
std::string serialized = ss.str(); in->size = ob.size();
in->pBuffer = ob.detach();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
delete[] __emu_buffer; delete[] __emu_buffer;
@ -1023,29 +1020,23 @@ namespace SoD
//store away the emu struct //store away the emu struct
uchar* __emu_buffer = in->pBuffer; uchar* __emu_buffer = in->pBuffer;
//ItemPacket_Struct* old_item_pkt = (ItemPacket_Struct*)__emu_buffer;
//InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(old_item_pkt->SerializedItem);
InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(&__emu_buffer[4]); InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(&__emu_buffer[4]);
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
ss.write((const char*)__emu_buffer, 4); ob.write((const char*)__emu_buffer, 4);
SerializeItem(ss, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0); SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
if (ss.tellp() == last_pos) { if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id); Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in; delete in;
return; return;
} }
std::string serialized = ss.str(); in->size = ob.size();
in->pBuffer = ob.detach();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
//ItemPacket_Struct* new_item_pkt = (ItemPacket_Struct*)in->pBuffer;
//new_item_pkt->PacketType = old_item_pkt->PacketType;
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
delete[] __emu_buffer; delete[] __emu_buffer;
@ -3540,7 +3531,7 @@ namespace SoD
return NextItemInstSerialNumber; return NextItemInstSerialNumber;
} }
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id_in, uint8 depth) void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
{ {
const Item_Struct *item = inst->GetUnscaledItem(); const Item_Struct *item = inst->GetUnscaledItem();
@ -3569,19 +3560,19 @@ namespace SoD
hdr.unknown062 = 0; hdr.unknown062 = 0;
hdr.ItemClass = item->ItemClass; hdr.ItemClass = item->ItemClass;
ss.write((const char*)&hdr, sizeof(SoD::structs::ItemSerializationHeader)); ob.write((const char*)&hdr, sizeof(SoD::structs::ItemSerializationHeader));
if (strlen(item->Name) > 0) if (strlen(item->Name) > 0)
ss.write(item->Name, strlen(item->Name)); ob.write(item->Name, strlen(item->Name));
ss.write("\0", 1); ob.write("\0", 1);
if (strlen(item->Lore) > 0) if (strlen(item->Lore) > 0)
ss.write(item->Lore, strlen(item->Lore)); ob.write(item->Lore, strlen(item->Lore));
ss.write("\0", 1); ob.write("\0", 1);
if (strlen(item->IDFile) > 0) if (strlen(item->IDFile) > 0)
ss.write(item->IDFile, strlen(item->IDFile)); ob.write(item->IDFile, strlen(item->IDFile));
ss.write("\0", 1); ob.write("\0", 1);
SoD::structs::ItemBodyStruct ibs; SoD::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(SoD::structs::ItemBodyStruct)); memset(&ibs, 0, sizeof(SoD::structs::ItemBodyStruct));
@ -3670,12 +3661,12 @@ namespace SoD
ibs.FactionAmt4 = item->FactionAmt4; ibs.FactionAmt4 = item->FactionAmt4;
ibs.FactionMod4 = item->FactionMod4; ibs.FactionMod4 = item->FactionMod4;
ss.write((const char*)&ibs, sizeof(SoD::structs::ItemBodyStruct)); ob.write((const char*)&ibs, sizeof(SoD::structs::ItemBodyStruct));
//charm text //charm text
if (strlen(item->CharmFile) > 0) if (strlen(item->CharmFile) > 0)
ss.write((const char*)item->CharmFile, strlen(item->CharmFile)); ob.write((const char*)item->CharmFile, strlen(item->CharmFile));
ss.write("\0", 1); ob.write("\0", 1);
SoD::structs::ItemSecondaryBodyStruct isbs; SoD::structs::ItemSecondaryBodyStruct isbs;
memset(&isbs, 0, sizeof(SoD::structs::ItemSecondaryBodyStruct)); memset(&isbs, 0, sizeof(SoD::structs::ItemSecondaryBodyStruct));
@ -3703,11 +3694,11 @@ namespace SoD
isbs.book = item->Book; isbs.book = item->Book;
isbs.booktype = item->BookType; isbs.booktype = item->BookType;
ss.write((const char*)&isbs, sizeof(SoD::structs::ItemSecondaryBodyStruct)); ob.write((const char*)&isbs, sizeof(SoD::structs::ItemSecondaryBodyStruct));
if (strlen(item->Filename) > 0) if (strlen(item->Filename) > 0)
ss.write((const char*)item->Filename, strlen(item->Filename)); ob.write((const char*)item->Filename, strlen(item->Filename));
ss.write("\0", 1); ob.write("\0", 1);
SoD::structs::ItemTertiaryBodyStruct itbs; SoD::structs::ItemTertiaryBodyStruct itbs;
memset(&itbs, 0, sizeof(SoD::structs::ItemTertiaryBodyStruct)); memset(&itbs, 0, sizeof(SoD::structs::ItemTertiaryBodyStruct));
@ -3731,7 +3722,7 @@ namespace SoD
itbs.no_transfer = item->NoTransfer; itbs.no_transfer = item->NoTransfer;
itbs.expendablearrow = item->ExpendableArrow; itbs.expendablearrow = item->ExpendableArrow;
ss.write((const char*)&itbs, sizeof(SoD::structs::ItemTertiaryBodyStruct)); ob.write((const char*)&itbs, sizeof(SoD::structs::ItemTertiaryBodyStruct));
// Effect Structures Broken down to allow variable length strings for effect names // Effect Structures Broken down to allow variable length strings for effect names
int32 effect_unknown = 0; int32 effect_unknown = 0;
@ -3748,13 +3739,13 @@ namespace SoD
ices.recast = item->RecastDelay; ices.recast = item->RecastDelay;
ices.recast_type = item->RecastType; ices.recast_type = item->RecastType;
ss.write((const char*)&ices, sizeof(SoD::structs::ClickEffectStruct)); ob.write((const char*)&ices, sizeof(SoD::structs::ClickEffectStruct));
if (strlen(item->ClickName) > 0) if (strlen(item->ClickName) > 0)
ss.write((const char*)item->ClickName, strlen(item->ClickName)); ob.write((const char*)item->ClickName, strlen(item->ClickName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7 ob.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7
SoD::structs::ProcEffectStruct ipes; SoD::structs::ProcEffectStruct ipes;
memset(&ipes, 0, sizeof(SoD::structs::ProcEffectStruct)); memset(&ipes, 0, sizeof(SoD::structs::ProcEffectStruct));
@ -3765,13 +3756,13 @@ namespace SoD
ipes.level = item->Proc.Level; ipes.level = item->Proc.Level;
ipes.procrate = item->ProcRate; ipes.procrate = item->ProcRate;
ss.write((const char*)&ipes, sizeof(SoD::structs::ProcEffectStruct)); ob.write((const char*)&ipes, sizeof(SoD::structs::ProcEffectStruct));
if (strlen(item->ProcName) > 0) if (strlen(item->ProcName) > 0)
ss.write((const char*)item->ProcName, strlen(item->ProcName)); ob.write((const char*)item->ProcName, strlen(item->ProcName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown5 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown5
SoD::structs::WornEffectStruct iwes; SoD::structs::WornEffectStruct iwes;
memset(&iwes, 0, sizeof(SoD::structs::WornEffectStruct)); memset(&iwes, 0, sizeof(SoD::structs::WornEffectStruct));
@ -3781,13 +3772,13 @@ namespace SoD
iwes.type = item->Worn.Type; iwes.type = item->Worn.Type;
iwes.level = item->Worn.Level; iwes.level = item->Worn.Level;
ss.write((const char*)&iwes, sizeof(SoD::structs::WornEffectStruct)); ob.write((const char*)&iwes, sizeof(SoD::structs::WornEffectStruct));
if (strlen(item->WornName) > 0) if (strlen(item->WornName) > 0)
ss.write((const char*)item->WornName, strlen(item->WornName)); ob.write((const char*)item->WornName, strlen(item->WornName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
SoD::structs::WornEffectStruct ifes; SoD::structs::WornEffectStruct ifes;
memset(&ifes, 0, sizeof(SoD::structs::WornEffectStruct)); memset(&ifes, 0, sizeof(SoD::structs::WornEffectStruct));
@ -3797,13 +3788,13 @@ namespace SoD
ifes.type = item->Focus.Type; ifes.type = item->Focus.Type;
ifes.level = item->Focus.Level; ifes.level = item->Focus.Level;
ss.write((const char*)&ifes, sizeof(SoD::structs::WornEffectStruct)); ob.write((const char*)&ifes, sizeof(SoD::structs::WornEffectStruct));
if (strlen(item->FocusName) > 0) if (strlen(item->FocusName) > 0)
ss.write((const char*)item->FocusName, strlen(item->FocusName)); ob.write((const char*)item->FocusName, strlen(item->FocusName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
SoD::structs::WornEffectStruct ises; SoD::structs::WornEffectStruct ises;
memset(&ises, 0, sizeof(SoD::structs::WornEffectStruct)); memset(&ises, 0, sizeof(SoD::structs::WornEffectStruct));
@ -3813,13 +3804,13 @@ namespace SoD
ises.type = item->Scroll.Type; ises.type = item->Scroll.Type;
ises.level = item->Scroll.Level; ises.level = item->Scroll.Level;
ss.write((const char*)&ises, sizeof(SoD::structs::WornEffectStruct)); ob.write((const char*)&ises, sizeof(SoD::structs::WornEffectStruct));
if (strlen(item->ScrollName) > 0) if (strlen(item->ScrollName) > 0)
ss.write((const char*)item->ScrollName, strlen(item->ScrollName)); ob.write((const char*)item->ScrollName, strlen(item->ScrollName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// End of Effects // End of Effects
SoD::structs::ItemQuaternaryBodyStruct iqbs; SoD::structs::ItemQuaternaryBodyStruct iqbs;
@ -3849,12 +3840,12 @@ namespace SoD
iqbs.SpellDmg = item->SpellDmg; iqbs.SpellDmg = item->SpellDmg;
iqbs.Clairvoyance = item->Clairvoyance; iqbs.Clairvoyance = item->Clairvoyance;
ss.write((const char*)&iqbs, sizeof(SoD::structs::ItemQuaternaryBodyStruct)); ob.write((const char*)&iqbs, sizeof(SoD::structs::ItemQuaternaryBodyStruct));
std::stringstream::pos_type count_pos = ss.tellp(); std::stringstream::pos_type count_pos = ob.tellp();
uint32 subitem_count = 0; uint32 subitem_count = 0;
ss.write((const char*)&subitem_count, sizeof(uint32)); ob.write((const char*)&subitem_count, sizeof(uint32));
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) { for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
ItemInst* sub = inst->GetItem(index); ItemInst* sub = inst->GetItem(index);
@ -3871,20 +3862,14 @@ namespace SoD
else else
SubSlotNumber = slot_id_in; SubSlotNumber = slot_id_in;
ss.write((const char*)&index, sizeof(uint32)); ob.write((const char*)&index, sizeof(uint32));
SerializeItem(ss, sub, SubSlotNumber, (depth + 1)); SerializeItem(ob, sub, SubSlotNumber, (depth + 1));
++subitem_count; ++subitem_count;
} }
if (subitem_count) { if (subitem_count)
std::stringstream::pos_type cur_pos = ss.tellp(); ob.overwrite(count_pos, (const char*)&subitem_count, sizeof(uint32));
ss.seekp(count_pos);
ss.write((const char*)&subitem_count, sizeof(uint32));
ss.seekp(cur_pos);
}
} }
static inline uint32 ServerToSoDSlot(uint32 serverSlot) static inline uint32 ServerToSoDSlot(uint32 serverSlot)

View File

@ -22,7 +22,7 @@ namespace SoF
static OpcodeManager *opcodes = nullptr; static OpcodeManager *opcodes = nullptr;
static Strategy struct_strategy; static Strategy struct_strategy;
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id, uint8 depth); void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth);
// server to client inventory location converters // server to client inventory location converters
static inline uint32 ServerToSoFSlot(uint32 serverSlot); static inline uint32 ServerToSoFSlot(uint32 serverSlot);
@ -343,24 +343,21 @@ namespace SoF
InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer; InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer;
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
ss.write((const char*)&item_count, sizeof(uint32)); ob.write((const char*)&item_count, sizeof(uint32));
for (int index = 0; index < item_count; ++index, ++eq) { for (int index = 0; index < item_count; ++index, ++eq) {
SerializeItem(ss, (const ItemInst*)eq->inst, eq->slot_id, 0); SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
if (ss.tellp() == last_pos) if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id); Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
last_pos = ss.tellp(); last_pos = ob.tellp();
} }
std::string serialized = ss.str(); in->size = ob.size();
in->pBuffer = ob.detach();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
delete[] __emu_buffer; delete[] __emu_buffer;
@ -823,29 +820,23 @@ namespace SoF
//store away the emu struct //store away the emu struct
uchar* __emu_buffer = in->pBuffer; uchar* __emu_buffer = in->pBuffer;
//ItemPacket_Struct* old_item_pkt = (ItemPacket_Struct*)__emu_buffer;
//InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(old_item_pkt->SerializedItem);
InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(&__emu_buffer[4]); InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(&__emu_buffer[4]);
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
ss.write((const char*)__emu_buffer, 4); ob.write((const char*)__emu_buffer, 4);
SerializeItem(ss, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0); SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
if (ss.tellp() == last_pos) { if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id); Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in; delete in;
return; return;
} }
std::string serialized = ss.str(); in->size = ob.size();
in->pBuffer = ob.detach();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
//ItemPacket_Struct* new_item_pkt = (ItemPacket_Struct*)in->pBuffer;
//new_item_pkt->PacketType = old_item_pkt->PacketType;
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
delete[] __emu_buffer; delete[] __emu_buffer;
@ -2865,7 +2856,7 @@ namespace SoF
return NextItemInstSerialNumber; return NextItemInstSerialNumber;
} }
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id_in, uint8 depth) void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
{ {
const Item_Struct *item = inst->GetUnscaledItem(); const Item_Struct *item = inst->GetUnscaledItem();
@ -2893,19 +2884,19 @@ namespace SoF
hdr.unknown061 = 0; hdr.unknown061 = 0;
hdr.ItemClass = item->ItemClass; hdr.ItemClass = item->ItemClass;
ss.write((const char*)&hdr, sizeof(SoF::structs::ItemSerializationHeader)); ob.write((const char*)&hdr, sizeof(SoF::structs::ItemSerializationHeader));
if (strlen(item->Name) > 0) if (strlen(item->Name) > 0)
ss.write(item->Name, strlen(item->Name)); ob.write(item->Name, strlen(item->Name));
ss.write("\0", 1); ob.write("\0", 1);
if (strlen(item->Lore) > 0) if (strlen(item->Lore) > 0)
ss.write(item->Lore, strlen(item->Lore)); ob.write(item->Lore, strlen(item->Lore));
ss.write("\0", 1); ob.write("\0", 1);
if (strlen(item->IDFile) > 0) if (strlen(item->IDFile) > 0)
ss.write(item->IDFile, strlen(item->IDFile)); ob.write(item->IDFile, strlen(item->IDFile));
ss.write("\0", 1); ob.write("\0", 1);
SoF::structs::ItemBodyStruct ibs; SoF::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(SoF::structs::ItemBodyStruct)); memset(&ibs, 0, sizeof(SoF::structs::ItemBodyStruct));
@ -2994,12 +2985,12 @@ namespace SoF
ibs.FactionAmt4 = item->FactionAmt4; ibs.FactionAmt4 = item->FactionAmt4;
ibs.FactionMod4 = item->FactionMod4; ibs.FactionMod4 = item->FactionMod4;
ss.write((const char*)&ibs, sizeof(SoF::structs::ItemBodyStruct)); ob.write((const char*)&ibs, sizeof(SoF::structs::ItemBodyStruct));
//charm text //charm text
if (strlen(item->CharmFile) > 0) if (strlen(item->CharmFile) > 0)
ss.write((const char*)item->CharmFile, strlen(item->CharmFile)); ob.write((const char*)item->CharmFile, strlen(item->CharmFile));
ss.write("\0", 1); ob.write("\0", 1);
SoF::structs::ItemSecondaryBodyStruct isbs; SoF::structs::ItemSecondaryBodyStruct isbs;
memset(&isbs, 0, sizeof(SoF::structs::ItemSecondaryBodyStruct)); memset(&isbs, 0, sizeof(SoF::structs::ItemSecondaryBodyStruct));
@ -3027,11 +3018,11 @@ namespace SoF
isbs.book = item->Book; isbs.book = item->Book;
isbs.booktype = item->BookType; isbs.booktype = item->BookType;
ss.write((const char*)&isbs, sizeof(SoF::structs::ItemSecondaryBodyStruct)); ob.write((const char*)&isbs, sizeof(SoF::structs::ItemSecondaryBodyStruct));
if (strlen(item->Filename) > 0) if (strlen(item->Filename) > 0)
ss.write((const char*)item->Filename, strlen(item->Filename)); ob.write((const char*)item->Filename, strlen(item->Filename));
ss.write("\0", 1); ob.write("\0", 1);
SoF::structs::ItemTertiaryBodyStruct itbs; SoF::structs::ItemTertiaryBodyStruct itbs;
memset(&itbs, 0, sizeof(SoF::structs::ItemTertiaryBodyStruct)); memset(&itbs, 0, sizeof(SoF::structs::ItemTertiaryBodyStruct));
@ -3055,7 +3046,7 @@ namespace SoF
itbs.no_transfer = item->NoTransfer; itbs.no_transfer = item->NoTransfer;
itbs.expendablearrow = item->ExpendableArrow; itbs.expendablearrow = item->ExpendableArrow;
ss.write((const char*)&itbs, sizeof(SoF::structs::ItemTertiaryBodyStruct)); ob.write((const char*)&itbs, sizeof(SoF::structs::ItemTertiaryBodyStruct));
// Effect Structures Broken down to allow variable length strings for effect names // Effect Structures Broken down to allow variable length strings for effect names
int32 effect_unknown = 0; int32 effect_unknown = 0;
@ -3072,13 +3063,13 @@ namespace SoF
ices.recast = item->RecastDelay; ices.recast = item->RecastDelay;
ices.recast_type = item->RecastType; ices.recast_type = item->RecastType;
ss.write((const char*)&ices, sizeof(SoF::structs::ClickEffectStruct)); ob.write((const char*)&ices, sizeof(SoF::structs::ClickEffectStruct));
if (strlen(item->ClickName) > 0) if (strlen(item->ClickName) > 0)
ss.write((const char*)item->ClickName, strlen(item->ClickName)); ob.write((const char*)item->ClickName, strlen(item->ClickName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7 ob.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7
SoF::structs::ProcEffectStruct ipes; SoF::structs::ProcEffectStruct ipes;
memset(&ipes, 0, sizeof(SoF::structs::ProcEffectStruct)); memset(&ipes, 0, sizeof(SoF::structs::ProcEffectStruct));
@ -3089,13 +3080,13 @@ namespace SoF
ipes.level = item->Proc.Level; ipes.level = item->Proc.Level;
ipes.procrate = item->ProcRate; ipes.procrate = item->ProcRate;
ss.write((const char*)&ipes, sizeof(SoF::structs::ProcEffectStruct)); ob.write((const char*)&ipes, sizeof(SoF::structs::ProcEffectStruct));
if (strlen(item->ProcName) > 0) if (strlen(item->ProcName) > 0)
ss.write((const char*)item->ProcName, strlen(item->ProcName)); ob.write((const char*)item->ProcName, strlen(item->ProcName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown5 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown5
SoF::structs::WornEffectStruct iwes; SoF::structs::WornEffectStruct iwes;
memset(&iwes, 0, sizeof(SoF::structs::WornEffectStruct)); memset(&iwes, 0, sizeof(SoF::structs::WornEffectStruct));
@ -3105,13 +3096,13 @@ namespace SoF
iwes.type = item->Worn.Type; iwes.type = item->Worn.Type;
iwes.level = item->Worn.Level; iwes.level = item->Worn.Level;
ss.write((const char*)&iwes, sizeof(SoF::structs::WornEffectStruct)); ob.write((const char*)&iwes, sizeof(SoF::structs::WornEffectStruct));
if (strlen(item->WornName) > 0) if (strlen(item->WornName) > 0)
ss.write((const char*)item->WornName, strlen(item->WornName)); ob.write((const char*)item->WornName, strlen(item->WornName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
SoF::structs::WornEffectStruct ifes; SoF::structs::WornEffectStruct ifes;
memset(&ifes, 0, sizeof(SoF::structs::WornEffectStruct)); memset(&ifes, 0, sizeof(SoF::structs::WornEffectStruct));
@ -3121,13 +3112,13 @@ namespace SoF
ifes.type = item->Focus.Type; ifes.type = item->Focus.Type;
ifes.level = item->Focus.Level; ifes.level = item->Focus.Level;
ss.write((const char*)&ifes, sizeof(SoF::structs::WornEffectStruct)); ob.write((const char*)&ifes, sizeof(SoF::structs::WornEffectStruct));
if (strlen(item->FocusName) > 0) if (strlen(item->FocusName) > 0)
ss.write((const char*)item->FocusName, strlen(item->FocusName)); ob.write((const char*)item->FocusName, strlen(item->FocusName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
SoF::structs::WornEffectStruct ises; SoF::structs::WornEffectStruct ises;
memset(&ises, 0, sizeof(SoF::structs::WornEffectStruct)); memset(&ises, 0, sizeof(SoF::structs::WornEffectStruct));
@ -3137,13 +3128,13 @@ namespace SoF
ises.type = item->Scroll.Type; ises.type = item->Scroll.Type;
ises.level = item->Scroll.Level; ises.level = item->Scroll.Level;
ss.write((const char*)&ises, sizeof(SoF::structs::WornEffectStruct)); ob.write((const char*)&ises, sizeof(SoF::structs::WornEffectStruct));
if (strlen(item->ScrollName) > 0) if (strlen(item->ScrollName) > 0)
ss.write((const char*)item->ScrollName, strlen(item->ScrollName)); ob.write((const char*)item->ScrollName, strlen(item->ScrollName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// End of Effects // End of Effects
SoF::structs::ItemQuaternaryBodyStruct iqbs; SoF::structs::ItemQuaternaryBodyStruct iqbs;
@ -3172,12 +3163,12 @@ namespace SoF
iqbs.HealAmt = item->HealAmt; iqbs.HealAmt = item->HealAmt;
iqbs.SpellDmg = item->SpellDmg; iqbs.SpellDmg = item->SpellDmg;
ss.write((const char*)&iqbs, sizeof(SoF::structs::ItemQuaternaryBodyStruct)); ob.write((const char*)&iqbs, sizeof(SoF::structs::ItemQuaternaryBodyStruct));
std::stringstream::pos_type count_pos = ss.tellp(); std::stringstream::pos_type count_pos = ob.tellp();
uint32 subitem_count = 0; uint32 subitem_count = 0;
ss.write((const char*)&subitem_count, sizeof(uint32)); ob.write((const char*)&subitem_count, sizeof(uint32));
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) { for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
ItemInst* sub = inst->GetItem(index); ItemInst* sub = inst->GetItem(index);
@ -3194,20 +3185,14 @@ namespace SoF
else else
SubSlotNumber = slot_id_in; SubSlotNumber = slot_id_in;
ss.write((const char*)&index, sizeof(uint32)); ob.write((const char*)&index, sizeof(uint32));
SerializeItem(ss, sub, SubSlotNumber, (depth + 1)); SerializeItem(ob, sub, SubSlotNumber, (depth + 1));
++subitem_count; ++subitem_count;
} }
if (subitem_count) { if (subitem_count)
std::stringstream::pos_type cur_pos = ss.tellp(); ob.overwrite(count_pos, (const char*)&subitem_count, sizeof(uint32));
ss.seekp(count_pos);
ss.write((const char*)&subitem_count, sizeof(uint32));
ss.seekp(cur_pos);
}
} }
static inline uint32 ServerToSoFSlot(uint32 serverSlot) static inline uint32 ServerToSoFSlot(uint32 serverSlot)

View File

@ -20,7 +20,7 @@ namespace Titanium
static OpcodeManager *opcodes = nullptr; static OpcodeManager *opcodes = nullptr;
static Strategy struct_strategy; static Strategy struct_strategy;
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id_in, uint8 depth); void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth);
// server to client inventory location converters // server to client inventory location converters
static inline int16 ServerToTitaniumSlot(uint32 serverSlot); static inline int16 ServerToTitaniumSlot(uint32 serverSlot);
@ -272,25 +272,23 @@ namespace Titanium
delete in; delete in;
return; return;
} }
InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer; InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer;
//do the transform... //do the transform...
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
for (int r = 0; r < itemcount; r++, eq++) { for (int r = 0; r < itemcount; r++, eq++) {
SerializeItem(ss, (const ItemInst*)eq->inst, eq->slot_id, 0); SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
if (ss.tellp() == last_pos) if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id); Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
last_pos = ss.tellp(); last_pos = ob.tellp();
} }
std::string serialized = ss.str(); in->size = ob.size();
in->pBuffer = ob.detach();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
delete[] __emu_buffer; delete[] __emu_buffer;
@ -720,29 +718,23 @@ namespace Titanium
//store away the emu struct //store away the emu struct
uchar* __emu_buffer = in->pBuffer; uchar* __emu_buffer = in->pBuffer;
//ItemPacket_Struct* old_item_pkt = (ItemPacket_Struct*)__emu_buffer;
//InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(old_item_pkt->SerializedItem);
InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(&__emu_buffer[4]); InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(&__emu_buffer[4]);
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
ss.write((const char*)__emu_buffer, 4); ob.write((const char*)__emu_buffer, 4);
SerializeItem(ss, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0); SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
if (ss.tellp() == last_pos) { if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id); Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in; delete in;
return; return;
} }
std::string serialized = ss.str(); in->size = ob.size();
in->pBuffer = ob.detach();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
//ItemPacket_Struct* new_item_pkt = (ItemPacket_Struct*)in->pBuffer;
//new_item_pkt->PacketType = old_item_pkt->PacketType;
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
delete[] __emu_buffer; delete[] __emu_buffer;
@ -2083,241 +2075,241 @@ namespace Titanium
} }
// file scope helper methods // file scope helper methods
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id_in, uint8 depth) void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
{ {
const char* protection = "\\\\\\\\\\"; const char* protection = "\\\\\\\\\\";
const Item_Struct* item = inst->GetUnscaledItem(); const Item_Struct* item = inst->GetUnscaledItem();
ss << StringFormat("%.*s%s", (depth ? (depth - 1) : 0), protection, (depth ? "\"" : "")); // For leading quotes (and protection) if a subitem; ob << StringFormat("%.*s%s", (depth ? (depth - 1) : 0), protection, (depth ? "\"" : "")); // For leading quotes (and protection) if a subitem;
// Instance data // Instance data
ss << itoa((inst->IsStackable() ? inst->GetCharges() : 0)); // stack count ob << itoa((inst->IsStackable() ? inst->GetCharges() : 0)); // stack count
ss << '|' << itoa(0); // unknown ob << '|' << itoa(0); // unknown
ss << '|' << itoa((!inst->GetMerchantSlot() ? slot_id_in : inst->GetMerchantSlot())); // inst slot/merchant slot ob << '|' << itoa((!inst->GetMerchantSlot() ? slot_id_in : inst->GetMerchantSlot())); // inst slot/merchant slot
ss << '|' << itoa(inst->GetPrice()); // merchant price ob << '|' << itoa(inst->GetPrice()); // merchant price
ss << '|' << itoa((!inst->GetMerchantSlot() ? 1 : inst->GetMerchantCount())); // inst count/merchant count ob << '|' << itoa((!inst->GetMerchantSlot() ? 1 : inst->GetMerchantCount())); // inst count/merchant count
ss << '|' << itoa((inst->IsScaling() ? (inst->GetExp() / 100) : 0)); // inst experience ob << '|' << itoa((inst->IsScaling() ? (inst->GetExp() / 100) : 0)); // inst experience
ss << '|' << itoa((!inst->GetMerchantSlot() ? inst->GetSerialNumber() : inst->GetMerchantSlot())); // merchant serial number ob << '|' << itoa((!inst->GetMerchantSlot() ? inst->GetSerialNumber() : inst->GetMerchantSlot())); // merchant serial number
ss << '|' << itoa(inst->GetRecastTimestamp()); // recast timestamp ob << '|' << itoa(inst->GetRecastTimestamp()); // recast timestamp
ss << '|' << itoa(((inst->IsStackable() ? ((inst->GetItem()->ItemType == ItemTypePotion) ? 1 : 0) : inst->GetCharges()))); // charge count ob << '|' << itoa(((inst->IsStackable() ? ((inst->GetItem()->ItemType == ItemTypePotion) ? 1 : 0) : inst->GetCharges()))); // charge count
ss << '|' << itoa((inst->IsAttuned() ? 1 : 0)); // inst attuned ob << '|' << itoa((inst->IsAttuned() ? 1 : 0)); // inst attuned
ss << '|' << itoa(0); // unknown ob << '|' << itoa(0); // unknown
ss << '|'; ob << '|';
ss << StringFormat("%.*s\"", depth, protection); // Quotes (and protection, if needed) around static data ob << StringFormat("%.*s\"", depth, protection); // Quotes (and protection, if needed) around static data
// Item data // Item data
ss << itoa(item->ItemClass); ob << itoa(item->ItemClass);
ss << '|' << item->Name; ob << '|' << item->Name;
ss << '|' << item->Lore; ob << '|' << item->Lore;
ss << '|' << item->IDFile; ob << '|' << item->IDFile;
ss << '|' << itoa(item->ID); ob << '|' << itoa(item->ID);
ss << '|' << itoa(((item->Weight > 255) ? 255 : item->Weight)); ob << '|' << itoa(((item->Weight > 255) ? 255 : item->Weight));
ss << '|' << itoa(item->NoRent); ob << '|' << itoa(item->NoRent);
ss << '|' << itoa(item->NoDrop); ob << '|' << itoa(item->NoDrop);
ss << '|' << itoa(item->Size); ob << '|' << itoa(item->Size);
ss << '|' << itoa(item->Slots); ob << '|' << itoa(item->Slots);
ss << '|' << itoa(item->Price); ob << '|' << itoa(item->Price);
ss << '|' << itoa(item->Icon); ob << '|' << itoa(item->Icon);
ss << '|' << "0"; ob << '|' << "0";
ss << '|' << "0"; ob << '|' << "0";
ss << '|' << itoa(item->BenefitFlag); ob << '|' << itoa(item->BenefitFlag);
ss << '|' << itoa(item->Tradeskills); ob << '|' << itoa(item->Tradeskills);
ss << '|' << itoa(item->CR); ob << '|' << itoa(item->CR);
ss << '|' << itoa(item->DR); ob << '|' << itoa(item->DR);
ss << '|' << itoa(item->PR); ob << '|' << itoa(item->PR);
ss << '|' << itoa(item->MR); ob << '|' << itoa(item->MR);
ss << '|' << itoa(item->FR); ob << '|' << itoa(item->FR);
ss << '|' << itoa(item->AStr); ob << '|' << itoa(item->AStr);
ss << '|' << itoa(item->ASta); ob << '|' << itoa(item->ASta);
ss << '|' << itoa(item->AAgi); ob << '|' << itoa(item->AAgi);
ss << '|' << itoa(item->ADex); ob << '|' << itoa(item->ADex);
ss << '|' << itoa(item->ACha); ob << '|' << itoa(item->ACha);
ss << '|' << itoa(item->AInt); ob << '|' << itoa(item->AInt);
ss << '|' << itoa(item->AWis); ob << '|' << itoa(item->AWis);
ss << '|' << itoa(item->HP); ob << '|' << itoa(item->HP);
ss << '|' << itoa(item->Mana); ob << '|' << itoa(item->Mana);
ss << '|' << itoa(item->AC); ob << '|' << itoa(item->AC);
ss << '|' << itoa(item->Deity); ob << '|' << itoa(item->Deity);
ss << '|' << itoa(item->SkillModValue); ob << '|' << itoa(item->SkillModValue);
ss << '|' << itoa(item->SkillModMax); ob << '|' << itoa(item->SkillModMax);
ss << '|' << itoa(item->SkillModType); ob << '|' << itoa(item->SkillModType);
ss << '|' << itoa(item->BaneDmgRace); ob << '|' << itoa(item->BaneDmgRace);
ss << '|' << itoa(item->BaneDmgAmt); ob << '|' << itoa(item->BaneDmgAmt);
ss << '|' << itoa(item->BaneDmgBody); ob << '|' << itoa(item->BaneDmgBody);
ss << '|' << itoa(item->Magic); ob << '|' << itoa(item->Magic);
ss << '|' << itoa(item->CastTime_); ob << '|' << itoa(item->CastTime_);
ss << '|' << itoa(item->ReqLevel); ob << '|' << itoa(item->ReqLevel);
ss << '|' << itoa(item->BardType); ob << '|' << itoa(item->BardType);
ss << '|' << itoa(item->BardValue); ob << '|' << itoa(item->BardValue);
ss << '|' << itoa(item->Light); ob << '|' << itoa(item->Light);
ss << '|' << itoa(item->Delay); ob << '|' << itoa(item->Delay);
ss << '|' << itoa(item->RecLevel); ob << '|' << itoa(item->RecLevel);
ss << '|' << itoa(item->RecSkill); ob << '|' << itoa(item->RecSkill);
ss << '|' << itoa(item->ElemDmgType); ob << '|' << itoa(item->ElemDmgType);
ss << '|' << itoa(item->ElemDmgAmt); ob << '|' << itoa(item->ElemDmgAmt);
ss << '|' << itoa(item->Range); ob << '|' << itoa(item->Range);
ss << '|' << itoa(item->Damage); ob << '|' << itoa(item->Damage);
ss << '|' << itoa(item->Color); ob << '|' << itoa(item->Color);
ss << '|' << itoa(item->Classes); ob << '|' << itoa(item->Classes);
ss << '|' << itoa(item->Races); ob << '|' << itoa(item->Races);
ss << '|' << "0"; ob << '|' << "0";
ss << '|' << itoa(item->MaxCharges); ob << '|' << itoa(item->MaxCharges);
ss << '|' << itoa(item->ItemType); ob << '|' << itoa(item->ItemType);
ss << '|' << itoa(item->Material); ob << '|' << itoa(item->Material);
ss << '|' << StringFormat("%f", item->SellRate); ob << '|' << StringFormat("%f", item->SellRate);
ss << '|' << "0"; ob << '|' << "0";
ss << '|' << itoa(item->CastTime_); ob << '|' << itoa(item->CastTime_);
ss << '|' << "0"; ob << '|' << "0";
ss << '|' << itoa(item->ProcRate); ob << '|' << itoa(item->ProcRate);
ss << '|' << itoa(item->CombatEffects); ob << '|' << itoa(item->CombatEffects);
ss << '|' << itoa(item->Shielding); ob << '|' << itoa(item->Shielding);
ss << '|' << itoa(item->StunResist); ob << '|' << itoa(item->StunResist);
ss << '|' << itoa(item->StrikeThrough); ob << '|' << itoa(item->StrikeThrough);
ss << '|' << itoa(item->ExtraDmgSkill); ob << '|' << itoa(item->ExtraDmgSkill);
ss << '|' << itoa(item->ExtraDmgAmt); ob << '|' << itoa(item->ExtraDmgAmt);
ss << '|' << itoa(item->SpellShield); ob << '|' << itoa(item->SpellShield);
ss << '|' << itoa(item->Avoidance); ob << '|' << itoa(item->Avoidance);
ss << '|' << itoa(item->Accuracy); ob << '|' << itoa(item->Accuracy);
ss << '|' << itoa(item->CharmFileID); ob << '|' << itoa(item->CharmFileID);
ss << '|' << itoa(item->FactionMod1); ob << '|' << itoa(item->FactionMod1);
ss << '|' << itoa(item->FactionMod2); ob << '|' << itoa(item->FactionMod2);
ss << '|' << itoa(item->FactionMod3); ob << '|' << itoa(item->FactionMod3);
ss << '|' << itoa(item->FactionMod4); ob << '|' << itoa(item->FactionMod4);
ss << '|' << itoa(item->FactionAmt1); ob << '|' << itoa(item->FactionAmt1);
ss << '|' << itoa(item->FactionAmt2); ob << '|' << itoa(item->FactionAmt2);
ss << '|' << itoa(item->FactionAmt3); ob << '|' << itoa(item->FactionAmt3);
ss << '|' << itoa(item->FactionAmt4); ob << '|' << itoa(item->FactionAmt4);
ss << '|' << item->CharmFile; ob << '|' << item->CharmFile;
ss << '|' << itoa(item->AugType); ob << '|' << itoa(item->AugType);
ss << '|' << itoa(item->AugSlotType[0]); ob << '|' << itoa(item->AugSlotType[0]);
ss << '|' << itoa(item->AugSlotVisible[0]); ob << '|' << itoa(item->AugSlotVisible[0]);
ss << '|' << itoa(item->AugSlotType[1]); ob << '|' << itoa(item->AugSlotType[1]);
ss << '|' << itoa(item->AugSlotVisible[1]); ob << '|' << itoa(item->AugSlotVisible[1]);
ss << '|' << itoa(item->AugSlotType[2]); ob << '|' << itoa(item->AugSlotType[2]);
ss << '|' << itoa(item->AugSlotVisible[2]); ob << '|' << itoa(item->AugSlotVisible[2]);
ss << '|' << itoa(item->AugSlotType[3]); ob << '|' << itoa(item->AugSlotType[3]);
ss << '|' << itoa(item->AugSlotVisible[3]); ob << '|' << itoa(item->AugSlotVisible[3]);
ss << '|' << itoa(item->AugSlotType[4]); ob << '|' << itoa(item->AugSlotType[4]);
ss << '|' << itoa(item->AugSlotVisible[4]); ob << '|' << itoa(item->AugSlotVisible[4]);
ss << '|' << itoa(item->LDoNTheme); ob << '|' << itoa(item->LDoNTheme);
ss << '|' << itoa(item->LDoNPrice); ob << '|' << itoa(item->LDoNPrice);
ss << '|' << itoa(item->LDoNSold); ob << '|' << itoa(item->LDoNSold);
ss << '|' << itoa(item->BagType); ob << '|' << itoa(item->BagType);
ss << '|' << itoa(item->BagSlots); ob << '|' << itoa(item->BagSlots);
ss << '|' << itoa(item->BagSize); ob << '|' << itoa(item->BagSize);
ss << '|' << itoa(item->BagWR); ob << '|' << itoa(item->BagWR);
ss << '|' << itoa(item->Book); ob << '|' << itoa(item->Book);
ss << '|' << itoa(item->BookType); ob << '|' << itoa(item->BookType);
ss << '|' << item->Filename; ob << '|' << item->Filename;
ss << '|' << itoa(item->BaneDmgRaceAmt); ob << '|' << itoa(item->BaneDmgRaceAmt);
ss << '|' << itoa(item->AugRestrict); ob << '|' << itoa(item->AugRestrict);
ss << '|' << itoa(item->LoreGroup); ob << '|' << itoa(item->LoreGroup);
ss << '|' << itoa(item->PendingLoreFlag); ob << '|' << itoa(item->PendingLoreFlag);
ss << '|' << itoa(item->ArtifactFlag); ob << '|' << itoa(item->ArtifactFlag);
ss << '|' << itoa(item->SummonedFlag); ob << '|' << itoa(item->SummonedFlag);
ss << '|' << itoa(item->Favor); ob << '|' << itoa(item->Favor);
ss << '|' << itoa(item->FVNoDrop); ob << '|' << itoa(item->FVNoDrop);
ss << '|' << itoa(item->Endur); ob << '|' << itoa(item->Endur);
ss << '|' << itoa(item->DotShielding); ob << '|' << itoa(item->DotShielding);
ss << '|' << itoa(item->Attack); ob << '|' << itoa(item->Attack);
ss << '|' << itoa(item->Regen); ob << '|' << itoa(item->Regen);
ss << '|' << itoa(item->ManaRegen); ob << '|' << itoa(item->ManaRegen);
ss << '|' << itoa(item->EnduranceRegen); ob << '|' << itoa(item->EnduranceRegen);
ss << '|' << itoa(item->Haste); ob << '|' << itoa(item->Haste);
ss << '|' << itoa(item->DamageShield); ob << '|' << itoa(item->DamageShield);
ss << '|' << itoa(item->RecastDelay); ob << '|' << itoa(item->RecastDelay);
ss << '|' << itoa(item->RecastType); ob << '|' << itoa(item->RecastType);
ss << '|' << itoa(item->GuildFavor); ob << '|' << itoa(item->GuildFavor);
ss << '|' << itoa(item->AugDistiller); ob << '|' << itoa(item->AugDistiller);
ss << '|' << "0"; // unknown ob << '|' << "0"; // unknown
ss << '|' << "0"; // unknown ob << '|' << "0"; // unknown
ss << '|' << itoa(item->Attuneable); ob << '|' << itoa(item->Attuneable);
ss << '|' << itoa(item->NoPet); ob << '|' << itoa(item->NoPet);
ss << '|' << "0"; // unknown ob << '|' << "0"; // unknown
ss << '|' << itoa(item->PointType); ob << '|' << itoa(item->PointType);
ss << '|' << itoa(item->PotionBelt); ob << '|' << itoa(item->PotionBelt);
ss << '|' << itoa(item->PotionBeltSlots); ob << '|' << itoa(item->PotionBeltSlots);
ss << '|' << itoa(item->StackSize); ob << '|' << itoa(item->StackSize);
ss << '|' << itoa(item->NoTransfer); ob << '|' << itoa(item->NoTransfer);
ss << '|' << itoa(item->Stackable); ob << '|' << itoa(item->Stackable);
ss << '|' << itoa(item->Click.Effect); ob << '|' << itoa(item->Click.Effect);
ss << '|' << itoa(item->Click.Type); ob << '|' << itoa(item->Click.Type);
ss << '|' << itoa(item->Click.Level2); ob << '|' << itoa(item->Click.Level2);
ss << '|' << itoa(item->Click.Level); ob << '|' << itoa(item->Click.Level);
ss << '|' << "0"; // Click name ob << '|' << "0"; // Click name
ss << '|' << itoa(item->Proc.Effect); ob << '|' << itoa(item->Proc.Effect);
ss << '|' << itoa(item->Proc.Type); ob << '|' << itoa(item->Proc.Type);
ss << '|' << itoa(item->Proc.Level2); ob << '|' << itoa(item->Proc.Level2);
ss << '|' << itoa(item->Proc.Level); ob << '|' << itoa(item->Proc.Level);
ss << '|' << "0"; // Proc name ob << '|' << "0"; // Proc name
ss << '|' << itoa(item->Worn.Effect); ob << '|' << itoa(item->Worn.Effect);
ss << '|' << itoa(item->Worn.Type); ob << '|' << itoa(item->Worn.Type);
ss << '|' << itoa(item->Worn.Level2); ob << '|' << itoa(item->Worn.Level2);
ss << '|' << itoa(item->Worn.Level); ob << '|' << itoa(item->Worn.Level);
ss << '|' << "0"; // Worn name ob << '|' << "0"; // Worn name
ss << '|' << itoa(item->Focus.Effect); ob << '|' << itoa(item->Focus.Effect);
ss << '|' << itoa(item->Focus.Type); ob << '|' << itoa(item->Focus.Type);
ss << '|' << itoa(item->Focus.Level2); ob << '|' << itoa(item->Focus.Level2);
ss << '|' << itoa(item->Focus.Level); ob << '|' << itoa(item->Focus.Level);
ss << '|' << "0"; // Focus name ob << '|' << "0"; // Focus name
ss << '|' << itoa(item->Scroll.Effect); ob << '|' << itoa(item->Scroll.Effect);
ss << '|' << itoa(item->Scroll.Type); ob << '|' << itoa(item->Scroll.Type);
ss << '|' << itoa(item->Scroll.Level2); ob << '|' << itoa(item->Scroll.Level2);
ss << '|' << itoa(item->Scroll.Level); ob << '|' << itoa(item->Scroll.Level);
ss << '|' << "0"; // Scroll name ob << '|' << "0"; // Scroll name
ss << StringFormat("%.*s\"", depth, protection); // Quotes (and protection, if needed) around static data ob << StringFormat("%.*s\"", depth, protection); // Quotes (and protection, if needed) around static data
// Sub data // Sub data
for (int index = SUB_INDEX_BEGIN; index < consts::ITEM_CONTAINER_SIZE; ++index) { for (int index = SUB_INDEX_BEGIN; index < consts::ITEM_CONTAINER_SIZE; ++index) {
ss << '|'; ob << '|';
ItemInst* sub = inst->GetItem(index); ItemInst* sub = inst->GetItem(index);
if (!sub) if (!sub)
continue; continue;
SerializeItem(ss, sub, 0, (depth + 1)); SerializeItem(ob, sub, 0, (depth + 1));
} }
ss << StringFormat("%.*s%s", (depth ? (depth - 1) : 0), protection, (depth ? "\"" : "")); // For trailing quotes (and protection) if a subitem; ob << StringFormat("%.*s%s", (depth ? (depth - 1) : 0), protection, (depth ? "\"" : "")); // For trailing quotes (and protection) if a subitem;
if (!depth) if (!depth)
ss.write("\0", 1); ob.write("\0", 1);
} }
static inline int16 ServerToTitaniumSlot(uint32 serverSlot) static inline int16 ServerToTitaniumSlot(uint32 serverSlot)

View File

@ -22,7 +22,7 @@ namespace UF
static OpcodeManager *opcodes = nullptr; static OpcodeManager *opcodes = nullptr;
static Strategy struct_strategy; static Strategy struct_strategy;
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id, uint8 depth); void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth);
// server to client inventory location converters // server to client inventory location converters
static inline uint32 ServerToUFSlot(uint32 serverSlot); static inline uint32 ServerToUFSlot(uint32 serverSlot);
@ -499,24 +499,21 @@ namespace UF
InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer; InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer;
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
ss.write((const char*)&item_count, sizeof(uint32)); ob.write((const char*)&item_count, sizeof(uint32));
for (int index = 0; index < item_count; ++index, ++eq) { for (int index = 0; index < item_count; ++index, ++eq) {
SerializeItem(ss, (const ItemInst*)eq->inst, eq->slot_id, 0); SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
if (ss.tellp() == last_pos) if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id); Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
last_pos = ss.tellp(); last_pos = ob.tellp();
} }
std::string serialized = ss.str(); in->size = ob.size();
in->pBuffer = ob.detach();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
delete[] __emu_buffer; delete[] __emu_buffer;
@ -1249,29 +1246,23 @@ namespace UF
//store away the emu struct //store away the emu struct
uchar* __emu_buffer = in->pBuffer; uchar* __emu_buffer = in->pBuffer;
//ItemPacket_Struct* old_item_pkt = (ItemPacket_Struct*)__emu_buffer;
//InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(old_item_pkt->SerializedItem);
InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(&__emu_buffer[4]); InternalSerializedItem_Struct* int_struct = (InternalSerializedItem_Struct*)(&__emu_buffer[4]);
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
ss.write((const char*)__emu_buffer, 4); ob.write((const char*)__emu_buffer, 4);
SerializeItem(ss, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0); SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
if (ss.tellp() == last_pos) { if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id); Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in; delete in;
return; return;
} }
std::string serialized = ss.str(); in->size = ob.size();
in->pBuffer = ob.detach();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
//ItemPacket_Struct* new_item_pkt = (ItemPacket_Struct*)in->pBuffer;
//new_item_pkt->PacketType = old_item_pkt->PacketType;
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
delete[] __emu_buffer; delete[] __emu_buffer;
@ -3815,7 +3806,7 @@ namespace UF
return NextItemInstSerialNumber; return NextItemInstSerialNumber;
} }
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id_in, uint8 depth) void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
{ {
const Item_Struct *item = inst->GetUnscaledItem(); const Item_Struct *item = inst->GetUnscaledItem();
@ -3840,7 +3831,7 @@ namespace UF
hdr.unknown052 = 0; hdr.unknown052 = 0;
hdr.isEvolving = item->EvolvingItem; hdr.isEvolving = item->EvolvingItem;
ss.write((const char*)&hdr, sizeof(UF::structs::ItemSerializationHeader)); ob.write((const char*)&hdr, sizeof(UF::structs::ItemSerializationHeader));
if (item->EvolvingItem > 0) { if (item->EvolvingItem > 0) {
UF::structs::EvolvingItem evotop; UF::structs::EvolvingItem evotop;
@ -3854,7 +3845,7 @@ namespace UF
evotop.Activated = 1; evotop.Activated = 1;
evotop.evomaxlevel = item->EvolvingMax; evotop.evomaxlevel = item->EvolvingMax;
ss.write((const char*)&evotop, sizeof(UF::structs::EvolvingItem)); ob.write((const char*)&evotop, sizeof(UF::structs::EvolvingItem));
} }
//ORNAMENT IDFILE / ICON - //ORNAMENT IDFILE / ICON -
@ -3864,15 +3855,15 @@ namespace UF
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem(); const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
ornaIcon = aug_weap->Icon; ornaIcon = aug_weap->Icon;
ss.write(aug_weap->IDFile, strlen(aug_weap->IDFile)); ob.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
} }
else if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) { else if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
ornaIcon = inst->GetOrnamentationIcon(); ornaIcon = inst->GetOrnamentationIcon();
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile()); char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
ss.write(tmp, strlen(tmp)); ob.write(tmp, strlen(tmp));
} }
ss.write("\0", 1); ob.write("\0", 1);
UF::structs::ItemSerializationHeaderFinish hdrf; UF::structs::ItemSerializationHeaderFinish hdrf;
@ -3882,19 +3873,19 @@ namespace UF
hdrf.isCopied = 0; //Flag for item to be 'Copied' hdrf.isCopied = 0; //Flag for item to be 'Copied'
hdrf.ItemClass = item->ItemClass; hdrf.ItemClass = item->ItemClass;
ss.write((const char*)&hdrf, sizeof(UF::structs::ItemSerializationHeaderFinish)); ob.write((const char*)&hdrf, sizeof(UF::structs::ItemSerializationHeaderFinish));
if (strlen(item->Name) > 0) if (strlen(item->Name) > 0)
ss.write(item->Name, strlen(item->Name)); ob.write(item->Name, strlen(item->Name));
ss.write("\0", 1); ob.write("\0", 1);
if (strlen(item->Lore) > 0) if (strlen(item->Lore) > 0)
ss.write(item->Lore, strlen(item->Lore)); ob.write(item->Lore, strlen(item->Lore));
ss.write("\0", 1); ob.write("\0", 1);
if (strlen(item->IDFile) > 0) if (strlen(item->IDFile) > 0)
ss.write(item->IDFile, strlen(item->IDFile)); ob.write(item->IDFile, strlen(item->IDFile));
ss.write("\0", 1); ob.write("\0", 1);
UF::structs::ItemBodyStruct ibs; UF::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(UF::structs::ItemBodyStruct)); memset(&ibs, 0, sizeof(UF::structs::ItemBodyStruct));
@ -3983,12 +3974,12 @@ namespace UF
ibs.FactionAmt4 = item->FactionAmt4; ibs.FactionAmt4 = item->FactionAmt4;
ibs.FactionMod4 = item->FactionMod4; ibs.FactionMod4 = item->FactionMod4;
ss.write((const char*)&ibs, sizeof(UF::structs::ItemBodyStruct)); ob.write((const char*)&ibs, sizeof(UF::structs::ItemBodyStruct));
//charm text //charm text
if (strlen(item->CharmFile) > 0) if (strlen(item->CharmFile) > 0)
ss.write((const char*)item->CharmFile, strlen(item->CharmFile)); ob.write((const char*)item->CharmFile, strlen(item->CharmFile));
ss.write("\0", 1); ob.write("\0", 1);
UF::structs::ItemSecondaryBodyStruct isbs; UF::structs::ItemSecondaryBodyStruct isbs;
memset(&isbs, 0, sizeof(UF::structs::ItemSecondaryBodyStruct)); memset(&isbs, 0, sizeof(UF::structs::ItemSecondaryBodyStruct));
@ -4016,11 +4007,11 @@ namespace UF
isbs.book = item->Book; isbs.book = item->Book;
isbs.booktype = item->BookType; isbs.booktype = item->BookType;
ss.write((const char*)&isbs, sizeof(UF::structs::ItemSecondaryBodyStruct)); ob.write((const char*)&isbs, sizeof(UF::structs::ItemSecondaryBodyStruct));
if (strlen(item->Filename) > 0) if (strlen(item->Filename) > 0)
ss.write((const char*)item->Filename, strlen(item->Filename)); ob.write((const char*)item->Filename, strlen(item->Filename));
ss.write("\0", 1); ob.write("\0", 1);
UF::structs::ItemTertiaryBodyStruct itbs; UF::structs::ItemTertiaryBodyStruct itbs;
memset(&itbs, 0, sizeof(UF::structs::ItemTertiaryBodyStruct)); memset(&itbs, 0, sizeof(UF::structs::ItemTertiaryBodyStruct));
@ -4044,7 +4035,7 @@ namespace UF
itbs.no_transfer = item->NoTransfer; itbs.no_transfer = item->NoTransfer;
itbs.expendablearrow = item->ExpendableArrow; itbs.expendablearrow = item->ExpendableArrow;
ss.write((const char*)&itbs, sizeof(UF::structs::ItemTertiaryBodyStruct)); ob.write((const char*)&itbs, sizeof(UF::structs::ItemTertiaryBodyStruct));
// Effect Structures Broken down to allow variable length strings for effect names // Effect Structures Broken down to allow variable length strings for effect names
int32 effect_unknown = 0; int32 effect_unknown = 0;
@ -4061,13 +4052,13 @@ namespace UF
ices.recast = item->RecastDelay; ices.recast = item->RecastDelay;
ices.recast_type = item->RecastType; ices.recast_type = item->RecastType;
ss.write((const char*)&ices, sizeof(UF::structs::ClickEffectStruct)); ob.write((const char*)&ices, sizeof(UF::structs::ClickEffectStruct));
if (strlen(item->ClickName) > 0) if (strlen(item->ClickName) > 0)
ss.write((const char*)item->ClickName, strlen(item->ClickName)); ob.write((const char*)item->ClickName, strlen(item->ClickName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7 ob.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7
UF::structs::ProcEffectStruct ipes; UF::structs::ProcEffectStruct ipes;
memset(&ipes, 0, sizeof(UF::structs::ProcEffectStruct)); memset(&ipes, 0, sizeof(UF::structs::ProcEffectStruct));
@ -4078,13 +4069,13 @@ namespace UF
ipes.level = item->Proc.Level; ipes.level = item->Proc.Level;
ipes.procrate = item->ProcRate; ipes.procrate = item->ProcRate;
ss.write((const char*)&ipes, sizeof(UF::structs::ProcEffectStruct)); ob.write((const char*)&ipes, sizeof(UF::structs::ProcEffectStruct));
if (strlen(item->ProcName) > 0) if (strlen(item->ProcName) > 0)
ss.write((const char*)item->ProcName, strlen(item->ProcName)); ob.write((const char*)item->ProcName, strlen(item->ProcName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown5 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown5
UF::structs::WornEffectStruct iwes; UF::structs::WornEffectStruct iwes;
memset(&iwes, 0, sizeof(UF::structs::WornEffectStruct)); memset(&iwes, 0, sizeof(UF::structs::WornEffectStruct));
@ -4094,13 +4085,13 @@ namespace UF
iwes.type = item->Worn.Type; iwes.type = item->Worn.Type;
iwes.level = item->Worn.Level; iwes.level = item->Worn.Level;
ss.write((const char*)&iwes, sizeof(UF::structs::WornEffectStruct)); ob.write((const char*)&iwes, sizeof(UF::structs::WornEffectStruct));
if (strlen(item->WornName) > 0) if (strlen(item->WornName) > 0)
ss.write((const char*)item->WornName, strlen(item->WornName)); ob.write((const char*)item->WornName, strlen(item->WornName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
UF::structs::WornEffectStruct ifes; UF::structs::WornEffectStruct ifes;
memset(&ifes, 0, sizeof(UF::structs::WornEffectStruct)); memset(&ifes, 0, sizeof(UF::structs::WornEffectStruct));
@ -4110,13 +4101,13 @@ namespace UF
ifes.type = item->Focus.Type; ifes.type = item->Focus.Type;
ifes.level = item->Focus.Level; ifes.level = item->Focus.Level;
ss.write((const char*)&ifes, sizeof(UF::structs::WornEffectStruct)); ob.write((const char*)&ifes, sizeof(UF::structs::WornEffectStruct));
if (strlen(item->FocusName) > 0) if (strlen(item->FocusName) > 0)
ss.write((const char*)item->FocusName, strlen(item->FocusName)); ob.write((const char*)item->FocusName, strlen(item->FocusName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
UF::structs::WornEffectStruct ises; UF::structs::WornEffectStruct ises;
memset(&ises, 0, sizeof(UF::structs::WornEffectStruct)); memset(&ises, 0, sizeof(UF::structs::WornEffectStruct));
@ -4126,13 +4117,13 @@ namespace UF
ises.type = item->Scroll.Type; ises.type = item->Scroll.Type;
ises.level = item->Scroll.Level; ises.level = item->Scroll.Level;
ss.write((const char*)&ises, sizeof(UF::structs::WornEffectStruct)); ob.write((const char*)&ises, sizeof(UF::structs::WornEffectStruct));
if (strlen(item->ScrollName) > 0) if (strlen(item->ScrollName) > 0)
ss.write((const char*)item->ScrollName, strlen(item->ScrollName)); ob.write((const char*)item->ScrollName, strlen(item->ScrollName));
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// Bard Effect? // Bard Effect?
UF::structs::WornEffectStruct ibes; UF::structs::WornEffectStruct ibes;
@ -4144,18 +4135,18 @@ namespace UF
ibes.level = item->Bard.Level; ibes.level = item->Bard.Level;
//ibes.unknown6 = 0xffffffff; //ibes.unknown6 = 0xffffffff;
ss.write((const char*)&ibes, sizeof(UF::structs::WornEffectStruct)); ob.write((const char*)&ibes, sizeof(UF::structs::WornEffectStruct));
/* /*
if(strlen(item->BardName) > 0) if(strlen(item->BardName) > 0)
{ {
ss.write((const char*)item->BardName, strlen(item->BardName)); ob.write((const char*)item->BardName, strlen(item->BardName));
ss.write((const char*)&null_term, sizeof(uint8)); ob.write((const char*)&null_term, sizeof(uint8));
} }
else */ else */
ss.write("\0", 1); ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// End of Effects // End of Effects
UF::structs::ItemQuaternaryBodyStruct iqbs; UF::structs::ItemQuaternaryBodyStruct iqbs;
@ -4185,12 +4176,12 @@ namespace UF
iqbs.SpellDmg = item->SpellDmg; iqbs.SpellDmg = item->SpellDmg;
iqbs.Clairvoyance = item->Clairvoyance; iqbs.Clairvoyance = item->Clairvoyance;
ss.write((const char*)&iqbs, sizeof(UF::structs::ItemQuaternaryBodyStruct)); ob.write((const char*)&iqbs, sizeof(UF::structs::ItemQuaternaryBodyStruct));
std::stringstream::pos_type count_pos = ss.tellp(); std::stringstream::pos_type count_pos = ob.tellp();
uint32 subitem_count = 0; uint32 subitem_count = 0;
ss.write((const char*)&subitem_count, sizeof(uint32)); ob.write((const char*)&subitem_count, sizeof(uint32));
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) { for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
ItemInst* sub = inst->GetItem(index); ItemInst* sub = inst->GetItem(index);
@ -4207,20 +4198,14 @@ namespace UF
else else
SubSlotNumber = slot_id_in; SubSlotNumber = slot_id_in;
ss.write((const char*)&index, sizeof(uint32)); ob.write((const char*)&index, sizeof(uint32));
SerializeItem(ss, sub, SubSlotNumber, (depth + 1)); SerializeItem(ob, sub, SubSlotNumber, (depth + 1));
++subitem_count; ++subitem_count;
} }
if (subitem_count) { if (subitem_count)
std::stringstream::pos_type cur_pos = ss.tellp(); ob.overwrite(count_pos, (const char*)&subitem_count, sizeof(uint32));
ss.seekp(count_pos);
ss.write((const char*)&subitem_count, sizeof(uint32));
ss.seekp(cur_pos);
}
} }
static inline uint32 ServerToUFSlot(uint32 serverSlot) static inline uint32 ServerToUFSlot(uint32 serverSlot)

View File

@ -415,3 +415,46 @@ void find_replace(std::string& string_subject, const std::string& search_string,
index = string_subject.find_first_of(search_string); index = string_subject.find_first_of(search_string);
} }
} }
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 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
*/
void EQEmu::OutBuffer::overwrite(OutBuffer::pos_type position, const char *_Str, std::streamsize _Count)
{
auto last_pos = tellp();
seekp(position);
write(_Str, _Count);
seekp(last_pos);
}
uchar* EQEmu::OutBuffer::detach()
{
size_t buffer_size = tellp();
if (buffer_size == 0)
return nullptr;
uchar* out_buffer = new uchar[buffer_size];
memcpy(out_buffer, str().c_str(), buffer_size);
flush();
return out_buffer;
}

View File

@ -53,4 +53,36 @@ void MakeLowerString(const char *source, char *target);
void RemoveApostrophes(std::string &s); void RemoveApostrophes(std::string &s);
void find_replace(std::string& string_subject, const std::string& search_string, const std::string& replace_string); void find_replace(std::string& string_subject, const std::string& search_string, const std::string& replace_string);
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 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
*/
namespace EQEmu
{
class OutBuffer : public std::stringstream {
public:
inline size_t size() { return tellp(); }
void overwrite(OutBuffer::pos_type position, const char *_Str, std::streamsize _Count);
uchar* detach();
};
}
#endif #endif

View File

@ -759,8 +759,8 @@ void Client::BulkSendInventoryItems()
RemoveDuplicateLore(false); RemoveDuplicateLore(false);
MoveSlotNotAllowed(false); MoveSlotNotAllowed(false);
std::stringstream ss(std::stringstream::in | std::stringstream::out); EQEmu::OutBuffer ob;
std::stringstream::pos_type last_pos = ss.tellp(); EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
// Possessions items // Possessions items
for (int16 slot_id = SLOT_BEGIN; slot_id < EQEmu::legacy::TYPE_POSSESSIONS_SIZE; slot_id++) { for (int16 slot_id = SLOT_BEGIN; slot_id < EQEmu::legacy::TYPE_POSSESSIONS_SIZE; slot_id++) {
@ -768,24 +768,24 @@ void Client::BulkSendInventoryItems()
if (!inst) if (!inst)
continue; continue;
inst->Serialize(ss, slot_id); inst->Serialize(ob, slot_id);
if (ss.tellp() == last_pos) if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", slot_id); Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", slot_id);
last_pos = ss.tellp(); last_pos = ob.tellp();
} }
// PowerSource item // PowerSource item
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) { if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) {
const ItemInst* inst = m_inv[EQEmu::legacy::SlotPowerSource]; const ItemInst* inst = m_inv[EQEmu::legacy::SlotPowerSource];
if (inst) { if (inst) {
inst->Serialize(ss, EQEmu::legacy::SlotPowerSource); inst->Serialize(ob, EQEmu::legacy::SlotPowerSource);
if (ss.tellp() == last_pos) if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", EQEmu::legacy::SlotPowerSource); Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", EQEmu::legacy::SlotPowerSource);
last_pos = ss.tellp(); last_pos = ob.tellp();
} }
} }
@ -795,12 +795,12 @@ void Client::BulkSendInventoryItems()
if (!inst) if (!inst)
continue; continue;
inst->Serialize(ss, slot_id); inst->Serialize(ob, slot_id);
if (ss.tellp() == last_pos) if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", slot_id); Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", slot_id);
last_pos = ss.tellp(); last_pos = ob.tellp();
} }
// SharedBank items // SharedBank items
@ -809,19 +809,17 @@ void Client::BulkSendInventoryItems()
if (!inst) if (!inst)
continue; continue;
inst->Serialize(ss, slot_id); inst->Serialize(ob, slot_id);
if (ss.tellp() == last_pos) if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", slot_id); Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", slot_id);
last_pos = ss.tellp(); last_pos = ob.tellp();
} }
std::string serialized = ss.str(); EQApplicationPacket* outapp = new EQApplicationPacket(OP_CharInventory);
outapp->size = ob.size();
EQApplicationPacket* outapp = new EQApplicationPacket(OP_CharInventory, serialized.size()); outapp->pBuffer = ob.detach();
memcpy(outapp->pBuffer, serialized.c_str(), serialized.size());
QueuePacket(outapp); QueuePacket(outapp);
safe_delete(outapp); safe_delete(outapp);
} }