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/bodytypes.h"
#include "string_util.h"
#include <list>
#include <map>
#include <sstream>
//#include <sstream>
namespace ItemField
@ -413,7 +415,7 @@ public:
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; }
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 void SetSerialNumber(int32 id) { m_SerialNumber = id; }

View File

@ -24,7 +24,7 @@ namespace RoF
static OpcodeManager *opcodes = nullptr;
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
static inline structs::InventorySlot_Struct ServerToRoFSlot(uint32 serverSlot);
@ -557,24 +557,21 @@ namespace RoF
InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer;
std::stringstream ss(std::stringstream::in | std::stringstream::out);
std::stringstream::pos_type last_pos = ss.tellp();
EQEmu::OutBuffer ob;
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) {
SerializeItem(ss, (const ItemInst*)eq->inst, eq->slot_id, 0);
if (ss.tellp() == last_pos)
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
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);
last_pos = ss.tellp();
last_pos = ob.tellp();
}
std::string serialized = ss.str();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
@ -1492,30 +1489,24 @@ namespace RoF
//store away the emu struct
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]);
std::stringstream ss(std::stringstream::in | std::stringstream::out);
std::stringstream::pos_type last_pos = ss.tellp();
EQEmu::OutBuffer ob;
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);
if (ss.tellp() == last_pos) {
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in;
return;
}
std::string serialized = ss.str();
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());
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@ -5180,7 +5171,7 @@ namespace RoF
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();
@ -5212,7 +5203,7 @@ namespace RoF
hdr.unknown052 = 0;
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) {
RoF::structs::EvolvingItem evotop;
@ -5226,7 +5217,7 @@ namespace RoF
evotop.Activated = 1;
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
@ -5241,16 +5232,16 @@ namespace RoF
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
//Mainhand
ss.write(tmp, strlen(tmp));
ss.write("\0", 1);
ob.write(tmp, strlen(tmp));
ob.write("\0", 1);
//Offhand
ss.write(tmp, strlen(tmp));
ss.write("\0", 1);
ob.write(tmp, strlen(tmp));
ob.write("\0", 1);
}
else {
ss.write("\0", 1); // no main hand Ornamentation
ss.write("\0", 1); // no off hand Ornamentation
ob.write("\0", 1); // no main hand Ornamentation
ob.write("\0", 1); // no off hand Ornamentation
}
RoF::structs::ItemSerializationHeaderFinish hdrf;
@ -5264,21 +5255,21 @@ namespace RoF
hdrf.unknowna5 = 0;
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)
ss.write(item->Name, strlen(item->Name));
ss.write("\0", 1);
ob.write(item->Name, strlen(item->Name));
ob.write("\0", 1);
if (strlen(item->Lore) > 0)
ss.write(item->Lore, strlen(item->Lore));
ss.write("\0", 1);
ob.write(item->Lore, strlen(item->Lore));
ob.write("\0", 1);
if (strlen(item->IDFile) > 0)
ss.write(item->IDFile, strlen(item->IDFile));
ss.write("\0", 1);
ob.write(item->IDFile, strlen(item->IDFile));
ob.write("\0", 1);
ss.write("\0", 1);
ob.write("\0", 1);
RoF::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(RoF::structs::ItemBodyStruct));
@ -5369,12 +5360,12 @@ namespace RoF
ibs.FactionAmt4 = item->FactionAmt4;
ibs.FactionMod4 = item->FactionMod4;
ss.write((const char*)&ibs, sizeof(RoF::structs::ItemBodyStruct));
ob.write((const char*)&ibs, sizeof(RoF::structs::ItemBodyStruct));
//charm text
if (strlen(item->CharmFile) > 0)
ss.write((const char*)item->CharmFile, strlen(item->CharmFile));
ss.write("\0", 1);
ob.write((const char*)item->CharmFile, strlen(item->CharmFile));
ob.write("\0", 1);
RoF::structs::ItemSecondaryBodyStruct isbs;
memset(&isbs, 0, sizeof(RoF::structs::ItemSecondaryBodyStruct));
@ -5403,11 +5394,11 @@ namespace RoF
isbs.book = item->Book;
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)
ss.write((const char*)item->Filename, strlen(item->Filename));
ss.write("\0", 1);
ob.write((const char*)item->Filename, strlen(item->Filename));
ob.write("\0", 1);
RoF::structs::ItemTertiaryBodyStruct itbs;
memset(&itbs, 0, sizeof(RoF::structs::ItemTertiaryBodyStruct));
@ -5442,7 +5433,7 @@ namespace RoF
itbs.unknown13 = 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
int32 effect_unknown = 0;
@ -5459,13 +5450,13 @@ namespace RoF
ices.recast = item->RecastDelay;
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)
ss.write((const char*)item->ClickName, strlen(item->ClickName));
ss.write("\0", 1);
ob.write((const char*)item->ClickName, strlen(item->ClickName));
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;
memset(&ipes, 0, sizeof(RoF::structs::ProcEffectStruct));
@ -5476,13 +5467,13 @@ namespace RoF
ipes.level = item->Proc.Level;
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)
ss.write((const char*)item->ProcName, strlen(item->ProcName));
ss.write("\0", 1);
ob.write((const char*)item->ProcName, strlen(item->ProcName));
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;
memset(&iwes, 0, sizeof(RoF::structs::WornEffectStruct));
@ -5492,13 +5483,13 @@ namespace RoF
iwes.type = item->Worn.Type;
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)
ss.write((const char*)item->WornName, strlen(item->WornName));
ss.write("\0", 1);
ob.write((const char*)item->WornName, strlen(item->WornName));
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;
memset(&ifes, 0, sizeof(RoF::structs::WornEffectStruct));
@ -5508,13 +5499,13 @@ namespace RoF
ifes.type = item->Focus.Type;
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)
ss.write((const char*)item->FocusName, strlen(item->FocusName));
ss.write("\0", 1);
ob.write((const char*)item->FocusName, strlen(item->FocusName));
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;
memset(&ises, 0, sizeof(RoF::structs::WornEffectStruct));
@ -5524,13 +5515,13 @@ namespace RoF
ises.type = item->Scroll.Type;
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)
ss.write((const char*)item->ScrollName, strlen(item->ScrollName));
ss.write("\0", 1);
ob.write((const char*)item->ScrollName, strlen(item->ScrollName));
ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// Bard Effect?
RoF::structs::WornEffectStruct ibes;
@ -5542,7 +5533,7 @@ namespace RoF
ibes.level = 0;
//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)
@ -5551,9 +5542,9 @@ namespace RoF
ss.write((const char*)&null_term, sizeof(uint8));
}
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
RoF::structs::ItemQuaternaryBodyStruct iqbs;
@ -5586,12 +5577,12 @@ namespace RoF
iqbs.unknown30 = 0;
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;
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) {
ItemInst* sub = inst->GetItem(index);
@ -5608,20 +5599,14 @@ namespace RoF
else
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;
}
if (subitem_count) {
std::stringstream::pos_type cur_pos = ss.tellp();
ss.seekp(count_pos);
ss.write((const char*)&subitem_count, sizeof(uint32));
ss.seekp(cur_pos);
}
if (subitem_count)
ob.overwrite(count_pos, (const char*)&subitem_count, sizeof(uint32));
}
static inline structs::InventorySlot_Struct ServerToRoFSlot(uint32 serverSlot)

