mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-28 00:31:30 +00:00
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:
parent
273574d4db
commit
ca278d029e
@ -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;
|
||||
}
|
||||
|
||||
@ -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_;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user