Fix for Memory Buffer stuff, have yet to compile so not sure if that's enough. Partial work on RoF inventory bulk send

This commit is contained in:
KimLS 2015-02-22 19:38:44 -08:00
parent 273574d4db
commit ca278d029e
10 changed files with 233 additions and 74 deletions

View File

@ -89,10 +89,25 @@ bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr<ItemInstan
return container.Put(slot.slot_, inst);
}
return false;
}
bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest) {
return false;
}
}
bool EQEmu::Inventory::Serialize(MemoryBuffer &buf) {
buf.SetWritePosition(0);
buf.SetReadPosition(0);
buf.Resize(0);
bool value = false;
for(auto &iter : impl_->containers_) {
bool v = iter.second.Serialize(buf, iter.first);
if(v && !value) {
value = true;
}
}
return value;
}

View File

@ -61,7 +61,7 @@ namespace EQEmu
bool Put(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst);
bool Swap(const InventorySlot &src, const InventorySlot &dest);
void Serialize();
bool Serialize(MemoryBuffer &buf);
private:
struct impl;
impl *impl_;

View File

@ -56,3 +56,17 @@ bool EQEmu::ItemContainer::Delete(const int slot_id) {
return true;
}
}
bool EQEmu::ItemContainer::Serialize(MemoryBuffer &buf, int container_number) {
if(impl_->items.size() == 0) {
return false;
}
for(auto &iter : impl_->items) {
buf.Write<int32>(container_number);
buf.Write<int32>(iter.first);
buf.Write<void*>(iter.second.get());
}
return true;
}

View File

@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define COMMON_ITEM_CONTAINER_H
#include "item_instance.h"
#include "memory_buffer.h"
#include <memory>
namespace EQEmu
@ -34,6 +35,8 @@ namespace EQEmu
std::shared_ptr<ItemInstance> Get(const int slot_id);
bool Put(const int slot_id, std::shared_ptr<ItemInstance> inst);
bool Delete(const int slot_id);
bool Serialize(MemoryBuffer &buf, int container_number);
private:
ItemContainer(const ItemContainer &other);
ItemContainer& operator=(const ItemContainer &other);

View File

@ -69,6 +69,12 @@ struct InternalSerializedItem_Struct {
const void * inst;
};
struct SerializedItemInstance_Struct {
int32 container_id;
int32 slot_id;
void *inst;
};
// use EmuConstants::ITEM_COMMON_SIZE
//#define MAX_AUGMENT_SLOTS 5

View File