View File

@ -24,7 +24,7 @@ namespace RoF2
static OpcodeManager *opcodes = nullptr;
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
static inline structs::InventorySlot_Struct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType = ItemPacketInvalid);
@ -628,24 +628,21 @@ namespace RoF2
InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer;
std::stringstream ss(std::stringstream::in | std::stringstream::out);
std::stringstream::pos_type last_pos = ss.tellp();
EQEmu::OutBuffer ob;
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) {
SerializeItem(ss, (const ItemInst*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
if (ss.tellp() == last_pos)
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
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);
last_pos = ss.tellp();
last_pos = ob.tellp();
}
std::string serialized = ss.str();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
@ -1563,29 +1560,24 @@ namespace RoF2
//store away the emu struct
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]);
std::stringstream ss(std::stringstream::in | std::stringstream::out);
std::stringstream::pos_type last_pos = ss.tellp();
EQEmu::OutBuffer ob;
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);
if (ss.tellp() == last_pos) {
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in;
return;
}
std::string serialized = ss.str();
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());
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
@ -5451,7 +5443,7 @@ namespace RoF2
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();
@ -5483,7 +5475,7 @@ namespace RoF2
hdr.unknown052 = 0;
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) {
RoF2::structs::EvolvingItem evotop;
@ -5497,7 +5489,7 @@ namespace RoF2
evotop.Activated = 1;
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
@ -5512,16 +5504,16 @@ namespace RoF2
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
//Mainhand
ss.write(tmp, strlen(tmp));
ss.write("\0", 1);
ob.write(tmp, strlen(tmp));
ob.write("\0", 1);
//Offhand
ss.write(tmp, strlen(tmp));
ss.write("\0", 1);
ob.write(tmp, strlen(tmp));
ob.write("\0", 1);
}
else {
ss.write("\0", 1); // no main hand Ornamentation
ss.write("\0", 1); // no off hand Ornamentation
ob.write("\0", 1); // no main hand Ornamentation
ob.write("\0", 1); // no off hand Ornamentation
}
RoF2::structs::ItemSerializationHeaderFinish hdrf;
@ -5535,21 +5527,21 @@ namespace RoF2
hdrf.unknowna5 = 0;
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)
ss.write(item->Name, strlen(item->Name));
ss.write("\0", 1);
ob.write(item->Name, strlen(item->Name));
ob.write("\0", 1);
if (strlen(item->Lore) > 0)
ss.write(item->Lore, strlen(item->Lore));
ss.write("\0", 1);
ob.write(item->Lore, strlen(item->Lore));
ob.write("\0", 1);
if (strlen(item->IDFile) > 0)
ss.write(item->IDFile, strlen(item->IDFile));
ss.write("\0", 1);
ob.write(item->IDFile, strlen(item->IDFile));
ob.write("\0", 1);
ss.write("\0", 1);
ob.write("\0", 1);
RoF2::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(RoF2::structs::ItemBodyStruct));
@ -5640,12 +5632,12 @@ namespace RoF2
ibs.FactionAmt4 = item->FactionAmt4;
ibs.FactionMod4 = item->FactionMod4;
ss.write((const char*)&ibs, sizeof(RoF2::structs::ItemBodyStruct));
ob.write((const char*)&ibs, sizeof(RoF2::structs::ItemBodyStruct));
//charm text
if (strlen(item->CharmFile) > 0)
ss.write((const char*)item->CharmFile, strlen(item->CharmFile));
ss.write("\0", 1);
ob.write((const char*)item->CharmFile, strlen(item->CharmFile));
ob.write("\0", 1);
RoF2::structs::ItemSecondaryBodyStruct isbs;
memset(&isbs, 0, sizeof(RoF2::structs::ItemSecondaryBodyStruct));
@ -5674,11 +5666,11 @@ namespace RoF2
isbs.book = item->Book;
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)
ss.write((const char*)item->Filename, strlen(item->Filename));
ss.write("\0", 1);
ob.write((const char*)item->Filename, strlen(item->Filename));
ob.write("\0", 1);
RoF2::structs::ItemTertiaryBodyStruct itbs;
memset(&itbs, 0, sizeof(RoF2::structs::ItemTertiaryBodyStruct));
@ -5713,7 +5705,7 @@ namespace RoF2
itbs.unknown13 = 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
int32 effect_unknown = 0;
@ -5730,13 +5722,13 @@ namespace RoF2
ices.recast = item->RecastDelay;
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)
ss.write((const char*)item->ClickName, strlen(item->ClickName));
ss.write("\0", 1);
ob.write((const char*)item->ClickName, strlen(item->ClickName));
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;
memset(&ipes, 0, sizeof(RoF2::structs::ProcEffectStruct));
@ -5747,13 +5739,13 @@ namespace RoF2
ipes.level = item->Proc.Level;
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)
ss.write((const char*)item->ProcName, strlen(item->ProcName));
ss.write("\0", 1);
ob.write((const char*)item->ProcName, strlen(item->ProcName));
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;
memset(&iwes, 0, sizeof(RoF2::structs::WornEffectStruct));
@ -5763,13 +5755,13 @@ namespace RoF2
iwes.type = item->Worn.Type;
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)
ss.write((const char*)item->WornName, strlen(item->WornName));
ss.write("\0", 1);
ob.write((const char*)item->WornName, strlen(item->WornName));
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;
memset(&ifes, 0, sizeof(RoF2::structs::WornEffectStruct));
@ -5779,13 +5771,13 @@ namespace RoF2
ifes.type = item->Focus.Type;
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)
ss.write((const char*)item->FocusName, strlen(item->FocusName));
ss.write("\0", 1);
ob.write((const char*)item->FocusName, strlen(item->FocusName));
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;
memset(&ises, 0, sizeof(RoF2::structs::WornEffectStruct));
@ -5795,13 +5787,13 @@ namespace RoF2
ises.type = item->Scroll.Type;
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)
ss.write((const char*)item->ScrollName, strlen(item->ScrollName));
ss.write("\0", 1);
ob.write((const char*)item->ScrollName, strlen(item->ScrollName));
ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// Bard Effect?
RoF2::structs::WornEffectStruct ibes;
@ -5813,18 +5805,18 @@ namespace RoF2
ibes.level = item->Bard.Level;
//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)
{
ss.write((const char*)item->BardName, strlen(item->BardName));
ss.write((const char*)&null_term, sizeof(uint8));
ob.write((const char*)item->BardName, strlen(item->BardName));
ob.write((const char*)&null_term, sizeof(uint8));
}
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
RoF2::structs::ItemQuaternaryBodyStruct iqbs;
@ -5867,12 +5859,12 @@ namespace RoF2
iqbs.unknown38 = 0;
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;
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) {
ItemInst* sub = inst->GetItem(index);
@ -5889,20 +5881,14 @@ namespace RoF2
else
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;
}
if (subitem_count) {
std::stringstream::pos_type cur_pos = ss.tellp();
ss.seekp(count_pos);
ss.write((const char*)&subitem_count, sizeof(uint32));
ss.seekp(cur_pos);
}
if (subitem_count)
ob.overwrite(count_pos, (const char*)&subitem_count, sizeof(uint32));
}
static inline structs::InventorySlot_Struct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType)

