mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-23 03:51:30 +00:00
Basic item summoning, fix for saving not working 100 pct, deletion works, cursor queue should work too.
This commit is contained in:
parent
316aa5ef73
commit
dda8ae4803
@ -22,6 +22,7 @@
|
|||||||
#include "data_verification.h"
|
#include "data_verification.h"
|
||||||
#include "string_util.h"
|
#include "string_util.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
bool EQEmu::InventorySlot::IsValid() const {
|
bool EQEmu::InventorySlot::IsValid() const {
|
||||||
if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotCharm, PersonalSlotCursor)) {
|
if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotCharm, PersonalSlotCursor)) {
|
||||||
@ -225,7 +226,28 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!src.IsValid() || !dest.IsValid()) {
|
if(!src.IsValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(src.Type() == InvTypeCursorBuffer || dest.Type() == InvTypeCursorBuffer) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dest.IsDelete()) {
|
||||||
|
impl_->data_model_->Begin();
|
||||||
|
bool v = _destroy(src);
|
||||||
|
if(v) {
|
||||||
|
impl_->data_model_->Commit();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
impl_->data_model_->Rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!dest.IsValid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,17 +274,6 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl_->data_model_->Begin();
|
impl_->data_model_->Begin();
|
||||||
if(dest.IsDelete()) {
|
|
||||||
bool v = _destroy(src);
|
|
||||||
if(v) {
|
|
||||||
impl_->data_model_->Commit();
|
|
||||||
} else {
|
|
||||||
impl_->data_model_->Rollback();
|
|
||||||
}
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i_src->IsStackable()) {
|
if(i_src->IsStackable()) {
|
||||||
//move # charges from src to dest
|
//move # charges from src to dest
|
||||||
|
|
||||||
@ -356,6 +367,109 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EQEmu::Inventory::Summon(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst) {
|
||||||
|
if(!inst)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(CheckLoreConflict(inst->GetBaseItem())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cur = Get(slot);
|
||||||
|
if(cur) {
|
||||||
|
if(slot.IsCursor()) {
|
||||||
|
PushToCursorBuffer(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_->data_model_->Begin();
|
||||||
|
bool v = Put(slot, inst);
|
||||||
|
if(v) {
|
||||||
|
impl_->data_model_->Insert(slot, inst);
|
||||||
|
impl_->data_model_->Commit();
|
||||||
|
} else {
|
||||||
|
impl_->data_model_->Rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EQEmu::Inventory::PushToCursorBuffer(std::shared_ptr<ItemInstance> inst) {
|
||||||
|
if(impl_->containers_.count(InvTypeCursorBuffer) == 0) {
|
||||||
|
impl_->containers_.insert(std::pair<int, ItemContainer>(InvTypeCursorBuffer, ItemContainer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 top = 0;
|
||||||
|
auto &container = impl_->containers_[InvTypeCursorBuffer];
|
||||||
|
auto iter = container.Begin();
|
||||||
|
while(iter != container.End()) {
|
||||||
|
top = iter->first;
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
InventorySlot slot(InvTypeCursorBuffer, top + 1);
|
||||||
|
impl_->data_model_->Begin();
|
||||||
|
bool v = Put(slot, inst);
|
||||||
|
if(v) {
|
||||||
|
impl_->data_model_->Insert(slot, inst);
|
||||||
|
impl_->data_model_->Commit();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
impl_->data_model_->Rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EQEmu::Inventory::PopFromCursorBuffer() {
|
||||||
|
InventorySlot cursor(InvTypePersonal, PersonalSlotCursor);
|
||||||
|
auto inst = Get(cursor);
|
||||||
|
if(inst) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(impl_->containers_.count(InvTypeCursorBuffer) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 top = 0;
|
||||||
|
auto &container = impl_->containers_[InvTypeCursorBuffer];
|
||||||
|
auto iter = container.Begin();
|
||||||
|
while(iter != container.End()) {
|
||||||
|
top = iter->first;
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
InventorySlot slot(InvTypeCursorBuffer, top);
|
||||||
|
inst = Get(slot);
|
||||||
|
|
||||||
|
if(inst) {
|
||||||
|
impl_->data_model_->Begin();
|
||||||
|
|
||||||
|
bool v = _destroy(slot);
|
||||||
|
impl_->data_model_->Delete(slot);
|
||||||
|
|
||||||
|
if(!v) {
|
||||||
|
impl_->data_model_->Rollback();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = Put(cursor, inst);
|
||||||
|
impl_->data_model_->Insert(cursor, inst);
|
||||||
|
if(!v) {
|
||||||
|
impl_->data_model_->Rollback();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_->data_model_->Commit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) {
|
int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) {
|
||||||
if(slot.Type() != 0)
|
if(slot.Type() != 0)
|
||||||
return _MaterialInvalid;
|
return _MaterialInvalid;
|
||||||
@ -441,17 +555,59 @@ bool EQEmu::Inventory::CanEquip(std::shared_ptr<EQEmu::ItemInstance> inst, const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo: check deity
|
||||||
if(!item->IsEquipable(impl_->race_, impl_->class_)) {
|
if(!item->IsEquipable(impl_->race_, impl_->class_)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Checking augments
|
||||||
|
auto iter = inst->GetContainer()->Begin();
|
||||||
|
auto end = inst->GetContainer()->End();
|
||||||
|
while(iter != end) {
|
||||||
|
if(!CanEquip(iter->second, InventorySlot(slot.Type(), slot.Slot(), slot.BagIndex(), iter->first))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EQEmu::Inventory::CheckLoreConflict(const ItemData *item) {
|
||||||
|
if(!item)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!item->LoreFlag)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(item->LoreGroup == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(item->LoreGroup == 0xFFFFFFFF) {
|
||||||
|
//look everywhere except shared bank
|
||||||
|
for(auto &container : impl_->containers_) {
|
||||||
|
if(container.first != InvTypeSharedBank && container.second.HasItem(item->ID)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//look everywhere except shared bank
|
||||||
|
for(auto &container : impl_->containers_) {
|
||||||
|
if(container.first != InvTypeSharedBank && container.second.HasItemByLoreGroup(item->LoreGroup)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool EQEmu::Inventory::Serialize(MemoryBuffer &buf) {
|
bool EQEmu::Inventory::Serialize(MemoryBuffer &buf) {
|
||||||
buf.SetWritePosition(0);
|
buf.SetWritePosition(0);
|
||||||
buf.SetReadPosition(0);
|
buf.SetReadPosition(0);
|
||||||
buf.Resize(0);
|
buf.Resize(0);
|
||||||
|
buf.Write<int32>(105);
|
||||||
|
|
||||||
bool value = false;
|
bool value = false;
|
||||||
for(auto &iter : impl_->containers_) {
|
for(auto &iter : impl_->containers_) {
|
||||||
|
|||||||
@ -135,11 +135,15 @@ namespace EQEmu
|
|||||||
std::shared_ptr<ItemInstance> Get(const InventorySlot &slot);
|
std::shared_ptr<ItemInstance> Get(const InventorySlot &slot);
|
||||||
bool Put(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst);
|
bool Put(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst);
|
||||||
bool Swap(const InventorySlot &src, const InventorySlot &dest, int charges);
|
bool Swap(const InventorySlot &src, const InventorySlot &dest, int charges);
|
||||||
|
bool Summon(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst);
|
||||||
|
bool PushToCursorBuffer(std::shared_ptr<ItemInstance> inst);
|
||||||
|
bool PopFromCursorBuffer();
|
||||||
|
|
||||||
//utility
|
//utility
|
||||||
static int CalcMaterialFromSlot(const InventorySlot &slot);
|
static int CalcMaterialFromSlot(const InventorySlot &slot);
|
||||||
static InventorySlot CalcSlotFromMaterial(int material);
|
static InventorySlot CalcSlotFromMaterial(int material);
|
||||||
bool CanEquip(std::shared_ptr<EQEmu::ItemInstance> inst, const EQEmu::InventorySlot &slot);
|
bool CanEquip(std::shared_ptr<EQEmu::ItemInstance> inst, const EQEmu::InventorySlot &slot);
|
||||||
|
bool CheckLoreConflict(const ItemData *item);
|
||||||
bool Serialize(MemoryBuffer &buf);
|
bool Serialize(MemoryBuffer &buf);
|
||||||
|
|
||||||
//testing
|
//testing
|
||||||
|
|||||||
@ -153,9 +153,23 @@ void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, std::s
|
|||||||
DataEvent evt;
|
DataEvent evt;
|
||||||
evt.evt = DB_Insert;
|
evt.evt = DB_Insert;
|
||||||
evt.inst = iter->second;
|
evt.inst = iter->second;
|
||||||
evt.slot = InventorySlot(slot.Type(), slot.Slot(), -1, iter->first);
|
evt.slot = InventorySlot(slot.Type(), slot.Slot(), iter->first, -1);
|
||||||
impl_->events_.push_back(evt);
|
impl_->events_.push_back(evt);
|
||||||
|
|
||||||
|
//do augments here
|
||||||
|
if(evt.inst->GetBaseItem()->ItemClass == ItemClassCommon) {
|
||||||
|
auto inst_container = evt.inst->GetContainer();
|
||||||
|
auto inst_iter = inst_container->Begin();
|
||||||
|
while(inst_iter != inst_container->End()) {
|
||||||
|
DataEvent evt;
|
||||||
|
evt.evt = DB_Insert;
|
||||||
|
evt.inst = inst_iter->second;
|
||||||
|
evt.slot = InventorySlot(slot.Type(), slot.Slot(), iter->first, inst_iter->first);
|
||||||
|
impl_->events_.push_back(evt);
|
||||||
|
++inst_iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,14 +180,15 @@ void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, std::s
|
|||||||
DataEvent evt;
|
DataEvent evt;
|
||||||
evt.evt = DB_Insert;
|
evt.evt = DB_Insert;
|
||||||
evt.inst = iter->second;
|
evt.inst = iter->second;
|
||||||
evt.slot = InventorySlot(slot.Type(), slot.Slot(), iter->first);
|
evt.slot = InventorySlot(slot.Type(), slot.Slot(), -1, iter->first);
|
||||||
impl_->events_.push_back(evt);
|
impl_->events_.push_back(evt);
|
||||||
|
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(inst->GetBaseItem()->ItemClass == ItemClassCommon) {
|
else if(slot.AugIndex() < 0 && inst->GetBaseItem()->ItemClass == ItemClassCommon) {
|
||||||
|
//bag item that can have augs
|
||||||
//if common put all augment contents in
|
//if common put all augment contents in
|
||||||
auto container = inst->GetContainer();
|
auto container = inst->GetContainer();
|
||||||
auto iter = container->Begin();
|
auto iter = container->Begin();
|
||||||
@ -181,7 +196,7 @@ void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, std::s
|
|||||||
DataEvent evt;
|
DataEvent evt;
|
||||||
evt.evt = DB_Insert;
|
evt.evt = DB_Insert;
|
||||||
evt.inst = iter->second;
|
evt.inst = iter->second;
|
||||||
evt.slot = InventorySlot(slot.Type(), slot.Slot(), iter->first, slot.BagIndex());
|
evt.slot = InventorySlot(slot.Type(), slot.Slot(), slot.BagIndex(), iter->first);
|
||||||
impl_->events_.push_back(evt);
|
impl_->events_.push_back(evt);
|
||||||
|
|
||||||
++iter;
|
++iter;
|
||||||
|
|||||||
@ -29,11 +29,11 @@ namespace EQEmu
|
|||||||
InventoryNullDataModel() { }
|
InventoryNullDataModel() { }
|
||||||
virtual ~InventoryNullDataModel() { }
|
virtual ~InventoryNullDataModel() { }
|
||||||
|
|
||||||
virtual void Begin() { printf("NDM: Begin\n"); }
|
virtual void Begin() { }
|
||||||
virtual bool Commit() { printf("NDM: Commit\n"); return true; }
|
virtual bool Commit() { return true; }
|
||||||
virtual void Rollback() { printf("NDM: Rollback\n"); }
|
virtual void Rollback() { }
|
||||||
virtual void Insert(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst) { printf("NDM: Insert %s %s\n", slot.ToString().c_str(), inst ? inst->GetBaseItem()->Name : "Null" ); }
|
virtual void Insert(const InventorySlot &slot, std::shared_ptr<ItemInstance> inst) { }
|
||||||
virtual void Delete(const InventorySlot &slot) { printf("NDM: Delete %s\n", slot.ToString().c_str()); }
|
virtual void Delete(const InventorySlot &slot) { }
|
||||||
};
|
};
|
||||||
} // EQEmu
|
} // EQEmu
|
||||||
|
|
||||||
|
|||||||
@ -65,6 +65,29 @@ bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr<ItemInstance>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EQEmu::ItemContainer::HasItem(uint32 item_id) {
|
||||||
|
for(auto &item : impl_->items_) {
|
||||||
|
if(item.second->GetBaseItem()->ID == item_id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EQEmu::ItemContainer::HasItemByLoreGroup(uint32 loregroup) {
|
||||||
|
if(loregroup == 0xFFFFFFFF)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for(auto &item : impl_->items_) {
|
||||||
|
if(item.second->GetBaseItem()->LoreGroup == loregroup) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 EQEmu::ItemContainer::Size() {
|
uint32 EQEmu::ItemContainer::Size() {
|
||||||
return (uint32)impl_->items_.size();
|
return (uint32)impl_->items_.size();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,11 @@ namespace EQEmu
|
|||||||
std::shared_ptr<ItemInstance> Get(const int slot_id);
|
std::shared_ptr<ItemInstance> Get(const int slot_id);
|
||||||
bool Put(const int slot_id, std::shared_ptr<ItemInstance> inst);
|
bool Put(const int slot_id, std::shared_ptr<ItemInstance> inst);
|
||||||
bool Delete(const int slot_id);
|
bool Delete(const int slot_id);
|
||||||
|
|
||||||
|
//Utility
|
||||||
|
bool HasItem(uint32 item_id);
|
||||||
|
bool HasItemByLoreGroup(uint32 loregroup);
|
||||||
|
|
||||||
uint32 Size();
|
uint32 Size();
|
||||||
uint32 Size() const;
|
uint32 Size() const;
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,8 @@ bool EQEmu::ItemContainerDefaultSerialization::Serialize(MemoryBuffer &buf, cons
|
|||||||
for(auto &iter : items) {
|
for(auto &iter : items) {
|
||||||
buf.Write<int32>(container_number);
|
buf.Write<int32>(container_number);
|
||||||
buf.Write<int32>(iter.first);
|
buf.Write<int32>(iter.first);
|
||||||
|
buf.Write<int32>(-1);
|
||||||
|
buf.Write<int32>(-1);
|
||||||
buf.Write<void*>(iter.second.get());
|
buf.Write<void*>(iter.second.get());
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,8 @@ bool EQEmu::ItemContainerPersonalSerialization::Serialize(MemoryBuffer &buf, con
|
|||||||
if(iter.first < 33) {
|
if(iter.first < 33) {
|
||||||
buf.Write<int32>(container_number);
|
buf.Write<int32>(container_number);
|
||||||
buf.Write<int32>(iter.first);
|
buf.Write<int32>(iter.first);
|
||||||
|
buf.Write<int32>(-1);
|
||||||
|
buf.Write<int32>(-1);
|
||||||
buf.Write<void*>(iter.second.get());
|
buf.Write<void*>(iter.second.get());
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,6 +72,8 @@ struct InternalSerializedItem_Struct {
|
|||||||
struct SerializedItemInstance_Struct {
|
struct SerializedItemInstance_Struct {
|
||||||
int32 container_id;
|
int32 container_id;
|
||||||
int32 slot_id;
|
int32 slot_id;
|
||||||
|
int32 bag_id;
|
||||||
|
int32 aug_id;
|
||||||
void *inst;
|
void *inst;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -602,18 +602,18 @@ namespace RoF2
|
|||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
|
|
||||||
size_t entry_size = sizeof(int32) * 2 + sizeof(void*);
|
size_t entry_size = sizeof(SerializedItemInstance_Struct);
|
||||||
size_t entries = in->size / entry_size;
|
size_t entries = (in->size - sizeof(int32)) / entry_size;
|
||||||
|
|
||||||
if(entries == 0 || in->size % entry_size != 0) {
|
if(entries == 0 || (in->size - sizeof(int32)) % entry_size != 0) {
|
||||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
|
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
|
||||||
opcodes->EmuToName(in->GetOpcode()), in->size, entry_size);
|
opcodes->EmuToName(in->GetOpcode()), (in->size - sizeof(int32)), entry_size);
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *__emu_buffer = in->pBuffer;
|
unsigned char *__emu_buffer = in->pBuffer;
|
||||||
SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)__emu_buffer;
|
SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)(__emu_buffer + sizeof(int32));
|
||||||
EQEmu::MemoryBuffer packet_data;
|
EQEmu::MemoryBuffer packet_data;
|
||||||
packet_data.Write<uint32>(entries);
|
packet_data.Write<uint32>(entries);
|
||||||
|
|
||||||
@ -1490,33 +1490,41 @@ namespace RoF2
|
|||||||
|
|
||||||
ENCODE(OP_ItemPacket)
|
ENCODE(OP_ItemPacket)
|
||||||
{
|
{
|
||||||
delete *p;
|
EQApplicationPacket *in = *p;
|
||||||
|
*p = nullptr;
|
||||||
|
|
||||||
////consume the packet
|
size_t entry_size = sizeof(SerializedItemInstance_Struct);
|
||||||
//EQApplicationPacket *in = *p;
|
size_t entries = (in->size - sizeof(int32)) / entry_size;
|
||||||
//*p = nullptr;
|
|
||||||
//
|
if(entries == 0 || entries > 1 || (in->size - sizeof(int32)) % entry_size != 0) {
|
||||||
//unsigned char *__emu_buffer = in->pBuffer;
|
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
|
||||||
//ItemPacket_Struct *old_item_pkt = (ItemPacket_Struct *)__emu_buffer;
|
opcodes->EmuToName(in->GetOpcode()), (in->size - sizeof(int32)), entry_size);
|
||||||
//InternalSerializedItem_Struct *int_struct = (InternalSerializedItem_Struct *)(old_item_pkt->SerializedItem);
|
delete in;
|
||||||
//
|
return;
|
||||||
//uint32 length;
|
}
|
||||||
//char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0, old_item_pkt->PacketType);
|
|
||||||
//
|
unsigned char *__emu_buffer = in->pBuffer;
|
||||||
//if (!serialized) {
|
|
||||||
// Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
|
int32 *packet_type = (int32*)(__emu_buffer);
|
||||||
// delete in;
|
SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)(__emu_buffer + sizeof(int32));
|
||||||
// return;
|
EQEmu::MemoryBuffer packet_data;
|
||||||
//}
|
packet_data.Write<int32>(*packet_type);
|
||||||
//in->size = length + 4;
|
|
||||||
//in->pBuffer = new unsigned char[in->size];
|
EQEmu::ItemInstance *inst = (EQEmu::ItemInstance*)sis->inst;
|
||||||
//ItemPacket_Struct *new_item_pkt = (ItemPacket_Struct *)in->pBuffer;
|
if(!inst) {
|
||||||
//new_item_pkt->PacketType = old_item_pkt->PacketType;
|
delete in;
|
||||||
//memcpy(new_item_pkt->SerializedItem, serialized, length);
|
return;
|
||||||
//
|
}
|
||||||
//delete[] __emu_buffer;
|
|
||||||
//safe_delete_array(serialized);
|
SerializeItem(packet_data, inst, sis->container_id, sis->slot_id, sis->bag_id, sis->slot_id);
|
||||||
//dest->FastQueuePacket(&in, ack_req);
|
|
||||||
|
in->pBuffer = new uchar[packet_data.Size()];
|
||||||
|
in->size = packet_data.Size();
|
||||||
|
memcpy(in->pBuffer, packet_data, in->size);
|
||||||
|
|
||||||
|
|
||||||
|
delete[] __emu_buffer;
|
||||||
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_ItemVerifyReply)
|
ENCODE(OP_ItemVerifyReply)
|
||||||
|
|||||||
@ -818,13 +818,28 @@ public:
|
|||||||
void QSSwapItemAuditor(MoveItemOld_Struct* move_in, bool postaction_call = false);
|
void QSSwapItemAuditor(MoveItemOld_Struct* move_in, bool postaction_call = false);
|
||||||
void PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootItem_Struct** bag_item_data = 0);
|
void PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootItem_Struct** bag_item_data = 0);
|
||||||
bool AutoPutLootInInventory(ItemInst& inst, bool try_worn = false, bool try_cursor = true, ServerLootItem_Struct** bag_item_data = 0);
|
bool AutoPutLootInInventory(ItemInst& inst, bool try_worn = false, bool try_cursor = true, ServerLootItem_Struct** bag_item_data = 0);
|
||||||
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, bool attuned = false, uint16 to_slot = MainCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0);
|
bool SummonItem(uint32 item_id, int16 charges = -1,
|
||||||
|
uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, bool attuned = false,
|
||||||
|
uint16 to_slot = MainCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0);
|
||||||
void SetStats(uint8 type,int16 set_val);
|
void SetStats(uint8 type,int16 set_val);
|
||||||
void IncStats(uint8 type,int16 increase_val);
|
void IncStats(uint8 type,int16 increase_val);
|
||||||
void DropItem(int16 slot_id);
|
void DropItem(int16 slot_id);
|
||||||
|
|
||||||
//New Inventory
|
//New Inventory
|
||||||
bool SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlot &dest, int number_in_stack);
|
bool SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlot &dest, int number_in_stack);
|
||||||
|
bool SummonItem(uint32 item_id,
|
||||||
|
int16 charges,
|
||||||
|
const EQEmu::InventorySlot &slot,
|
||||||
|
uint32 aug1 = 0,
|
||||||
|
uint32 aug2 = 0,
|
||||||
|
uint32 aug3 = 0,
|
||||||
|
uint32 aug4 = 0,
|
||||||
|
uint32 aug5 = 0,
|
||||||
|
uint32 aug6 = 0,
|
||||||
|
bool attuned = false,
|
||||||
|
uint32 ornament_icon = 0,
|
||||||
|
uint32 ornament_idfile = 0,
|
||||||
|
uint32 ornament_hero_model = 0);
|
||||||
|
|
||||||
//
|
//
|
||||||
// class Client::TextLink
|
// class Client::TextLink
|
||||||
@ -881,6 +896,9 @@ public:
|
|||||||
bool IsValidSlot(uint32 slot);
|
bool IsValidSlot(uint32 slot);
|
||||||
bool IsBankSlot(uint32 slot);
|
bool IsBankSlot(uint32 slot);
|
||||||
|
|
||||||
|
//inv2
|
||||||
|
void SendItemPacket(const EQEmu::InventorySlot &slot, std::shared_ptr<EQEmu::ItemInstance> inst, ItemPacketType packet_type);
|
||||||
|
|
||||||
inline bool IsTrader() const { return(Trader); }
|
inline bool IsTrader() const { return(Trader); }
|
||||||
inline bool IsBuyer() const { return(Buyer); }
|
inline bool IsBuyer() const { return(Buyer); }
|
||||||
eqFilterMode GetFilter(eqFilterType filter_id) const { return ClientFilters[filter_id]; }
|
eqFilterMode GetFilter(eqFilterType filter_id) const { return ClientFilters[filter_id]; }
|
||||||
|
|||||||
@ -1722,14 +1722,11 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
*/
|
*/
|
||||||
if (loaditems) { /* Dont load if a length error occurs */
|
if (loaditems) { /* Dont load if a length error occurs */
|
||||||
BulkSendInventoryItems();
|
BulkSendInventoryItems();
|
||||||
// /* Send stuff on the cursor which isnt sent in bulk */
|
EQEmu::InventorySlot slot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor);
|
||||||
// for (auto iter = m_inv.cursor_cbegin(); iter != m_inv.cursor_cend(); ++iter) {
|
auto cursor = m_inventory.Get(slot);
|
||||||
// /* First item cursor is sent in bulk inventory packet */
|
if(cursor) {
|
||||||
// if (iter == m_inv.cursor_cbegin())
|
SendItemPacket(slot, cursor, ItemPacketSummonItem);
|
||||||
// continue;
|
}
|
||||||
// const ItemInst *inst = *iter;
|
|
||||||
// SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Task Packets */
|
/* Task Packets */
|
||||||
|
|||||||
@ -5418,24 +5418,25 @@ void command_summonitem(Client *c, const Seperator *sep)
|
|||||||
item_status = static_cast<int16>(item->MinStatus);
|
item_status = static_cast<int16>(item->MinStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EQEmu::InventorySlot cursor(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor);
|
||||||
if (item_status > c->Admin())
|
if (item_status > c->Admin())
|
||||||
c->Message(13, "Error: Insufficient status to summon this item.");
|
c->Message(13, "Error: Insufficient status to summon this item.");
|
||||||
else if (sep->argnum==2 && sep->IsNumber(2))
|
else if (sep->argnum==2 && sep->IsNumber(2))
|
||||||
c->SummonItem(itemid, atoi(sep->arg[2]));
|
c->SummonItem(itemid, atoi(sep->arg[2]), cursor);
|
||||||
else if (sep->argnum==3)
|
else if (sep->argnum==3)
|
||||||
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]));
|
c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]));
|
||||||
else if (sep->argnum==4)
|
else if (sep->argnum==4)
|
||||||
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]));
|
c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]));
|
||||||
else if (sep->argnum==5)
|
else if (sep->argnum==5)
|
||||||
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]));
|
c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]));
|
||||||
else if (sep->argnum==6)
|
else if (sep->argnum==6)
|
||||||
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]));
|
c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]));
|
||||||
else if (sep->argnum==7)
|
else if (sep->argnum==7)
|
||||||
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]));
|
c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]));
|
||||||
else if (sep->argnum==8)
|
else if (sep->argnum==8)
|
||||||
c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]), atoi(sep->arg[8]));
|
c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]), atoi(sep->arg[8]));
|
||||||
else {
|
else {
|
||||||
c->SummonItem(itemid);
|
c->SummonItem(itemid, -1, cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2427,52 +2427,74 @@ uint32 Client::GetEquipmentColor(uint8 material_slot) const
|
|||||||
// Send an item packet (including all subitems of the item)
|
// Send an item packet (including all subitems of the item)
|
||||||
void Client::SendItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type)
|
void Client::SendItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type)
|
||||||
{
|
{
|
||||||
if (!inst)
|
// if (!inst)
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// // Serialize item into |-delimited string
|
||||||
|
// std::string packet = inst->Serialize(slot_id);
|
||||||
|
//
|
||||||
|
// EmuOpcode opcode = OP_Unknown;
|
||||||
|
// EQApplicationPacket* outapp = nullptr;
|
||||||
|
// ItemPacket_Struct* itempacket = nullptr;
|
||||||
|
//
|
||||||
|
// // Construct packet
|
||||||
|
// opcode = (packet_type==ItemPacketViewLink) ? OP_ItemLinkResponse : OP_ItemPacket;
|
||||||
|
// outapp = new EQApplicationPacket(opcode, packet.length()+sizeof(ItemPacket_Struct));
|
||||||
|
// itempacket = (ItemPacket_Struct*)outapp->pBuffer;
|
||||||
|
// memcpy(itempacket->SerializedItem, packet.c_str(), packet.length());
|
||||||
|
// itempacket->PacketType = packet_type;
|
||||||
|
//
|
||||||
|
//#if EQDEBUG >= 9
|
||||||
|
// DumpPacket(outapp);
|
||||||
|
//#endif
|
||||||
|
// FastQueuePacket(&outapp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::SendItemPacket(const EQEmu::InventorySlot &slot, std::shared_ptr<EQEmu::ItemInstance> inst, ItemPacketType packet_type) {
|
||||||
|
if(!inst) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Serialize item into |-delimited string
|
EQEmu::MemoryBuffer item;
|
||||||
std::string packet = inst->Serialize(slot_id);
|
|
||||||
|
|
||||||
EmuOpcode opcode = OP_Unknown;
|
EmuOpcode opcode = OP_Unknown;
|
||||||
EQApplicationPacket* outapp = nullptr;
|
opcode = (packet_type == ItemPacketViewLink) ? OP_ItemLinkResponse : OP_ItemPacket;
|
||||||
ItemPacket_Struct* itempacket = nullptr;
|
|
||||||
|
|
||||||
// Construct packet
|
item.Write<int32>((int32)packet_type);
|
||||||
opcode = (packet_type==ItemPacketViewLink) ? OP_ItemLinkResponse : OP_ItemPacket;
|
item.Write<int32>(slot.Type());
|
||||||
outapp = new EQApplicationPacket(opcode, packet.length()+sizeof(ItemPacket_Struct));
|
item.Write<int32>(slot.Slot());
|
||||||
itempacket = (ItemPacket_Struct*)outapp->pBuffer;
|
item.Write<int32>(slot.BagIndex());
|
||||||
memcpy(itempacket->SerializedItem, packet.c_str(), packet.length());
|
item.Write<int32>(slot.AugIndex());
|
||||||
itempacket->PacketType = packet_type;
|
item.Write<void*>(inst.get());
|
||||||
|
|
||||||
#if EQDEBUG >= 9
|
EQApplicationPacket outapp(opcode, item.Size());
|
||||||
DumpPacket(outapp);
|
memcpy(outapp.pBuffer, item, item.Size());
|
||||||
#endif
|
QueuePacket(&outapp);
|
||||||
FastQueuePacket(&outapp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EQApplicationPacket* Client::ReturnItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type)
|
EQApplicationPacket* Client::ReturnItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type)
|
||||||
{
|
{
|
||||||
if (!inst)
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
// if (!inst)
|
||||||
// Serialize item into |-delimited string
|
// return nullptr;
|
||||||
std::string packet = inst->Serialize(slot_id);
|
//
|
||||||
|
// // Serialize item into |-delimited string
|
||||||
EmuOpcode opcode = OP_Unknown;
|
// std::string packet = inst->Serialize(slot_id);
|
||||||
EQApplicationPacket* outapp = nullptr;
|
//
|
||||||
BulkItemPacket_Struct* itempacket = nullptr;
|
// EmuOpcode opcode = OP_Unknown;
|
||||||
|
// EQApplicationPacket* outapp = nullptr;
|
||||||
// Construct packet
|
// BulkItemPacket_Struct* itempacket = nullptr;
|
||||||
opcode = OP_ItemPacket;
|
//
|
||||||
outapp = new EQApplicationPacket(opcode, packet.length()+1);
|
// // Construct packet
|
||||||
itempacket = (BulkItemPacket_Struct*)outapp->pBuffer;
|
// opcode = OP_ItemPacket;
|
||||||
memcpy(itempacket->SerializedItem, packet.c_str(), packet.length());
|
// outapp = new EQApplicationPacket(opcode, packet.length()+1);
|
||||||
|
// itempacket = (BulkItemPacket_Struct*)outapp->pBuffer;
|
||||||
#if EQDEBUG >= 9
|
// memcpy(itempacket->SerializedItem, packet.c_str(), packet.length());
|
||||||
DumpPacket(outapp);
|
//
|
||||||
#endif
|
//#if EQDEBUG >= 9
|
||||||
|
// DumpPacket(outapp);
|
||||||
return outapp;
|
//#endif
|
||||||
|
//
|
||||||
|
// return outapp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int16 BandolierSlotToWeaponSlot(int BandolierSlot)
|
static int16 BandolierSlotToWeaponSlot(int BandolierSlot)
|
||||||
@ -3143,7 +3165,16 @@ bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlo
|
|||||||
} else {
|
} else {
|
||||||
Message(0, "Swap failure!\n");
|
Message(0, "Swap failure!\n");
|
||||||
//should kick the player here...
|
//should kick the player here...
|
||||||
|
}
|
||||||
|
|
||||||
|
EQEmu::InventorySlot cursor(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor);
|
||||||
|
if(!m_inventory.Get(cursor)) {
|
||||||
|
if(m_inventory.PopFromCursorBuffer()) {
|
||||||
|
auto c_inst = m_inventory.Get(cursor);
|
||||||
|
if(c_inst) {
|
||||||
|
SendItemPacket(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), c_inst, ItemPacketSummonItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(auto_attack && res && recalc_weapon_speed) {
|
if(auto_attack && res && recalc_weapon_speed) {
|
||||||
@ -3157,3 +3188,90 @@ bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlo
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Client::SummonItem(uint32 item_id,
|
||||||
|
int16 charges,
|
||||||
|
const EQEmu::InventorySlot &slot,
|
||||||
|
uint32 aug1,
|
||||||
|
uint32 aug2,
|
||||||
|
uint32 aug3,
|
||||||
|
uint32 aug4,
|
||||||
|
uint32 aug5,
|
||||||
|
uint32 aug6,
|
||||||
|
bool attuned,
|
||||||
|
uint32 ornament_icon,
|
||||||
|
uint32 ornament_idfile,
|
||||||
|
uint32 ornament_hero_model)
|
||||||
|
{
|
||||||
|
std::shared_ptr<EQEmu::ItemInstance> inst = database.CreateItem(item_id, charges);
|
||||||
|
if(!inst)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(inst->GetBaseItem()->ItemClass == ItemClassCommon) {
|
||||||
|
if(aug1) {
|
||||||
|
std::shared_ptr<EQEmu::ItemInstance> aug = database.CreateItem(aug1);
|
||||||
|
if(!aug)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!inst->Put(0, aug)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(aug2) {
|
||||||
|
std::shared_ptr<EQEmu::ItemInstance> aug = database.CreateItem(aug2);
|
||||||
|
if(!aug)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!inst->Put(1, aug)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(aug3) {
|
||||||
|
std::shared_ptr<EQEmu::ItemInstance> aug = database.CreateItem(aug3);
|
||||||
|
if(!aug)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!inst->Put(2, aug)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(aug4) {
|
||||||
|
std::shared_ptr<EQEmu::ItemInstance> aug = database.CreateItem(aug4);
|
||||||
|
if(!aug)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!inst->Put(3, aug)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(aug5) {
|
||||||
|
std::shared_ptr<EQEmu::ItemInstance> aug = database.CreateItem(aug5);
|
||||||
|
if(!aug)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!inst->Put(4, aug)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(aug6) {
|
||||||
|
std::shared_ptr<EQEmu::ItemInstance> aug = database.CreateItem(aug6);
|
||||||
|
if(!aug)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!inst->Put(5, aug)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = m_inventory.Summon(slot, inst);
|
||||||
|
if(res) {
|
||||||
|
SendItemPacket(slot, inst, ItemPacketSummonItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user