@ -76,6 +76,25 @@ EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(MemoryBuffer &&other) {
return *this;
}
EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator+=(const MemoryBuffer &rhs) {
if(!rhs.buffer_) {
return *this;
}
if(buffer_) {
size_t old_size = size_;
Resize(size_ + rhs.size_);
memcpy(&buffer_[old_size], rhs.buffer_, rhs.size_);
} else {
buffer_ = new uchar[rhs.capacity_];
memcpy(buffer_, rhs.buffer_, rhs.capacity_);
size_ = rhs.size_;
capacity_ = rhs.capacity_;
}
return *this;
}
EQEmu::MemoryBuffer::~MemoryBuffer() { Clear(); }
uchar& EQEmu::MemoryBuffer::operator[](size_t pos) {
@ -112,7 +131,7 @@ size_t EQEmu::MemoryBuffer::Capacity() const {
void EQEmu::MemoryBuffer::Resize(size_t sz) {
if(!buffer_) {
size_t new_size = sz + 32;
size_t new_size = sz + 64;
buffer_ = new uchar[new_size];
capacity_ = new_size;
size_ = sz;
@ -143,6 +162,8 @@ void EQEmu::MemoryBuffer::Clear() {
size_ = 0;
capacity_ = 0;
write_pos_ = 0;
read_pos_ = 0;
}
void EQEmu::MemoryBuffer::Zero() {

View File

@ -35,6 +35,8 @@ namespace EQEmu
MemoryBuffer(MemoryBuffer &&other);
MemoryBuffer& operator=(const MemoryBuffer &other);
MemoryBuffer& operator=(MemoryBuffer &&other);
MemoryBuffer& operator+=(const MemoryBuffer &rhs);
friend MemoryBuffer operator+(MemoryBuffer lhs, const MemoryBuffer& rhs) { return lhs += rhs; }
~MemoryBuffer();
uchar& operator[](size_t pos);
@ -78,27 +80,18 @@ namespace EQEmu
return temp;
}
template<>
void Write<std::string>(std::string val) {
void Write(const std::string &val) {
Write(val.c_str(), val.length());
Write((uint8)0);
}
template<>
void Write<const std::string&>(const std::string &val) {
Write(val.c_str(), val.length());
Write((uint8)0);
}
template<>
void Write<const char*>(const char *val) {
void Write(const char *val) {
size_t len = strlen(val);
Write(val, len);
Write((uint8)0);
}
template<>
std::string Read<std::string>() {
std::string ReadString() {
std::string ret;
size_t len = strlen((const char*)&buffer_[read_pos_]);
ret.resize(len);

View File

@ -12,6 +12,7 @@
#include "../item.h"
#include "rof2_structs.h"
#include "../rulesys.h"
#include "../memory_buffer.h"
#include <iostream>
#include <sstream>
@ -598,71 +599,90 @@ namespace RoF2
{
//consume the packet
EQApplicationPacket *in = *p;
*p = nullptr;
if (in->size == 0) {
in->size = 4;
in->pBuffer = new uchar[in->size];
*((uint32 *)in->pBuffer) = 0;
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) {
in->SetReadPosition(0);
size_t entry_size = sizeof(int32) * 2 + sizeof(void*);
size_t entries = in->size / entry_size;
if(entries == 0 || in->size % entry_size != 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));
opcodes->EmuToName(in->GetOpcode()), in->size, entry_size);
delete in;
return;
}
InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
//SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)in->pBuffer;
//EQEmu::MemoryBuffer packet_data;
//packet_data.Write<uint32>(entries);
//
//for(size_t i = 0; i < entries; ++i) {
// //SerializeItem((const EQEmu::ItemInstance*)
// //char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0, ItemPacketCharInventory);
//}
in->pBuffer = new uchar[4];
*(uint32 *)in->pBuffer = ItemCount;
in->size = 4;
for (int r = 0; r < ItemCount; r++, eq++) {
uint32 Length = 0;
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0, ItemPacketCharInventory);
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);
}
}
delete[] __emu_buffer;
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
//Log.Hex(Logs::Netcode, in->pBuffer, in->size);
dest->FastQueuePacket(&in, ack_req);
//if (in->size == 0) {
//
// in->size = 4;
// in->pBuffer = new uchar[in->size];
//
// *((uint32 *)in->pBuffer) = 0;
//
// 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) {
//
// 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));
//
// delete in;
//
// return;
//}
//
//InternalSerializedItem_Struct *eq = (InternalSerializedItem_Struct *)in->pBuffer;
//
//in->pBuffer = new uchar[4];
//*(uint32 *)in->pBuffer = ItemCount;
//in->size = 4;
//
//for (int r = 0; r < ItemCount; r++, eq++) {
//
// uint32 Length = 0;
//
// char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0, ItemPacketCharInventory);
//
// 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);
// }
//}
//
//delete[] __emu_buffer;
//
////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending inventory to client");
////Log.Hex(Logs::Netcode, in->pBuffer, in->size);
//
//dest->FastQueuePacket(&in, ack_req);
}
ENCODE(OP_ClickObjectAction)

View File

@ -35,6 +35,7 @@ public:
TEST_ADD(MemoryBufferTest::MoveTest);
TEST_ADD(MemoryBufferTest::ZeroTest);
TEST_ADD(MemoryBufferTest::ClearTest);
TEST_ADD(MemoryBufferTest::AddTest)
}
~MemoryBufferTest() {
@ -93,8 +94,8 @@ private:
uint16 b = mb.Read<uint16>();
uint32 c = mb.Read<uint32>();
uint64 d = mb.Read<uint64>();
std::string s1 = mb.Read<std::string>();
std::string s2 = mb.Read<std::string>();
std::string s1 = mb.ReadString();
std::string s2 = mb.ReadString();
TEST_ASSERT(a == 0);
TEST_ASSERT(b == 5);
@ -504,6 +505,83 @@ private:
TEST_ASSERT(data == nullptr);
}
void AddTest()
{
EQEmu::MemoryBuffer mb2;
EQEmu::MemoryBuffer mb3;
mb2 += mb3;
TEST_ASSERT(!mb2);
TEST_ASSERT(mb2.Size() == 0);
mb2.Write("test1");
mb2.Write("test2");
mb2 += mb3;
TEST_ASSERT(mb2);
TEST_ASSERT(mb2.Size() == 12);
uchar *data = (uchar*)mb2;
TEST_ASSERT(data != nullptr);
TEST_ASSERT(data[0] == 't');
TEST_ASSERT(data[1] == 'e');
TEST_ASSERT(data[2] == 's');
TEST_ASSERT(data[3] == 't');
TEST_ASSERT(data[4] == '1');
TEST_ASSERT(data[5] == 0);
TEST_ASSERT(data[6] == 't');
TEST_ASSERT(data[7] == 'e');
TEST_ASSERT(data[8] == 's');
TEST_ASSERT(data[9] == 't');
TEST_ASSERT(data[10] == '2');
TEST_ASSERT(data[11] == 0);
mb3 += mb2;
TEST_ASSERT(mb3);
TEST_ASSERT(mb3.Size() == 12);
data = (uchar*)mb3;
TEST_ASSERT(data != nullptr);
TEST_ASSERT(data[0] == 't');
TEST_ASSERT(data[1] == 'e');
TEST_ASSERT(data[2] == 's');
TEST_ASSERT(data[3] == 't');
TEST_ASSERT(data[4] == '1');
TEST_ASSERT(data[5] == 0);
TEST_ASSERT(data[6] == 't');
TEST_ASSERT(data[7] == 'e');
TEST_ASSERT(data[8] == 's');
TEST_ASSERT(data[9] == 't');
TEST_ASSERT(data[10] == '2');
TEST_ASSERT(data[11] == 0);
mb2.Clear();
mb3.Clear();
mb2.Write("test1");
mb3.Write("test2");
mb2 += mb3;
TEST_ASSERT(mb2);
TEST_ASSERT(mb2.Size() == 12);
data = (uchar*)mb2;
TEST_ASSERT(data != nullptr);
TEST_ASSERT(data[0] == 't');
TEST_ASSERT(data[1] == 'e');
TEST_ASSERT(data[2] == 's');
TEST_ASSERT(data[3] == 't');
TEST_ASSERT(data[4] == '1');
TEST_ASSERT(data[5] == 0);
TEST_ASSERT(data[6] == 't');
TEST_ASSERT(data[7] == 'e');
TEST_ASSERT(data[8] == 's');
TEST_ASSERT(data[9] == 't');
TEST_ASSERT(data[10] == '2');
TEST_ASSERT(data[11] == 0);
}
EQEmu::MemoryBuffer mb;
};

View File

@ -815,6 +815,15 @@ void Client::OnDisconnect(bool hard_disconnect) {
}
void Client::BulkSendInventoryItems() {
EQEmu::MemoryBuffer items;
if(!m_inventory.Serialize(items)) {
return;
}
EQApplicationPacket* outapp = new EQApplicationPacket(OP_CharInventory, items.Size());
memcpy(outapp->pBuffer, items, items.Size());
//int16 slot_id = 0;
//
//// LINKDEAD TRADE ITEMS