View File

@ -22,7 +22,7 @@ namespace SoD
static OpcodeManager *opcodes = nullptr;
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
static inline uint32 ServerToSoDSlot(uint32 ServerSlot);
@ -361,25 +361,22 @@ namespace SoD
InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer;
std::stringstream ss(std::stringstream::in | std::stringstream::out);
std::stringstream::pos_type last_pos = ss.tellp();
EQEmu::OutBuffer ob;
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) {
SerializeItem(ss, (const ItemInst*)eq->inst, eq->slot_id, 0);
if (ss.tellp() == last_pos)
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
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);
last_pos = ss.tellp();
last_pos = ob.tellp();
}
std::string serialized = ss.str();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@ -1023,30 +1020,24 @@ namespace SoD
//store away the emu struct
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]);
std::stringstream ss(std::stringstream::in | std::stringstream::out);
std::stringstream::pos_type last_pos = ss.tellp();
EQEmu::OutBuffer ob;
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);
if (ss.tellp() == last_pos) {
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in;
return;
}
std::string serialized = ss.str();
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());
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@ -3540,7 +3531,7 @@ namespace SoD
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();
@ -3569,19 +3560,19 @@ namespace SoD
hdr.unknown062 = 0;
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)
ss.write(item->Name, strlen(item->Name));
ss.write("\0", 1);
ob.write(item->Name, strlen(item->Name));
ob.write("\0", 1);
if (strlen(item->Lore) > 0)
ss.write(item->Lore, strlen(item->Lore));
ss.write("\0", 1);
ob.write(item->Lore, strlen(item->Lore));
ob.write("\0", 1);
if (strlen(item->IDFile) > 0)
ss.write(item->IDFile, strlen(item->IDFile));
ss.write("\0", 1);
ob.write(item->IDFile, strlen(item->IDFile));
ob.write("\0", 1);
SoD::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(SoD::structs::ItemBodyStruct));
@ -3670,12 +3661,12 @@ namespace SoD
ibs.FactionAmt4 = item->FactionAmt4;
ibs.FactionMod4 = item->FactionMod4;
ss.write((const char*)&ibs, sizeof(SoD::structs::ItemBodyStruct));
ob.write((const char*)&ibs, sizeof(SoD::structs::ItemBodyStruct));
//charm text
if (strlen(item->CharmFile) > 0)
ss.write((const char*)item->CharmFile, strlen(item->CharmFile));
ss.write("\0", 1);
ob.write((const char*)item->CharmFile, strlen(item->CharmFile));
ob.write("\0", 1);
SoD::structs::ItemSecondaryBodyStruct isbs;
memset(&isbs, 0, sizeof(SoD::structs::ItemSecondaryBodyStruct));
@ -3703,11 +3694,11 @@ namespace SoD
isbs.book = item->Book;
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)
ss.write((const char*)item->Filename, strlen(item->Filename));
ss.write("\0", 1);
ob.write((const char*)item->Filename, strlen(item->Filename));
ob.write("\0", 1);
SoD::structs::ItemTertiaryBodyStruct itbs;
memset(&itbs, 0, sizeof(SoD::structs::ItemTertiaryBodyStruct));
@ -3731,7 +3722,7 @@ namespace SoD
itbs.no_transfer = item->NoTransfer;
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
int32 effect_unknown = 0;
@ -3748,13 +3739,13 @@ namespace SoD
ices.recast = item->RecastDelay;
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)
ss.write((const char*)item->ClickName, strlen(item->ClickName));
ss.write("\0", 1);
ob.write((const char*)item->ClickName, strlen(item->ClickName));
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;
memset(&ipes, 0, sizeof(SoD::structs::ProcEffectStruct));
@ -3765,13 +3756,13 @@ namespace SoD
ipes.level = item->Proc.Level;
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)
ss.write((const char*)item->ProcName, strlen(item->ProcName));
ss.write("\0", 1);
ob.write((const char*)item->ProcName, strlen(item->ProcName));
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;
memset(&iwes, 0, sizeof(SoD::structs::WornEffectStruct));
@ -3781,13 +3772,13 @@ namespace SoD
iwes.type = item->Worn.Type;
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)
ss.write((const char*)item->WornName, strlen(item->WornName));
ss.write("\0", 1);
ob.write((const char*)item->WornName, strlen(item->WornName));
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;
memset(&ifes, 0, sizeof(SoD::structs::WornEffectStruct));
@ -3797,13 +3788,13 @@ namespace SoD
ifes.type = item->Focus.Type;
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)
ss.write((const char*)item->FocusName, strlen(item->FocusName));
ss.write("\0", 1);
ob.write((const char*)item->FocusName, strlen(item->FocusName));
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;
memset(&ises, 0, sizeof(SoD::structs::WornEffectStruct));
@ -3813,13 +3804,13 @@ namespace SoD
ises.type = item->Scroll.Type;
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)
ss.write((const char*)item->ScrollName, strlen(item->ScrollName));
ss.write("\0", 1);
ob.write((const char*)item->ScrollName, strlen(item->ScrollName));
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
SoD::structs::ItemQuaternaryBodyStruct iqbs;
@ -3849,12 +3840,12 @@ namespace SoD
iqbs.SpellDmg = item->SpellDmg;
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;
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) {
ItemInst* sub = inst->GetItem(index);
@ -3871,20 +3862,14 @@ namespace SoD
else
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;
}
if (subitem_count) {
std::stringstream::pos_type cur_pos = ss.tellp();
ss.seekp(count_pos);
ss.write((const char*)&subitem_count, sizeof(uint32));
ss.seekp(cur_pos);
}
if (subitem_count)
ob.overwrite(count_pos, (const char*)&subitem_count, sizeof(uint32));
}
static inline uint32 ServerToSoDSlot(uint32 serverSlot)

