mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 03:08:26 +00:00
Reworked client translators' SerializeItem() to recursive, single buffer methodology
This commit is contained in:
+99
-197
@@ -22,7 +22,7 @@ namespace SoF
|
||||
static OpcodeManager *opcodes = nullptr;
|
||||
static Strategy struct_strategy;
|
||||
|
||||
char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth);
|
||||
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id, uint8 depth);
|
||||
|
||||
// server to client inventory location converters
|
||||
static inline uint32 ServerToSoFSlot(uint32 serverSlot);
|
||||
@@ -317,26 +317,23 @@ namespace SoF
|
||||
ENCODE(OP_CharInventory)
|
||||
{
|
||||
//consume the packet
|
||||
EQApplicationPacket *in = *p;
|
||||
|
||||
EQApplicationPacket* in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
if (in->size == 0) {
|
||||
if (!in->size) {
|
||||
in->size = 4;
|
||||
in->pBuffer = new uchar[in->size];
|
||||
*((uint32 *)in->pBuffer) = 0;
|
||||
memset(in->pBuffer, 0, in->size);
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
return;
|
||||
}
|
||||
|
||||
//store away the emu struct
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
int ItemCount = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
|
||||
if (ItemCount == 0 || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
|
||||
uchar* __emu_buffer = in->pBuffer;
|
||||
|
||||
int item_count = in->size / sizeof(InternalSerializedItem_Struct);
|
||||
if (!item_count || (in->size % sizeof(InternalSerializedItem_Struct)) != 0) {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
|
||||
opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(InternalSerializedItem_Struct));
|
||||
|
||||
@@ -344,41 +341,28 @@ namespace SoF
|
||||
return;
|
||||
}
|
||||
|
||||
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
|
||||
InternalSerializedItem_Struct* eq = (InternalSerializedItem_Struct*)in->pBuffer;
|
||||
|
||||
in->pBuffer = new uchar[4];
|
||||
*(uint32 *)in->pBuffer = ItemCount;
|
||||
in->size = 4;
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out);
|
||||
std::stringstream::pos_type last_pos = ss.tellp();
|
||||
|
||||
for (int r = 0; r < ItemCount; r++, eq++) {
|
||||
ss.write((const char*)&item_count, sizeof(uint32));
|
||||
|
||||
uint32 Length = 0;
|
||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||
SerializeItem(ss, (const ItemInst*)eq->inst, eq->slot_id, 0);
|
||||
if (ss.tellp() == last_pos)
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
|
||||
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
|
||||
|
||||
if (Serialized) {
|
||||
uchar *OldBuffer = in->pBuffer;
|
||||
|
||||
in->pBuffer = new uchar[in->size + Length];
|
||||
memcpy(in->pBuffer, OldBuffer, in->size);
|
||||
|
||||
safe_delete_array(OldBuffer);
|
||||
|
||||
memcpy(in->pBuffer + in->size, Serialized, Length);
|
||||
in->size += Length;
|
||||
|
||||
safe_delete_array(Serialized);
|
||||
|
||||
}
|
||||
else {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
}
|
||||
last_pos = ss.tellp();
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
std::string serialized = ss.str();
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
|
||||
//Log.Hex(Logs::Netcode, in->pBuffer, in->size);
|
||||
in->size = serialized.size();
|
||||
in->pBuffer = new uchar[in->size];
|
||||
memcpy(in->pBuffer, serialized.c_str(), serialized.size());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
@@ -834,29 +818,37 @@ namespace SoF
|
||||
ENCODE(OP_ItemPacket)
|
||||
{
|
||||
//consume the packet
|
||||
EQApplicationPacket *in = *p;
|
||||
EQApplicationPacket* in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
ItemPacket_Struct *old_item_pkt = (ItemPacket_Struct *)__emu_buffer;
|
||||
InternalSerializedItem_Struct *int_struct = (InternalSerializedItem_Struct *)(old_item_pkt->SerializedItem);
|
||||
//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]);
|
||||
|
||||
uint32 length;
|
||||
char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0);
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out);
|
||||
std::stringstream::pos_type last_pos = ss.tellp();
|
||||
|
||||
if (!serialized) {
|
||||
ss.write((const char*)__emu_buffer, 4);
|
||||
|
||||
SerializeItem(ss, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
|
||||
if (ss.tellp() == last_pos) {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
in->size = length + 4;
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
ItemPacket_Struct *new_item_pkt = (ItemPacket_Struct *)in->pBuffer;
|
||||
new_item_pkt->PacketType = old_item_pkt->PacketType;
|
||||
memcpy(new_item_pkt->SerializedItem, serialized, length);
|
||||
|
||||
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());
|
||||
|
||||
delete[] __emu_buffer;
|
||||
safe_delete_array(serialized);
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
@@ -2873,34 +2865,26 @@ namespace SoF
|
||||
return NextItemInstSerialNumber;
|
||||
}
|
||||
|
||||
char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth)
|
||||
void SerializeItem(std::stringstream& ss, const ItemInst *inst, int16 slot_id_in, uint8 depth)
|
||||
{
|
||||
uint8 null_term = 0;
|
||||
bool stackable = inst->IsStackable();
|
||||
uint32 merchant_slot = inst->GetMerchantSlot();
|
||||
uint32 charges = inst->GetCharges();
|
||||
if (!stackable && charges > 254)
|
||||
charges = 0xFFFFFFFF;
|
||||
|
||||
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
|
||||
|
||||
const Item_Struct *item = inst->GetUnscaledItem();
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name);
|
||||
|
||||
SoF::structs::ItemSerializationHeader hdr;
|
||||
hdr.stacksize = stackable ? charges : 1;
|
||||
|
||||
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 254) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
|
||||
hdr.unknown004 = 0;
|
||||
|
||||
int32 slot_id = ServerToSoFSlot(slot_id_in);
|
||||
|
||||
hdr.slot = (merchant_slot == 0) ? slot_id : merchant_slot;
|
||||
hdr.slot = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : slot_id);
|
||||
hdr.price = inst->GetPrice();
|
||||
hdr.merchant_slot = (merchant_slot == 0) ? 1 : inst->GetMerchantCount();
|
||||
hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0;
|
||||
hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot;
|
||||
hdr.merchant_slot = (inst->GetMerchantSlot() ? inst->GetMerchantCount() : 1);
|
||||
hdr.scaled_value = (inst->IsScaling() ? (inst->GetExp() / 100) : 0);
|
||||
hdr.instance_id = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : inst->GetSerialNumber());
|
||||
hdr.unknown028 = 0;
|
||||
hdr.last_cast_time = inst->GetRecastTimestamp();
|
||||
hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges);
|
||||
hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0;
|
||||
hdr.charges = (inst->IsStackable() ? (item->MaxCharges ? 1 : 0) : ((inst->GetCharges() > 254) ? 0xFFFFFFFF : inst->GetCharges()));
|
||||
hdr.inst_nodrop = (inst->IsAttuned() ? 1 : 0);
|
||||
hdr.unknown044 = 0;
|
||||
hdr.unknown048 = 0;
|
||||
hdr.unknown052 = 0;
|
||||
@@ -2912,41 +2896,23 @@ namespace SoF
|
||||
ss.write((const char*)&hdr, sizeof(SoF::structs::ItemSerializationHeader));
|
||||
|
||||
if (strlen(item->Name) > 0)
|
||||
{
|
||||
ss.write(item->Name, strlen(item->Name));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
ss.write("\0", 1);
|
||||
|
||||
if (strlen(item->Lore) > 0)
|
||||
{
|
||||
ss.write(item->Lore, strlen(item->Lore));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
ss.write("\0", 1);
|
||||
|
||||
if (strlen(item->IDFile) > 0)
|
||||
{
|
||||
ss.write(item->IDFile, strlen(item->IDFile));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
ss.write("\0", 1);
|
||||
|
||||
SoF::structs::ItemBodyStruct ibs;
|
||||
memset(&ibs, 0, sizeof(SoF::structs::ItemBodyStruct));
|
||||
|
||||
ibs.id = item->ID;
|
||||
// weight is uint8 in the struct, and some weights exceed that, so capping at 255.
|
||||
ibs.weight = (item->Weight > 255) ? 255 : item->Weight;
|
||||
ibs.weight = ((item->Weight > 255) ? 255 : item->Weight);
|
||||
ibs.norent = item->NoRent;
|
||||
ibs.nodrop = item->NoDrop;
|
||||
ibs.attune = item->Attuneable;
|
||||
@@ -3032,14 +2998,8 @@ namespace SoF
|
||||
|
||||
//charm text
|
||||
if (strlen(item->CharmFile) > 0)
|
||||
{
|
||||
ss.write((const char*)item->CharmFile, strlen(item->CharmFile));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
ss.write("\0", 1);
|
||||
|
||||
SoF::structs::ItemSecondaryBodyStruct isbs;
|
||||
memset(&isbs, 0, sizeof(SoF::structs::ItemSecondaryBodyStruct));
|
||||
@@ -3047,11 +3007,10 @@ namespace SoF
|
||||
isbs.augtype = item->AugType;
|
||||
isbs.augrestrict = item->AugRestrict;
|
||||
|
||||
for (int x = 0; x < consts::ITEM_COMMON_SIZE; x++)
|
||||
{
|
||||
isbs.augslots[x].type = item->AugSlotType[x];
|
||||
isbs.augslots[x].visible = item->AugSlotVisible[x];
|
||||
isbs.augslots[x].unknown = item->AugSlotUnk2[x];
|
||||
for (int index = 0; index < consts::ITEM_COMMON_SIZE; ++index) {
|
||||
isbs.augslots[index].type = item->AugSlotType[index];
|
||||
isbs.augslots[index].visible = item->AugSlotVisible[index];
|
||||
isbs.augslots[index].unknown = item->AugSlotUnk2[index];
|
||||
}
|
||||
|
||||
isbs.ldonpoint_type = item->PointType;
|
||||
@@ -3071,14 +3030,8 @@ namespace SoF
|
||||
ss.write((const char*)&isbs, sizeof(SoF::structs::ItemSecondaryBodyStruct));
|
||||
|
||||
if (strlen(item->Filename) > 0)
|
||||
{
|
||||
ss.write((const char*)item->Filename, strlen(item->Filename));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
ss.write("\0", 1);
|
||||
|
||||
SoF::structs::ItemTertiaryBodyStruct itbs;
|
||||
memset(&itbs, 0, sizeof(SoF::structs::ItemTertiaryBodyStruct));
|
||||
@@ -3098,7 +3051,7 @@ namespace SoF
|
||||
|
||||
itbs.potion_belt_enabled = item->PotionBelt;
|
||||
itbs.potion_belt_slots = item->PotionBeltSlots;
|
||||
itbs.stacksize = stackable ? item->StackSize : 0;
|
||||
itbs.stacksize = (inst->IsStackable() ? item->StackSize : 0);
|
||||
itbs.no_transfer = item->NoTransfer;
|
||||
itbs.expendablearrow = item->ExpendableArrow;
|
||||
|
||||
@@ -3122,14 +3075,8 @@ namespace SoF
|
||||
ss.write((const char*)&ices, sizeof(SoF::structs::ClickEffectStruct));
|
||||
|
||||
if (strlen(item->ClickName) > 0)
|
||||
{
|
||||
ss.write((const char*)item->ClickName, strlen(item->ClickName));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
ss.write("\0", 1);
|
||||
|
||||
ss.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7
|
||||
|
||||
@@ -3145,14 +3092,8 @@ namespace SoF
|
||||
ss.write((const char*)&ipes, sizeof(SoF::structs::ProcEffectStruct));
|
||||
|
||||
if (strlen(item->ProcName) > 0)
|
||||
{
|
||||
ss.write((const char*)item->ProcName, strlen(item->ProcName));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
ss.write("\0", 1);
|
||||
|
||||
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown5
|
||||
|
||||
@@ -3167,14 +3108,8 @@ namespace SoF
|
||||
ss.write((const char*)&iwes, sizeof(SoF::structs::WornEffectStruct));
|
||||
|
||||
if (strlen(item->WornName) > 0)
|
||||
{
|
||||
ss.write((const char*)item->WornName, strlen(item->WornName));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
ss.write("\0", 1);
|
||||
|
||||
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
|
||||
|
||||
@@ -3189,14 +3124,8 @@ namespace SoF
|
||||
ss.write((const char*)&ifes, sizeof(SoF::structs::WornEffectStruct));
|
||||
|
||||
if (strlen(item->FocusName) > 0)
|
||||
{
|
||||
ss.write((const char*)item->FocusName, strlen(item->FocusName));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
ss.write("\0", 1);
|
||||
|
||||
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
|
||||
|
||||
@@ -3211,14 +3140,8 @@ namespace SoF
|
||||
ss.write((const char*)&ises, sizeof(SoF::structs::WornEffectStruct));
|
||||
|
||||
if (strlen(item->ScrollName) > 0)
|
||||
{
|
||||
ss.write((const char*)item->ScrollName, strlen(item->ScrollName));
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
else
|
||||
{
|
||||
ss.write((const char*)&null_term, sizeof(uint8));
|
||||
}
|
||||
ss.write("\0", 1);
|
||||
|
||||
ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6
|
||||
// End of Effects
|
||||
@@ -3248,64 +3171,43 @@ namespace SoF
|
||||
iqbs.HeroicSVCorrup = item->HeroicSVCorrup;
|
||||
iqbs.HealAmt = item->HealAmt;
|
||||
iqbs.SpellDmg = item->SpellDmg;
|
||||
//iqbs.clairvoyance = item->Clairvoyance;
|
||||
|
||||
iqbs.subitem_count = 0;
|
||||
|
||||
char *SubSerializations[10]; // <watch>
|
||||
|
||||
uint32 SubLengths[10];
|
||||
|
||||
for (int x = SUB_INDEX_BEGIN; x < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++x) {
|
||||
|
||||
SubSerializations[x] = nullptr;
|
||||
const ItemInst* subitem = ((const ItemInst*)inst)->GetItem(x);
|
||||
|
||||
if (subitem) {
|
||||
|
||||
int SubSlotNumber;
|
||||
|
||||
iqbs.subitem_count++;
|
||||
|
||||
if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END) // (< 30) - no cursor?
|
||||
//SubSlotNumber = (((slot_id_in + 3) * 10) + x + 1);
|
||||
SubSlotNumber = (((slot_id_in + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + x + 1);
|
||||
else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END)
|
||||
//SubSlotNumber = (((slot_id_in - 2000) * 10) + 2030 + x + 1);
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::BANK_BAGS_BEGIN + x);
|
||||
else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END)
|
||||
//SubSlotNumber = (((slot_id_in - 2500) * 10) + 2530 + x + 1);
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + x);
|
||||
else
|
||||
SubSlotNumber = slot_id_in; // ???????
|
||||
|
||||
/*
|
||||
// TEST CODE: <watch>
|
||||
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
|
||||
*/
|
||||
|
||||
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ss.write((const char*)&iqbs, sizeof(SoF::structs::ItemQuaternaryBodyStruct));
|
||||
|
||||
for (int x = 0; x < 10; ++x) {
|
||||
std::stringstream::pos_type count_pos = ss.tellp();
|
||||
uint32 subitem_count = 0;
|
||||
|
||||
if (SubSerializations[x]) {
|
||||
ss.write((const char*)&x, sizeof(uint32));
|
||||
ss.write(SubSerializations[x], SubLengths[x]);
|
||||
ss.write((const char*)&subitem_count, sizeof(uint32));
|
||||
|
||||
safe_delete_array(SubSerializations[x]);
|
||||
}
|
||||
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
|
||||
ItemInst* sub = inst->GetItem(index);
|
||||
if (!sub)
|
||||
continue;
|
||||
|
||||
int SubSlotNumber = INVALID_INDEX;
|
||||
if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END)
|
||||
SubSlotNumber = (((slot_id_in + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + index + 1);
|
||||
else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END)
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
|
||||
else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END)
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
|
||||
else
|
||||
SubSlotNumber = slot_id_in;
|
||||
|
||||
ss.write((const char*)&index, sizeof(uint32));
|
||||
|
||||
SerializeItem(ss, sub, SubSlotNumber, (depth + 1));
|
||||
++subitem_count;
|
||||
}
|
||||
|
||||
char* item_serial = new char[ss.tellp()];
|
||||
memset(item_serial, 0, ss.tellp());
|
||||
memcpy(item_serial, ss.str().c_str(), ss.tellp());
|
||||
if (subitem_count) {
|
||||
std::stringstream::pos_type cur_pos = ss.tellp();
|
||||
ss.seekp(count_pos);
|
||||
|
||||
*length = ss.tellp();
|
||||
return item_serial;
|
||||
ss.write((const char*)&subitem_count, sizeof(uint32));
|
||||
|
||||
ss.seekp(cur_pos);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32 ServerToSoFSlot(uint32 serverSlot)
|
||||
|
||||
Reference in New Issue
Block a user