View File

@ -22,7 +22,7 @@ namespace SoF
static OpcodeManager *opcodes = nullptr;
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
static inline uint32 ServerToSoFSlot(uint32 serverSlot);
@ -343,25 +343,22 @@ namespace SoF
InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer;
std::stringstream ss(std::stringstream::in | std::stringstream::out);
std::stringstream::pos_type last_pos = ss.tellp();
EQEmu::OutBuffer ob;
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) {
SerializeItem(ss, (const ItemInst*)eq->inst, eq->slot_id, 0);
if (ss.tellp() == last_pos)
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
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);
last_pos = ss.tellp();
last_pos = ob.tellp();
}
std::string serialized = ss.str();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@ -823,30 +820,24 @@ namespace SoF
//store away the emu struct
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]);
std::stringstream ss(std::stringstream::in | std::stringstream::out);
std::stringstream::pos_type last_pos = ss.tellp();
EQEmu::OutBuffer ob;
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);
if (ss.tellp() == last_pos) {
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in;
return;
}
std::string serialized = ss.str();
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());
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@ -2865,7 +2856,7 @@ namespace SoF
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();
@ -2893,19 +2884,19 @@ namespace SoF
hdr.unknown061 = 0;
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)
ss.write(item->Name, strlen(item->Name));
ss.write("\0", 1);
ob.write(item->Name, strlen(item->Name));
ob.write("\0", 1);
if (strlen(item->Lore) > 0)
ss.write(item->Lore, strlen(item->Lore));
ss.write("\0", 1);
ob.write(item->Lore, strlen(item->Lore));
ob.write("\0", 1);
if (strlen(item->IDFile) > 0)
ss.write(item->IDFile, strlen(item->IDFile));
ss.write("\0", 1);
ob.write(item->IDFile, strlen(item->IDFile));
ob.write("\0", 1);
SoF::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(SoF::structs::ItemBodyStruct));
@ -2994,12 +2985,12 @@ namespace SoF
ibs.FactionAmt4 = item->FactionAmt4;
ibs.FactionMod4 = item->FactionMod4;
ss.write((const char*)&ibs, sizeof(SoF::structs::ItemBodyStruct));
ob.write((const char*)&ibs, sizeof(SoF::structs::ItemBodyStruct));
//charm text
if (strlen(item->CharmFile) > 0)
ss.write((const char*)item->CharmFile, strlen(item->CharmFile));
ss.write("\0", 1);
ob.write((const char*)item->CharmFile, strlen(item->CharmFile));
ob.write("\0", 1);
SoF::structs::ItemSecondaryBodyStruct isbs;
memset(&isbs, 0, sizeof(SoF::structs::ItemSecondaryBodyStruct));
@ -3027,11 +3018,11 @@ namespace SoF
isbs.book = item->Book;
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)
ss.write((const char*)item->Filename, strlen(item->Filename));
ss.write("\0", 1);
ob.write((const char*)item->Filename, strlen(item->Filename));
ob.write("\0", 1);
SoF::structs::ItemTertiaryBodyStruct itbs;
memset(&itbs, 0, sizeof(SoF::structs::ItemTertiaryBodyStruct));
@ -3055,7 +3046,7 @@ namespace SoF
itbs.no_transfer = item->NoTransfer;
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
int32 effect_unknown = 0;
@ -3072,13 +3063,13 @@ namespace SoF
ices.recast = item->RecastDelay;
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)
ss.write((const char*)item->ClickName, strlen(item->ClickName));
ss.write("\0", 1);
ob.write((const char*)item->ClickName, strlen(item->ClickName));
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;
memset(&ipes, 0, sizeof(SoF::structs::ProcEffectStruct));
@ -3089,13 +3080,13 @@ namespace SoF
ipes.level = item->Proc.Level;
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)
ss.write((const char*)item->ProcName, strlen(item->ProcName));
ss.write("\0", 1);
ob.write((const char*)item->ProcName, strlen(item->ProcName));
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;
memset(&iwes, 0, sizeof(SoF::structs::WornEffectStruct));
@ -3105,13 +3096,13 @@ namespace SoF
iwes.type = item->Worn.Type;
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)
ss.write((const char*)item->WornName, strlen(item->WornName));
ss.write("\0", 1);
ob.write((const char*)item->WornName, strlen(item->WornName));
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;
memset(&ifes, 0, sizeof(SoF::structs::WornEffectStruct));
@ -3121,13 +3112,13 @@ namespace SoF
ifes.type = item->Focus.Type;
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)
ss.write((const char*)item->FocusName, strlen(item->FocusName));
ss.write("\0", 1);
ob.write((const char*)item->FocusName, strlen(item->FocusName));
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;
memset(&ises, 0, sizeof(SoF::structs::WornEffectStruct));
@ -3137,13 +3128,13 @@ namespace SoF
ises.type = item->Scroll.Type;
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)
ss.write((const char*)item->ScrollName, strlen(item->ScrollName));
ss.write("\0", 1);
ob.write((const char*)item->ScrollName, strlen(item->ScrollName));
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
SoF::structs::ItemQuaternaryBodyStruct iqbs;
@ -3172,12 +3163,12 @@ namespace SoF
iqbs.HealAmt = item->HealAmt;
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;
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) {
ItemInst* sub = inst->GetItem(index);
@ -3194,20 +3185,14 @@ namespace SoF
else
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;
}
if (subitem_count) {
std::stringstream::pos_type cur_pos = ss.tellp();
ss.seekp(count_pos);
ss.write((const char*)&subitem_count, sizeof(uint32));
ss.seekp(cur_pos);
}
if (subitem_count)
ob.overwrite(count_pos, (const char*)&subitem_count, sizeof(uint32));
}
static inline uint32 ServerToSoFSlot(uint32 serverSlot)

View File

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

View File

@ -22,7 +22,7 @@ namespace UF
static OpcodeManager *opcodes = nullptr;
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
static inline uint32 ServerToUFSlot(uint32 serverSlot);
@ -499,25 +499,22 @@ namespace UF
InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer;
std::stringstream ss(std::stringstream::in | std::stringstream::out);
std::stringstream::pos_type last_pos = ss.tellp();
EQEmu::OutBuffer ob;
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) {
SerializeItem(ss, (const ItemInst*)eq->inst, eq->slot_id, 0);
if (ss.tellp() == last_pos)
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
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);
last_pos = ss.tellp();
last_pos = ob.tellp();
}
std::string serialized = ss.str();
in->size = serialized.size();
in->pBuffer = new uchar[in->size];
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@ -1249,30 +1246,24 @@ namespace UF
//store away the emu struct
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]);
std::stringstream ss(std::stringstream::in | std::stringstream::out);
std::stringstream::pos_type last_pos = ss.tellp();
EQEmu::OutBuffer ob;
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);
if (ss.tellp() == last_pos) {
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in;
return;
}
std::string serialized = ss.str();
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());
in->size = ob.size();
in->pBuffer = ob.detach();
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@ -3815,7 +3806,7 @@ namespace UF
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();
@ -3840,7 +3831,7 @@ namespace UF
hdr.unknown052 = 0;
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) {
UF::structs::EvolvingItem evotop;
@ -3854,7 +3845,7 @@ namespace UF
evotop.Activated = 1;
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 -
@ -3864,15 +3855,15 @@ namespace UF
const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
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()) {
ornaIcon = inst->GetOrnamentationIcon();
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;
@ -3882,19 +3873,19 @@ namespace UF
hdrf.isCopied = 0; //Flag for item to be 'Copied'
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)
ss.write(item->Name, strlen(item->Name));
ss.write("\0", 1);
ob.write(item->Name, strlen(item->Name));
ob.write("\0", 1);
if (strlen(item->Lore) > 0)
ss.write(item->Lore, strlen(item->Lore));
ss.write("\0", 1);
ob.write(item->Lore, strlen(item->Lore));
ob.write("\0", 1);
if (strlen(item->IDFile) > 0)
ss.write(item->IDFile, strlen(item->IDFile));
ss.write("\0", 1);
ob.write(item->IDFile, strlen(item->IDFile));
ob.write("\0", 1);
UF::structs::ItemBodyStruct ibs;
memset(&ibs, 0, sizeof(UF::structs::ItemBodyStruct));
@ -3983,12 +3974,12 @@ namespace UF
ibs.FactionAmt4 = item->FactionAmt4;
ibs.FactionMod4 = item->FactionMod4;
ss.write((const char*)&ibs, sizeof(UF::structs::ItemBodyStruct));
ob.write((const char*)&ibs, sizeof(UF::structs::ItemBodyStruct));
//charm text
if (strlen(item->CharmFile) > 0)
ss.write((const char*)item->CharmFile, strlen(item->CharmFile));
ss.write("\0", 1);
ob.write((const char*)item->CharmFile, strlen(item->CharmFile));
ob.write("\0", 1);
UF::structs::ItemSecondaryBodyStruct isbs;
memset(&isbs, 0, sizeof(UF::structs::ItemSecondaryBodyStruct));
@ -4016,11 +4007,11 @@ namespace UF
isbs.book = item->Book;
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)
ss.write((const char*)item->Filename, strlen(item->Filename));
ss.write("\0", 1);
ob.write((const char*)item->Filename, strlen(item->Filename));
ob.write("\0", 1);
UF::structs::ItemTertiaryBodyStruct itbs;
memset(&itbs, 0, sizeof(UF::structs::ItemTertiaryBodyStruct));
@ -4044,7 +4035,7 @@ namespace UF
itbs.no_transfer = item->NoTransfer;
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
int32 effect_unknown = 0;
@ -4061,13 +4052,13 @@ namespace UF
ices.recast = item->RecastDelay;
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)
ss.write((const char*)item->ClickName, strlen(item->ClickName));
ss.write("\0", 1);
ob.write((const char*)item->ClickName, strlen(item->ClickName));
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;
memset(&ipes, 0, sizeof(UF::structs::ProcEffectStruct));
@ -4078,13 +4069,13 @@ namespace UF
ipes.level = item->Proc.Level;
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)
ss.write((const char*)item->ProcName, strlen(item->ProcName));
ss.write("\0", 1);
ob.write((const char*)item->ProcName, strlen(item->ProcName));
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;
memset(&iwes, 0, sizeof(UF::structs::WornEffectStruct));
@ -4094,13 +4085,13 @@ namespace UF
iwes.type = item->Worn.Type;
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)
ss.write((const char*)item->WornName, strlen(item->WornName));
ss.write("\0", 1);
ob.write((const char*)item->WornName, strlen(item->WornName));
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;
memset(&ifes, 0, sizeof(UF::structs::WornEffectStruct));
@ -4110,13 +4101,13 @@ namespace UF
ifes.type = item->Focus.Type;
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)
ss.write((const char*)item->FocusName, strlen(item->FocusName));
ss.write("\0", 1);
ob.write((const char*)item->FocusName, strlen(item->FocusName));
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;
memset(&ises, 0, sizeof(UF::structs::WornEffectStruct));
@ -4126,13 +4117,13 @@ namespace UF
ises.type = item->Scroll.Type;
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)
ss.write((const char*)item->ScrollName, strlen(item->ScrollName));
ss.write("\0", 1);
ob.write((const char*)item->ScrollName, strlen(item->ScrollName));
ob.write("\0", 1);
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
ob.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
// Bard Effect?
UF::structs::WornEffectStruct ibes;
@ -4144,18 +4135,18 @@ namespace UF
ibes.level = item->Bard.Level;
//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)
{
ss.write((const char*)item->BardName, strlen(item->BardName));
ss.write((const char*)&null_term, sizeof(uint8));
ob.write((const char*)item->BardName, strlen(item->BardName));
ob.write((const char*)&null_term, sizeof(uint8));
}
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
UF::structs::ItemQuaternaryBodyStruct iqbs;
@ -4185,12 +4176,12 @@ namespace UF
iqbs.SpellDmg = item->SpellDmg;
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;
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) {
ItemInst* sub = inst->GetItem(index);
@ -4207,20 +4198,14 @@ namespace UF
else
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;
}
if (subitem_count) {
std::stringstream::pos_type cur_pos = ss.tellp();
ss.seekp(count_pos);
ss.write((const char*)&subitem_count, sizeof(uint32));
ss.seekp(cur_pos);
}
if (subitem_count)
ob.overwrite(count_pos, (const char*)&subitem_count, sizeof(uint32));
}
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);
}
}
/* 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 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

View File

@ -759,8 +759,8 @@ void Client::BulkSendInventoryItems()
RemoveDuplicateLore(false);
MoveSlotNotAllowed(false);
std::stringstream ss(std::stringstream::in | std::stringstream::out);
std::stringstream::pos_type last_pos = ss.tellp();
EQEmu::OutBuffer ob;
EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
// Possessions items
for (int16 slot_id = SLOT_BEGIN; slot_id < EQEmu::legacy::TYPE_POSSESSIONS_SIZE; slot_id++) {
@ -768,24 +768,24 @@ void Client::BulkSendInventoryItems()
if (!inst)
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);
last_pos = ss.tellp();
last_pos = ob.tellp();
}
// PowerSource item
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) {
const ItemInst* inst = m_inv[EQEmu::legacy::SlotPowerSource];
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);
last_pos = ss.tellp();
last_pos = ob.tellp();
}
}
@ -795,12 +795,12 @@ void Client::BulkSendInventoryItems()
if (!inst)
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);
last_pos = ss.tellp();
last_pos = ob.tellp();
}
// SharedBank items
@ -809,19 +809,17 @@ void Client::BulkSendInventoryItems()
if (!inst)
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);
last_pos = ss.tellp();
last_pos = ob.tellp();
}
std::string serialized = ss.str();
EQApplicationPacket* outapp = new EQApplicationPacket(OP_CharInventory, serialized.size());
memcpy(outapp->pBuffer, serialized.c_str(), serialized.size());
EQApplicationPacket* outapp = new EQApplicationPacket(OP_CharInventory);
outapp->size = ob.size();
outapp->pBuffer = ob.detach();
QueuePacket(outapp);
safe_delete(outapp);
}