From b75e6308ddbc6b6e0d5b29f48921d0055b94aa07 Mon Sep 17 00:00:00 2001 From: KimLS Date: Tue, 17 Feb 2015 13:42:21 -0800 Subject: [PATCH 01/27] Renamed Inventory to InventoryOld --- common/database.cpp | 2 +- common/database.h | 4 +- common/item.cpp | 166 ++++++++++++++++++++-------------------- common/item.h | 10 +-- common/patches/rof.cpp | 4 +- common/patches/rof2.cpp | 4 +- common/patches/sod.cpp | 2 +- common/patches/sof.cpp | 2 +- common/patches/uf.cpp | 2 +- common/shareddb.cpp | 24 +++--- common/shareddb.h | 10 +-- world/client.cpp | 2 +- world/worlddb.cpp | 6 +- zone/bonuses.cpp | 4 +- zone/bot.cpp | 14 ++-- zone/bot.h | 4 +- zone/client.cpp | 4 +- zone/client.h | 6 +- zone/client_packet.cpp | 4 +- zone/command.cpp | 10 +-- zone/corpse.cpp | 10 +-- zone/inventory.cpp | 58 +++++++------- zone/lua_inventory.cpp | 2 +- zone/lua_inventory.h | 12 +-- zone/merc.cpp | 2 +- zone/merc.h | 2 +- zone/mob.cpp | 6 +- zone/npc.cpp | 4 +- zone/tradeskills.cpp | 14 ++-- zone/trading.cpp | 22 +++--- zone/zone.cpp | 2 +- 31 files changed, 209 insertions(+), 209 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 31566d82f..9b64c79f3 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -677,7 +677,7 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe } /* This only for new Character creation storing */ -bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv) { +bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, InventoryOld* inv) { uint32 charid = 0; char zone[50]; float x, y, z; diff --git a/common/database.h b/common/database.h index f3b8ba8c1..b28fd4d8f 100644 --- a/common/database.h +++ b/common/database.h @@ -36,7 +36,7 @@ //atoi is not uint32 or uint32 safe!!!! #define atoul(str) strtoul(str, nullptr, 10) -class Inventory; +class InventoryOld; class MySQLRequestResult; class Client; @@ -102,7 +102,7 @@ public: bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp); bool SetHackerFlag(const char* accountname, const char* charactername, const char* hacked); bool SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone); - bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv); + bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, InventoryOld* inv); bool UpdateName(const char* oldname, const char* newname); /* General Information Queries */ diff --git a/common/item.cpp b/common/item.cpp index 0e2f0f574..e5252a9d0 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -105,9 +105,9 @@ ItemInst* ItemInstQueue::peek_front() const // -// class Inventory +// class InventoryOld // -Inventory::~Inventory() +InventoryOld::~InventoryOld() { for (auto iter = m_worn.begin(); iter != m_worn.end(); ++iter) { safe_delete(iter->second); @@ -135,7 +135,7 @@ Inventory::~Inventory() m_trade.clear(); } -void Inventory::CleanDirty() { +void InventoryOld::CleanDirty() { auto iter = dirty_inst.begin(); while (iter != dirty_inst.end()) { delete (*iter); @@ -144,14 +144,14 @@ void Inventory::CleanDirty() { dirty_inst.clear(); } -void Inventory::MarkDirty(ItemInst *inst) { +void InventoryOld::MarkDirty(ItemInst *inst) { if (inst) { dirty_inst.push_back(inst); } } // Retrieve item at specified slot; returns false if item not found -ItemInst* Inventory::GetItem(int16 slot_id) const +ItemInst* InventoryOld::GetItem(int16 slot_id) const { ItemInst* result = nullptr; @@ -186,37 +186,37 @@ ItemInst* Inventory::GetItem(int16 slot_id) const // Inner bag slots else if (slot_id >= EmuConstants::TRADE_BAGS_BEGIN && slot_id <= EmuConstants::TRADE_BAGS_END) { // Trade bag slots - ItemInst* inst = _GetItem(m_trade, Inventory::CalcSlotId(slot_id)); + ItemInst* inst = _GetItem(m_trade, InventoryOld::CalcSlotId(slot_id)); if (inst && inst->IsType(ItemClassContainer)) { - result = inst->GetItem(Inventory::CalcBagIdx(slot_id)); + result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id)); } } else if (slot_id >= EmuConstants::SHARED_BANK_BAGS_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) { // Shared Bank bag slots - ItemInst* inst = _GetItem(m_shbank, Inventory::CalcSlotId(slot_id)); + ItemInst* inst = _GetItem(m_shbank, InventoryOld::CalcSlotId(slot_id)); if (inst && inst->IsType(ItemClassContainer)) { - result = inst->GetItem(Inventory::CalcBagIdx(slot_id)); + result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id)); } } else if (slot_id >= EmuConstants::BANK_BAGS_BEGIN && slot_id <= EmuConstants::BANK_BAGS_END) { // Bank bag slots - ItemInst* inst = _GetItem(m_bank, Inventory::CalcSlotId(slot_id)); + ItemInst* inst = _GetItem(m_bank, InventoryOld::CalcSlotId(slot_id)); if (inst && inst->IsType(ItemClassContainer)) { - result = inst->GetItem(Inventory::CalcBagIdx(slot_id)); + result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id)); } } else if (slot_id >= EmuConstants::CURSOR_BAG_BEGIN && slot_id <= EmuConstants::CURSOR_BAG_END) { // Cursor bag slots ItemInst* inst = m_cursor.peek_front(); if (inst && inst->IsType(ItemClassContainer)) { - result = inst->GetItem(Inventory::CalcBagIdx(slot_id)); + result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id)); } } else if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END) { // Personal inventory bag slots - ItemInst* inst = _GetItem(m_inv, Inventory::CalcSlotId(slot_id)); + ItemInst* inst = _GetItem(m_inv, InventoryOld::CalcSlotId(slot_id)); if (inst && inst->IsType(ItemClassContainer)) { - result = inst->GetItem(Inventory::CalcBagIdx(slot_id)); + result = inst->GetItem(InventoryOld::CalcBagIdx(slot_id)); } } @@ -224,13 +224,13 @@ ItemInst* Inventory::GetItem(int16 slot_id) const } // Retrieve item at specified position within bag -ItemInst* Inventory::GetItem(int16 slot_id, uint8 bagidx) const +ItemInst* InventoryOld::GetItem(int16 slot_id, uint8 bagidx) const { - return GetItem(Inventory::CalcSlotId(slot_id, bagidx)); + return GetItem(InventoryOld::CalcSlotId(slot_id, bagidx)); } // Put an item snto specified slot -int16 Inventory::PutItem(int16 slot_id, const ItemInst& inst) +int16 InventoryOld::PutItem(int16 slot_id, const ItemInst& inst) { // Clean up item already in slot (if exists) DeleteItem(slot_id); @@ -245,19 +245,19 @@ int16 Inventory::PutItem(int16 slot_id, const ItemInst& inst) return _PutItem(slot_id, inst.Clone()); } -int16 Inventory::PushCursor(const ItemInst& inst) +int16 InventoryOld::PushCursor(const ItemInst& inst) { m_cursor.push(inst.Clone()); return MainCursor; } -ItemInst* Inventory::GetCursorItem() +ItemInst* InventoryOld::GetCursorItem() { return m_cursor.peek_front(); } // Swap items in inventory -bool Inventory::SwapItem(int16 slot_a, int16 slot_b) +bool InventoryOld::SwapItem(int16 slot_a, int16 slot_b) { // Temp holding areas for a and b ItemInst* inst_a = GetItem(slot_a); @@ -273,7 +273,7 @@ bool Inventory::SwapItem(int16 slot_a, int16 slot_b) } // Remove item from inventory (with memory delete) -bool Inventory::DeleteItem(int16 slot_id, uint8 quantity) +bool InventoryOld::DeleteItem(int16 slot_id, uint8 quantity) { // Pop item out of inventory map (or queue) ItemInst* item_to_delete = PopItem(slot_id); @@ -293,7 +293,7 @@ bool Inventory::DeleteItem(int16 slot_id, uint8 quantity) ((item_to_delete->GetItem()->MaxCharges == 0) || item_to_delete->IsExpendable())) ) { // Item can now be destroyed - Inventory::MarkDirty(item_to_delete); + InventoryOld::MarkDirty(item_to_delete); return true; } } @@ -303,19 +303,19 @@ bool Inventory::DeleteItem(int16 slot_id, uint8 quantity) return false; } - Inventory::MarkDirty(item_to_delete); + InventoryOld::MarkDirty(item_to_delete); return true; } // Checks All items in a bag for No Drop -bool Inventory::CheckNoDrop(int16 slot_id) { +bool InventoryOld::CheckNoDrop(int16 slot_id) { ItemInst* inst = GetItem(slot_id); if (!inst) return false; if (!inst->GetItem()->NoDrop) return true; if (inst->GetItem()->ItemClass == 1) { for (uint8 i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) { - ItemInst* bagitem = GetItem(Inventory::CalcSlotId(slot_id, i)); + ItemInst* bagitem = GetItem(InventoryOld::CalcSlotId(slot_id, i)); if (bagitem && !bagitem->GetItem()->NoDrop) return true; } @@ -325,7 +325,7 @@ bool Inventory::CheckNoDrop(int16 slot_id) { // Remove item from bucket without memory delete // Returns item pointer if full delete was successful -ItemInst* Inventory::PopItem(int16 slot_id) +ItemInst* InventoryOld::PopItem(int16 slot_id) { ItemInst* p = nullptr; @@ -358,9 +358,9 @@ ItemInst* Inventory::PopItem(int16 slot_id) } else { // Is slot inside bag? - ItemInst* baginst = GetItem(Inventory::CalcSlotId(slot_id)); + ItemInst* baginst = GetItem(InventoryOld::CalcSlotId(slot_id)); if (baginst != nullptr && baginst->IsType(ItemClassContainer)) { - p = baginst->PopItem(Inventory::CalcBagIdx(slot_id)); + p = baginst->PopItem(InventoryOld::CalcBagIdx(slot_id)); } } @@ -368,7 +368,7 @@ ItemInst* Inventory::PopItem(int16 slot_id) return p; } -bool Inventory::HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity) { +bool InventoryOld::HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity) { if (ItemToTry->Stackable) { @@ -388,7 +388,7 @@ bool Inventory::HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity) { } if (InvItem && InvItem->IsType(ItemClassContainer)) { - int16 BaseSlotID = Inventory::CalcSlotId(i, SUB_BEGIN); + int16 BaseSlotID = InventoryOld::CalcSlotId(i, SUB_BEGIN); uint8 BagSize = InvItem->GetItem()->BagSlots; for (uint8 BagSlot = SUB_BEGIN; BagSlot < BagSize; BagSlot++) { @@ -432,7 +432,7 @@ bool Inventory::HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity) { } else if (InvItem->IsType(ItemClassContainer) && CanItemFitInContainer(ItemToTry, InvItem->GetItem())) { - int16 BaseSlotID = Inventory::CalcSlotId(i, SUB_BEGIN); + int16 BaseSlotID = InventoryOld::CalcSlotId(i, SUB_BEGIN); uint8 BagSize = InvItem->GetItem()->BagSlots; @@ -468,7 +468,7 @@ bool Inventory::HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity) { //This function has a flaw in that it only returns the last stack that it looked at //when quantity is greater than 1 and not all of quantity can be found in 1 stack. -int16 Inventory::HasItem(uint32 item_id, uint8 quantity, uint8 where) +int16 InventoryOld::HasItem(uint32 item_id, uint8 quantity, uint8 where) { int16 slot_id = INVALID_INDEX; @@ -518,7 +518,7 @@ int16 Inventory::HasItem(uint32 item_id, uint8 quantity, uint8 where) } //this function has the same quantity flaw mentioned above in HasItem() -int16 Inventory::HasItemByUse(uint8 use, uint8 quantity, uint8 where) +int16 InventoryOld::HasItemByUse(uint8 use, uint8 quantity, uint8 where) { int16 slot_id = INVALID_INDEX; @@ -564,7 +564,7 @@ int16 Inventory::HasItemByUse(uint8 use, uint8 quantity, uint8 where) return slot_id; } -int16 Inventory::HasItemByLoreGroup(uint32 loregroup, uint8 where) +int16 InventoryOld::HasItemByLoreGroup(uint32 loregroup, uint8 where) { int16 slot_id = INVALID_INDEX; @@ -612,7 +612,7 @@ int16 Inventory::HasItemByLoreGroup(uint32 loregroup, uint8 where) // Locate an available inventory slot // Returns slot_id when there's one available, else SLOT_INVALID -int16 Inventory::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, bool is_arrow) +int16 InventoryOld::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, bool is_arrow) { // Check basic inventory for (int16 i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; i++) { @@ -631,7 +631,7 @@ int16 Inventory::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, boo continue; } - int16 base_slot_id = Inventory::CalcSlotId(i, SUB_BEGIN); + int16 base_slot_id = InventoryOld::CalcSlotId(i, SUB_BEGIN); uint8 slots = inst->GetItem()->BagSlots; uint8 j; @@ -656,9 +656,9 @@ int16 Inventory::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, boo } // This is a mix of HasSpaceForItem and FindFreeSlot..due to existing coding behavior, it was better to add a new helper function... -int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { +int16 InventoryOld::FindFreeSlotForTradeItem(const ItemInst* inst) { // Do not arbitrarily use this function..it is designed for use with Client::ResetTrade() and Client::FinishTrade(). - // If you have a need, use it..but, understand it is not a compatible replacement for Inventory::FindFreeSlot(). + // If you have a need, use it..but, understand it is not a compatible replacement for InventoryOld::FindFreeSlot(). // // I'll probably implement a bitmask in the new inventory system to avoid having to adjust stack bias -U @@ -701,7 +701,7 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { continue; if ((sub_inst->GetID() == inst->GetID()) && (sub_inst->GetCharges() < sub_inst->GetItem()->StackSize)) - return Inventory::CalcSlotId(free_slot, free_bag_slot); + return InventoryOld::CalcSlotId(free_slot, free_bag_slot); } } } @@ -717,7 +717,7 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) { if (!main_inst->GetItem(free_bag_slot)) - return Inventory::CalcSlotId(free_slot, free_bag_slot); + return InventoryOld::CalcSlotId(free_slot, free_bag_slot); } } } @@ -732,7 +732,7 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) { if (!main_inst->GetItem(free_bag_slot)) - return Inventory::CalcSlotId(free_slot, free_bag_slot); + return InventoryOld::CalcSlotId(free_slot, free_bag_slot); } } } @@ -754,7 +754,7 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) { if (!main_inst->GetItem(free_bag_slot)) - return Inventory::CalcSlotId(free_slot, free_bag_slot); + return InventoryOld::CalcSlotId(free_slot, free_bag_slot); } } } @@ -764,7 +764,7 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { } // Opposite of below: Get parent bag slot_id from a slot inside of bag -int16 Inventory::CalcSlotId(int16 slot_id) { +int16 InventoryOld::CalcSlotId(int16 slot_id) { int16 parent_slot_id = INVALID_INDEX; // this is not a bag range... using this risks over-writing existing items @@ -792,8 +792,8 @@ int16 Inventory::CalcSlotId(int16 slot_id) { } // Calculate slot_id for an item within a bag -int16 Inventory::CalcSlotId(int16 bagslot_id, uint8 bagidx) { - if (!Inventory::SupportsContainers(bagslot_id)) +int16 InventoryOld::CalcSlotId(int16 bagslot_id, uint8 bagidx) { + if (!InventoryOld::SupportsContainers(bagslot_id)) return INVALID_INDEX; int16 slot_id = INVALID_INDEX; @@ -817,7 +817,7 @@ int16 Inventory::CalcSlotId(int16 bagslot_id, uint8 bagidx) { return slot_id; } -uint8 Inventory::CalcBagIdx(int16 slot_id) { +uint8 InventoryOld::CalcBagIdx(int16 slot_id) { uint8 index = 0; // this is not a bag range... using this risks over-writing existing items @@ -846,7 +846,7 @@ uint8 Inventory::CalcBagIdx(int16 slot_id) { return index; } -int16 Inventory::CalcSlotFromMaterial(uint8 material) +int16 InventoryOld::CalcSlotFromMaterial(uint8 material) { switch (material) { @@ -873,7 +873,7 @@ int16 Inventory::CalcSlotFromMaterial(uint8 material) } } -uint8 Inventory::CalcMaterialFromSlot(int16 equipslot) +uint8 InventoryOld::CalcMaterialFromSlot(int16 equipslot) { switch (equipslot) { @@ -901,7 +901,7 @@ uint8 Inventory::CalcMaterialFromSlot(int16 equipslot) } } -bool Inventory::CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container) { +bool InventoryOld::CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container) { if (!ItemToTry || !Container) return false; @@ -918,7 +918,7 @@ bool Inventory::CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_S return true; } -bool Inventory::SupportsClickCasting(int16 slot_id) +bool InventoryOld::SupportsClickCasting(int16 slot_id) { // there are a few non-potion items that identify as ItemTypePotion..so, we still need to ubiquitously include the equipment range if ((uint16)slot_id <= EmuConstants::GENERAL_END || slot_id == MainPowerSource) @@ -934,7 +934,7 @@ bool Inventory::SupportsClickCasting(int16 slot_id) return false; } -bool Inventory::SupportsPotionBeltCasting(int16 slot_id) +bool InventoryOld::SupportsPotionBeltCasting(int16 slot_id) { if ((uint16)slot_id <= EmuConstants::GENERAL_END || slot_id == MainPowerSource || (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END)) return true; @@ -943,7 +943,7 @@ bool Inventory::SupportsPotionBeltCasting(int16 slot_id) } // Test whether a given slot can support a container item -bool Inventory::SupportsContainers(int16 slot_id) +bool InventoryOld::SupportsContainers(int16 slot_id) { if ((slot_id == MainCursor) || (slot_id >= EmuConstants::GENERAL_BEGIN && slot_id <= EmuConstants::GENERAL_END) || @@ -957,7 +957,7 @@ bool Inventory::SupportsContainers(int16 slot_id) return false; } -int Inventory::GetSlotByItemInst(ItemInst *inst) { +int InventoryOld::GetSlotByItemInst(ItemInst *inst) { if (!inst) return INVALID_INDEX; @@ -993,7 +993,7 @@ int Inventory::GetSlotByItemInst(ItemInst *inst) { return INVALID_INDEX; } -uint8 Inventory::FindHighestLightValue() +uint8 InventoryOld::FindHighestLightValue() { uint8 light_value = NOT_USED; @@ -1023,7 +1023,7 @@ uint8 Inventory::FindHighestLightValue() return light_value; } -void Inventory::dumpEntireInventory() { +void InventoryOld::dumpEntireInventory() { dumpWornItems(); dumpInventory(); @@ -1033,29 +1033,29 @@ void Inventory::dumpEntireInventory() { std::cout << std::endl; } -void Inventory::dumpWornItems() { +void InventoryOld::dumpWornItems() { std::cout << "Worn items:" << std::endl; dumpItemCollection(m_worn); } -void Inventory::dumpInventory() { +void InventoryOld::dumpInventory() { std::cout << "Inventory items:" << std::endl; dumpItemCollection(m_inv); } -void Inventory::dumpBankItems() { +void InventoryOld::dumpBankItems() { std::cout << "Bank items:" << std::endl; dumpItemCollection(m_bank); } -void Inventory::dumpSharedBankItems() { +void InventoryOld::dumpSharedBankItems() { std::cout << "Shared Bank items:" << std::endl; dumpItemCollection(m_shbank); } -int Inventory::GetSlotByItemInstCollection(const std::map &collection, ItemInst *inst) { +int InventoryOld::GetSlotByItemInstCollection(const std::map &collection, ItemInst *inst) { for (auto iter = collection.begin(); iter != collection.end(); ++iter) { ItemInst *t_inst = iter->second; if (t_inst == inst) { @@ -1065,7 +1065,7 @@ int Inventory::GetSlotByItemInstCollection(const std::map &col if (t_inst && !t_inst->IsType(ItemClassContainer)) { for (auto b_iter = t_inst->_cbegin(); b_iter != t_inst->_cend(); ++b_iter) { if (b_iter->second == inst) { - return Inventory::CalcSlotId(iter->first, b_iter->first); + return InventoryOld::CalcSlotId(iter->first, b_iter->first); } } } @@ -1074,7 +1074,7 @@ int Inventory::GetSlotByItemInstCollection(const std::map &col return -1; } -void Inventory::dumpItemCollection(const std::map &collection) +void InventoryOld::dumpItemCollection(const std::map &collection) { for (auto it = collection.cbegin(); it != collection.cend(); ++it) { auto inst = it->second; @@ -1088,7 +1088,7 @@ void Inventory::dumpItemCollection(const std::map &collection) } } -void Inventory::dumpBagContents(ItemInst *inst, std::map::const_iterator *it) +void InventoryOld::dumpBagContents(ItemInst *inst, std::map::const_iterator *it) { if (!inst || !inst->IsType(ItemClassContainer)) return; @@ -1099,7 +1099,7 @@ void Inventory::dumpBagContents(ItemInst *inst, std::map::cons if (!baginst || !baginst->GetItem()) continue; - std::string subSlot = StringFormat(" Slot %d: %s (%d)", Inventory::CalcSlotId((*it)->first, itb->first), + std::string subSlot = StringFormat(" Slot %d: %s (%d)", InventoryOld::CalcSlotId((*it)->first, itb->first), baginst->GetItem()->Name, (baginst->GetCharges() <= 0) ? 1 : baginst->GetCharges()); std::cout << subSlot << std::endl; } @@ -1107,7 +1107,7 @@ void Inventory::dumpBagContents(ItemInst *inst, std::map::cons } // Internal Method: Retrieves item within an inventory bucket -ItemInst* Inventory::_GetItem(const std::map& bucket, int16 slot_id) const +ItemInst* InventoryOld::_GetItem(const std::map& bucket, int16 slot_id) const { auto it = bucket.find(slot_id); if (it != bucket.end()) { @@ -1120,7 +1120,7 @@ ItemInst* Inventory::_GetItem(const std::map& bucket, int16 sl // Internal Method: "put" item into bucket, without regard for what is currently in bucket // Assumes item has already been allocated -int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst) +int16 InventoryOld::_PutItem(int16 slot_id, ItemInst* inst) { // What happens here when we _PutItem(MainCursor)? Bad things..really bad things... // @@ -1166,25 +1166,25 @@ int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst) } else { // Slot must be within a bag - parentSlot = Inventory::CalcSlotId(slot_id); + parentSlot = InventoryOld::CalcSlotId(slot_id); ItemInst* baginst = GetItem(parentSlot); // Get parent bag if (baginst && baginst->IsType(ItemClassContainer)) { - baginst->_PutItem(Inventory::CalcBagIdx(slot_id), inst); + baginst->_PutItem(InventoryOld::CalcBagIdx(slot_id), inst); result = slot_id; } } if (result == INVALID_INDEX) { - Log.Out(Logs::General, Logs::Error, "Inventory::_PutItem: Invalid slot_id specified (%i) with parent slot id (%i)", slot_id, parentSlot); - Inventory::MarkDirty(inst); // Slot not found, clean up + Log.Out(Logs::General, Logs::Error, "InventoryOld::_PutItem: Invalid slot_id specified (%i) with parent slot id (%i)", slot_id, parentSlot); + InventoryOld::MarkDirty(inst); // Slot not found, clean up } return result; } // Internal Method: Checks an inventory bucket for a particular item -int16 Inventory::_HasItem(std::map& bucket, uint32 item_id, uint8 quantity) +int16 InventoryOld::_HasItem(std::map& bucket, uint32 item_id, uint8 quantity) { uint8 quantity_found = 0; @@ -1212,7 +1212,7 @@ int16 Inventory::_HasItem(std::map& bucket, uint32 item_id, ui if (bag_inst->GetID() == item_id) { quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges(); if (quantity_found >= quantity) - return Inventory::CalcSlotId(iter->first, bag_iter->first); + return InventoryOld::CalcSlotId(iter->first, bag_iter->first); } for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { @@ -1226,7 +1226,7 @@ int16 Inventory::_HasItem(std::map& bucket, uint32 item_id, ui } // Internal Method: Checks an inventory queue type bucket for a particular item -int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity) +int16 InventoryOld::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity) { // The downfall of this (these) queue procedure is that callers presume that when an item is // found, it is presented as being available on the cursor. In cases of a parity check, this @@ -1260,7 +1260,7 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity) if (bag_inst->GetID() == item_id) { quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges(); if (quantity_found >= quantity) - return Inventory::CalcSlotId(MainCursor, bag_iter->first); + return InventoryOld::CalcSlotId(MainCursor, bag_iter->first); } for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { @@ -1277,7 +1277,7 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity) } // Internal Method: Checks an inventory bucket for a particular item -int16 Inventory::_HasItemByUse(std::map& bucket, uint8 use, uint8 quantity) +int16 InventoryOld::_HasItemByUse(std::map& bucket, uint8 use, uint8 quantity) { uint8 quantity_found = 0; @@ -1300,7 +1300,7 @@ int16 Inventory::_HasItemByUse(std::map& bucket, uint8 use, ui if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->ItemType == use) { quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges(); if (quantity_found >= quantity) - return Inventory::CalcSlotId(iter->first, bag_iter->first); + return InventoryOld::CalcSlotId(iter->first, bag_iter->first); } } } @@ -1309,7 +1309,7 @@ int16 Inventory::_HasItemByUse(std::map& bucket, uint8 use, ui } // Internal Method: Checks an inventory queue type bucket for a particular item -int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity) +int16 InventoryOld::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity) { uint8 quantity_found = 0; @@ -1332,7 +1332,7 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity) if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->ItemType == use) { quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges(); if (quantity_found >= quantity) - return Inventory::CalcSlotId(MainCursor, bag_iter->first); + return InventoryOld::CalcSlotId(MainCursor, bag_iter->first); } } @@ -1343,7 +1343,7 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity) return INVALID_INDEX; } -int16 Inventory::_HasItemByLoreGroup(std::map& bucket, uint32 loregroup) +int16 InventoryOld::_HasItemByLoreGroup(std::map& bucket, uint32 loregroup) { for (auto iter = bucket.begin(); iter != bucket.end(); ++iter) { auto inst = iter->second; @@ -1367,7 +1367,7 @@ int16 Inventory::_HasItemByLoreGroup(std::map& bucket, uint32 if (bag_inst == nullptr) { continue; } if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->LoreGroup == loregroup) - return Inventory::CalcSlotId(iter->first, bag_iter->first); + return InventoryOld::CalcSlotId(iter->first, bag_iter->first); for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { auto aug_inst = bag_inst->GetAugment(index); @@ -1383,7 +1383,7 @@ int16 Inventory::_HasItemByLoreGroup(std::map& bucket, uint32 } // Internal Method: Checks an inventory queue type bucket for a particular item -int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup) +int16 InventoryOld::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup) { for (auto iter = iqueue.cbegin(); iter != iqueue.cend(); ++iter) { auto inst = *iter; @@ -1407,7 +1407,7 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup) if (bag_inst == nullptr) { continue; } if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->LoreGroup == loregroup) - return Inventory::CalcSlotId(MainCursor, bag_iter->first); + return InventoryOld::CalcSlotId(MainCursor, bag_iter->first); for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { auto aug_inst = bag_inst->GetAugment(index); @@ -2150,7 +2150,7 @@ ItemInst* ItemInst::Clone() const bool ItemInst::IsSlotAllowed(int16 slot_id) const { // 'SupportsContainers' and 'slot_id > 21' previously saw the reassigned PowerSource slot (9999 to 22) as valid -U if (!m_item) { return false; } - else if (Inventory::SupportsContainers(slot_id)) { return true; } + else if (InventoryOld::SupportsContainers(slot_id)) { return true; } else if (m_item->Slots & (1 << slot_id)) { return true; } else if (slot_id == MainPowerSource && (m_item->Slots & (1 << 22))) { return true; } // got lazy... else if (slot_id != MainPowerSource && slot_id > EmuConstants::EQUIPMENT_END) { return true; } diff --git a/common/item.h b/common/item.h index 906e00313..b1227df33 100644 --- a/common/item.h +++ b/common/item.h @@ -104,9 +104,9 @@ protected: }; // ######################################## -// Class: Inventory +// Class: InventoryOld // Character inventory -class Inventory +class InventoryOld { friend class ItemInst; public: @@ -114,8 +114,8 @@ public: // Public Methods /////////////////////////////// - Inventory() { m_version = ClientVersion::Unknown; m_versionset = false; } - ~Inventory(); + InventoryOld() { m_version = ClientVersion::Unknown; m_versionset = false; } + ~InventoryOld(); // Inventory v2 creep bool SetInventoryVersion(ClientVersion version) { @@ -425,7 +425,7 @@ protected: std::map::const_iterator _cbegin() { return m_contents.cbegin(); } std::map::const_iterator _cend() { return m_contents.cend(); } - friend class Inventory; + friend class InventoryOld; void _PutItem(uint8 index, ItemInst* inst) { m_contents[index] = inst; } diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index cb95bfdb1..94c42a1f2 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -5031,7 +5031,7 @@ namespace RoF ss.write(tmp, strlen(tmp)); ss.write((const char*)&null_term, sizeof(uint8)); ornaIcon = inst->GetOrnamentationIcon(); - heroModel = inst->GetOrnamentHeroModel(Inventory::CalcMaterialFromSlot(slot_id_in)); + heroModel = inst->GetOrnamentHeroModel(InventoryOld::CalcMaterialFromSlot(slot_id_in)); } else { @@ -5474,7 +5474,7 @@ namespace RoF /* // TEST CODE: - SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x); + SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x); */ SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1); diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 5cab22a60..f8b48c1c0 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -5194,7 +5194,7 @@ namespace RoF2 ss.write(tmp, strlen(tmp)); ss.write((const char*)&null_term, sizeof(uint8)); ornaIcon = inst->GetOrnamentationIcon(); - heroModel = inst->GetOrnamentHeroModel(Inventory::CalcMaterialFromSlot(slot_id_in)); + heroModel = inst->GetOrnamentHeroModel(InventoryOld::CalcMaterialFromSlot(slot_id_in)); } else { @@ -5650,7 +5650,7 @@ namespace RoF2 /* // TEST CODE: - SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x); + SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x); */ SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1, packet_type); diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index 488f51e87..59412726e 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -3913,7 +3913,7 @@ namespace SoD /* // TEST CODE: - SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x); + SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x); */ SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1); diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index ab956a28d..bd6bfff37 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -3235,7 +3235,7 @@ namespace SoF /* // TEST CODE: - SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x); + SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x); */ SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1); diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index 11fdb3c7b..b31590a3c 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -4214,7 +4214,7 @@ namespace UF /* // TEST CODE: - SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x); + SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x); */ SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1); diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 0e057812d..94a1ba226 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -208,10 +208,10 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, i auto results = QueryDatabase(query); // Save bag contents, if slot supports bag contents - if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id)) + if (inst->IsType(ItemClassContainer) && InventoryOld::SupportsContainers(slot_id)) for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) { const ItemInst* baginst = inst->GetItem(idx); - SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx)); + SaveInventory(char_id, baginst, InventoryOld::CalcSlotId(slot_id, idx)); } if (!results.Success()) { @@ -252,10 +252,10 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, auto results = QueryDatabase(query); // Save bag contents, if slot supports bag contents - if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id)) { + if (inst->IsType(ItemClassContainer) && InventoryOld::SupportsContainers(slot_id)) { for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) { const ItemInst* baginst = inst->GetItem(idx); - SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx)); + SaveInventory(char_id, baginst, InventoryOld::CalcSlotId(slot_id, idx)); } } @@ -276,10 +276,10 @@ bool SharedDatabase::DeleteInventorySlot(uint32 char_id, int16 slot_id) { } // Delete bag slots, if need be - if (!Inventory::SupportsContainers(slot_id)) + if (!InventoryOld::SupportsContainers(slot_id)) return true; - int16 base_slot_id = Inventory::CalcSlotId(slot_id, SUB_BEGIN); + int16 base_slot_id = InventoryOld::CalcSlotId(slot_id, SUB_BEGIN); query = StringFormat("DELETE FROM inventory WHERE charid = %i AND slotid >= %i AND slotid < %i", char_id, base_slot_id, (base_slot_id+10)); results = QueryDatabase(query); @@ -302,10 +302,10 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) { } // Delete bag slots, if need be - if (!Inventory::SupportsContainers(slot_id)) + if (!InventoryOld::SupportsContainers(slot_id)) return true; - int16 base_slot_id = Inventory::CalcSlotId(slot_id, SUB_BEGIN); + int16 base_slot_id = InventoryOld::CalcSlotId(slot_id, SUB_BEGIN); query = StringFormat("DELETE FROM sharedbank WHERE acctid = %i " "AND slotid >= %i AND slotid < %i", account_id, base_slot_id, (base_slot_id+10)); @@ -345,7 +345,7 @@ bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) { return true; } -bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) { +bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, InventoryOld* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) { const Item_Struct* myitem; @@ -382,7 +382,7 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, // Retrieve shared bank inventory based on either account or character -bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid) +bool SharedDatabase::GetSharedBank(uint32 id, InventoryOld *inv, bool is_charid) { std::string query; @@ -482,7 +482,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid) } // Overloaded: Retrieve character inventory based on character id -bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv) +bool SharedDatabase::GetInventory(uint32 char_id, InventoryOld *inv) { // Retrieve character inventory std::string query = @@ -625,7 +625,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv) } // Overloaded: Retrieve character inventory based on account_id and character name -bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv) +bool SharedDatabase::GetInventory(uint32 account_id, char *name, InventoryOld *inv) { // Retrieve character inventory std::string query = diff --git a/common/shareddb.h b/common/shareddb.h index aef325380..ce608b4a1 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -14,7 +14,7 @@ #include class EvolveInfo; -class Inventory; +class InventoryOld; class ItemInst; struct BaseDataStruct; struct InspectMessage_Struct; @@ -65,15 +65,15 @@ class SharedDatabase : public Database bool UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id); bool UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id); bool VerifyInventory(uint32 account_id, int16 slot_id, const ItemInst* inst); - bool GetSharedBank(uint32 id, Inventory* inv, bool is_charid); + bool GetSharedBank(uint32 id, InventoryOld* inv, bool is_charid); int32 GetSharedPlatinum(uint32 account_id); bool SetSharedPlatinum(uint32 account_id, int32 amount_to_add); - bool GetInventory(uint32 char_id, Inventory* inv); - bool GetInventory(uint32 account_id, char* name, Inventory* inv); + bool GetInventory(uint32 char_id, InventoryOld* inv); + bool GetInventory(uint32 account_id, char* name, InventoryOld* inv); std::map GetItemRecastTimestamps(uint32 char_id); uint32 GetItemRecastTimestamp(uint32 char_id, uint32 recast_type); void ClearOldRecastTimestamps(uint32 char_id); - bool SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin); + bool SetStartingItems(PlayerProfile_Struct* pp, InventoryOld* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin); std::string GetBook(const char *txtfile); diff --git a/world/client.cpp b/world/client.cpp index ace58ffea..0b1cc2640 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -1347,7 +1347,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc) { PlayerProfile_Struct pp; ExtendedProfile_Struct ext; - Inventory inv; + InventoryOld inv; time_t bday = time(nullptr); char startzone[50]={0}; uint32 i; diff --git a/world/worlddb.cpp b/world/worlddb.cpp index 223ae89d6..07d931958 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -34,7 +34,7 @@ extern std::vector character_create_race_class_combos; // the current stuff is at the bottom of this function void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs, uint32 ClientVersion) { - Inventory *inv; + InventoryOld *inv; uint8 has_home = 0; uint8 has_bind = 0; @@ -167,7 +167,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* } /* Load Inventory */ - inv = new Inventory; + inv = new InventoryOld; if (GetInventory(account_id, cs->name[char_num], inv)) { const Item_Struct* item = nullptr; @@ -176,7 +176,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* for (uint32 matslot = 0; matslot < _MaterialCount; matslot++) { - invslot = Inventory::CalcSlotFromMaterial(matslot); + invslot = InventoryOld::CalcSlotFromMaterial(matslot); if (invslot == INVALID_INDEX) { continue; } inst = inv->GetItem(invslot); diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index a76860ce4..d3e32127d 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -3173,7 +3173,7 @@ bool Client::CalcItemScale(uint32 slot_x, uint32 slot_y) { // TEST CODE: test for bazaar trader crashing with charm items if (Trader) if (i >= EmuConstants::GENERAL_BAGS_BEGIN && i <= EmuConstants::GENERAL_BAGS_END) { - ItemInst* parent_item = m_inv.GetItem(Inventory::CalcSlotId(i)); + ItemInst* parent_item = m_inv.GetItem(InventoryOld::CalcSlotId(i)); if (parent_item && parent_item->GetItem()->ID == 17899) // trader satchel continue; } @@ -3266,7 +3266,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) { // TEST CODE: test for bazaar trader crashing with charm items if (Trader) if (i >= EmuConstants::GENERAL_BAGS_BEGIN && i <= EmuConstants::GENERAL_BAGS_END) { - ItemInst* parent_item = m_inv.GetItem(Inventory::CalcSlotId(i)); + ItemInst* parent_item = m_inv.GetItem(InventoryOld::CalcSlotId(i)); if (parent_item && parent_item->GetItem()->ID == 17899) // trader satchel continue; } diff --git a/zone/bot.cpp b/zone/bot.cpp index 4b42fac37..b449ebfe0 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -4138,7 +4138,7 @@ void Bot::Spawn(Client* botCharacterOwner, std::string* errorMessage) { for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) { itemID = GetBotItemBySlot(i); if(itemID != 0) { - materialFromSlot = Inventory::CalcMaterialFromSlot(i); + materialFromSlot = InventoryOld::CalcMaterialFromSlot(i); if(materialFromSlot != 0xFF) this->SendWearChange(materialFromSlot); } @@ -4191,7 +4191,7 @@ void Bot::RemoveBotItemBySlot(uint32 slotID, std::string *errorMessage) { } // Retrieves all the inventory records from the database for this bot. -void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) { +void Bot::GetBotItems(std::string* errorMessage, InventoryOld &inv) { if(this->GetBotID() == 0) return; @@ -5081,7 +5081,7 @@ ItemInst* Bot::GetBotItem(uint32 slotID) { // Adds the specified item it bot to the NPC equipment array and to the bot inventory collection. void Bot::BotAddEquipItem(int slot, uint32 id) { if(slot > 0 && id > 0) { - uint8 materialFromSlot = Inventory::CalcMaterialFromSlot(slot); + uint8 materialFromSlot = InventoryOld::CalcMaterialFromSlot(slot); if(materialFromSlot != _MaterialInvalid) { equipment[slot] = id; // npc has more than just material slots. Valid material should mean valid inventory index @@ -5097,7 +5097,7 @@ void Bot::BotAddEquipItem(int slot, uint32 id) { // Erases the specified item from bot the NPC equipment array and from the bot inventory collection. void Bot::BotRemoveEquipItem(int slot) { if(slot > 0) { - uint8 materialFromSlot = Inventory::CalcMaterialFromSlot(slot); + uint8 materialFromSlot = InventoryOld::CalcMaterialFromSlot(slot); if(materialFromSlot != _MaterialInvalid) { equipment[slot] = 0; // npc has more than just material slots. Valid material should mean valid inventory index @@ -5669,7 +5669,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli bool UpdateClient = false; bool already_returned = false; - Inventory& clientInventory = client->GetInv(); + InventoryOld& clientInventory = client->GetInv(); const ItemInst* inst = clientInventory[i]; if(inst) { items[i] = inst->GetItem()->ID; @@ -11281,7 +11281,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { if(!results.Success()) return; - uint8 slotmaterial = Inventory::CalcMaterialFromSlot(setslot); + uint8 slotmaterial = InventoryOld::CalcMaterialFromSlot(setslot); c->GetTarget()->CastToBot()->SendWearChange(slotmaterial); } else { @@ -15974,7 +15974,7 @@ uint32 Bot::GetEquipmentColor(uint8 material_slot) const uint32 botid = this->GetBotID(); //Translate code slot # to DB slot # - slotid = Inventory::CalcSlotFromMaterial(material_slot); + slotid = InventoryOld::CalcSlotFromMaterial(material_slot); if (slotid == INVALID_INDEX) return 0; diff --git a/zone/bot.h b/zone/bot.h index 7dd354358..295eff175 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -579,7 +579,7 @@ private: bool _petChooser; uint8 _petChooserID; bool berserk; - Inventory m_inv; + InventoryOld m_inv; double _lastTotalPlayTime; time_t _startTotalPlayTime; Mob* _previousTarget; @@ -651,7 +651,7 @@ private: void SetBotID(uint32 botID); // Private "Inventory" Methods - void GetBotItems(std::string* errorMessage, Inventory &inv); + void GetBotItems(std::string* errorMessage, InventoryOld &inv); void BotRemoveEquipItem(int slot); void BotAddEquipItem(int slot, uint32 id); uint32 GetBotItemBySlot(uint32 slotID); diff --git a/zone/client.cpp b/zone/client.cpp index 63a9b5073..1a7d81405 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2705,7 +2705,7 @@ void Client::SetMaterial(int16 in_slot, uint32 item_id) { const Item_Struct* item = database.GetItem(item_id); if (item && (item->ItemClass==ItemClassCommon)) { - uint8 matslot = Inventory::CalcMaterialFromSlot(in_slot); + uint8 matslot = InventoryOld::CalcMaterialFromSlot(in_slot); if (matslot != _MaterialInvalid) { m_pp.item_material[matslot] = GetEquipmentMaterial(matslot); @@ -3047,7 +3047,7 @@ void Client::SetTint(int16 in_slot, uint32 color) { // Still need to reconcile bracer01 versus bracer02 void Client::SetTint(int16 in_slot, Color_Struct& color) { - uint8 matslot = Inventory::CalcMaterialFromSlot(in_slot); + uint8 matslot = InventoryOld::CalcMaterialFromSlot(in_slot); if (matslot != _MaterialInvalid) { m_pp.item_tint[matslot].color = color.color; diff --git a/zone/client.h b/zone/client.h index f2325ccca..85177aee2 100644 --- a/zone/client.h +++ b/zone/client.h @@ -333,8 +333,8 @@ public: inline uint8 GetAnon() const { return m_pp.anon; } inline PlayerProfile_Struct& GetPP() { return m_pp; } inline ExtendedProfile_Struct& GetEPP() { return m_epp; } - inline Inventory& GetInv() { return m_inv; } - inline const Inventory& GetInv() const { return m_inv; } + inline InventoryOld& GetInv() { return m_inv; } + inline const InventoryOld& GetInv() const { return m_inv; } inline PetInfo* GetPetInfo(uint16 pet) { return (pet==1)?&m_suspendedminion:&m_petinfo; } inline InspectMessage_Struct& GetInspectMessage() { return m_inspect_message; } inline const InspectMessage_Struct& GetInspectMessage() const { return m_inspect_message; } @@ -1405,7 +1405,7 @@ private: PlayerProfile_Struct m_pp; ExtendedProfile_Struct m_epp; - Inventory m_inv; + InventoryOld m_inv; Object* m_tradeskill_object; PetInfo m_petinfo; // current pet data, used while loading from and saving to DB PetInfo m_suspendedminion; // pet data for our suspended minion. diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 2d60b444e..b0cde60c7 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -2969,7 +2969,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) { ItemInst *tobe_auged = nullptr, *auged_with = nullptr; int8 slot = -1; - Inventory& user_inv = GetInv(); + InventoryOld& user_inv = GetInv(); uint16 slot_id = in_augment->container_slot; uint16 aug_slot_id = in_augment->augment_slot; @@ -3039,7 +3039,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) { ItemInst *tobe_auged = nullptr, *auged_with = nullptr; int8 slot = -1; - Inventory& user_inv = GetInv(); + InventoryOld& user_inv = GetInv(); uint16 slot_id = in_augment->container_slot; uint16 aug_slot_id = in_augment->augment_slot; //it's actually solvent slot diff --git a/zone/command.cpp b/zone/command.cpp index ff81e73ed..28eabb057 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -2602,7 +2602,7 @@ void command_peekinv(Client *c, const Seperator *sep) item_link = linker.GenerateLink(); c->Message((item_data == nullptr), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", - Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); + InventoryOld::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); } } @@ -2636,7 +2636,7 @@ void command_peekinv(Client *c, const Seperator *sep) item_link = linker.GenerateLink(); c->Message((item_data == nullptr), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", - Inventory::CalcSlotId(MainCursor, indexSub), MainCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); + InventoryOld::CalcSlotId(MainCursor, indexSub), MainCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); } } } @@ -2673,7 +2673,7 @@ void command_peekinv(Client *c, const Seperator *sep) item_link = linker.GenerateLink(); c->Message((item_data == nullptr), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", - Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); + InventoryOld::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); } } @@ -2695,7 +2695,7 @@ void command_peekinv(Client *c, const Seperator *sep) item_link = linker.GenerateLink(); c->Message((item_data == nullptr), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", - Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); + InventoryOld::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); } } @@ -2718,7 +2718,7 @@ void command_peekinv(Client *c, const Seperator *sep) item_link = linker.GenerateLink(); c->Message((item_data == nullptr), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i", - Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); + InventoryOld::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())); } } diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 767159ce7..df03783c3 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -409,7 +409,7 @@ void Corpse::MoveItemToCorpse(Client *client, ItemInst *inst, int16 equipSlot, s if (equipSlot < EmuConstants::GENERAL_BEGIN || equipSlot > MainCursor) { break; } for (auto sub_index = SUB_BEGIN; sub_index < EmuConstants::ITEM_CONTAINER_SIZE; ++sub_index) { - int16 real_bag_slot = Inventory::CalcSlotId(equipSlot, sub_index); + int16 real_bag_slot = InventoryOld::CalcSlotId(equipSlot, sub_index); auto bag_inst = client->GetInv().GetItem(real_bag_slot); if (bag_inst == nullptr) { continue; } @@ -683,8 +683,8 @@ ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct** } } - if (sitem && bag_item_data && Inventory::SupportsContainers(sitem->equip_slot)) { - int16 bagstart = Inventory::CalcSlotId(sitem->equip_slot, SUB_BEGIN); + if (sitem && bag_item_data && InventoryOld::SupportsContainers(sitem->equip_slot)) { + int16 bagstart = InventoryOld::CalcSlotId(sitem->equip_slot, SUB_BEGIN); cur = itemlist.begin(); end = itemlist.end(); @@ -738,7 +738,7 @@ void Corpse::RemoveItem(ServerLootItem_Struct* item_data) is_corpse_changed = true; itemlist.erase(iter); - uint8 material = Inventory::CalcMaterialFromSlot(sitem->equip_slot); // autos to unsigned char + uint8 material = InventoryOld::CalcMaterialFromSlot(sitem->equip_slot); // autos to unsigned char if (material != _MaterialInvalid) SendWearChange(material); @@ -1397,7 +1397,7 @@ uint32 Corpse::GetEquipment(uint8 material_slot) const { return NO_ITEM; } - invslot = Inventory::CalcSlotFromMaterial(material_slot); + invslot = InventoryOld::CalcSlotFromMaterial(material_slot); if(invslot == INVALID_INDEX) // GetWornItem() should be returning a NO_ITEM for any invalid index... return NO_ITEM; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 69f1de882..6d149067c 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -765,7 +765,7 @@ void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_upd ItemInst* bagitem = m_inv[slot_id]->GetItem(bag_idx); if(bagitem) { - int16 bagslot_id = Inventory::CalcSlotId(slot_id, bag_idx); + int16 bagslot_id = InventoryOld::CalcSlotId(slot_id, bag_idx); qsaudit->items[++parent_offset].char_slot = bagslot_id; qsaudit->items[parent_offset].item_id = bagitem->GetID(); @@ -864,7 +864,7 @@ bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client if (client_update) { SendItemPacket(slot_id, &inst, ((slot_id == MainCursor) ? ItemPacketSummonItem : ItemPacketTrade)); - //SendWearChange(Inventory::CalcMaterialFromSlot(slot_id)); + //SendWearChange(InventoryOld::CalcMaterialFromSlot(slot_id)); } if (slot_id == MainCursor) { @@ -901,7 +901,7 @@ void Client::PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootI if(bag_item_data[i] == nullptr) continue; const ItemInst *bagitem = database.CreateItem(bag_item_data[i]->item_id, bag_item_data[i]->charges, bag_item_data[i]->aug_1, bag_item_data[i]->aug_2, bag_item_data[i]->aug_3, bag_item_data[i]->aug_4, bag_item_data[i]->aug_5, bag_item_data[i]->aug_6, bag_item_data[i]->attuned); - interior_slot = Inventory::CalcSlotId(slot_id, i); + interior_slot = InventoryOld::CalcSlotId(slot_id, i); Log.Out(Logs::Detail, Logs::Inventory, "Putting bag loot item %s (%d) into slot %d (bag slot %d)", inst.GetItem()->Name, inst.GetItem()->ID, interior_slot, i); PutLootInInventory(interior_slot, *bagitem); safe_delete(bagitem); @@ -928,7 +928,7 @@ bool Client::TryStacking(ItemInst* item, uint8 type, bool try_worn, bool try_cur } for (i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; i++) { for (uint8 j = SUB_BEGIN; j < EmuConstants::ITEM_CONTAINER_SIZE; j++) { - uint16 slotid = Inventory::CalcSlotId(i, j); + uint16 slotid = InventoryOld::CalcSlotId(i, j); ItemInst* tmp_inst = m_inv.GetItem(slotid); if(tmp_inst && tmp_inst->GetItem()->ID == item_id && tmp_inst->GetCharges() < tmp_inst->GetItem()->StackSize) { @@ -981,7 +981,7 @@ bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_curs if (inst.IsEquipable(i)) { // Equippable at this slot? //send worn to everyone... PutLootInInventory(i, inst); - uint8 worn_slot_material = Inventory::CalcMaterialFromSlot(i); + uint8 worn_slot_material = InventoryOld::CalcMaterialFromSlot(i); if (worn_slot_material != _MaterialInvalid) { SendWearChange(worn_slot_material); } @@ -1481,8 +1481,8 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { if(src_slot_id >= EmuConstants::SHARED_BANK_BEGIN && src_slot_id <= EmuConstants::SHARED_BANK_END && src_inst->IsType(ItemClassContainer)){ for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) { const ItemInst* baginst = src_inst->GetItem(idx); - if(baginst && !database.VerifyInventory(account_id, Inventory::CalcSlotId(src_slot_id, idx), baginst)){ - DeleteItemInInventory(Inventory::CalcSlotId(src_slot_id, idx),0,false); + if(baginst && !database.VerifyInventory(account_id, InventoryOld::CalcSlotId(src_slot_id, idx), baginst)){ + DeleteItemInInventory(InventoryOld::CalcSlotId(src_slot_id, idx),0,false); } } } @@ -1496,8 +1496,8 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { if(dst_slot_id >= EmuConstants::SHARED_BANK_BEGIN && dst_slot_id <= EmuConstants::SHARED_BANK_END && dst_inst->IsType(ItemClassContainer)){ for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) { const ItemInst* baginst = dst_inst->GetItem(idx); - if(baginst && !database.VerifyInventory(account_id, Inventory::CalcSlotId(dst_slot_id, idx), baginst)){ - DeleteItemInInventory(Inventory::CalcSlotId(dst_slot_id, idx),0,false); + if(baginst && !database.VerifyInventory(account_id, InventoryOld::CalcSlotId(dst_slot_id, idx), baginst)){ + DeleteItemInInventory(InventoryOld::CalcSlotId(dst_slot_id, idx),0,false); } } } @@ -1539,7 +1539,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { if(m_tradeskill_object != nullptr) { if (src_slot_id >= EmuConstants::WORLD_BEGIN && src_slot_id <= EmuConstants::WORLD_END) { // Picking up item from world container - ItemInst* inst = m_tradeskill_object->PopItem(Inventory::CalcBagIdx(src_slot_id)); + ItemInst* inst = m_tradeskill_object->PopItem(InventoryOld::CalcBagIdx(src_slot_id)); if (inst) { PutItemInInventory(dst_slot_id, *inst, false); safe_delete(inst); @@ -1551,7 +1551,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } else if (dst_slot_id >= EmuConstants::WORLD_BEGIN && dst_slot_id <= EmuConstants::WORLD_END) { // Putting item into world container, which may swap (or pile onto) with existing item - uint8 world_idx = Inventory::CalcBagIdx(dst_slot_id); + uint8 world_idx = InventoryOld::CalcBagIdx(dst_slot_id); ItemInst* world_inst = m_tradeskill_object->PopItem(world_idx); // Case 1: No item in container, unidirectional "Put" @@ -1798,7 +1798,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { Message(15, "Inventory Desyncronization detected: Resending slot data..."); if((move_slots->from_slot >= EmuConstants::EQUIPMENT_BEGIN && move_slots->from_slot <= EmuConstants::CURSOR_BAG_END) || move_slots->from_slot == MainPowerSource) { - int16 resync_slot = (Inventory::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : Inventory::CalcSlotId(move_slots->from_slot); + int16 resync_slot = (InventoryOld::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : InventoryOld::CalcSlotId(move_slots->from_slot); if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { // This prevents the client from crashing when closing any 'phantom' bags -U const Item_Struct* token_struct = database.GetItem(22292); // 'Copper Coin' @@ -1823,7 +1823,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { else { Message(13, "Could not resyncronize source slot %i.", move_slots->from_slot); } } else { - int16 resync_slot = (Inventory::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : Inventory::CalcSlotId(move_slots->from_slot); + int16 resync_slot = (InventoryOld::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : InventoryOld::CalcSlotId(move_slots->from_slot); if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { if(m_inv[resync_slot]) { const Item_Struct* token_struct = database.GetItem(22292); // 'Copper Coin' @@ -1841,7 +1841,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { } if((move_slots->to_slot >= EmuConstants::EQUIPMENT_BEGIN && move_slots->to_slot <= EmuConstants::CURSOR_BAG_END) || move_slots->to_slot == MainPowerSource) { - int16 resync_slot = (Inventory::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : Inventory::CalcSlotId(move_slots->to_slot); + int16 resync_slot = (InventoryOld::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : InventoryOld::CalcSlotId(move_slots->to_slot); if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { const Item_Struct* token_struct = database.GetItem(22292); // 'Copper Coin' ItemInst* token_inst = database.CreateItem(token_struct, 1); @@ -1865,7 +1865,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { else { Message(13, "Could not resyncronize destination slot %i.", move_slots->to_slot); } } else { - int16 resync_slot = (Inventory::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : Inventory::CalcSlotId(move_slots->to_slot); + int16 resync_slot = (InventoryOld::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : InventoryOld::CalcSlotId(move_slots->to_slot); if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { if(m_inv[resync_slot]) { const Item_Struct* token_struct = database.GetItem(22292); // 'Copper Coin' @@ -1925,8 +1925,8 @@ void Client::QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call) { const ItemInst* from_baginst = from_inst->GetItem(bag_idx); if(from_baginst) { - qsaudit->items[move_count].from_slot = Inventory::CalcSlotId(from_slot_id, bag_idx); - qsaudit->items[move_count].to_slot = Inventory::CalcSlotId(to_slot_id, bag_idx); + qsaudit->items[move_count].from_slot = InventoryOld::CalcSlotId(from_slot_id, bag_idx); + qsaudit->items[move_count].to_slot = InventoryOld::CalcSlotId(to_slot_id, bag_idx); qsaudit->items[move_count].item_id = from_baginst->GetID(); qsaudit->items[move_count].charges = from_baginst->GetCharges(); qsaudit->items[move_count].aug_1 = from_baginst->GetAugmentItemID(1); @@ -1958,8 +1958,8 @@ void Client::QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call) { const ItemInst* to_baginst = to_inst->GetItem(bag_idx); if(to_baginst) { - qsaudit->items[move_count].from_slot = Inventory::CalcSlotId(to_slot_id, bag_idx); - qsaudit->items[move_count].to_slot = Inventory::CalcSlotId(from_slot_id, bag_idx); + qsaudit->items[move_count].from_slot = InventoryOld::CalcSlotId(to_slot_id, bag_idx); + qsaudit->items[move_count].to_slot = InventoryOld::CalcSlotId(from_slot_id, bag_idx); qsaudit->items[move_count].item_id = to_baginst->GetID(); qsaudit->items[move_count].charges = to_baginst->GetCharges(); qsaudit->items[move_count].aug_1 = to_baginst->GetAugmentItemID(1); @@ -2382,7 +2382,7 @@ uint32 Client::GetEquipment(uint8 material_slot) const return 0; } - invslot = Inventory::CalcSlotFromMaterial(material_slot); + invslot = InventoryOld::CalcSlotFromMaterial(material_slot); if (invslot == INVALID_INDEX) { return 0; @@ -2560,7 +2560,7 @@ void Client::SetBandolier(const EQApplicationPacket *app) { if (slot == INVALID_INDEX) { if (m_inv.GetItem(MainCursor)) { if (m_inv.GetItem(MainCursor)->GetItem()->ID == m_pp.bandoliers[bss->number].items[BandolierSlot].item_id && - m_inv.GetItem(MainCursor)->GetCharges() >= 1) { // '> 0' the same, but this matches Inventory::_HasItem conditional check + m_inv.GetItem(MainCursor)->GetCharges() >= 1) { // '> 0' the same, but this matches InventoryOld::_HasItem conditional check slot = MainCursor; } else if (m_inv.GetItem(MainCursor)->GetItem()->ItemClass == 1) { @@ -2736,7 +2736,7 @@ bool Client::MoveItemToInventory(ItemInst *ItemToReturn, bool UpdateClient) { // if (InvItem && InvItem->IsType(ItemClassContainer)) { - int16 BaseSlotID = Inventory::CalcSlotId(i, SUB_BEGIN); + int16 BaseSlotID = InventoryOld::CalcSlotId(i, SUB_BEGIN); uint8 BagSize=InvItem->GetItem()->BagSlots; @@ -2786,9 +2786,9 @@ bool Client::MoveItemToInventory(ItemInst *ItemToReturn, bool UpdateClient) { return true; } - if(InvItem->IsType(ItemClassContainer) && Inventory::CanItemFitInContainer(ItemToReturn->GetItem(), InvItem->GetItem())) { + if(InvItem->IsType(ItemClassContainer) && InventoryOld::CanItemFitInContainer(ItemToReturn->GetItem(), InvItem->GetItem())) { - int16 BaseSlotID = Inventory::CalcSlotId(i, SUB_BEGIN); + int16 BaseSlotID = InventoryOld::CalcSlotId(i, SUB_BEGIN); uint8 BagSize=InvItem->GetItem()->BagSlots; @@ -3052,7 +3052,7 @@ bool Client::InterrogateInventory_error(int16 head, int16 index, const ItemInst* return false; } -void Inventory::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value) { +void InventoryOld::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value) { ItemInst *inst = GetItem(slot_id); if(inst) { inst->SetCustomData(identifier, value); @@ -3060,7 +3060,7 @@ void Inventory::SetCustomItemData(uint32 character_id, int16 slot_id, std::strin } } -void Inventory::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value) { +void InventoryOld::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value) { ItemInst *inst = GetItem(slot_id); if(inst) { inst->SetCustomData(identifier, value); @@ -3068,7 +3068,7 @@ void Inventory::SetCustomItemData(uint32 character_id, int16 slot_id, std::strin } } -void Inventory::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value) { +void InventoryOld::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value) { ItemInst *inst = GetItem(slot_id); if(inst) { inst->SetCustomData(identifier, value); @@ -3076,7 +3076,7 @@ void Inventory::SetCustomItemData(uint32 character_id, int16 slot_id, std::strin } } -void Inventory::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value) { +void InventoryOld::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value) { ItemInst *inst = GetItem(slot_id); if(inst) { inst->SetCustomData(identifier, value); @@ -3084,7 +3084,7 @@ void Inventory::SetCustomItemData(uint32 character_id, int16 slot_id, std::strin } } -std::string Inventory::GetCustomItemData(int16 slot_id, std::string identifier) { +std::string InventoryOld::GetCustomItemData(int16 slot_id, std::string identifier) { ItemInst *inst = GetItem(slot_id); if(inst) { return inst->GetCustomData(identifier); diff --git a/zone/lua_inventory.cpp b/zone/lua_inventory.cpp index 498835926..e2578603c 100644 --- a/zone/lua_inventory.cpp +++ b/zone/lua_inventory.cpp @@ -164,7 +164,7 @@ int Lua_Inventory::GetSlotByItemInst(Lua_ItemInst inst) { } luabind::scope lua_register_inventory() { - return luabind::class_("Inventory") + return luabind::class_("InventoryOld") .def(luabind::constructor<>()) .def("GetItem", (Lua_ItemInst(Lua_Inventory::*)(int))&Lua_Inventory::GetItem) .def("GetItem", (Lua_ItemInst(Lua_Inventory::*)(int,int))&Lua_Inventory::GetItem) diff --git a/zone/lua_inventory.h b/zone/lua_inventory.h index ca49a55e6..12e531050 100644 --- a/zone/lua_inventory.h +++ b/zone/lua_inventory.h @@ -4,7 +4,7 @@ #include "lua_ptr.h" -class Inventory; +class InventoryOld; class Lua_ItemInst; class Lua_Item; @@ -14,16 +14,16 @@ namespace luabind { luabind::scope lua_register_inventory(); -class Lua_Inventory : public Lua_Ptr +class Lua_Inventory : public Lua_Ptr { - typedef Inventory NativeType; + typedef InventoryOld NativeType; public: Lua_Inventory() : Lua_Ptr(nullptr) { } - Lua_Inventory(Inventory *d) : Lua_Ptr(d) { } + Lua_Inventory(InventoryOld *d) : Lua_Ptr(d) { } virtual ~Lua_Inventory() { } - operator Inventory*() { - return reinterpret_cast(GetLuaPtrData()); + operator InventoryOld*() { + return reinterpret_cast(GetLuaPtrData()); } Lua_ItemInst GetItem(int slot_id); diff --git a/zone/merc.cpp b/zone/merc.cpp index 059ccb316..acae1b80c 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -5022,7 +5022,7 @@ void Merc::UpdateMercAppearance() { for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) { itemID = equipment[i]; if(itemID != NO_ITEM) { - materialFromSlot = Inventory::CalcMaterialFromSlot(i); + materialFromSlot = InventoryOld::CalcMaterialFromSlot(i); if(materialFromSlot != _MaterialInvalid) this->SendWearChange(materialFromSlot); } diff --git a/zone/merc.h b/zone/merc.h index 82136c15d..4c8749164 100644 --- a/zone/merc.h +++ b/zone/merc.h @@ -381,7 +381,7 @@ private: uint8 _OwnerClientVersion; uint32 _currentStance; - Inventory m_inv; + InventoryOld m_inv; int32 max_end; int32 cur_end; bool _medding; diff --git a/zone/mob.cpp b/zone/mob.cpp index ea86ff4dc..2829d1a65 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2547,7 +2547,7 @@ uint32 NPC::GetEquipment(uint8 material_slot) const { if(material_slot > 8) return 0; - int16 invslot = Inventory::CalcSlotFromMaterial(material_slot); + int16 invslot = InventoryOld::CalcSlotFromMaterial(material_slot); if (invslot == INVALID_INDEX) return 0; return equipment[invslot]; @@ -2645,7 +2645,7 @@ int32 Mob::GetEquipmentMaterial(uint8 material_slot) const { if (this->IsClient()) { - int16 invslot = Inventory::CalcSlotFromMaterial(material_slot); + int16 invslot = InventoryOld::CalcSlotFromMaterial(material_slot); if (invslot == INVALID_INDEX) { return 0; @@ -2690,7 +2690,7 @@ int32 Mob::GetHerosForgeModel(uint8 material_slot) const uint32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); const Item_Struct *item; item = database.GetItem(GetEquipment(material_slot)); - int16 invslot = Inventory::CalcSlotFromMaterial(material_slot); + int16 invslot = InventoryOld::CalcSlotFromMaterial(material_slot); if (item != 0 && invslot != INVALID_INDEX) { diff --git a/zone/npc.cpp b/zone/npc.cpp index 5d180e994..20648db3c 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -473,7 +473,7 @@ void NPC::CheckMinMaxLevel(Mob *them) if(themlevel < (*cur)->min_level || themlevel > (*cur)->max_level) { - material = Inventory::CalcMaterialFromSlot((*cur)->equip_slot); + material = InventoryOld::CalcMaterialFromSlot((*cur)->equip_slot); if (material != _MaterialInvalid) SendWearChange(material); @@ -1285,7 +1285,7 @@ int32 NPC::GetEquipmentMaterial(uint8 material_slot) const if (material_slot >= _MaterialCount) return 0; - int16 invslot = Inventory::CalcSlotFromMaterial(material_slot); + int16 invslot = InventoryOld::CalcSlotFromMaterial(material_slot); if (invslot == INVALID_INDEX) return 0; diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 07ae6d2a5..cc8a37a69 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -55,7 +55,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme else { // Check to see if they have an inventory container type 53 that is used for this. - Inventory& user_inv = user->GetInv(); + InventoryOld& user_inv = user->GetInv(); ItemInst* inst = nullptr; inst = user_inv.GetItem(in_augment->container_slot); @@ -218,7 +218,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme const ItemInst* inst = container->GetItem(i); if (inst) { - user->DeleteItemInInventory(Inventory::CalcSlotId(in_augment->container_slot,i),0,true); + user->DeleteItemInInventory(InventoryOld::CalcSlotId(in_augment->container_slot,i),0,true); } } // Explicitly mark container as cleared. @@ -247,7 +247,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob return; } - Inventory& user_inv = user->GetInv(); + InventoryOld& user_inv = user->GetInv(); PlayerProfile_Struct& user_pp = user->GetPP(); ItemInst* container = nullptr; ItemInst* inst = nullptr; @@ -286,7 +286,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob bool AllowAll = RuleB(Inventory, AllowAnyWeaponTransformation); if (inst && ItemInst::CanTransform(inst->GetItem(), container->GetItem(), AllowAll)) { const Item_Struct* new_weapon = inst->GetItem(); - user->DeleteItemInInventory(Inventory::CalcSlotId(in_combine->container_slot, 0), 0, true); + user->DeleteItemInInventory(InventoryOld::CalcSlotId(in_combine->container_slot, 0), 0, true); container->Clear(); user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), MainCursor, container->GetItem()->Icon, atoi(container->GetItem()->IDFile + 2)); user->Message_StringID(4, TRANSFORM_COMPLETE, inst->GetItem()->Name); @@ -306,7 +306,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob const ItemInst* inst = container->GetItem(0); if (inst && inst->GetOrnamentationIcon() && inst->GetOrnamentationIcon()) { const Item_Struct* new_weapon = inst->GetItem(); - user->DeleteItemInInventory(Inventory::CalcSlotId(in_combine->container_slot, 0), 0, true); + user->DeleteItemInInventory(InventoryOld::CalcSlotId(in_combine->container_slot, 0), 0, true); container->Clear(); user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), MainCursor, 0, 0); user->Message_StringID(4, TRANSFORM_COMPLETE, inst->GetItem()->Name); @@ -395,7 +395,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob for (uint8 i = MAIN_BEGIN; i < EmuConstants::MAP_WORLD_SIZE; i++) { const ItemInst* inst = container->GetItem(i); if (inst) { - user->DeleteItemInInventory(Inventory::CalcSlotId(in_combine->container_slot,i),0,true); + user->DeleteItemInInventory(InventoryOld::CalcSlotId(in_combine->container_slot,i),0,true); } } container->Clear(); @@ -492,7 +492,7 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac memset(counts, 0, sizeof(counts)); //search for all the items in their inventory - Inventory& user_inv = user->GetInv(); + InventoryOld& user_inv = user->GetInv(); uint8 count = 0; uint8 needcount = 0; diff --git a/zone/trading.cpp b/zone/trading.cpp index 047aa3a6a..8d498c034 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -174,7 +174,7 @@ void Trade::SendItemData(const ItemInst* inst, int16 dest_slot_id) with->SendItemPacket(dest_slot_id - EmuConstants::TRADE_BEGIN, inst, ItemPacketTradeView); if (inst->GetItem()->ItemClass == 1) { for (uint16 i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) { - uint16 bagslot_id = Inventory::CalcSlotId(dest_slot_id, i); + uint16 bagslot_id = InventoryOld::CalcSlotId(dest_slot_id, i); const ItemInst* bagitem = trader->GetInv().GetItem(bagslot_id); if (bagitem) { with->SendItemPacket(bagslot_id - EmuConstants::TRADE_BEGIN, bagitem, ItemPacketTradeView); @@ -317,7 +317,7 @@ void Trade::DumpTrade() if (inst) { Log.Out(Logs::Detail, Logs::Trading, "\tBagItem %i (Charges=%i, Slot=%i)", inst->GetItem()->ID, inst->GetCharges(), - Inventory::CalcSlotId(i, j)); + InventoryOld::CalcSlotId(i, j)); } } } @@ -368,7 +368,7 @@ void Client::ResetTrade() { break; if (partial_inst->GetID() != inst->GetID()) { - Log.Out(Logs::Detail, Logs::None, "[CLIENT] Client::ResetTrade() - an incompatible location reference was returned by Inventory::FindFreeSlotForTradeItem()"); + Log.Out(Logs::Detail, Logs::None, "[CLIENT] Client::ResetTrade() - an incompatible location reference was returned by InventoryOld::FindFreeSlotForTradeItem()"); break; } @@ -530,9 +530,9 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st detail = new QSTradeItems_Struct; detail->from_id = this->character_id; - detail->from_slot = Inventory::CalcSlotId(trade_slot, sub_slot); + detail->from_slot = InventoryOld::CalcSlotId(trade_slot, sub_slot); detail->to_id = other->CharacterID(); - detail->to_slot = Inventory::CalcSlotId(free_slot, sub_slot); + detail->to_slot = InventoryOld::CalcSlotId(free_slot, sub_slot); detail->item_id = bag_inst->GetID(); detail->charges = (!bag_inst->IsStackable() ? 1 : bag_inst->GetCharges()); detail->aug_1 = bag_inst->GetAugmentItemID(1); @@ -588,7 +588,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st break; if (partial_inst->GetID() != inst->GetID()) { - Log.Out(Logs::Detail, Logs::Trading, "[CLIENT] Client::ResetTrade() - an incompatible location reference was returned by Inventory::FindFreeSlotForTradeItem()"); + Log.Out(Logs::Detail, Logs::Trading, "[CLIENT] Client::ResetTrade() - an incompatible location reference was returned by InventoryOld::FindFreeSlotForTradeItem()"); break; } @@ -849,7 +849,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st strcpy(detail->action_type, "HANDIN"); - detail->char_slot = Inventory::CalcSlotId(trade_slot, sub_slot); + detail->char_slot = InventoryOld::CalcSlotId(trade_slot, sub_slot); detail->item_id = trade_baginst->GetID(); detail->charges = (!trade_inst->IsStackable() ? 1 : trade_inst->GetCharges()); detail->aug_1 = trade_baginst->GetAugmentItemID(1); @@ -1237,7 +1237,7 @@ uint32 Client::FindTraderItemSerialNumber(int32 ItemID) { if (item && item->GetItem()->ID == 17899){ //Traders Satchel for (int x = SUB_BEGIN; x < EmuConstants::ITEM_CONTAINER_SIZE; x++) { // we already have the parent bag and a contents iterator..why not just iterate the bag!?? - SlotID = Inventory::CalcSlotId(i, x); + SlotID = InventoryOld::CalcSlotId(i, x); item = this->GetInv().GetItem(SlotID); if (item) { if (item->GetID() == ItemID) @@ -1260,7 +1260,7 @@ ItemInst* Client::FindTraderItemBySerialNumber(int32 SerialNumber){ if(item && item->GetItem()->ID == 17899){ //Traders Satchel for(int x = SUB_BEGIN; x < EmuConstants::ITEM_CONTAINER_SIZE; x++) { // we already have the parent bag and a contents iterator..why not just iterate the bag!?? - SlotID = Inventory::CalcSlotId(i, x); + SlotID = InventoryOld::CalcSlotId(i, x); item = this->GetInv().GetItem(SlotID); if(item) { if(item->GetSerialNumber() == SerialNumber) @@ -1290,7 +1290,7 @@ GetItems_Struct* Client::GetTraderItems(){ item = this->GetInv().GetItem(i); if(item && item->GetItem()->ID == 17899){ //Traders Satchel for(int x = SUB_BEGIN; x < EmuConstants::ITEM_CONTAINER_SIZE; x++) { - SlotID = Inventory::CalcSlotId(i, x); + SlotID = InventoryOld::CalcSlotId(i, x); item = this->GetInv().GetItem(SlotID); @@ -1314,7 +1314,7 @@ uint16 Client::FindTraderItem(int32 SerialNumber, uint16 Quantity){ item = this->GetInv().GetItem(i); if(item && item->GetItem()->ID == 17899){ //Traders Satchel for(int x = SUB_BEGIN; x < EmuConstants::ITEM_CONTAINER_SIZE; x++){ - SlotID = Inventory::CalcSlotId(i, x); + SlotID = InventoryOld::CalcSlotId(i, x); item = this->GetInv().GetItem(SlotID); diff --git a/zone/zone.cpp b/zone/zone.cpp index 6cd81929f..25a8488f8 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1173,7 +1173,7 @@ bool Zone::Process() { if(spawn2_timer.Check()) { LinkedListIterator iterator(spawn2_list); - Inventory::CleanDirty(); + InventoryOld::CleanDirty(); iterator.Reset(); while (iterator.MoreElements()) { From 701e194ece5c5123b5008ddd4c9746d442453539 Mon Sep 17 00:00:00 2001 From: KimLS Date: Tue, 17 Feb 2015 18:06:22 -0800 Subject: [PATCH 02/27] Renamed Item_Struct to ItemData --- common/CMakeLists.txt | 6 ++- common/eq_constants.h | 2 +- common/eq_packet_structs.h | 4 +- common/inventory.cpp | 20 ++++++++++ common/inventory.h | 32 +++++++++++++++ common/item.cpp | 26 ++++++------- common/item.h | 20 +++++----- common/{item_struct.h => item_data.h} | 33 ++++++---------- common/item_instance.cpp | 19 +++++++++ common/item_instance.h | 32 +++++++++++++++ common/patches/rof.cpp | 2 +- common/patches/rof2.cpp | 2 +- common/patches/rof2_structs.h | 2 +- common/patches/rof_structs.h | 2 +- common/patches/sod.cpp | 2 +- common/patches/sod_structs.h | 2 +- common/patches/sof.cpp | 2 +- common/patches/sof_structs.h | 2 +- common/patches/titanium.cpp | 2 +- common/patches/titanium_structs.h | 2 +- common/patches/uf.cpp | 4 +- common/patches/uf_structs.h | 2 +- common/shareddb.cpp | 28 +++++++------- common/shareddb.h | 12 +++--- shared_memory/items.cpp | 4 +- tests/fixed_memory_test.h | 46 +++++++++++----------- world/worlddb.cpp | 2 +- zone/aa.cpp | 2 +- zone/attack.cpp | 30 +++++++------- zone/bonuses.cpp | 12 +++--- zone/bot.cpp | 54 +++++++++++++------------- zone/bot.h | 2 +- zone/client.cpp | 22 +++++------ zone/client.h | 24 ++++++------ zone/client_mods.cpp | 2 +- zone/client_packet.cpp | 56 +++++++++++++-------------- zone/client_process.cpp | 6 +-- zone/command.cpp | 12 +++--- zone/corpse.cpp | 12 +++--- zone/effects.cpp | 2 +- zone/embparser.cpp | 2 +- zone/embxs.cpp | 2 +- zone/entity.cpp | 4 +- zone/forage.cpp | 4 +- zone/guild_mgr.cpp | 16 ++++---- zone/inventory.cpp | 36 ++++++++--------- zone/loottables.cpp | 14 +++---- zone/lua_item.cpp | 2 +- zone/lua_item.h | 12 +++--- zone/lua_parser_events.cpp | 2 +- zone/merc.cpp | 14 +++---- zone/merc.h | 4 +- zone/mob.cpp | 14 +++---- zone/mob.h | 18 ++++----- zone/mod_functions.cpp | 8 ++-- zone/npc.cpp | 8 ++-- zone/npc.h | 8 ++-- zone/object.cpp | 6 +-- zone/perl_mob.cpp | 2 +- zone/pets.cpp | 4 +- zone/questmgr.cpp | 10 ++--- zone/special_attacks.cpp | 40 +++++++++---------- zone/spell_effects.cpp | 20 +++++----- zone/spells.cpp | 8 ++-- zone/tasks.cpp | 4 +- zone/tradeskills.cpp | 16 ++++---- zone/trading.cpp | 24 ++++++------ zone/tune.cpp | 2 +- zone/zonedb.cpp | 6 +-- 69 files changed, 477 insertions(+), 381 deletions(-) create mode 100644 common/inventory.cpp create mode 100644 common/inventory.h rename common/{item_struct.h => item_data.h} (94%) create mode 100644 common/item_instance.cpp create mode 100644 common/item_instance.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index f847957db..a992b8feb 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -30,8 +30,10 @@ SET(common_sources faction.cpp guild_base.cpp guilds.cpp + inventory.cpp ipc_mutex.cpp item.cpp + item_instance.cpp md5.cpp memory_mapped_file.cpp misc.cpp @@ -135,10 +137,12 @@ SET(common_headers global_define.h guild_base.h guilds.h + inventory.h ipc_mutex.h item.h + item_data.h item_fieldlist.h - item_struct.h + item_instance.h languages.h linked_list.h loottable.h diff --git a/common/eq_constants.h b/common/eq_constants.h index 14f695069..ee312f6b4 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -259,7 +259,7 @@ enum AugmentationRestrictionTypes : uint8 { /* ** Container use types ** -** This correlates to world 'object.type' (object.h/Object.cpp) as well as Item_Struct.BagType +** This correlates to world 'object.type' (object.h/Object.cpp) as well as ItemData.BagType ** ** (ref: database, web forums and eqstr_us.txt) */ diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index cd30cf3d1..98ccb0da1 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -24,7 +24,7 @@ #include #include #include "../common/version.h" -//#include "../common/item_struct.h" +//#include "../common/item_data.h" static const uint32 BUFF_COUNT = 25; static const uint32 MAX_MERC = 100; @@ -2082,7 +2082,7 @@ struct AdventureLeaderboard_Struct /*struct Item_Shop_Struct { uint16 merchantid; uint8 itemtype; - Item_Struct item; + ItemData item; uint8 iss_unknown001[6]; };*/ diff --git a/common/inventory.cpp b/common/inventory.cpp new file mode 100644 index 000000000..b63ba4eaf --- /dev/null +++ b/common/inventory.cpp @@ -0,0 +1,20 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 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 +*/ + +#include "inventory.h" + diff --git a/common/inventory.h b/common/inventory.h new file mode 100644 index 000000000..9816bd8dd --- /dev/null +++ b/common/inventory.h @@ -0,0 +1,32 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 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 +*/ + +#ifndef COMMON_INVENTORY_H +#define COMMON_INVENTORY_H + +namespace EQEmu +{ + class Inventory + { + public: + private: + }; + +} // EQEmu + +#endif diff --git a/common/item.cpp b/common/item.cpp index e5252a9d0..ca3af8066 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -368,7 +368,7 @@ ItemInst* InventoryOld::PopItem(int16 slot_id) return p; } -bool InventoryOld::HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity) { +bool InventoryOld::HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity) { if (ItemToTry->Stackable) { @@ -901,7 +901,7 @@ uint8 InventoryOld::CalcMaterialFromSlot(int16 equipslot) } } -bool InventoryOld::CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container) { +bool InventoryOld::CanItemFitInContainer(const ItemData *ItemToTry, const ItemData *Container) { if (!ItemToTry || !Container) return false; @@ -1429,7 +1429,7 @@ int16 InventoryOld::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup) // // class ItemInst // -ItemInst::ItemInst(const Item_Struct* item, int16 charges) { +ItemInst::ItemInst(const ItemData* item, int16 charges) { m_use_type = ItemInstNormal; m_item = item; m_charges = charges; @@ -1539,7 +1539,7 @@ ItemInst::ItemInst(const ItemInst& copy) m_evolveLvl = copy.m_evolveLvl; m_activated = copy.m_activated; if (copy.m_scaledItem) - m_scaledItem = new Item_Struct(*copy.m_scaledItem); + m_scaledItem = new ItemData(*copy.m_scaledItem); else m_scaledItem = nullptr; @@ -1758,7 +1758,7 @@ void ItemInst::ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent) continue; } - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); if (item == nullptr) { cur = m_contents.erase(cur); continue; @@ -1899,7 +1899,7 @@ bool ItemInst::UpdateOrnamentationInfo() { int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); if (GetOrnamentationAug(ornamentationAugtype)) { - const Item_Struct* ornamentItem; + const ItemData* ornamentItem; ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem(); if (ornamentItem != nullptr) { @@ -1926,7 +1926,7 @@ bool ItemInst::UpdateOrnamentationInfo() { return ornamentSet; } -bool ItemInst::CanTransform(const Item_Struct *ItemToTry, const Item_Struct *Container, bool AllowAll) { +bool ItemInst::CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll) { if (!ItemToTry || !Container) return false; if (ItemToTry->ItemType == ItemTypeArrow || strnlen(Container->CharmFile, 30) == 0) @@ -2060,7 +2060,7 @@ bool ItemInst::IsAmmo() const } -const Item_Struct* ItemInst::GetItem() const +const ItemData* ItemInst::GetItem() const { if (!m_item) return nullptr; @@ -2071,7 +2071,7 @@ const Item_Struct* ItemInst::GetItem() const return m_item; } -const Item_Struct* ItemInst::GetUnscaledItem() const +const ItemData* ItemInst::GetUnscaledItem() const { // No operator calls and defaults to nullptr return m_item; @@ -2179,10 +2179,10 @@ void ItemInst::ScaleItem() { return; if (m_scaledItem) { - memcpy(m_scaledItem, m_item, sizeof(Item_Struct)); + memcpy(m_scaledItem, m_item, sizeof(ItemData)); } else { - m_scaledItem = new Item_Struct(*m_item); + m_scaledItem = new ItemData(*m_item); } float Mult = (float)(GetExp()) / 10000; // scaling is determined by exp, with 10,000 being full stats @@ -2326,9 +2326,9 @@ EvolveInfo::~EvolveInfo() { // -// struct Item_Struct +// struct ItemData // -bool Item_Struct::IsEquipable(uint16 Race, uint16 Class_) const +bool ItemData::IsEquipable(uint16 Race, uint16 Class_) const { bool IsRace = false; bool IsClass = false; diff --git a/common/item.h b/common/item.h index b1227df33..d5f83c2d8 100644 --- a/common/item.h +++ b/common/item.h @@ -27,7 +27,7 @@ class ItemParse; // Parses item packets class EvolveInfo; // Stores information about an evolving item family #include "../common/eq_constants.h" -#include "../common/item_struct.h" +#include "../common/item_data.h" #include "../common/timer.h" #include @@ -168,7 +168,7 @@ public: ItemInst* PopItem(int16 slot_id); // Check whether there is space for the specified number of the specified item. - bool HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity); + bool HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity); // Check whether item exists in inventory // where argument specifies OR'd list of invWhere constants to look @@ -193,7 +193,7 @@ public: static int16 CalcSlotFromMaterial(uint8 material); static uint8 CalcMaterialFromSlot(int16 equipslot); - static bool CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container); + static bool CanItemFitInContainer(const ItemData *ItemToTry, const ItemData *Container); // Test for valid inventory casting slot bool SupportsClickCasting(int16 slot_id); @@ -270,7 +270,7 @@ public: ///////////////////////// // Constructors/Destructor - ItemInst(const Item_Struct* item = nullptr, int16 charges = 0); + ItemInst(const ItemData* item = nullptr, int16 charges = 0); ItemInst(SharedDatabase *db, uint32 item_id, int16 charges = 0); @@ -331,7 +331,7 @@ public: bool IsAugmented(); ItemInst* GetOrnamentationAug(int32 ornamentationAugtype) const; bool UpdateOrnamentationInfo(); - static bool CanTransform(const Item_Struct *ItemToTry, const Item_Struct *Container, bool AllowAll = false); + static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false); // Has attack/delay? bool IsWeapon() const; @@ -340,8 +340,8 @@ public: // Accessors const uint32 GetID() const { return ((m_item) ? m_item->ID : NO_ITEM); } const uint32 GetItemScriptID() const { return ((m_item) ? m_item->ScriptFileID : NO_ITEM); } - const Item_Struct* GetItem() const; - const Item_Struct* GetUnscaledItem() const; + const ItemData* GetItem() const; + const ItemData* GetUnscaledItem() const; int16 GetCharges() const { return m_charges; } void SetCharges(int16 charges) { m_charges = charges; } @@ -376,7 +376,7 @@ public: // Allows treatment of this object as though it were a pointer to m_item operator bool() const { return (m_item != nullptr); } - // Compare inner Item_Struct of two ItemInst objects + // Compare inner ItemData of two ItemInst objects bool operator==(const ItemInst& right) const { return (this->m_item == right.m_item); } bool operator!=(const ItemInst& right) const { return (this->m_item != right.m_item); } @@ -431,7 +431,7 @@ protected: void _PutItem(uint8 index, ItemInst* inst) { m_contents[index] = inst; } ItemInstTypes m_use_type; // Usage type for item - const Item_Struct* m_item; // Ptr to item data + const ItemData* m_item; // Ptr to item data int16 m_charges; // # of charges for chargeable items uint32 m_price; // Bazaar /trader price uint32 m_color; @@ -443,7 +443,7 @@ protected: uint32 m_exp; int8 m_evolveLvl; bool m_activated; - Item_Struct* m_scaledItem; + ItemData* m_scaledItem; EvolveInfo* m_evolveInfo; bool m_scaling; uint32 m_ornamenticon; diff --git a/common/item_struct.h b/common/item_data.h similarity index 94% rename from common/item_struct.h rename to common/item_data.h index 3ef26db94..e5a8fb395 100644 --- a/common/item_struct.h +++ b/common/item_data.h @@ -16,8 +16,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 04111-1307 USA */ -#ifndef ITEM_STRUCT_H -#define ITEM_STRUCT_H +#ifndef COMMON_ITEM_DATA_H +#define COMMON_ITEM_DATA_H /* * Note: (Doodman) @@ -35,7 +35,7 @@ * * Note #3: (Doodman) * Please take care when adding new found data fields to add them - * to the appropriate structure. Item_Struct has elements that are + * to the appropriate structure. ItemData has elements that are * global to all types of items only. * * Note #4: (Doodman) @@ -46,7 +46,7 @@ #include "eq_dictionary.h" /* -** Child struct of Item_Struct: +** Child struct of ItemData: ** Effect data: Click, Proc, Focus, Worn, Scroll ** */ @@ -72,7 +72,7 @@ struct InternalSerializedItem_Struct { // use EmuConstants::ITEM_COMMON_SIZE //#define MAX_AUGMENT_SLOTS 5 -struct Item_Struct { +struct ItemData { bool IsEquipable(uint16 Race, uint16 Class) const; // Non packet based fields uint8 MinStatus; @@ -99,17 +99,10 @@ struct Item_Struct { uint32 Favor; // Individual favor uint32 GuildFavor; // Guild favor uint32 PointType; - - //uint32 Unk117; - //uint32 Unk118; - //uint32 Unk121; - //uint32 Unk124; - uint8 BagType; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types - uint8 BagSlots; // Number of slots: can only be 2, 4, 6, 8, or 10 + uint8 BagSlots; // Number of slots uint8 BagSize; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT uint8 BagWR; // 0->100 - bool BenefitFlag; bool Tradeskills; // Is this a tradeskill item? int8 CR; // Save vs Cold @@ -128,7 +121,6 @@ struct Item_Struct { int32 Mana; // Mana int32 AC; // AC uint32 Deity; // Bitmask of Deities that can equip this item - //uint32 Unk033 int32 SkillModValue; // % Mod to skill specified in SkillModType uint32 SkillModType; // Type of skill for SkillModValue to apply to uint32 BaneDmgRace; // Bane Damage Race @@ -150,13 +142,11 @@ struct Item_Struct { uint32 Color; // RR GG BB 00 <-- as it appears in pc uint32 Classes; // Bitfield of classes that can equip item (1 << class#) uint32 Races; // Bitfield of races that can equip item (1 << race#) - //uint32 Unk054; int16 MaxCharges; // Maximum charges items can hold: -1 if not a chargeable item uint8 ItemType; // Item Type/Skill (itemClass* from above) uint8 Material; // Item material type uint32 HerosForgeModel;// Hero's Forge Armor Model Type (2-13?) float SellRate; // Sell rate - //uint32 Unk059; union { uint32 Fulfilment; // Food fulfilment (How long it lasts) int16 CastTime; // Cast Time for clicky effects, in milliseconds @@ -211,7 +201,6 @@ struct Item_Struct { int16 StackSize; uint8 PotionBeltSlots; ItemEffect_Struct Click, Proc, Worn, Focus, Scroll, Bard; - uint8 Book; // 0=Not book, 1=Book uint32 BookType; char Filename[33]; // Filename for book data @@ -240,11 +229,11 @@ struct Item_Struct { uint32 ScriptFileID; uint16 ExpendableArrow; uint32 Clairvoyance; - char ClickName[65]; - char ProcName[65]; - char WornName[65]; - char FocusName[65]; - char ScrollName[65]; + char ClickName[65]; + char ProcName[65]; + char WornName[65]; + char FocusName[65]; + char ScrollName[65]; }; diff --git a/common/item_instance.cpp b/common/item_instance.cpp new file mode 100644 index 000000000..0a8fb4940 --- /dev/null +++ b/common/item_instance.cpp @@ -0,0 +1,19 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 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 +*/ + +#include "item_instance.h" diff --git a/common/item_instance.h b/common/item_instance.h new file mode 100644 index 000000000..8ba559681 --- /dev/null +++ b/common/item_instance.h @@ -0,0 +1,32 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 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 +*/ + +#ifndef COMMON_ITEM_INSTANCE_H +#define COMMON_ITEM_INSTANCE_H + +namespace EQEmu +{ + class ItemInstance + { + public: + private: + }; + +} // EQEmu + +#endif diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 94c42a1f2..6118b3426 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -4972,7 +4972,7 @@ namespace RoF std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary); - const Item_Struct *item = inst->GetUnscaledItem(); + const ItemData *item = inst->GetUnscaledItem(); //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name); RoF::structs::ItemSerializationHeader hdr; diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index f8b48c1c0..0e67bcd92 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -5136,7 +5136,7 @@ namespace RoF2 std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary); - const Item_Struct *item = inst->GetUnscaledItem(); + const ItemData *item = inst->GetUnscaledItem(); //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name); RoF2::structs::ItemSerializationHeader hdr; diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index e4e11ae8b..38d574759 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -2280,7 +2280,7 @@ struct AdventureLeaderboard_Struct /*struct Item_Shop_Struct { uint16 merchantid; uint8 itemtype; - Item_Struct item; + ItemData item; uint8 iss_unknown001[6]; };*/ diff --git a/common/patches/rof_structs.h b/common/patches/rof_structs.h index 417ff2e64..97d1ce796 100644 --- a/common/patches/rof_structs.h +++ b/common/patches/rof_structs.h @@ -2309,7 +2309,7 @@ struct AdventureLeaderboard_Struct /*struct Item_Shop_Struct { uint16 merchantid; uint8 itemtype; - Item_Struct item; + ItemData item; uint8 iss_unknown001[6]; };*/ diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index 59412726e..f73cffc07 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -3515,7 +3515,7 @@ namespace SoD std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary); - const Item_Struct *item = inst->GetUnscaledItem(); + const ItemData *item = inst->GetUnscaledItem(); //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name); SoD::structs::ItemSerializationHeader hdr; hdr.stacksize = stackable ? charges : 1; diff --git a/common/patches/sod_structs.h b/common/patches/sod_structs.h index 810c59b1e..2d1507e4b 100644 --- a/common/patches/sod_structs.h +++ b/common/patches/sod_structs.h @@ -1958,7 +1958,7 @@ struct AdventureLeaderboard_Struct /*struct Item_Shop_Struct { uint16 merchantid; uint8 itemtype; - Item_Struct item; + ItemData item; uint8 iss_unknown001[6]; };*/ diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index bd6bfff37..64273b7ba 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -2839,7 +2839,7 @@ namespace SoF std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary); - const Item_Struct *item = inst->GetUnscaledItem(); + const ItemData *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; diff --git a/common/patches/sof_structs.h b/common/patches/sof_structs.h index 32b275716..b9a76518c 100644 --- a/common/patches/sof_structs.h +++ b/common/patches/sof_structs.h @@ -1931,7 +1931,7 @@ struct AdventureLeaderboard_Struct /*struct Item_Shop_Struct { uint16 merchantid; uint8 itemtype; - Item_Struct item; + ItemData item; uint8 iss_unknown001[6]; };*/ diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index 3be2d7d70..296307e7d 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -1989,7 +1989,7 @@ namespace Titanium int16 slot_id = ServerToTitaniumSlot(slot_id_in); uint32 merchant_slot = inst->GetMerchantSlot(); int16 charges = inst->GetCharges(); - const Item_Struct *item = inst->GetUnscaledItem(); + const ItemData *item = inst->GetUnscaledItem(); int i; uint32 sub_length; diff --git a/common/patches/titanium_structs.h b/common/patches/titanium_structs.h index 19d82d6af..6dc20ae72 100644 --- a/common/patches/titanium_structs.h +++ b/common/patches/titanium_structs.h @@ -1687,7 +1687,7 @@ struct AdventureRequestResponse_Struct{ /*struct Item_Shop_Struct { uint16 merchantid; uint8 itemtype; - Item_Struct item; + ItemData item; uint8 iss_unknown001[6]; };*/ diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index b31590a3c..31b6be0e5 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -3760,7 +3760,7 @@ namespace UF std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary); - const Item_Struct *item = inst->GetUnscaledItem(); + const ItemData *item = inst->GetUnscaledItem(); //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name); UF::structs::ItemSerializationHeader hdr; hdr.stacksize = stackable ? charges : 1; @@ -3798,7 +3798,7 @@ namespace UF //ORNAMENT IDFILE / ICON - uint16 ornaIcon = 0; if (inst->GetOrnamentationAug(ornamentationAugtype)) { - const Item_Struct *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem(); + const ItemData *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem(); ss.write(aug_weap->IDFile, strlen(aug_weap->IDFile)); ss.write((const char*)&null_term, sizeof(uint8)); ornaIcon = aug_weap->Icon; diff --git a/common/patches/uf_structs.h b/common/patches/uf_structs.h index fb4d00de3..62b9199ba 100644 --- a/common/patches/uf_structs.h +++ b/common/patches/uf_structs.h @@ -2016,7 +2016,7 @@ struct AdventureLeaderboard_Struct /*struct Item_Shop_Struct { uint16 merchantid; uint8 itemtype; - Item_Struct item; + ItemData item; uint8 iss_unknown001[6]; };*/ diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 94a1ba226..c1766b5c0 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -347,7 +347,7 @@ bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) { bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, InventoryOld* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) { - const Item_Struct* myitem; + const ItemData* myitem; std::string query = StringFormat("SELECT itemid, item_charges, slot FROM starting_items " "WHERE (race = %i or race = 0) AND (class = %i or class = 0) AND " @@ -419,7 +419,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, InventoryOld *inv, bool is_charid) aug[4] = (uint32)atoi(row[7]); aug[5] = (uint32)atoi(row[8]); - const Item_Struct *item = GetItem(item_id); + const ItemData *item = GetItem(item_id); if (!item) { Log.Out(Logs::General, Logs::Error, @@ -521,7 +521,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, InventoryOld *inv) uint32 ornament_idfile = (uint32)atoul(row[13]); uint32 ornament_hero_model = (uint32)atoul(row[14]); - const Item_Struct *item = GetItem(item_id); + const ItemData *item = GetItem(item_id); if (!item) { Log.Out(Logs::General, Logs::Error, @@ -662,7 +662,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, InventoryOld *i uint32 ornament_idfile = (uint32)atoul(row[13]); uint32 ornament_hero_model = (uint32)atoul(row[14]); - const Item_Struct *item = GetItem(item_id); + const ItemData *item = GetItem(item_id); int16 put_slot_id = INVALID_INDEX; if (!item) continue; @@ -806,12 +806,12 @@ bool SharedDatabase::LoadItems() { if(items == -1) { EQ_EXCEPT("SharedDatabase", "Database returned no result"); } - uint32 size = static_cast(EQEmu::FixedMemoryHashSet::estimated_size(items, max_item)); + uint32 size = static_cast(EQEmu::FixedMemoryHashSet::estimated_size(items, max_item)); if(items_mmf->Size() != size) { EQ_EXCEPT("SharedDatabase", "Couldn't load items because items_mmf->Size() != size"); } - items_hash = new EQEmu::FixedMemoryHashSet(reinterpret_cast(items_mmf->Get()), size); + items_hash = new EQEmu::FixedMemoryHashSet(reinterpret_cast(items_mmf->Get()), size); mutex.Unlock(); } catch(std::exception& ex) { Log.Out(Logs::General, Logs::Error, "Error Loading Items: %s", ex.what()); @@ -822,7 +822,7 @@ bool SharedDatabase::LoadItems() { } void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id) { - EQEmu::FixedMemoryHashSet hash(reinterpret_cast(data), size, items, max_item_id); + EQEmu::FixedMemoryHashSet hash(reinterpret_cast(data), size, items, max_item_id); char ndbuffer[4]; bool disableNoRent = false; @@ -850,7 +850,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_ } } - Item_Struct item; + ItemData item; const std::string query = "SELECT source," #define F(x) "`"#x"`," @@ -863,7 +863,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_ } for(auto row = results.begin(); row != results.end(); ++row) { - memset(&item, 0, sizeof(Item_Struct)); + memset(&item, 0, sizeof(ItemData)); item.ItemClass = (uint8)atoi(row[ItemField::itemclass]); strcpy(item.Name,row[ItemField::name]); @@ -1078,7 +1078,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_ } -const Item_Struct* SharedDatabase::GetItem(uint32 id) { +const ItemData* SharedDatabase::GetItem(uint32 id) { if (id == 0) { return nullptr; @@ -1097,7 +1097,7 @@ const Item_Struct* SharedDatabase::GetItem(uint32 id) { return nullptr; } -const Item_Struct* SharedDatabase::IterateItems(uint32* id) { +const ItemData* SharedDatabase::IterateItems(uint32* id) { if(!items_hash || !id) { return nullptr; } @@ -1255,7 +1255,7 @@ bool SharedDatabase::LoadNPCFactionLists() { // Create appropriate ItemInst class ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned) { - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; ItemInst* inst = nullptr; item = GetItem(item_id); @@ -1282,7 +1282,7 @@ ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1, // Create appropriate ItemInst class -ItemInst* SharedDatabase::CreateItem(const Item_Struct* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned) +ItemInst* SharedDatabase::CreateItem(const ItemData* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned) { ItemInst* inst = nullptr; if (item) { @@ -1306,7 +1306,7 @@ ItemInst* SharedDatabase::CreateItem(const Item_Struct* item, int16 charges, uin return inst; } -ItemInst* SharedDatabase::CreateBaseItem(const Item_Struct* item, int16 charges) { +ItemInst* SharedDatabase::CreateBaseItem(const ItemData* item, int16 charges) { ItemInst* inst = nullptr; if (item) { // if maxcharges is -1 that means it is an unlimited use item. diff --git a/common/shareddb.h b/common/shareddb.h index ce608b4a1..9f7708919 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -20,7 +20,7 @@ struct BaseDataStruct; struct InspectMessage_Struct; struct PlayerProfile_Struct; struct SPDat_Spell_Struct; -struct Item_Struct; +struct ItemData; struct NPCFactionList; struct LootTable_Struct; struct LootDrop_Struct; @@ -82,8 +82,8 @@ class SharedDatabase : public Database Item Methods */ ItemInst* CreateItem(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); - ItemInst* CreateItem(const Item_Struct* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); - ItemInst* CreateBaseItem(const Item_Struct* item, int16 charges = 0); + ItemInst* CreateItem(const ItemData* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); + ItemInst* CreateBaseItem(const ItemData* item, int16 charges = 0); /* Shared Memory crap @@ -93,8 +93,8 @@ class SharedDatabase : public Database void GetItemsCount(int32 &item_count, uint32 &max_id); void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id); bool LoadItems(); - const Item_Struct* IterateItems(uint32* id); - const Item_Struct* GetItem(uint32 id); + const ItemData* IterateItems(uint32* id); + const ItemData* GetItem(uint32 id); const EvolveInfo* GetEvolveInfo(uint32 loregroup); //faction lists @@ -130,7 +130,7 @@ class SharedDatabase : public Database EQEmu::MemoryMappedFile *skill_caps_mmf; EQEmu::MemoryMappedFile *items_mmf; - EQEmu::FixedMemoryHashSet *items_hash; + EQEmu::FixedMemoryHashSet *items_hash; EQEmu::MemoryMappedFile *faction_mmf; EQEmu::FixedMemoryHashSet *faction_hash; EQEmu::MemoryMappedFile *loot_table_mmf; diff --git a/shared_memory/items.cpp b/shared_memory/items.cpp index 48b81b6fc..1a02e8022 100644 --- a/shared_memory/items.cpp +++ b/shared_memory/items.cpp @@ -22,7 +22,7 @@ #include "../common/ipc_mutex.h" #include "../common/memory_mapped_file.h" #include "../common/eqemu_exception.h" -#include "../common/item_struct.h" +#include "../common/item_data.h" void LoadItems(SharedDatabase *database) { EQEmu::IPCMutex mutex("items"); @@ -35,7 +35,7 @@ void LoadItems(SharedDatabase *database) { EQ_EXCEPT("Shared Memory", "Unable to get any items from the database."); } - uint32 size = static_cast(EQEmu::FixedMemoryHashSet::estimated_size(items, max_item)); + uint32 size = static_cast(EQEmu::FixedMemoryHashSet::estimated_size(items, max_item)); EQEmu::MemoryMappedFile mmf("shared/items", size); mmf.ZeroFile(); diff --git a/tests/fixed_memory_test.h b/tests/fixed_memory_test.h index fcff0c9e8..98ba842ee 100644 --- a/tests/fixed_memory_test.h +++ b/tests/fixed_memory_test.h @@ -27,7 +27,7 @@ class FixedMemoryHashTest : public Test::Suite { typedef void(FixedMemoryHashTest::*TestFunction)(void); public: FixedMemoryHashTest() { - size_ = EQEmu::FixedMemoryHashSet::estimated_size(72000, 190000); + size_ = EQEmu::FixedMemoryHashSet::estimated_size(72000, 190000); data_ = new uint8[size_]; memset(data_, 0, size_); TEST_ADD(FixedMemoryHashTest::InitTest); @@ -49,7 +49,7 @@ public: private: void InitTest() { - EQEmu::FixedMemoryHashSet hash(data_, size_, 72000, 190000); + EQEmu::FixedMemoryHashSet hash(data_, size_, 72000, 190000); TEST_ASSERT(!hash.exists(1001)); TEST_ASSERT(hash.size() == 0); TEST_ASSERT(hash.max_size() == 72000); @@ -57,7 +57,7 @@ public: } void LoadTest() { - EQEmu::FixedMemoryHashSet hash(data_, size_); + EQEmu::FixedMemoryHashSet hash(data_, size_); TEST_ASSERT(!hash.exists(1001)); TEST_ASSERT(hash.size() == 0); TEST_ASSERT(hash.max_size() == 72000); @@ -65,8 +65,8 @@ public: } void InsertTest() { - EQEmu::FixedMemoryHashSet hash(data_, size_); - Item_Struct item; + EQEmu::FixedMemoryHashSet hash(data_, size_); + ItemData item; memset(&item, 0, sizeof(item)); strcpy(item.Name, "Iron Sword"); item.ID = 1001; @@ -79,20 +79,20 @@ public: } void RetrieveTest() { - EQEmu::FixedMemoryHashSet hash(data_, size_); + EQEmu::FixedMemoryHashSet hash(data_, size_); TEST_ASSERT(hash.exists(1001)); TEST_ASSERT(hash.size() == 1); TEST_ASSERT(hash.max_size() == 72000); TEST_ASSERT(!hash.empty()); - Item_Struct item = hash[1001]; + ItemData item = hash[1001]; TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0); TEST_ASSERT(item.ID == 1001); } void OverwriteTest() { - EQEmu::FixedMemoryHashSet hash(data_, size_); - Item_Struct item; + EQEmu::FixedMemoryHashSet hash(data_, size_); + ItemData item; memset(&item, 0, sizeof(item)); strcpy(item.Name, "Steel Sword"); item.ID = 1001; @@ -105,20 +105,20 @@ public: } void OverwriteRetrieveTest() { - EQEmu::FixedMemoryHashSet hash(data_, size_); + EQEmu::FixedMemoryHashSet hash(data_, size_); TEST_ASSERT(hash.exists(1001)); TEST_ASSERT(hash.size() == 1); TEST_ASSERT((hash.max_size() == 72000)); TEST_ASSERT(!hash.empty()); - Item_Struct item = hash[1001]; + ItemData item = hash[1001]; TEST_ASSERT(strcmp(item.Name, "Steel Sword") == 0); TEST_ASSERT(item.ID == 1001); } void InsertAgainTest() { - EQEmu::FixedMemoryHashSet hash(data_, size_); - Item_Struct item; + EQEmu::FixedMemoryHashSet hash(data_, size_); + ItemData item; memset(&item, 0, sizeof(item)); strcpy(item.Name, "Iron Sword"); item.ID = 1000; @@ -132,14 +132,14 @@ public: } void RetrieveAgainTest() { - EQEmu::FixedMemoryHashSet hash(data_, size_); + EQEmu::FixedMemoryHashSet hash(data_, size_); TEST_ASSERT(hash.exists(1000)); TEST_ASSERT(hash.exists(1001)); TEST_ASSERT(hash.size() == 2); TEST_ASSERT(hash.max_size() == 72000); TEST_ASSERT(!hash.empty()); - Item_Struct item = hash[1000]; + ItemData item = hash[1000]; TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0); TEST_ASSERT(item.ID == 1000); @@ -149,8 +149,8 @@ public: } void InsertBeginTest() { - EQEmu::FixedMemoryHashSet hash(data_, size_); - Item_Struct item; + EQEmu::FixedMemoryHashSet hash(data_, size_); + ItemData item; memset(&item, 0, sizeof(item)); strcpy(item.Name, "Bronze Sword"); item.ID = 0; @@ -165,7 +165,7 @@ public: } void RetrieveBeginTest() { - EQEmu::FixedMemoryHashSet hash(data_, size_); + EQEmu::FixedMemoryHashSet hash(data_, size_); TEST_ASSERT(hash.exists(1000)); TEST_ASSERT(hash.exists(1001)); TEST_ASSERT(hash.exists(0)); @@ -173,7 +173,7 @@ public: TEST_ASSERT(hash.max_size() == 72000); TEST_ASSERT(!hash.empty()); - Item_Struct item = hash[1000]; + ItemData item = hash[1000]; TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0); TEST_ASSERT(item.ID == 1000); @@ -187,8 +187,8 @@ public: } void InsertEndTest() { - EQEmu::FixedMemoryHashSet hash(data_, size_); - Item_Struct item; + EQEmu::FixedMemoryHashSet hash(data_, size_); + ItemData item; memset(&item, 0, sizeof(item)); strcpy(item.Name, "Jade Sword"); item.ID = 190000; @@ -204,7 +204,7 @@ public: } void RetrieveEndTest() { - EQEmu::FixedMemoryHashSet hash(data_, size_); + EQEmu::FixedMemoryHashSet hash(data_, size_); TEST_ASSERT(hash.exists(1000)); TEST_ASSERT(hash.exists(1001)); TEST_ASSERT(hash.exists(0)); @@ -213,7 +213,7 @@ public: TEST_ASSERT(hash.max_size() == 72000); TEST_ASSERT(!hash.empty()); - Item_Struct item = hash[1000]; + ItemData item = hash[1000]; TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0); TEST_ASSERT(item.ID == 1000); diff --git a/world/worlddb.cpp b/world/worlddb.cpp index 07d931958..ab6846686 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -170,7 +170,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* inv = new InventoryOld; if (GetInventory(account_id, cs->name[char_num], inv)) { - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; const ItemInst* inst = nullptr; int16 invslot = 0; diff --git a/zone/aa.cpp b/zone/aa.cpp index b0208326a..7c7b2eb11 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -879,7 +879,7 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration) uint32 sitem = 0; sitem = CorpseToUse->GetWornItem(x); if(sitem){ - const Item_Struct * itm = database.GetItem(sitem); + const ItemData * itm = database.GetItem(sitem); npca->AddLootDrop(itm, &npca->itemlist, 1, 1, 127, true, true); } } diff --git a/zone/attack.cpp b/zone/attack.cpp index 814a474e8..87bbd8b7c 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -55,7 +55,7 @@ bool Mob::AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* w // Determine animation int type = 0; if (weapon && weapon->IsType(ItemClassCommon)) { - const Item_Struct* item = weapon->GetItem(); + const ItemData* item = weapon->GetItem(); Log.Out(Logs::Detail, Logs::Attack, "Weapon skill : %i", item->ItemType); @@ -806,9 +806,9 @@ int32 Client::GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, //Returns the weapon damage against the input mob //if we cannot hit the mob with the current weapon we will get a value less than or equal to zero //Else we know we can hit. -//GetWeaponDamage(mob*, const Item_Struct*) is intended to be used for mobs or any other situation where we do not have a client inventory item +//GetWeaponDamage(mob*, const ItemData*) is intended to be used for mobs or any other situation where we do not have a client inventory item //GetWeaponDamage(mob*, const ItemInst*) is intended to be used for situations where we have a client inventory item -int Mob::GetWeaponDamage(Mob *against, const Item_Struct *weapon_item) { +int Mob::GetWeaponDamage(Mob *against, const ItemData *weapon_item) { int dmg = 0; int banedmg = 0; @@ -924,7 +924,7 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate //check for items being illegally attained if(weapon_item){ - const Item_Struct *mWeaponItem = weapon_item->GetItem(); + const ItemData *mWeaponItem = weapon_item->GetItem(); if(mWeaponItem){ if(mWeaponItem->ReqLevel > GetLevel()){ return 0; @@ -1246,7 +1246,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b // Damage bonuses apply only to hits from the main hand (Hand == MainPrimary) by characters level 28 and above // who belong to a melee class. If we're here, then all of these conditions apply. - ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const Item_Struct*) nullptr ); + ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const ItemData*) nullptr ); min_hit += (int) ucDamageBonus; max_hit += (int) ucDamageBonus; @@ -1257,7 +1257,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b if (Hand == MainSecondary) { if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc){ - ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const Item_Struct*) nullptr ); + ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const ItemData*) nullptr ); min_hit += (int) ucDamageBonus; max_hit += (int) ucDamageBonus; @@ -1739,7 +1739,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool } //figure out what weapon they are using, if any - const Item_Struct* weapon = nullptr; + const ItemData* weapon = nullptr; if (Hand == MainPrimary && equipment[MainPrimary] > 0) weapon = database.GetItem(equipment[MainPrimary]); else if (equipment[MainSecondary]) @@ -2642,7 +2642,7 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) { } } -uint8 Mob::GetWeaponDamageBonus( const Item_Struct *Weapon ) +uint8 Mob::GetWeaponDamageBonus( const ItemData *Weapon ) { // This function calculates and returns the damage bonus for the weapon identified by the parameter "Weapon". // Modified 9/21/2008 by Cantus @@ -3946,12 +3946,12 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) { } if(!weapon_g) { - TrySpellProc(nullptr, (const Item_Struct*)nullptr, on); + TrySpellProc(nullptr, (const ItemData*)nullptr, on); return; } if(!weapon_g->IsType(ItemClassCommon)) { - TrySpellProc(nullptr, (const Item_Struct*)nullptr, on); + TrySpellProc(nullptr, (const ItemData*)nullptr, on); return; } @@ -3964,7 +3964,7 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) { return; } -void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on, uint16 hand) +void Mob::TryWeaponProc(const ItemInst *inst, const ItemData *weapon, Mob *on, uint16 hand) { if (!weapon) @@ -4017,7 +4017,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on const ItemInst *aug_i = inst->GetAugment(r); if (!aug_i) // no aug, try next slot! continue; - const Item_Struct *aug = aug_i->GetItem(); + const ItemData *aug = aug_i->GetItem(); if (!aug) continue; @@ -4047,7 +4047,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on return; } -void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on, uint16 hand) +void Mob::TrySpellProc(const ItemInst *inst, const ItemData *weapon, Mob *on, uint16 hand) { float ProcBonus = static_cast(spellbonuses.SpellProcChance + itembonuses.SpellProcChance + aabonuses.SpellProcChance); @@ -4859,7 +4859,7 @@ void Client::SetAttackTimer() attack_timer.SetAtTrigger(4000, true); Timer *TimerToUse = nullptr; - const Item_Struct *PrimaryWeapon = nullptr; + const ItemData *PrimaryWeapon = nullptr; for (int i = MainRange; i <= MainSecondary; i++) { //pick a timer @@ -4872,7 +4872,7 @@ void Client::SetAttackTimer() else //invalid slot (hands will always hit this) continue; - const Item_Struct *ItemToUse = nullptr; + const ItemData *ItemToUse = nullptr; //find our item ItemInst *ci = GetInv().GetItem(i); diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index d3e32127d..34aac8191 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -151,7 +151,7 @@ void Client::CalcItemBonuses(StatBonuses* newbon) { AddItemBonuses(inst, newbon); //These are given special flags due to how often they are checked for various spell effects. - const Item_Struct *item = inst->GetItem(); + const ItemData *item = inst->GetItem(); if (i == MainSecondary && (item && item->ItemType == ItemTypeShield)) SetShieldEquiped(true); else if (i == MainPrimary && (item && item->ItemType == ItemType2HBlunt)) @@ -206,7 +206,7 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAu return; } - const Item_Struct *item = inst->GetItem(); + const ItemData *item = inst->GetItem(); if(!isTribute && !inst->IsEquipable(GetBaseRace(),GetClass())) { @@ -570,7 +570,7 @@ void Client::AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool if(inst->GetAugmentType()==0 && isAug == true) return; - const Item_Struct *item = inst->GetItem(); + const ItemData *item = inst->GetItem(); if(!inst->IsEquipable(GetBaseRace(),GetClass())) return; @@ -602,7 +602,7 @@ void Client::CalcEdibleBonuses(StatBonuses* newbon) { break; const ItemInst* inst = GetInv().GetItem(i); if (inst && inst->GetItem() && inst->IsType(ItemClassCommon)) { - const Item_Struct *item=inst->GetItem(); + const ItemData *item=inst->GetItem(); if (item->ItemType == ItemTypeFood && !food) food = true; else if (item->ItemType == ItemTypeDrink && !drink) @@ -618,7 +618,7 @@ void Client::CalcEdibleBonuses(StatBonuses* newbon) { break; const ItemInst* inst = GetInv().GetItem(i); if (inst && inst->GetItem() && inst->IsType(ItemClassCommon)) { - const Item_Struct *item=inst->GetItem(); + const ItemData *item=inst->GetItem(); if (item->ItemType == ItemTypeFood && !food) food = true; else if (item->ItemType == ItemTypeDrink && !drink) @@ -3053,7 +3053,7 @@ void NPC::CalcItemBonuses(StatBonuses *newbon) if(newbon){ for(int i = 0; i < EmuConstants::EQUIPMENT_SIZE; i++){ - const Item_Struct *cur = database.GetItem(equipment[i]); + const ItemData *cur = database.GetItem(equipment[i]); if(cur){ //basic stats newbon->AC += cur->AC; diff --git a/zone/bot.cpp b/zone/bot.cpp index b449ebfe0..47c7bd989 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -247,8 +247,8 @@ uint32 Bot::GetBotArcheryRange() if (!range_inst || !ammo_inst) return 0; - const Item_Struct *range_item = range_inst->GetItem(); - const Item_Struct *ammo_item = ammo_inst->GetItem(); + const ItemData *range_item = range_inst->GetItem(); + const ItemData *ammo_item = ammo_inst->GetItem(); // no item struct for whatever reason if (!range_item || !ammo_item) @@ -2991,12 +2991,12 @@ void Bot::BotRangedAttack(Mob* other) { } ItemInst* rangedItem = GetBotItem(MainRange); - const Item_Struct* RangeWeapon = 0; + const ItemData* RangeWeapon = 0; if(rangedItem) RangeWeapon = rangedItem->GetItem(); ItemInst* ammoItem = GetBotItem(MainAmmo); - const Item_Struct* Ammo = 0; + const ItemData* Ammo = 0; if(ammoItem) Ammo = ammoItem->GetItem(); @@ -3120,7 +3120,7 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes if(GetLevel() >= 28 && IsWarriorClass() ) { - int ucDamageBonus = GetWeaponDamageBonus((const Item_Struct*) nullptr ); + int ucDamageBonus = GetWeaponDamageBonus((const ItemData*) nullptr ); min_hit += (int) ucDamageBonus; max_hit += (int) ucDamageBonus; @@ -3165,7 +3165,7 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes if(skillinuse == SkillBash){ const ItemInst* inst = GetBotItem(MainSecondary); - const Item_Struct* botweapon = 0; + const ItemData* botweapon = 0; if(inst) botweapon = inst->GetItem(); if(botweapon) { @@ -3230,7 +3230,7 @@ void Bot::ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg) if (item_slot >= EmuConstants::EQUIPMENT_BEGIN){ const ItemInst* inst = GetBotItem(item_slot); - const Item_Struct* botweapon = 0; + const ItemData* botweapon = 0; if(inst) botweapon = inst->GetItem(); if(botweapon) @@ -3645,7 +3645,7 @@ void Bot::AI_Process() { //now off hand if(GetTarget() && attack_dw_timer.Check() && CanThisClassDualWield()) { const ItemInst* instweapon = GetBotItem(MainSecondary); - const Item_Struct* weapon = 0; + const ItemData* weapon = 0; //can only dual wield without a weapon if you're a monk if(instweapon || (botClass == MONK)) { if(instweapon) @@ -4381,7 +4381,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) { ns->spawn.helm = helmtexture; //0xFF; ns->spawn.equip_chest2 = texture; //0xFF; - const Item_Struct* item = 0; + const ItemData* item = 0; const ItemInst* inst = 0; uint32 spawnedbotid = 0; @@ -5682,7 +5682,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli //EQoffline: will give the items to the bots and change the bot stats if(inst && (GetBotOwner() == client->CastToMob()) && !IsEngaged()) { std::string TempErrorMessage; - const Item_Struct* mWeaponItem = inst->GetItem(); + const ItemData* mWeaponItem = inst->GetItem(); bool failedLoreCheck = false; for (int m = AUG_BEGIN; m GetAugment(m); @@ -5855,7 +5855,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli } } - const Item_Struct* item2 = 0; + const ItemData* item2 = 0; for(int y=beginSlotID; y<=endSlotID; ++y) { item2 = database.GetItem(items[y]); if(item2) { @@ -6156,7 +6156,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b // Damage bonuses apply only to hits from the main hand (Hand == MainPrimary) by characters level 28 and above // who belong to a melee class. If we're here, then all of these conditions apply. - ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const Item_Struct*) nullptr ); + ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const ItemData*) nullptr ); min_hit += (int) ucDamageBonus; max_hit += (int) ucDamageBonus; @@ -6167,7 +6167,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b if (Hand==MainSecondary) { if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc){ - ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const Item_Struct*) nullptr ); + ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const ItemData*) nullptr ); min_hit += (int) ucDamageBonus; max_hit += (int) ucDamageBonus; @@ -6755,8 +6755,8 @@ int32 Bot::GetBotFocusEffect(BotfocusType bottype, uint16 spell_id) { //Check if item focus effect exists for the client. if (itembonuses.FocusEffects[bottype]){ - const Item_Struct* TempItem = 0; - const Item_Struct* UsedItem = 0; + const ItemData* TempItem = 0; + const ItemData* UsedItem = 0; const ItemInst* TempInst = 0; uint16 UsedFocusID = 0; int32 Total = 0; @@ -6804,7 +6804,7 @@ int32 Bot::GetBotFocusEffect(BotfocusType bottype, uint16 spell_id) { aug = ins->GetAugment(y); if(aug) { - const Item_Struct* TempItemAug = aug->GetItem(); + const ItemData* TempItemAug = aug->GetItem(); if (TempItemAug && TempItemAug->Focus.Effect > 0 && TempItemAug->Focus.Effect != SPELL_UNKNOWN) { if(rand_effectiveness) { focus_max = CalcBotFocusEffect(bottype, TempItemAug->Focus.Effect, spell_id, true); @@ -7686,7 +7686,7 @@ void Bot::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, if(skill == SkillBash) { const ItemInst* inst = GetBotItem(MainSecondary); - const Item_Struct* botweapon = 0; + const ItemData* botweapon = 0; if(inst) botweapon = inst->GetItem(); if(botweapon) { @@ -7757,7 +7757,7 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) { bool bCanFrontalBS = false; const ItemInst* inst = GetBotItem(MainPrimary); - const Item_Struct* botpiercer = nullptr; + const ItemData* botpiercer = nullptr; if(inst) botpiercer = inst->GetItem(); if(!botpiercer || (botpiercer->ItemType != ItemType1HPiercing)) { @@ -8396,7 +8396,7 @@ void Bot::EquipBot(std::string* errorMessage) { GetBotItems(errorMessage, m_inv); const ItemInst* inst = 0; - const Item_Struct* item = 0; + const ItemData* item = 0; for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) { inst = GetBotItem(i); if(inst) { @@ -8596,7 +8596,7 @@ void Bot::SetAttackTimer() { attack_timer.SetAtTrigger(4000, true); Timer* TimerToUse = nullptr; - const Item_Struct* PrimaryWeapon = nullptr; + const ItemData* PrimaryWeapon = nullptr; for (int i = MainRange; i <= MainSecondary; i++) { //pick a timer @@ -8609,7 +8609,7 @@ void Bot::SetAttackTimer() { else //invalid slot (hands will always hit this) continue; - const Item_Struct* ItemToUse = nullptr; + const ItemData* ItemToUse = nullptr; ItemInst* ci = GetBotItem(i); if (ci) ItemToUse = ci->GetItem(); @@ -10818,7 +10818,7 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) { insr->TargetID = inspectedBot->GetNPCTypeID(); insr->playerid = inspectedBot->GetID(); - const Item_Struct* item = 0; + const ItemData* item = 0; const ItemInst* inst = 0; // Modded to display power source items (will only show up on SoF+ client inspect windows though.) @@ -10871,7 +10871,7 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) { void Bot::CalcItemBonuses() { memset(&itembonuses, 0, sizeof(StatBonuses)); - const Item_Struct* itemtmp = 0; + const ItemData* itemtmp = 0; for (int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) { const ItemInst* item = GetBotItem(i); @@ -11111,7 +11111,7 @@ void Bot::CalcBotStats(bool showtext) { } } -bool Bot::CheckLoreConflict(const Item_Struct* item) { +bool Bot::CheckLoreConflict(const ItemData* item) { if (!item) return false; if (!(item->LoreFlag)) @@ -11723,7 +11723,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { "Left Finger", "Right Finger", "Chest", "Legs", "Feet", "Waist", "Ammo" }; const ItemInst* inst = nullptr; - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; bool is2Hweapon = false; std::string item_link; @@ -11793,7 +11793,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { "Left Wrist", "Right Wrist", "Range", "Hands", "Primary Hand", "Secondary Hand", "Left Finger", "Right Finger", "Chest", "Legs", "Feet", "Waist", "Ammo" }; - const Item_Struct* itm = nullptr; + const ItemData* itm = nullptr; const ItemInst* itminst = c->GetTarget()->CastToBot()->GetBotItem(slotId); if(itminst) itm = itminst->GetItem(); @@ -16015,7 +16015,7 @@ int Bot::GetRawACNoShield(int &shield_ac) uint32 Bot::CalcCurrentWeight() { - const Item_Struct* TempItem = 0; + const ItemData* TempItem = 0; ItemInst* inst; uint32 Total = 0; diff --git a/zone/bot.h b/zone/bot.h index 295eff175..ff6aca57b 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -330,7 +330,7 @@ public: void BotTradeSwapItem(Client* client, int16 lootSlot, const ItemInst* inst, const ItemInst* inst_swap, uint32 equipableSlots, std::string* errorMessage, bool swap = true); void BotTradeAddItem(uint32 id, const ItemInst* inst, int16 charges, uint32 equipableSlots, uint16 lootSlot, std::string* errorMessage, bool addToDb = true); void EquipBot(std::string* errorMessage); - bool CheckLoreConflict(const Item_Struct* item); + bool CheckLoreConflict(const ItemData* item); uint32 GetEquipmentColor(uint8 material_slot) const; virtual void UpdateEquipLightValue() { equip_light = m_inv.FindHighestLightValue(); } diff --git a/zone/client.cpp b/zone/client.cpp index 1a7d81405..80c71dccf 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2508,7 +2508,7 @@ void Client::SetFeigned(bool in_feigned) { feigned=in_feigned; } -void Client::LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const Item_Struct* item, bool buying) +void Client::LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const ItemData* item, bool buying) { if(!player || !merchant || !item) return; @@ -2702,7 +2702,7 @@ bool Client::BindWound(Mob* bindmob, bool start, bool fail){ } void Client::SetMaterial(int16 in_slot, uint32 item_id) { - const Item_Struct* item = database.GetItem(item_id); + const ItemData* item = database.GetItem(item_id); if (item && (item->ItemClass==ItemClassCommon)) { uint8 matslot = InventoryOld::CalcMaterialFromSlot(in_slot); @@ -3748,7 +3748,7 @@ void Client::SendOPTranslocateConfirm(Mob *Caster, uint16 SpellID) { return; } -void Client::SendPickPocketResponse(Mob *from, uint32 amt, int type, const Item_Struct* item){ +void Client::SendPickPocketResponse(Mob *from, uint32 amt, int type, const ItemData* item){ EQApplicationPacket* outapp = new EQApplicationPacket(OP_PickPocket, sizeof(sPickPocket_Struct)); sPickPocket_Struct* pick_out = (sPickPocket_Struct*) outapp->pBuffer; pick_out->coin = amt; @@ -3920,7 +3920,7 @@ bool Client::KeyRingCheck(uint32 item_id) void Client::KeyRingList() { Message(4,"Keys on Keyring:"); - const Item_Struct *item = 0; + const ItemData *item = 0; for(std::list::iterator iter = keyring.begin(); iter != keyring.end(); ++iter) @@ -5691,7 +5691,7 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) { insr->TargetID = requester->GetID(); insr->playerid = requestee->GetID(); - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; const ItemInst* inst = nullptr; int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); for(int16 L = 0; L <= 20; L++) { @@ -5703,7 +5703,7 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) { strcpy(insr->itemnames[L], item->Name); if (inst && inst->GetOrnamentationAug(ornamentationAugtype)) { - const Item_Struct *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem(); + const ItemData *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem(); insr->itemicons[L] = aug_item->Icon; } else if (inst && inst->GetOrnamentationIcon()) @@ -6882,7 +6882,7 @@ void Client::SendAltCurrencies() { uint32 i = 0; std::list::iterator iter = zone->AlternateCurrencies.begin(); while(iter != zone->AlternateCurrencies.end()) { - const Item_Struct* item = database.GetItem((*iter).item_id); + const ItemData* item = database.GetItem((*iter).item_id); altc->entries[i].currency_number = (*iter).id; altc->entries[i].unknown00 = 1; altc->entries[i].currency_number2 = (*iter).id; @@ -7474,7 +7474,7 @@ void Client::DuplicateLoreMessage(uint32 ItemID) return; } - const Item_Struct *item = database.GetItem(ItemID); + const ItemData *item = database.GetItem(ItemID); if(!item) return; @@ -8217,7 +8217,7 @@ void Client::SetConsumption(int32 in_hunger, int32 in_thirst) safe_delete(outapp); } -void Client::Consume(const Item_Struct *item, uint8 type, int16 slot, bool auto_consume) +void Client::Consume(const ItemData *item, uint8 type, int16 slot, bool auto_consume) { if(!item) { return; } @@ -8421,7 +8421,7 @@ void Client::TextLink::generate_body() memset(&m_LinkBodyStruct, 0, sizeof(TextLinkBody_Struct)); - const Item_Struct* item_data = nullptr; + const ItemData* item_data = nullptr; switch (m_LinkType) { case linkBlank: @@ -8501,7 +8501,7 @@ void Client::TextLink::generate_text() return; } - const Item_Struct* item_data = nullptr; + const ItemData* item_data = nullptr; switch (m_LinkType) { case linkBlank: diff --git a/zone/client.h b/zone/client.h index 85177aee2..3686053c7 100644 --- a/zone/client.h +++ b/zone/client.h @@ -27,7 +27,7 @@ class Object; class Raid; class Seperator; class ServerPacket; -struct Item_Struct; +struct ItemData; #include "../common/timer.h" #include "../common/ptimer.h" @@ -42,7 +42,7 @@ struct Item_Struct; #include "../common/seperator.h" #include "../common/item.h" #include "../common/guilds.h" -#include "../common/item_struct.h" +#include "../common/item_data.h" #include "../common/clientversions.h" #include "aa.h" @@ -288,7 +288,7 @@ public: void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho); virtual bool Process(); - void LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const Item_Struct* item, bool buying); + void LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const ItemData* item, bool buying); void SendPacketQueue(bool Block = true); void QueuePacket(const EQApplicationPacket* app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL, eqFilterType filter=FilterNone); void FastQueuePacket(EQApplicationPacket** app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL); @@ -396,7 +396,7 @@ public: inline uint8 GetLanguageSkill(uint16 n) const { return m_pp.languages[n]; } - void SendPickPocketResponse(Mob *from, uint32 amt, int type, const Item_Struct* item = nullptr); + void SendPickPocketResponse(Mob *from, uint32 amt, int type, const ItemData* item = nullptr); inline const char* GetLastName() const { return lastname; } @@ -592,7 +592,7 @@ public: void AssignToInstance(uint16 instance_id); void RemoveFromInstance(uint16 instance_id); void WhoAll(); - bool CheckLoreConflict(const Item_Struct* item); + bool CheckLoreConflict(const ItemData* item); void ChangeLastName(const char* in_lastname); void GetGroupAAs(GroupLeadershipAA_Struct *into) const; void GetRaidAAs(RaidLeadershipAA_Struct *into) const; @@ -833,7 +833,7 @@ public: TextLink() { Reset(); } void SetLinkType(LinkType linkType) { m_LinkType = linkType; } - void SetItemData(const Item_Struct* itemData) { m_ItemData = itemData; } + void SetItemData(const ItemData* itemData) { m_ItemData = itemData; } void SetLootData(const ServerLootItem_Struct* lootData) { m_LootData = lootData; } void SetItemInst(const ItemInst* itemInst) { m_ItemInst = itemInst; } void SetProxyItemID(uint32 proxyItemID) { m_ProxyItemID = proxyItemID; } // mainly for saylinks..but, not limited to @@ -857,7 +857,7 @@ public: void generate_text(); int m_LinkType; - const Item_Struct* m_ItemData; + const ItemData* m_ItemData; const ServerLootItem_Struct* m_LootData; const ItemInst* m_ItemInst; uint32 m_ProxyItemID; @@ -870,7 +870,7 @@ public: bool m_Error; }; - int GetItemLinkHash(const ItemInst* inst); // move to Item_Struct..or make use of the pre-calculated database field + int GetItemLinkHash(const ItemInst* inst); // move to ItemData..or make use of the pre-calculated database field void SendItemLink(const ItemInst* inst, bool sendtoall=false); void SendLootItemInPacket(const ItemInst* inst, int16 slot_id); @@ -1214,7 +1214,7 @@ public: void LoadAccountFlags(); void SetAccountFlag(std::string flag, std::string val); std::string GetAccountFlag(std::string flag); float GetDamageMultiplier(SkillUseTypes); - void Consume(const Item_Struct *item, uint8 type, int16 slot, bool auto_consume); + void Consume(const ItemData *item, uint8 type, int16 slot, bool auto_consume); void PlayMP3(const char* fname); void ExpeditionSay(const char *str, int ExpID); int mod_client_damage(int damage, SkillUseTypes skillinuse, int hand, const ItemInst* weapon, Mob* other); @@ -1236,9 +1236,9 @@ public: int32 mod_client_xp(int32 in_exp, NPC *npc); uint32 mod_client_xp_for_level(uint32 xp, uint16 check_level); int mod_client_haste_cap(int cap); - int mod_consume(Item_Struct *item, ItemUseTypes type, int change); - int mod_food_value(const Item_Struct *item, int change); - int mod_drink_value(const Item_Struct *item, int change); + int mod_consume(ItemData *item, ItemUseTypes type, int change); + int mod_food_value(const ItemData *item, int change); + int mod_drink_value(const ItemData *item, int change); void SetEngagedRaidTarget(bool value) { EngagedRaidTarget = value; } bool GetEngagedRaidTarget() const { return EngagedRaidTarget; } diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index a3da654a2..688b792f4 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -1302,7 +1302,7 @@ int32 Client::CalcManaRegenCap() uint32 Client::CalcCurrentWeight() { - const Item_Struct* TempItem = 0; + const ItemData* TempItem = 0; ItemInst* ins; uint32 Total = 0; int x; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index b0cde60c7..d468432f9 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1914,7 +1914,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) merchantid = tmp->CastToNPC()->MerchantType; - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; bool found = false; std::list merlist = zone->merchanttable[merchantid]; std::list::const_iterator itr; @@ -2090,7 +2090,7 @@ void Client::Handle_OP_AdventureMerchantRequest(const EQApplicationPacket *app) merchantid = tmp->CastToNPC()->MerchantType; tmp->CastToNPC()->FaceTarget(this->CastToMob()); - const Item_Struct *item = 0; + const ItemData *item = 0; std::list merlist = zone->merchanttable[merchantid]; std::list::const_iterator itr; for (itr = merlist.begin(); itr != merlist.end() && count<255; ++itr){ @@ -2189,7 +2189,7 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app) return; } - const Item_Struct* item = database.GetItem(itemid); + const ItemData* item = database.GetItem(itemid); ItemInst* inst = GetInv().GetItem(ams_in->slot); if (!item || !inst){ Message(13, "You seemed to have misplaced that item..."); @@ -2464,7 +2464,7 @@ void Client::Handle_OP_AltCurrencyMerchantRequest(const EQApplicationPacket *app ss << alt_cur_id << "|1|" << alt_cur_id; uint32 count = 0; uint32 merchant_id = tar->MerchantType; - const Item_Struct *item = nullptr; + const ItemData *item = nullptr; std::list merlist = zone->merchanttable[merchant_id]; std::list::const_iterator itr; @@ -2524,7 +2524,7 @@ void Client::Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app) return; } - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; uint32 cost = 0; uint32 current_currency = GetAlternateCurrencyValue(alt_cur_id); uint32 merchant_id = tar->MerchantType; @@ -2670,7 +2670,7 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app) return; } - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; uint32 cost = 0; uint32 current_currency = GetAlternateCurrencyValue(alt_cur_id); uint32 merchant_id = tar->MerchantType; @@ -2763,7 +2763,7 @@ void Client::Handle_OP_AltCurrencySellSelection(const EQApplicationPacket *app) return; } - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; uint32 cost = 0; uint32 current_currency = GetAlternateCurrencyValue(alt_cur_id); uint32 merchant_id = tar->MerchantType; @@ -2938,7 +2938,7 @@ void Client::Handle_OP_AugmentInfo(const EQApplicationPacket *app) } AugmentInfo_Struct* AugInfo = (AugmentInfo_Struct*)app->pBuffer; - const Item_Struct * item = database.GetItem(AugInfo->itemid); + const ItemData * item = database.GetItem(AugInfo->itemid); if (item) { strn0cpy(AugInfo->augment_info, item->Name, 64); @@ -3378,7 +3378,7 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app) { BarterItemSearchLinkRequest_Struct* bislr = (BarterItemSearchLinkRequest_Struct*)app->pBuffer; - const Item_Struct* item = database.GetItem(bislr->ItemID); + const ItemData* item = database.GetItem(bislr->ItemID); if (!item) Message(13, "Error: This item does not exist!"); @@ -3411,7 +3411,7 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app) { BuyerItemSearchLinkRequest_Struct* bislr = (BuyerItemSearchLinkRequest_Struct*)app->pBuffer; - const Item_Struct* item = database.GetItem(bislr->ItemID); + const ItemData* item = database.GetItem(bislr->ItemID); if (!item) Message(13, "Error: This item does not exist!"); @@ -3450,7 +3450,7 @@ void Client::Handle_OP_BazaarInspect(const EQApplicationPacket *app) BazaarInspect_Struct* bis = (BazaarInspect_Struct*)app->pBuffer; - const Item_Struct* item = database.GetItem(bis->ItemID); + const ItemData* item = database.GetItem(bis->ItemID); if (!item) { Message(13, "Error: This item does not exist!"); @@ -3905,7 +3905,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) //bool cancast = true; if (inst && inst->IsType(ItemClassCommon)) { - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); if (item->Click.Effect != (uint32)castspell->spell_id) { database.SetMQDetectionFlag(account_name, name, "OP_CastSpell with item, tried to cast a different spell.", zone->GetShortName()); @@ -4746,7 +4746,7 @@ void Client::Handle_OP_Consume(const EQApplicationPacket *app) return; } - const Item_Struct* eat_item = myitem->GetItem(); + const ItemData* eat_item = myitem->GetItem(); if (pcs->type == 0x01) { Consume(eat_item, ItemTypeFood, pcs->slot, (pcs->auto_consumed == 0xffffffff)); } @@ -6826,7 +6826,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) return; } - const Item_Struct* CursorItem = CursorItemInst->GetItem(); + const ItemData* CursorItem = CursorItemInst->GetItem(); if (!CursorItem->NoDrop || CursorItemInst->IsAttuned()) { @@ -7895,7 +7895,7 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app) EQApplicationPacket* outapp = app->Copy(); InspectResponse_Struct* insr = (InspectResponse_Struct*)outapp->pBuffer; Mob* tmp = entity_list.GetMob(insr->TargetID); - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); for (int16 L = EmuConstants::EQUIPMENT_BEGIN; L <= MainWaist; L++) { @@ -7905,7 +7905,7 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app) if (item) { strcpy(insr->itemnames[L], item->Name); if (inst && inst->GetOrnamentationAug(ornamentationAugtype)) { - const Item_Struct *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem(); + const ItemData *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem(); insr->itemicons[L] = aug_item->Icon; } else if (inst->GetOrnamentationIcon()) { @@ -8003,7 +8003,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) //todo: verify ivrs->link_hash based on a rule, in case we don't care about people being able to sniff data from the item DB - const Item_Struct* item = database.GetItem(ivrs->item_id); + const ItemData* item = database.GetItem(ivrs->item_id); if (!item) { if (ivrs->item_id > 500000) { @@ -8113,7 +8113,7 @@ void Client::Handle_OP_ItemName(const EQApplicationPacket *app) return; } ItemNamePacket_Struct *p = (ItemNamePacket_Struct*)app->pBuffer; - const Item_Struct *item = 0; + const ItemData *item = 0; if ((item = database.GetItem(p->item_id)) != nullptr) { EQApplicationPacket* outapp = new EQApplicationPacket(OP_ItemName, sizeof(ItemNamePacket_Struct)); p = (ItemNamePacket_Struct*)outapp->pBuffer; @@ -8129,7 +8129,7 @@ void Client::Handle_OP_ItemPreview(const EQApplicationPacket *app) VERIFY_PACKET_LENGTH(OP_ItemPreview, app, ItemPreview_Struct); ItemPreview_Struct *ips = (ItemPreview_Struct *)app->pBuffer; - const Item_Struct* item = database.GetItem(ips->itemid); + const ItemData* item = database.GetItem(ips->itemid); if (item) { EQApplicationPacket* outapp = new EQApplicationPacket(OP_ItemPreview, strlen(item->Name) + strlen(item->Lore) + strlen(item->IDFile) + 898); @@ -8345,7 +8345,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) return; } - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); if (!item) { Message(0, "Error: item not found in inventory slot #%i", slot_id); DeleteItemInInventory(slot_id, 0, true); @@ -8393,13 +8393,13 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) int r; bool tryaug = false; ItemInst* clickaug = 0; - Item_Struct* augitem = 0; + ItemData* augitem = 0; for (r = 0; r < EmuConstants::ITEM_COMMON_SIZE; r++) { const ItemInst* aug_i = inst->GetAugment(r); if (!aug_i) continue; - const Item_Struct* aug = aug_i->GetItem(); + const ItemData* aug = aug_i->GetItem(); if (!aug) continue; @@ -8407,7 +8407,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) { tryaug = true; clickaug = (ItemInst*)aug_i; - augitem = (Item_Struct*)aug; + augitem = (ItemData*)aug; spell_id = aug->Click.Effect; break; } @@ -10440,7 +10440,7 @@ void Client::Handle_OP_PotionBelt(const EQApplicationPacket *app) } if (mptbs->Action == 0) { - const Item_Struct *BaseItem = database.GetItem(mptbs->ItemID); + const ItemData *BaseItem = database.GetItem(mptbs->ItemID); if (BaseItem) { m_pp.potionbelt.items[mptbs->SlotNumber].item_id = BaseItem->ID; m_pp.potionbelt.items[mptbs->SlotNumber].icon = BaseItem->Icon; @@ -11896,7 +11896,7 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app) return; if (inst) { - const Item_Struct* shield = inst->GetItem(); + const ItemData* shield = inst->GetItem(); if (shield && shield->ItemType == ItemTypeShield) { for (int x = 0; x < 2; x++) @@ -12004,7 +12004,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) break; } } - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; uint32 prevcharges = 0; if (item_id == 0) { //check to see if its on the temporary table std::list tmp_merlist = zone->tmpmerchanttable[tmp->GetNPCTypeID()]; @@ -12241,7 +12241,7 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) uint32 itemid = GetItemIDAt(mp->itemslot); if (itemid == 0) return; - const Item_Struct* item = database.GetItem(itemid); + const ItemData* item = database.GetItem(itemid); ItemInst* inst = GetInv().GetItem(mp->itemslot); if (!item || !inst){ Message(13, "You seemed to have misplaced that item.."); @@ -13338,7 +13338,7 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app) TradeItemsValid = false; break; } - const Item_Struct *Item = database.GetItem(gis->Items[i]); + const ItemData *Item = database.GetItem(gis->Items[i]); if (!Item) { Message(13, "Unexpected error. Unable to start trader mode"); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 3f9d0ee3a..8f640f7f7 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -966,12 +966,12 @@ void Client::BulkSendInventoryItems() #endif*/ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { - const Item_Struct* handyitem = nullptr; + const ItemData* handyitem = nullptr; uint32 numItemSlots = 80; //The max number of items passed in the transaction. if (ClientVersionBit & BIT_RoFAndLater) { // RoF+ can send 200 items numItemSlots = 200; } - const Item_Struct *item; + const ItemData *item; std::list merlist = zone->merchanttable[merchant_id]; std::list::const_iterator itr; Mob* merch = entity_list.GetMobByNpcTypeID(npcid); @@ -1229,7 +1229,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app) if(inst && inst->IsType(ItemClassCommon)) { - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); if(item && item->Scroll.Effect == (int32)(memspell->spell_id)) { diff --git a/zone/command.cpp b/zone/command.cpp index 28eabb057..6126699ce 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -2553,7 +2553,7 @@ void command_peekinv(Client *c, const Seperator *sep) Client* targetClient = c->GetTarget()->CastToClient(); const ItemInst* inst_main = nullptr; const ItemInst* inst_sub = nullptr; - const Item_Struct* item_data = nullptr; + const ItemData* item_data = nullptr; std::string item_link; Client::TextLink linker; linker.SetLinkType(linker.linkItemInst); @@ -5413,7 +5413,7 @@ void command_summonitem(Client *c, const Seperator *sep) else { uint32 itemid = atoi(sep->arg[1]); int16 item_status = 0; - const Item_Struct* item = database.GetItem(itemid); + const ItemData* item = database.GetItem(itemid); if(item) { item_status = static_cast(item->MinStatus); } @@ -5452,7 +5452,7 @@ void command_giveitem(Client *c, const Seperator *sep) Client *t = c->GetTarget()->CastToClient(); uint32 itemid = atoi(sep->arg[1]); int16 item_status = 0; - const Item_Struct* item = database.GetItem(itemid); + const ItemData* item = database.GetItem(itemid); if(item) { item_status = static_cast(item->MinStatus); } @@ -5505,7 +5505,7 @@ void command_itemsearch(Client *c, const Seperator *sep) { const char *search_criteria=sep->argplus[1]; - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; std::string item_link; Client::TextLink linker; linker.SetLinkType(linker.linkItemData); @@ -10179,7 +10179,7 @@ void command_zopp(Client *c, const Seperator *sep) uint32 itemid = atoi(sep->arg[3]); int16 charges = sep->argnum == 4 ? atoi(sep->arg[4]) : 1; // defaults to 1 charge if not specified - const Item_Struct* FakeItem = database.GetItem(itemid); + const ItemData* FakeItem = database.GetItem(itemid); if (!FakeItem) { c->Message(13, "Error: Item [%u] is not a valid item id.", itemid); @@ -10187,7 +10187,7 @@ void command_zopp(Client *c, const Seperator *sep) } int16 item_status = 0; - const Item_Struct* item = database.GetItem(itemid); + const ItemData* item = database.GetItem(itemid); if(item) { item_status = static_cast(item->MinStatus); } diff --git a/zone/corpse.cpp b/zone/corpse.cpp index df03783c3..b30c8266d 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -971,7 +971,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a safe_delete(outapp); if(Loot_Request_Type == 5) { int pkitem = GetPlayerKillItem(); - const Item_Struct* item = database.GetItem(pkitem); + const ItemData* item = database.GetItem(pkitem); ItemInst* inst = database.CreateItem(item, item->MaxCharges); if(inst) { if (item->RecastDelay) @@ -986,7 +986,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a } int i = 0; - const Item_Struct* item = 0; + const ItemData* item = 0; ItemList::iterator cur,end; cur = itemlist.begin(); end = itemlist.end(); @@ -1101,7 +1101,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) { being_looted_by = 0xFFFFFFFF; return; } - const Item_Struct* item = 0; + const ItemData* item = 0; ItemInst *inst = 0; ServerLootItem_Struct* item_data = nullptr, *bag_item_data[10]; @@ -1296,7 +1296,7 @@ void Corpse::QueryLoot(Client* to) { else x < corpselootlimit ? sitem->lootslot = x : sitem->lootslot = 0xFFFF; - const Item_Struct* item = database.GetItem(sitem->item_id); + const ItemData* item = database.GetItem(sitem->item_id); if (item) to->Message((sitem->lootslot == 0xFFFF), "LootSlot: %i (EquipSlot: %i) Item: %s (%d), Count: %i", static_cast(sitem->lootslot), sitem->equip_slot, item->Name, item->ID, sitem->charges); @@ -1310,7 +1310,7 @@ void Corpse::QueryLoot(Client* to) { } else { sitem->lootslot=y; - const Item_Struct* item = database.GetItem(sitem->item_id); + const ItemData* item = database.GetItem(sitem->item_id); if (item) to->Message(0, "LootSlot: %i Item: %s (%d), Count: %i", sitem->lootslot, item->Name, item->ID, sitem->charges); @@ -1405,7 +1405,7 @@ uint32 Corpse::GetEquipment(uint8 material_slot) const { } uint32 Corpse::GetEquipmentColor(uint8 material_slot) const { - const Item_Struct *item; + const ItemData *item; if(material_slot > EmuConstants::MATERIAL_END) { return 0; diff --git a/zone/effects.cpp b/zone/effects.cpp index 5cc024ce2..6aef1748e 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -459,7 +459,7 @@ int32 Client::GetActSpellCasttime(uint16 spell_id, int32 casttime) bool Client::TrainDiscipline(uint32 itemid) { //get the item info - const Item_Struct *item = database.GetItem(itemid); + const ItemData *item = database.GetItem(itemid); if(item == nullptr) { Message(13, "Unable to find the tome you turned in!"); Log.Out(Logs::General, Logs::Error, "Unable to find turned in tome id %lu\n", (unsigned long)itemid); diff --git a/zone/embparser.cpp b/zone/embparser.cpp index e222edfda..1ee89102a 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -864,7 +864,7 @@ void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlaye } else if(isItemQuest) { // need a valid ItemInst pointer check here..unsure how to cancel this process -U - const Item_Struct* item = iteminst->GetItem(); + const ItemData* item = iteminst->GetItem(); package_name = "qst_item_"; package_name += itoa(item->ID); } diff --git a/zone/embxs.cpp b/zone/embxs.cpp index 664416587..c94834d7c 100644 --- a/zone/embxs.cpp +++ b/zone/embxs.cpp @@ -29,7 +29,7 @@ const char *getItemName(unsigned itemid) { - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; item = database.GetItem(itemid); if (item) diff --git a/zone/entity.cpp b/zone/entity.cpp index b1b139473..b53469fbc 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -1860,7 +1860,7 @@ void EntityList::QueueClientsGuildBankItemUpdate(const GuildBankItemUpdate_Struc memcpy(outgbius, gbius, sizeof(GuildBankItemUpdate_Struct)); - const Item_Struct *Item = database.GetItem(gbius->ItemID); + const ItemData *Item = database.GetItem(gbius->ItemID); auto it = client_list.begin(); while (it != client_list.end()) { @@ -3746,7 +3746,7 @@ void EntityList::GroupMessage(uint32 gid, const char *from, const char *message) uint16 EntityList::CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time) { - const Item_Struct *is = database.GetItem(itemid); + const ItemData *is = database.GetItem(itemid); if (!is) return 0; diff --git a/zone/forage.cpp b/zone/forage.cpp index 96b0efcdc..e77ef64c2 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -295,7 +295,7 @@ void Client::GoFish() food_id = common_fish_ids[index]; } - const Item_Struct* food_item = database.GetItem(food_id); + const ItemData* food_item = database.GetItem(food_id); Message_StringID(MT_Skills, FISHING_SUCCESS); ItemInst* inst = database.CreateItem(food_item, 1); @@ -387,7 +387,7 @@ void Client::ForageItem(bool guarantee) { foragedfood = common_food_ids[index]; } - const Item_Struct* food_item = database.GetItem(foragedfood); + const ItemData* food_item = database.GetItem(foragedfood); if(!food_item) { Log.Out(Logs::General, Logs::Error, "nullptr returned from database.GetItem in ClientForageItem"); diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index a5188def9..97834ab17 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -692,7 +692,7 @@ void GuildBankManager::SendGuildBank(Client *c) { if((*Iterator)->Items.DepositArea[i].ItemID > 0) { - const Item_Struct *Item = database.GetItem((*Iterator)->Items.DepositArea[i].ItemID); + const ItemData *Item = database.GetItem((*Iterator)->Items.DepositArea[i].ItemID); if(!Item) continue; @@ -728,7 +728,7 @@ void GuildBankManager::SendGuildBank(Client *c) { if((*Iterator)->Items.MainArea[i].ItemID > 0) { - const Item_Struct *Item = database.GetItem((*Iterator)->Items.MainArea[i].ItemID); + const ItemData *Item = database.GetItem((*Iterator)->Items.MainArea[i].ItemID); if(!Item) continue; @@ -859,7 +859,7 @@ bool GuildBankManager::AddItem(uint32 GuildID, uint8 Area, uint32 ItemID, int32 return false; } - const Item_Struct *Item = database.GetItem(ItemID); + const ItemData *Item = database.GetItem(ItemID); GuildBankItemUpdate_Struct gbius; @@ -925,7 +925,7 @@ int GuildBankManager::Promote(uint32 guildID, int slotID) (*iter)->Items.DepositArea[slotID].ItemID = 0; - const Item_Struct *Item = database.GetItem((*iter)->Items.MainArea[mainSlot].ItemID); + const ItemData *Item = database.GetItem((*iter)->Items.MainArea[mainSlot].ItemID); GuildBankItemUpdate_Struct gbius; @@ -981,7 +981,7 @@ void GuildBankManager::SetPermissions(uint32 guildID, uint16 slotID, uint32 perm else (*iter)->Items.MainArea[slotID].WhoFor[0] = '\0'; - const Item_Struct *Item = database.GetItem((*iter)->Items.MainArea[slotID].ItemID); + const ItemData *Item = database.GetItem((*iter)->Items.MainArea[slotID].ItemID); GuildBankItemUpdate_Struct gbius; @@ -1112,7 +1112,7 @@ bool GuildBankManager::DeleteItem(uint32 guildID, uint16 area, uint16 slotID, ui bool deleted = true; - const Item_Struct *Item = database.GetItem(BankArea[slotID].ItemID); + const ItemData *Item = database.GetItem(BankArea[slotID].ItemID); if(!Item->Stackable || (quantity >= BankArea[slotID].Quantity)) { std::string query = StringFormat("DELETE FROM `guild_bank` WHERE `guildid` = %i " @@ -1173,7 +1173,7 @@ bool GuildBankManager::MergeStacks(uint32 GuildID, uint16 SlotID) if(BankArea[SlotID].ItemID == 0) return false; - const Item_Struct *Item = database.GetItem(BankArea[SlotID].ItemID); + const ItemData *Item = database.GetItem(BankArea[SlotID].ItemID); if(!Item->Stackable) return false; @@ -1271,7 +1271,7 @@ bool GuildBankManager::SplitStack(uint32 GuildID, uint16 SlotID, uint32 Quantity if(BankArea[SlotID].Quantity <= Quantity || Quantity == 0) return false; - const Item_Struct *Item = database.GetItem(BankArea[SlotID].ItemID); + const ItemData *Item = database.GetItem(BankArea[SlotID].ItemID); if(!Item->Stackable) return false; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 6d149067c..668710b0b 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -177,7 +177,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) { } -bool Client::CheckLoreConflict(const Item_Struct* item) +bool Client::CheckLoreConflict(const ItemData* item) { if (!item) { return false; } if (!item->LoreFlag) { return false; } @@ -195,7 +195,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, // TODO: update calling methods and script apis to handle a failure return - const Item_Struct* item = database.GetItem(item_id); + const ItemData* item = database.GetItem(item_id); // make sure the item exists if(item == nullptr) { @@ -247,7 +247,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, bool enforceusable = RuleB(Inventory, EnforceAugmentUsability); for (int iter = AUG_BEGIN; iter < EmuConstants::ITEM_COMMON_SIZE; ++iter) { - const Item_Struct* augtest = database.GetItem(augments[iter]); + const ItemData* augtest = database.GetItem(augments[iter]); if(augtest == nullptr) { if(augments[iter]) { @@ -1037,7 +1037,7 @@ void Client::MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type) #if 0 // TODO: needs clean-up to save references -bool MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint8 evolving, uint8 evolvedlevel) { +bool MakeItemLink(char* &ret_link, const ItemData *item, uint32 aug0, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint8 evolving, uint8 evolvedlevel) { //we're sending back the entire "link", minus the null characters & item name //that way, we can use it for regular links & Task links //note: initiator needs to pass us ret_link @@ -1152,7 +1152,7 @@ int Client::GetItemLinkHash(const ItemInst* inst) { if (!inst) //have to have an item to make the hash return 0; - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); char* hash_str = 0; /*register */int hash = 0; @@ -1246,7 +1246,7 @@ packet with the item number in it, but I cant seem to find it right now if (!inst) return; - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); const char* name2 = &item->Name[0]; EQApplicationPacket* outapp = new EQApplicationPacket(OP_ItemLinkText,strlen(name2)+68); char buffer2[135] = {0}; @@ -1518,7 +1518,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { else { auto ndh_item = ndh_inst->GetItem(); if (ndh_item == nullptr) { - ndh_item_data.append("[nullptr on Item_Struct*]"); + ndh_item_data.append("[nullptr on ItemData*]"); } else { ndh_item_data.append(StringFormat("name=%s", ndh_item->Name)); @@ -1560,8 +1560,8 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { m_inv.DeleteItem(src_slot_id); } else { - const Item_Struct* world_item = world_inst->GetItem(); - const Item_Struct* src_item = src_inst->GetItem(); + const ItemData* world_item = world_inst->GetItem(); + const ItemData* src_item = src_inst->GetItem(); if (world_item && src_item) { // Case 2: Same item on cursor, stacks, transfer of charges needed if ((world_item->ID == src_item->ID) && src_inst->IsStackable()) { @@ -1801,7 +1801,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { int16 resync_slot = (InventoryOld::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : InventoryOld::CalcSlotId(move_slots->from_slot); if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { // This prevents the client from crashing when closing any 'phantom' bags -U - const Item_Struct* token_struct = database.GetItem(22292); // 'Copper Coin' + const ItemData* token_struct = database.GetItem(22292); // 'Copper Coin' ItemInst* token_inst = database.CreateItem(token_struct, 1); SendItemPacket(resync_slot, token_inst, ItemPacketTrade); @@ -1826,7 +1826,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { int16 resync_slot = (InventoryOld::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : InventoryOld::CalcSlotId(move_slots->from_slot); if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { if(m_inv[resync_slot]) { - const Item_Struct* token_struct = database.GetItem(22292); // 'Copper Coin' + const ItemData* token_struct = database.GetItem(22292); // 'Copper Coin' ItemInst* token_inst = database.CreateItem(token_struct, 1); SendItemPacket(resync_slot, token_inst, ItemPacketTrade); @@ -1843,7 +1843,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { if((move_slots->to_slot >= EmuConstants::EQUIPMENT_BEGIN && move_slots->to_slot <= EmuConstants::CURSOR_BAG_END) || move_slots->to_slot == MainPowerSource) { int16 resync_slot = (InventoryOld::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : InventoryOld::CalcSlotId(move_slots->to_slot); if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { - const Item_Struct* token_struct = database.GetItem(22292); // 'Copper Coin' + const ItemData* token_struct = database.GetItem(22292); // 'Copper Coin' ItemInst* token_inst = database.CreateItem(token_struct, 1); SendItemPacket(resync_slot, token_inst, ItemPacketTrade); @@ -1868,7 +1868,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { int16 resync_slot = (InventoryOld::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : InventoryOld::CalcSlotId(move_slots->to_slot); if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { if(m_inv[resync_slot]) { - const Item_Struct* token_struct = database.GetItem(22292); // 'Copper Coin' + const ItemData* token_struct = database.GetItem(22292); // 'Copper Coin' ItemInst* token_inst = database.CreateItem(token_struct, 1); SendItemPacket(resync_slot, token_inst, ItemPacketTrade); @@ -2022,7 +2022,7 @@ void Client::DyeArmor(DyeStruct* dye){ #if 0 bool Client::DecreaseByItemType(uint32 type, uint8 amt) { - const Item_Struct* TempItem = 0; + const ItemData* TempItem = 0; ItemInst* ins; int x; for(x=EmuConstants::POSSESSIONS_BEGIN; x <= EmuConstants::POSSESSIONS_END; x++) @@ -2074,7 +2074,7 @@ bool Client::DecreaseByItemType(uint32 type, uint8 amt) { #endif bool Client::DecreaseByID(uint32 type, uint8 amt) { - const Item_Struct* TempItem = nullptr; + const ItemData* TempItem = nullptr; ItemInst* ins = nullptr; int x; int num = 0; @@ -2401,7 +2401,7 @@ uint32 Client::GetEquipment(uint8 material_slot) const #if 0 int32 Client::GetEquipmentMaterial(uint8 material_slot) { - const Item_Struct *item; + const ItemData *item; item = database.GetItem(GetEquipment(material_slot)); if(item != 0) @@ -2418,7 +2418,7 @@ uint32 Client::GetEquipmentColor(uint8 material_slot) const if (material_slot > EmuConstants::MATERIAL_END) return 0; - const Item_Struct *item = database.GetItem(GetEquipment(material_slot)); + const ItemData *item = database.GetItem(GetEquipment(material_slot)); if(item != nullptr) return ((m_pp.item_tint[material_slot].rgb.use_tint) ? m_pp.item_tint[material_slot].color : item->Color); @@ -2501,7 +2501,7 @@ void Client::CreateBandolier(const EQApplicationPacket *app) { strcpy(m_pp.bandoliers[bs->number].name, bs->name); const ItemInst* InvItem = nullptr; - const Item_Struct *BaseItem = nullptr; + const ItemData *BaseItem = nullptr; int16 WeaponSlot; for(int BandolierSlot = bandolierMainHand; BandolierSlot <= bandolierAmmo; BandolierSlot++) { diff --git a/zone/loottables.cpp b/zone/loottables.cpp index 0e269f13e..67022b259 100644 --- a/zone/loottables.cpp +++ b/zone/loottables.cpp @@ -119,7 +119,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml int charges = lds->Entries[i].multiplier; for(int j = 0; j < charges; ++j) { if(zone->random.Real(0.0, 100.0) <= lds->Entries[i].chance) { - const Item_Struct* dbitem = GetItem(lds->Entries[i].item_id); + const ItemData* dbitem = GetItem(lds->Entries[i].item_id); npc->AddLootDrop(dbitem, itemlist, lds->Entries[i].item_charges, lds->Entries[i].minlevel, lds->Entries[i].maxlevel, lds->Entries[i].equip_item > 0 ? true : false, false); } @@ -139,7 +139,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml float roll_t = 0.0f; bool active_item_list = false; for(uint32 i = 0; i < lds->NumEntries; ++i) { - const Item_Struct* db_item = GetItem(lds->Entries[i].item_id); + const ItemData* db_item = GetItem(lds->Entries[i].item_id); if(db_item) { roll_t += lds->Entries[i].chance; active_item_list = true; @@ -157,7 +157,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml for(int i = 0; i < item_count; ++i) { float roll = (float)zone->random.Real(0.0, roll_t); for(uint32 j = 0; j < lds->NumEntries; ++j) { - const Item_Struct* db_item = GetItem(lds->Entries[j].item_id); + const ItemData* db_item = GetItem(lds->Entries[j].item_id); if(db_item) { if(roll < lds->Entries[j].chance) { npc->AddLootDrop(db_item, itemlist, lds->Entries[j].item_charges, lds->Entries[j].minlevel, @@ -191,7 +191,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml } //if itemlist is null, just send wear changes -void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange) { +void NPC::AddLootDrop(const ItemData *item2, ItemList* itemlist, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange) { if(item2 == nullptr) return; @@ -228,7 +228,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge if (equipit) { uint8 eslot = 0xFF; char newid[20]; - const Item_Struct* compitem = nullptr; + const ItemData* compitem = nullptr; bool found = false; // track if we found an empty slot we fit into int32 foundslot = -1; // for multi-slot items @@ -380,14 +380,14 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge SendAppearancePacket(AT_Light, GetActiveLightValue()); } -void NPC::AddItem(const Item_Struct* item, uint16 charges, bool equipitem) { +void NPC::AddItem(const ItemData* item, uint16 charges, bool equipitem) { //slot isnt needed, its determined from the item. AddLootDrop(item, &itemlist, charges, 1, 127, equipitem, equipitem); } void NPC::AddItem(uint32 itemid, uint16 charges, bool equipitem) { //slot isnt needed, its determined from the item. - const Item_Struct * i = database.GetItem(itemid); + const ItemData * i = database.GetItem(itemid); if(i == nullptr) return; AddLootDrop(i, &itemlist, charges, 1, 127, equipitem, equipitem); diff --git a/zone/lua_item.cpp b/zone/lua_item.cpp index 16254c52e..003a4973e 100644 --- a/zone/lua_item.cpp +++ b/zone/lua_item.cpp @@ -7,7 +7,7 @@ #include "lua_item.h" Lua_Item::Lua_Item(uint32 item_id) { - const Item_Struct *t = database.GetItem(item_id); + const ItemData *t = database.GetItem(item_id); SetLuaPtrData(t); } diff --git a/zone/lua_item.h b/zone/lua_item.h index 961da1333..f7865c84d 100644 --- a/zone/lua_item.h +++ b/zone/lua_item.h @@ -4,7 +4,7 @@ #include "lua_ptr.h" -struct Item_Struct; +struct ItemData; namespace luabind { struct scope; @@ -12,17 +12,17 @@ namespace luabind { luabind::scope lua_register_item(); -class Lua_Item : public Lua_Ptr +class Lua_Item : public Lua_Ptr { - typedef const Item_Struct NativeType; + typedef const ItemData NativeType; public: Lua_Item(uint32 item_id); Lua_Item() : Lua_Ptr(nullptr) { } - Lua_Item(const Item_Struct *d) : Lua_Ptr(d) { } + Lua_Item(const ItemData *d) : Lua_Ptr(d) { } virtual ~Lua_Item() { } - operator const Item_Struct*() { - return reinterpret_cast(GetLuaPtrData()); + operator const ItemData*() { + return reinterpret_cast(GetLuaPtrData()); } int GetMinStatus(); diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index 2780d0212..9b5883e7c 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -297,7 +297,7 @@ void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, st void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector *extra_pointers) { - const Item_Struct *item = database.GetItem(extra_data); + const ItemData *item = database.GetItem(extra_data); if(item) { Lua_Item l_item(item); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); diff --git a/zone/merc.cpp b/zone/merc.cpp index acae1b80c..6b5ab0660 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -209,7 +209,7 @@ void Merc::CalcItemBonuses(StatBonuses* newbon) { for (i=0; iReqLevel) { @@ -1213,7 +1213,7 @@ void Merc::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) { { continue; } - const Item_Struct* item = database.GetItem(equipment[i]); + const ItemData* item = database.GetItem(equipment[i]); if(item) { ns->spawn.equipment[i].material = item->Material; @@ -2537,8 +2537,8 @@ int16 Merc::GetFocusEffect(focusType type, uint16 spell_id) { //Check if item focus effect exists for the client. if (itembonuses.FocusEffects[type]){ - const Item_Struct* TempItem = 0; - const Item_Struct* UsedItem = 0; + const ItemData* TempItem = 0; + const ItemData* UsedItem = 0; uint16 UsedFocusID = 0; int16 Total = 0; int16 focus_max = 0; @@ -4400,7 +4400,7 @@ void Merc::DoClassAttacks(Mob *target) { DoAnim(animKick); int32 dmg = 0; - if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){ + if(GetWeaponDamage(target, (const ItemData*)nullptr) <= 0){ dmg = -5; } else{ @@ -4422,7 +4422,7 @@ void Merc::DoClassAttacks(Mob *target) { DoAnim(animTailRake); int32 dmg = 0; - if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){ + if(GetWeaponDamage(target, (const ItemData*)nullptr) <= 0){ dmg = -5; } else{ diff --git a/zone/merc.h b/zone/merc.h index 4c8749164..d67baea94 100644 --- a/zone/merc.h +++ b/zone/merc.h @@ -8,7 +8,7 @@ class Corpse; class Group; class Mob; class Raid; -struct Item_Struct; +struct ItemData; struct MercTemplate; struct NPCType; struct NewSpawn_Struct; @@ -278,7 +278,7 @@ public: protected: void CalcItemBonuses(StatBonuses* newbon); - void AddItemBonuses(const Item_Struct *item, StatBonuses* newbon); + void AddItemBonuses(const ItemData *item, StatBonuses* newbon); int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat); int16 GetFocusEffect(focusType type, uint16 spell_id); diff --git a/zone/mob.cpp b/zone/mob.cpp index 2829d1a65..f7db3b6fa 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2206,7 +2206,7 @@ bool Mob::CanThisClassDualWield(void) const { // 2HS, 2HB, or 2HP if(pinst && pinst->IsWeapon()) { - const Item_Struct* item = pinst->GetItem(); + const ItemData* item = pinst->GetItem(); if((item->ItemType == ItemType2HBlunt) || (item->ItemType == ItemType2HSlash) || (item->ItemType == ItemType2HPiercing)) return false; @@ -2635,7 +2635,7 @@ int32 Mob::GetEquipmentMaterial(uint8 material_slot) const { uint32 equipmaterial = 0; int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); - const Item_Struct *item; + const ItemData *item; item = database.GetItem(GetEquipment(material_slot)); if (item != 0) @@ -2688,7 +2688,7 @@ int32 Mob::GetHerosForgeModel(uint8 material_slot) const if (material_slot >= 0 && material_slot < MaterialPrimary) { uint32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); - const Item_Struct *item; + const ItemData *item; item = database.GetItem(GetEquipment(material_slot)); int16 invslot = InventoryOld::CalcSlotFromMaterial(material_slot); @@ -2742,7 +2742,7 @@ int32 Mob::GetHerosForgeModel(uint8 material_slot) const uint32 Mob::GetEquipmentColor(uint8 material_slot) const { - const Item_Struct *item; + const ItemData *item; if (armor_tint[material_slot]) { @@ -2758,7 +2758,7 @@ uint32 Mob::GetEquipmentColor(uint8 material_slot) const uint32 Mob::IsEliteMaterialItem(uint8 material_slot) const { - const Item_Struct *item; + const ItemData *item; item = database.GetItem(GetEquipment(material_slot)); if(item != 0) @@ -3669,7 +3669,7 @@ int32 Mob::GetItemStat(uint32 itemid, const char *identifier) if (!inst) return 0; - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); if (!item) return 0; @@ -5367,7 +5367,7 @@ int32 Mob::GetSpellStat(uint32 spell_id, const char *identifier, uint8 slot) bool Mob::CanClassEquipItem(uint32 item_id) { - const Item_Struct* itm = nullptr; + const ItemData* itm = nullptr; itm = database.GetItem(item_id); if (!itm) diff --git a/zone/mob.h b/zone/mob.h index fb8148713..09b8d9d4a 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -38,7 +38,7 @@ class Group; class ItemInst; class NPC; class Raid; -struct Item_Struct; +struct ItemData; struct NewSpawn_Struct; struct PlayerPositionUpdateServer_Struct; @@ -711,7 +711,7 @@ public: inline void SetExtraHaste(int Haste) { ExtraHaste = Haste; } virtual int GetHaste(); - uint8 GetWeaponDamageBonus(const Item_Struct* Weapon); + uint8 GetWeaponDamageBonus(const ItemData* Weapon); uint16 GetDamageTable(SkillUseTypes skillinuse); virtual int GetMonkHandToHandDamage(void); @@ -735,10 +735,10 @@ public: int32 ReduceAllDamage(int32 damage); virtual void DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool HitChance=false, bool CanAvoid=true); - virtual void DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const Item_Struct* AmmoItem=nullptr, uint16 weapon_damage=0, int16 chance_mod=0,int16 focus=0, int ReuseTime=0, uint32 range_id=0, int AmmoSlot=0, float speed = 4.0f); + virtual void DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const ItemData* AmmoItem=nullptr, uint16 weapon_damage=0, int16 chance_mod=0,int16 focus=0, int ReuseTime=0, uint32 range_id=0, int AmmoSlot=0, float speed = 4.0f); virtual void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes skillinuse, int16 chance_mod=0, int16 focus=0, bool CanRiposte=false, int ReuseTime=0); - virtual void DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const ItemInst* Ammo=nullptr, uint16 weapon_damage=0, int16 chance_mod=0, int16 focus=0, int ReuseTime=0, uint32 range_id=0, uint32 ammo_id=0, const Item_Struct *AmmoItem=nullptr, int AmmoSlot=0, float speed= 4.0f); - bool TryProjectileAttack(Mob* other, const Item_Struct *item, SkillUseTypes skillInUse, uint16 weapon_dmg, const ItemInst* RangeWeapon, const ItemInst* Ammo, int AmmoSlot, float speed); + virtual void DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon=nullptr, const ItemInst* Ammo=nullptr, uint16 weapon_damage=0, int16 chance_mod=0, int16 focus=0, int ReuseTime=0, uint32 range_id=0, uint32 ammo_id=0, const ItemData *AmmoItem=nullptr, int AmmoSlot=0, float speed= 4.0f); + bool TryProjectileAttack(Mob* other, const ItemData *item, SkillUseTypes skillInUse, uint16 weapon_dmg, const ItemInst* RangeWeapon, const ItemInst* Ammo, int AmmoSlot, float speed); void ProjectileAttack(); inline bool HasProjectileAttack() const { return ActiveProjectileATK; } inline void SetProjectileAttack(bool value) { ActiveProjectileATK = value; } @@ -858,7 +858,7 @@ public: // HP Event inline int GetNextHPEvent() const { return nexthpevent; } void SetNextHPEvent( int hpevent ); - void SendItemAnimation(Mob *to, const Item_Struct *item, SkillUseTypes skillInUse, float velocity= 4.0); + void SendItemAnimation(Mob *to, const ItemData *item, SkillUseTypes skillInUse, float velocity= 4.0); inline int& GetNextIncHPEvent() { return nextinchpevent; } void SetNextIncHPEvent( int inchpevent ); @@ -1038,8 +1038,8 @@ protected: bool PassLimitToSkill(uint16 spell_id, uint16 skill); bool PassLimitClass(uint32 Classes_, uint16 Class_); void TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary); - void TryWeaponProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = MainPrimary); - void TrySpellProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = MainPrimary); + void TryWeaponProc(const ItemInst* inst, const ItemData* weapon, Mob *on, uint16 hand = MainPrimary); + void TrySpellProc(const ItemInst* inst, const ItemData* weapon, Mob *on, uint16 hand = MainPrimary); void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary); void ExecWeaponProc(const ItemInst* weapon, uint16 spell_id, Mob *on); virtual float GetProcChances(float ProcBonus, uint16 hand = MainPrimary); @@ -1048,7 +1048,7 @@ protected: virtual float GetAssassinateProcChances(uint16 ReuseTime); virtual float GetSkillProcChances(uint16 ReuseTime, uint16 hand = 0); // hand = MainCharm? uint16 GetWeaponSpeedbyHand(uint16 hand); - int GetWeaponDamage(Mob *against, const Item_Struct *weapon_item); + int GetWeaponDamage(Mob *against, const ItemData *weapon_item); int GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate = nullptr); int GetKickDamage(); int GetBashDamage(); diff --git a/zone/mod_functions.cpp b/zone/mod_functions.cpp index 6ae0eddad..c5cbce9ec 100644 --- a/zone/mod_functions.cpp +++ b/zone/mod_functions.cpp @@ -9,7 +9,7 @@ class ItemInst; class Spawn2; struct Consider_Struct; struct DBTradeskillRecipe_Struct; -struct Item_Struct; +struct ItemData; extern EntityList entity_list; extern Zone* zone; @@ -26,7 +26,7 @@ void Zone::mod_repop() { return; } void NPC::mod_prespawn(Spawn2 *sp) { return; } //Base damage from NPC::Attack -int NPC::mod_npc_damage(int damage, SkillUseTypes skillinuse, int hand, const Item_Struct* weapon, Mob* other) { return(damage); } +int NPC::mod_npc_damage(int damage, SkillUseTypes skillinuse, int hand, const ItemData* weapon, Mob* other) { return(damage); } //Mob c has been given credit for a kill. This is called after the regular EVENT_KILLED_MERIT event. void NPC::mod_npc_killed_merit(Mob* c) { return; } @@ -104,8 +104,8 @@ int32 Client::mod_client_xp(int32 in_xp, NPC *npc) { return(in_xp); } uint32 Client::mod_client_xp_for_level(uint32 xp, uint16 check_level) { return(xp); } //Food and drink values as computed by consume requests. Return < 0 to abort the request. -int Client::mod_food_value(const Item_Struct *item, int change) { return(change); } -int Client::mod_drink_value(const Item_Struct *item, int change) { return(change); } +int Client::mod_food_value(const ItemData *item, int change) { return(change); } +int Client::mod_drink_value(const ItemData *item, int change) { return(change); } //effect_vallue - Spell effect value as calculated by default formulas. You will want to ignore effects that don't lend themselves to scaling - pet ID's, gate coords, etc. int Mob::mod_effect_value(int effect_value, uint16 spell_id, int effect_type, Mob* caster) { return(effect_value); } diff --git a/zone/npc.cpp b/zone/npc.cpp index 20648db3c..a7c22ffed 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -27,7 +27,7 @@ #include "../common/clientversions.h" #include "../common/features.h" #include "../common/item.h" -#include "../common/item_struct.h" +#include "../common/item_data.h" #include "../common/linked_list.h" #include "../common/servertalk.h" @@ -509,7 +509,7 @@ void NPC::QueryLoot(Client* to) int x = 0; for(ItemList::iterator cur = itemlist.begin(); cur != itemlist.end(); ++cur, ++x) { - const Item_Struct* item = database.GetItem((*cur)->item_id); + const ItemData* item = database.GetItem((*cur)->item_id); if (item == nullptr) { Log.Out(Logs::General, Logs::Error, "Database error, invalid item"); continue; @@ -1375,7 +1375,7 @@ void NPC::PickPocket(Client* thief) { end = itemlist.end(); for(; cur != end && x < 49; ++cur) { ServerLootItem_Struct* citem = *cur; - const Item_Struct* item = database.GetItem(citem->item_id); + const ItemData* item = database.GetItem(citem->item_id); if (item) { inst = database.CreateItem(item, citem->charges); @@ -1401,7 +1401,7 @@ void NPC::PickPocket(Client* thief) { inst = database.CreateItem(steal_items[random], charges[random]); if (inst) { - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); if (item) { if (/*item->StealSkill || */steal_skill >= stealchance) diff --git a/zone/npc.h b/zone/npc.h index ee3dedf62..ecca9dec4 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -90,7 +90,7 @@ class Client; class Group; class Raid; class Spawn2; -struct Item_Struct; +struct ItemData; class NPC : public Mob { @@ -172,7 +172,7 @@ public: virtual void SpellProcess(); virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho); - void AddItem(const Item_Struct* item, uint16 charges, bool equipitem = true); + void AddItem(const ItemData* item, uint16 charges, bool equipitem = true); void AddItem(uint32 itemid, uint16 charges, bool equipitem = true); void AddLootTable(); void AddLootTable(uint32 ldid); @@ -264,7 +264,7 @@ public: bool IsTaunting() const { return taunting; } void PickPocket(Client* thief); void StartSwarmTimer(uint32 duration) { swarm_timer.Start(duration); } - void AddLootDrop(const Item_Struct*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false); + void AddLootDrop(const ItemData*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false); virtual void DoClassAttacks(Mob *target); void CheckSignal(); inline bool IsNotTargetableWithHotkey() const { return no_target_hotkey; } @@ -394,7 +394,7 @@ public: void SetMerchantProbability(uint8 amt) { probability = amt; } uint8 GetMerchantProbability() { return probability; } void mod_prespawn(Spawn2 *sp); - int mod_npc_damage(int damage, SkillUseTypes skillinuse, int hand, const Item_Struct* weapon, Mob* other); + int mod_npc_damage(int damage, SkillUseTypes skillinuse, int hand, const ItemData* weapon, Mob* other); void mod_npc_killed_merit(Mob* c); void mod_npc_killed(Mob* oos); void AISpellsList(Client *c); diff --git a/zone/object.cpp b/zone/object.cpp index 7dd97d355..4cdf1b0ad 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -138,7 +138,7 @@ Object::Object(Client* client, const ItemInst* inst) // Set object name if (inst) { - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); if (item && item->IDFile) { if (strlen(item->IDFile) == 0) { strcpy(m_data.object_name, DEFAULT_OBJECT_NAME); @@ -194,7 +194,7 @@ Object::Object(const ItemInst *inst, float x, float y, float z, float heading, u // Set object name if (inst) { - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); if (item && item->IDFile) { if (strlen(item->IDFile) == 0) { strcpy(m_data.object_name, DEFAULT_OBJECT_NAME); @@ -860,7 +860,7 @@ uint32 Object::GetItemID() return 0; } - const Item_Struct* item = this->m_inst->GetItem(); + const ItemData* item = this->m_inst->GetItem(); if (item == 0) { diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index a28d51376..471697a3c 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -8054,7 +8054,7 @@ XS(XS_Mob_DoThrowingAttackDmg) Mob * THIS; Mob* target; ItemInst* RangeWeapon = nullptr; - Item_Struct* item = nullptr; + ItemData* item = nullptr; uint16 weapon_damage = (uint16)SvIV(ST(4)); int16 chance_mod = (int16)SvIV(ST(5)); int16 focus = (int16)SvIV(ST(6)); diff --git a/zone/pets.cpp b/zone/pets.cpp index aaec461d4..f4a5ac7b1 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -407,7 +407,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, // like the special back items some focused pets may receive. uint32 petinv[EmuConstants::EQUIPMENT_SIZE]; memset(petinv, 0, sizeof(petinv)); - const Item_Struct *item = 0; + const ItemData *item = 0; if (database.GetBasePetItems(record.equipmentset, petinv)) { for (int i = 0; iNoDrop != 0) { //dont bother saving item charges for now, NPCs never use them //and nobody should be able to get them off the corpse..? diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 97992e0bc..38d90b848 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -737,7 +737,7 @@ void QuestManager::traindisc(int discipline_tome_item_id) { } bool QuestManager::isdisctome(int item_id) { - const Item_Struct *item = database.GetItem(item_id); + const ItemData *item = database.GetItem(item_id); if(item == nullptr) { return(false); } @@ -1227,7 +1227,7 @@ void QuestManager::settime(uint8 new_hour, uint8 new_min) { void QuestManager::itemlink(int item_id) { QuestManagerCurrentQuestVars(); if (initiator) { - const Item_Struct* item = database.GetItem(item_id); + const ItemData* item = database.GetItem(item_id); if (item == nullptr) return; @@ -2425,7 +2425,7 @@ void QuestManager::MerchantSetItem(uint32 NPCid, uint32 itemid, uint32 quantity) if (merchant == 0 || !merchant->IsNPC() || (merchant->GetClass() != MERCHANT)) return; // don't do anything if NPCid isn't a merchant - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; item = database.GetItem(itemid); if (!item) return; // if the item id doesn't correspond to a real item, do nothing @@ -2438,7 +2438,7 @@ uint32 QuestManager::MerchantCountItem(uint32 NPCid, uint32 itemid) { if (merchant == 0 || !merchant->IsNPC() || (merchant->GetClass() != MERCHANT)) return 0; // if it isn't a merchant, it doesn't have any items - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; item = database.GetItem(itemid); if (!item) return 0; // if it isn't a valid item, the merchant doesn't have any @@ -2461,7 +2461,7 @@ uint32 QuestManager::MerchantCountItem(uint32 NPCid, uint32 itemid) { // Item Link for use in Variables - "my $example_link = quest::varlink(item_id);" const char* QuestManager::varlink(char* perltext, int item_id) { QuestManagerCurrentQuestVars(); - const Item_Struct* item = database.GetItem(item_id); + const ItemData* item = database.GetItem(item_id); if (!item) return "INVALID ITEM ID IN VARLINK"; diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index c0844c2ac..9804cee19 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -119,7 +119,7 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, { hate += item->GetItem()->AC; } - const Item_Struct *itm = item->GetItem(); + const ItemData *itm = item->GetItem(); hate = hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100; } } @@ -474,7 +474,7 @@ int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type) } } else{ - if(GetWeaponDamage(other, (const Item_Struct*)nullptr) <= 0){ + if(GetWeaponDamage(other, (const ItemData*)nullptr) <= 0){ ndamage = -5; } } @@ -705,8 +705,8 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { return; } - const Item_Struct* RangeItem = RangeWeapon->GetItem(); - const Item_Struct* AmmoItem = Ammo->GetItem(); + const ItemData* RangeItem = RangeWeapon->GetItem(); + const ItemData* AmmoItem = Ammo->GetItem(); if(RangeItem->ItemType != ItemTypeBow) { Log.Out(Logs::Detail, Logs::Combat, "Ranged attack canceled. Ranged item is not a bow. type %d.", RangeItem->ItemType); @@ -730,7 +730,7 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { const ItemInst *pi = m_inv[r]; if(pi == nullptr || !pi->IsType(ItemClassContainer)) continue; - const Item_Struct* bagitem = pi->GetItem(); + const ItemData* bagitem = pi->GetItem(); if(!bagitem || bagitem->BagType != BagTypeQuiver) continue; @@ -809,7 +809,7 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { } void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemInst* Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime, - uint32 range_id, uint32 ammo_id, const Item_Struct *AmmoItem, int AmmoSlot, float speed) { + uint32 range_id, uint32 ammo_id, const ItemData *AmmoItem, int AmmoSlot, float speed) { if ((other == nullptr || ((IsClient() && CastToClient()->dead) || @@ -824,7 +824,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite const ItemInst* _RangeWeapon = nullptr; const ItemInst* _Ammo = nullptr; - const Item_Struct* ammo_lost = nullptr; + const ItemData* ammo_lost = nullptr; /* If LaunchProjectile is false this function will do archery damage on target, @@ -1017,7 +1017,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite } } -bool Mob::TryProjectileAttack(Mob* other, const Item_Struct *item, SkillUseTypes skillInUse, uint16 weapon_dmg, const ItemInst* RangeWeapon, const ItemInst* Ammo, int AmmoSlot, float speed){ +bool Mob::TryProjectileAttack(Mob* other, const ItemData *item, SkillUseTypes skillInUse, uint16 weapon_dmg, const ItemInst* RangeWeapon, const ItemInst* Ammo, int AmmoSlot, float speed){ if (!other) return false; @@ -1322,7 +1322,7 @@ void NPC::DoRangedAttackDmg(Mob* other, bool Launch, int16 damage_mod, int16 cha //try proc on hits and misses if(other && !other->HasDied()) - TrySpellProc(nullptr, (const Item_Struct*)nullptr, other, MainRange); + TrySpellProc(nullptr, (const ItemData*)nullptr, other, MainRange); if (HasSkillProcs() && other && !other->HasDied()) TrySkillProc(other, skillInUse, 0, false, MainRange); @@ -1376,7 +1376,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51 return; } - const Item_Struct* item = RangeWeapon->GetItem(); + const ItemData* item = RangeWeapon->GetItem(); if(item->ItemType != ItemTypeLargeThrowing && item->ItemType != ItemTypeSmallThrowing) { Log.Out(Logs::Detail, Logs::Combat, "Ranged attack canceled. Ranged item %d is not a throwing weapon. type %d.", item->ItemType); Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have nothing useful to throw!", GetItemIDAt(MainRange)); @@ -1437,7 +1437,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51 CommonBreakInvisible(); } -void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* AmmoItem, uint16 weapon_damage, int16 chance_mod,int16 focus, int ReuseTime, uint32 range_id, int AmmoSlot, float speed) +void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemData* AmmoItem, uint16 weapon_damage, int16 chance_mod,int16 focus, int ReuseTime, uint32 range_id, int AmmoSlot, float speed) { if ((other == nullptr || ((IsClient() && CastToClient()->dead) || @@ -1451,7 +1451,7 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite } const ItemInst* _RangeWeapon = nullptr; - const Item_Struct* ammo_lost = nullptr; + const ItemData* ammo_lost = nullptr; /* If LaunchProjectile is false this function will do archery damage on target, @@ -1575,7 +1575,7 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite } } -void Mob::SendItemAnimation(Mob *to, const Item_Struct *item, SkillUseTypes skillInUse, float velocity) { +void Mob::SendItemAnimation(Mob *to, const ItemData *item, SkillUseTypes skillInUse, float velocity) { EQApplicationPacket *outapp = new EQApplicationPacket(OP_SomeItemPacketMaybe, sizeof(Arrow_Struct)); Arrow_Struct *as = (Arrow_Struct *) outapp->pBuffer; as->type = 1; @@ -1625,7 +1625,7 @@ void Mob::ProjectileAnimation(Mob* to, int item_id, bool IsArrow, float speed, f if (!to) return; - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; uint8 item_type = 0; if(!item_id) { @@ -1766,7 +1766,7 @@ void NPC::DoClassAttacks(Mob *target) { DoAnim(animKick); int32 dmg = 0; - if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){ + if(GetWeaponDamage(target, (const ItemData*)nullptr) <= 0){ dmg = -5; } else{ @@ -1787,7 +1787,7 @@ void NPC::DoClassAttacks(Mob *target) { DoAnim(animTailRake); int32 dmg = 0; - if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){ + if(GetWeaponDamage(target, (const ItemData*)nullptr) <= 0){ dmg = -5; } else{ @@ -1840,7 +1840,7 @@ void NPC::DoClassAttacks(Mob *target) { DoAnim(animKick); int32 dmg = 0; - if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){ + if(GetWeaponDamage(target, (const ItemData*)nullptr) <= 0){ dmg = -5; } else{ @@ -1865,7 +1865,7 @@ void NPC::DoClassAttacks(Mob *target) { DoAnim(animTailRake); int32 dmg = 0; - if(GetWeaponDamage(target, (const Item_Struct*)nullptr) <= 0){ + if(GetWeaponDamage(target, (const ItemData*)nullptr) <= 0){ dmg = -5; } else{ @@ -2377,7 +2377,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes int32 max_hit = (2 * weapon_damage*GetDamageTable(skillinuse)) / 100; if(GetLevel() >= 28 && IsWarriorClass() ) { - int ucDamageBonus = GetWeaponDamageBonus((const Item_Struct*) nullptr ); + int ucDamageBonus = GetWeaponDamageBonus((const ItemData*) nullptr ); min_hit += (int) ucDamageBonus; max_hit += (int) ucDamageBonus; hate += ucDamageBonus; @@ -2390,7 +2390,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes if(item->GetItem()->ItemType == ItemTypeShield) { hate += item->GetItem()->AC; } - const Item_Struct *itm = item->GetItem(); + const ItemData *itm = item->GetItem(); hate = hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100; } } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 24eac51ee..d4a03949d 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -1143,7 +1143,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_SummonItem: { - const Item_Struct *item = database.GetItem(spell.base[i]); + const ItemData *item = database.GetItem(spell.base[i]); #ifdef SPELL_EFFECT_SPAM const char *itemname = item ? item->Name : "*Unknown Item*"; snprintf(effect_desc, _EDLEN, "Summon Item: %s (id %d)", itemname, spell.base[i]); @@ -1179,7 +1179,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) } case SE_SummonItemIntoBag: { - const Item_Struct *item = database.GetItem(spell.base[i]); + const ItemData *item = database.GetItem(spell.base[i]); #ifdef SPELL_EFFECT_SPAM const char *itemname = item ? item->Name : "*Unknown Item*"; snprintf(effect_desc, _EDLEN, "Summon Item In Bag: %s (id %d)", itemname, spell.base[i]); @@ -5191,7 +5191,7 @@ int16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) { //item focus if (itembonuses.FocusEffects[type]){ - const Item_Struct* TempItem = 0; + const ItemData* TempItem = 0; for(int x = EmuConstants::EQUIPMENT_BEGIN; x <= EmuConstants::EQUIPMENT_END; x++) { @@ -5222,7 +5222,7 @@ int16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) { aug = ins->GetAugment(y); if(aug) { - const Item_Struct* TempItemAug = aug->GetItem(); + const ItemData* TempItemAug = aug->GetItem(); if (TempItemAug && TempItemAug->Focus.Effect > 0 && IsValidSpell(TempItemAug->Focus.Effect)) { proc_spellid = CalcFocusEffect(type, TempItemAug->Focus.Effect, spell_id); if (IsValidSpell(proc_spellid)){ @@ -5317,8 +5317,8 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) { //Check if item focus effect exists for the client. if (itembonuses.FocusEffects[type]){ - const Item_Struct* TempItem = 0; - const Item_Struct* UsedItem = 0; + const ItemData* TempItem = 0; + const ItemData* UsedItem = 0; uint16 UsedFocusID = 0; int16 Total = 0; int16 focus_max = 0; @@ -5365,7 +5365,7 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) { aug = ins->GetAugment(y); if(aug) { - const Item_Struct* TempItemAug = aug->GetItem(); + const ItemData* TempItemAug = aug->GetItem(); if (TempItemAug && TempItemAug->Focus.Effect > 0 && TempItemAug->Focus.Effect != SPELL_UNKNOWN) { if(rand_effectiveness) { focus_max = CalcFocusEffect(type, TempItemAug->Focus.Effect, spell_id, true); @@ -5548,8 +5548,8 @@ int16 NPC::GetFocusEffect(focusType type, uint16 spell_id) { if (RuleB(Spells, NPC_UseFocusFromItems) && itembonuses.FocusEffects[type]){ - const Item_Struct* TempItem = 0; - const Item_Struct* UsedItem = 0; + const ItemData* TempItem = 0; + const ItemData* UsedItem = 0; uint16 UsedFocusID = 0; int16 Total = 0; int16 focus_max = 0; @@ -5557,7 +5557,7 @@ int16 NPC::GetFocusEffect(focusType type, uint16 spell_id) { //item focus for(int i = 0; i < EmuConstants::EQUIPMENT_SIZE; i++){ - const Item_Struct *cur = database.GetItem(equipment[i]); + const ItemData *cur = database.GetItem(equipment[i]); if(!cur) continue; diff --git a/zone/spells.cpp b/zone/spells.cpp index 849dacfbe..39badf5b6 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -1140,7 +1140,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, missingreags=true; } - const Item_Struct *item = database.GetItem(component); + const ItemData *item = database.GetItem(component); if(item) { c->Message_StringID(13, MISSING_SPELL_COMP_ITEM, item->Name); Log.Out(Logs::Detail, Logs::Spells, "Spell %d: Canceled. Missing required reagent %s (%d)", spell_id, item->Name, component); @@ -1200,7 +1200,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, { bool fromaug = false; const ItemInst* inst = CastToClient()->GetInv()[inventory_slot]; - Item_Struct* augitem = 0; + ItemData* augitem = 0; uint32 recastdelay = 0; uint32 recasttype = 0; @@ -1213,7 +1213,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, if (!aug_i) continue; - const Item_Struct* aug = aug_i->GetItem(); + const ItemData* aug = aug_i->GetItem(); if (!aug) continue; @@ -1249,7 +1249,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, if (inst && inst->IsType(ItemClassCommon) && (inst->GetItem()->Click.Effect == spell_id) && inst->GetCharges() || fromaug) { - //const Item_Struct* item = inst->GetItem(); + //const ItemData* item = inst->GetItem(); int16 charges = inst->GetItem()->MaxCharges; if(fromaug) { charges = -1; } //Don't destroy the parent item diff --git a/zone/tasks.cpp b/zone/tasks.cpp index 4f3fe8124..96acb1487 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -1866,7 +1866,7 @@ void ClientTaskState::RewardTask(Client *c, TaskInformation *Task) { if(!Task || !c) return; - const Item_Struct* Item; + const ItemData* Item; std::vector RewardList; switch(Task->RewardMethod) { @@ -2759,7 +2759,7 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN } if(ItemID) { - const Item_Struct* reward_item = database.GetItem(ItemID); + const ItemData* reward_item = database.GetItem(ItemID); Client::TextLink linker; linker.SetLinkType(linker.linkItemData); diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index cc8a37a69..4e3262de1 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -61,7 +61,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme inst = user_inv.GetItem(in_augment->container_slot); if (inst) { - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); if (item && inst->IsType(ItemClassContainer) && item->BagType == 53) { // We have found an appropriate inventory augmentation sealer @@ -267,7 +267,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob else { inst = user_inv.GetItem(in_combine->container_slot); if (inst) { - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); if (item && inst->IsType(ItemClassContainer)) { c_type = item->BagType; some_id = item->ID; @@ -285,7 +285,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob const ItemInst* inst = container->GetItem(0); bool AllowAll = RuleB(Inventory, AllowAnyWeaponTransformation); if (inst && ItemInst::CanTransform(inst->GetItem(), container->GetItem(), AllowAll)) { - const Item_Struct* new_weapon = inst->GetItem(); + const ItemData* new_weapon = inst->GetItem(); user->DeleteItemInInventory(InventoryOld::CalcSlotId(in_combine->container_slot, 0), 0, true); container->Clear(); user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), MainCursor, container->GetItem()->Icon, atoi(container->GetItem()->IDFile + 2)); @@ -305,7 +305,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob if (container->GetItem() && container->GetItem()->BagType == BagTypeDetransformationmold) { const ItemInst* inst = container->GetItem(0); if (inst && inst->GetOrnamentationIcon() && inst->GetOrnamentationIcon()) { - const Item_Struct* new_weapon = inst->GetItem(); + const ItemData* new_weapon = inst->GetItem(); user->DeleteItemInInventory(InventoryOld::CalcSlotId(in_combine->container_slot, 0), 0, true); container->Clear(); user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), MainCursor, 0, 0); @@ -529,7 +529,7 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac for(std::list::iterator it = MissingItems.begin(); it != MissingItems.end(); ++it) { - const Item_Struct* item = database.GetItem(*it); + const ItemData* item = database.GetItem(*it); if(item) user->Message_StringID(MT_Skills, TRADESKILL_MISSING_ITEM, item->Name); @@ -953,7 +953,7 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { break; } } - const Item_Struct* item = nullptr; + const ItemData* item = nullptr; if (spec->tradeskill == SkillBlacksmithing) { switch(GetAA(aaBlacksmithingMastery)) { @@ -1202,7 +1202,7 @@ bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint3 if (!inst) continue; - const Item_Struct* item = GetItem(inst->GetItem()->ID); + const ItemData* item = GetItem(inst->GetItem()->ID); if (!item) continue; @@ -1331,7 +1331,7 @@ bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint3 if(!inst) continue; - const Item_Struct* item = GetItem(inst->GetItem()->ID); + const ItemData* item = GetItem(inst->GetItem()->ID); if (!item) continue; diff --git a/zone/trading.cpp b/zone/trading.cpp index 8d498c034..5a41e7b74 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -885,7 +885,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st continue; } - const Item_Struct* item = inst->GetItem(); + const ItemData* item = inst->GetItem(); if(item && quest_npc == false) { // if it was not a NO DROP or Attuned item (or if a GM is trading), let the NPC have it if(GetGM() || (item->NoDrop != 0 && inst->IsAttuned() == false)) { @@ -894,7 +894,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st for(int16 bslot = SUB_BEGIN; bslot < item->BagSlots; bslot++) { const ItemInst* baginst = inst->GetItem(bslot); if (baginst) { - const Item_Struct* bagitem = baginst->GetItem(); + const ItemData* bagitem = baginst->GetItem(); if (bagitem && (GetGM() || (bagitem->NoDrop != 0 && baginst->IsAttuned() == false))) { tradingWith->CastToNPC()->AddLootDrop(bagitem, &tradingWith->CastToNPC()->itemlist, baginst->GetCharges(), 1, 127, true, true); @@ -1158,7 +1158,7 @@ void Client::SendTraderItem(uint32 ItemID, uint16 Quantity) { std::string Packet; int16 FreeSlotID=0; - const Item_Struct* item = database.GetItem(ItemID); + const ItemData* item = database.GetItem(ItemID); if(!item){ Log.Out(Logs::Detail, Logs::Trading, "Bogus item deleted in Client::SendTraderItem!\n"); @@ -1192,7 +1192,7 @@ void Client::SendSingleTraderItem(uint32 CharID, int SerialNumber) { } void Client::BulkSendTraderInventory(uint32 char_id) { - const Item_Struct *item; + const ItemData *item; TraderCharges_Struct* TraderItems = database.LoadTraderItemWithCharges(char_id); @@ -2021,7 +2021,7 @@ static void UpdateTraderCustomerItemsAdded(uint32 CustomerID, TraderCharges_Stru if(!Customer) return; - const Item_Struct *item = database.GetItem(ItemID); + const ItemData *item = database.GetItem(ItemID); if(!item) return; @@ -2065,7 +2065,7 @@ static void UpdateTraderCustomerPriceChanged(uint32 CustomerID, TraderCharges_St if(!Customer) return; - const Item_Struct *item = database.GetItem(ItemID); + const ItemData *item = database.GetItem(ItemID); if(!item) return; @@ -2224,7 +2224,7 @@ void Client::HandleTraderPriceUpdate(const EQApplicationPacket *app) { } - const Item_Struct *item = 0; + const ItemData *item = 0; if(IDOfItemToAdd) item = database.GetItem(IDOfItemToAdd); @@ -2390,7 +2390,7 @@ void Client::SendBuyerResults(char* searchString, uint32 searchID) { char *buf = (char *)outapp->pBuffer; - const Item_Struct* item = database.GetItem(itemID); + const ItemData* item = database.GetItem(itemID); if(!item) continue; @@ -2482,7 +2482,7 @@ void Client::ShowBuyLines(const EQApplicationPacket *app) { char *Buf = (char *)outapp->pBuffer; - const Item_Struct* item = database.GetItem(ItemID); + const ItemData* item = database.GetItem(ItemID); if(!item) continue; @@ -2524,7 +2524,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) { /*uint32 BuyerID2 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused /*uint32 Unknown3 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused - const Item_Struct *item = database.GetItem(ItemID); + const ItemData *item = database.GetItem(ItemID); if(!item || !Quantity || !Price || !QtyBuyerWants) return; @@ -2915,7 +2915,7 @@ void Client::UpdateBuyLine(const EQApplicationPacket *app) { /*uint32 UnknownZ =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused uint32 ItemCount = VARSTRUCT_DECODE_TYPE(uint32, Buf); - const Item_Struct *item = database.GetItem(ItemID); + const ItemData *item = database.GetItem(ItemID); if(!item) return; @@ -2979,7 +2979,7 @@ void Client::BuyerItemSearch(const EQApplicationPacket *app) { BuyerItemSearchResults_Struct* bisr = (BuyerItemSearchResults_Struct*)outapp->pBuffer; - const Item_Struct* item = 0; + const ItemData* item = 0; int Count=0; diff --git a/zone/tune.cpp b/zone/tune.cpp index 4153d5b84..cf0c394c3 100644 --- a/zone/tune.cpp +++ b/zone/tune.cpp @@ -630,7 +630,7 @@ int32 Client::GetMeleeDamage(Mob* other, bool GetMinDamage) if( Hand == MainPrimary && GetLevel() >= 28 && IsWarriorClass() ) { - ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const Item_Struct*) nullptr ); + ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const ItemData*) nullptr ); min_hit += (int) ucDamageBonus; max_hit += (int) ucDamageBonus; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index b99024c5c..88ae237c5 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -629,7 +629,7 @@ ItemInst* ZoneDatabase::LoadSingleTraderItem(uint32 CharID, int SerialNumber) { int Charges = atoi(row[3]); int Cost = atoi(row[4]); - const Item_Struct *item = database.GetItem(ItemID); + const ItemData *item = database.GetItem(ItemID); if(!item) { Log.Out(Logs::Detail, Logs::Trading, "Unable to create item\n"); @@ -684,7 +684,7 @@ void ZoneDatabase::UpdateTraderItemPrice(int CharID, uint32 ItemID, uint32 Charg Log.Out(Logs::Detail, Logs::Trading, "ZoneDatabase::UpdateTraderPrice(%i, %i, %i, %i)", CharID, ItemID, Charges, NewPrice); - const Item_Struct *item = database.GetItem(ItemID); + const ItemData *item = database.GetItem(ItemID); if(!item) return; @@ -1225,7 +1225,7 @@ bool ZoneDatabase::LoadCharacterPotions(uint32 character_id, PlayerProfile_Struc for (auto row = results.begin(); row != results.end(); ++row) { i = atoi(row[0]); /* Potion belt slot number */ uint32 item_id = atoi(row[1]); - const Item_Struct *item = database.GetItem(item_id); + const ItemData *item = database.GetItem(item_id); if(!item) continue; From a5274b9b6e52c6bf92be03de890503a825339628 Mon Sep 17 00:00:00 2001 From: KimLS Date: Wed, 18 Feb 2015 20:29:58 -0800 Subject: [PATCH 03/27] InventoryOld in client has been unhooked from loading/saving --- common/database.h | 1 + common/inventory.cpp | 18 ++ common/inventory.h | 24 +++ common/item_instance.cpp | 51 +++++ common/item_instance.h | 22 +++ common/shareddb.cpp | 408 ++++++++++++++++++++------------------- common/shareddb.h | 3 +- zone/client_packet.cpp | 2 +- zone/client_process.cpp | 50 ----- zone/mob.h | 6 + 10 files changed, 331 insertions(+), 254 deletions(-) diff --git a/common/database.h b/common/database.h index b28fd4d8f..c71d767df 100644 --- a/common/database.h +++ b/common/database.h @@ -27,6 +27,7 @@ #include "dbcore.h" #include "linked_list.h" #include "eq_packet_structs.h" +#include "inventory.h" #include #include diff --git a/common/inventory.cpp b/common/inventory.cpp index b63ba4eaf..5ca07becf 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -18,3 +18,21 @@ #include "inventory.h" +EQEmu::Inventory::Inventory() { +} + +EQEmu::Inventory::~Inventory() { +} + +std::shared_ptr EQEmu::Inventory::GetItem(InventoryType type, int16 slot) { + auto area = items_.find(type); + + if(area != items_.end()) { + auto item = area->second.find(slot); + if(item != area->second.end()) { + return item->second; + } + } + + return std::shared_ptr(nullptr); +} \ No newline at end of file diff --git a/common/inventory.h b/common/inventory.h index 9816bd8dd..163a5be57 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -19,12 +19,36 @@ #ifndef COMMON_INVENTORY_H #define COMMON_INVENTORY_H +#include "item_instance.h" +#include +#include +#include + namespace EQEmu { + enum InventoryType : int16 + { + InvTypePersonal, + InvTypeBank, + InvTypeSharedBank, + InvTypeTrade, + InvTypeWorld, + InvTypeCursorBuffer, + InvTypeTribute, + InvTypeTrophyTribute, + InvTypeGuildTribute + }; + class Inventory { public: + Inventory(); + ~Inventory(); + + std::shared_ptr GetItem(InventoryType type, int16 slot); + private: + std::map>> items_; }; } // EQEmu diff --git a/common/item_instance.cpp b/common/item_instance.cpp index 0a8fb4940..9427ec890 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -17,3 +17,54 @@ */ #include "item_instance.h" +#include "data_verification.h" + +EQEmu::ItemInstance::ItemInstance() { + base_item_ = nullptr; + modified_item_ = nullptr; + charges_ = -1; + color_ = 0; + attuned_ = false; + ornament_idfile_ = 0; + ornament_icon_ = 0; + ornament_hero_model_ = 0; + tracking_id_ = 0; +} + +EQEmu::ItemInstance::ItemInstance(const ItemData* idata) { + base_item_ = idata; + modified_item_ = nullptr; + charges_ = -1; + color_ = 0; + attuned_ = false; + ornament_idfile_ = 0; + ornament_icon_ = 0; + ornament_hero_model_ = 0; + tracking_id_ = 0; +} + +EQEmu::ItemInstance::ItemInstance(const ItemData* idata, int16 charges) { + base_item_ = idata; + modified_item_ = nullptr; + charges_ = charges; + color_ = 0; + attuned_ = false; + ornament_idfile_ = 0; + ornament_icon_ = 0; + ornament_hero_model_ = 0; + tracking_id_ = 0; +} + +EQEmu::ItemInstance::~ItemInstance() { +} + +std::shared_ptr EQEmu::ItemInstance::GetItem(int index) { + if(EQEmu::ValueWithin(index, 0, 200)) { + auto iter = contents_.find(index); + if(iter != contents_.end()) { + return iter->second; + } + } + + return std::shared_ptr(nullptr); +} diff --git a/common/item_instance.h b/common/item_instance.h index 8ba559681..582e80164 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -19,12 +19,34 @@ #ifndef COMMON_ITEM_INSTANCE_H #define COMMON_ITEM_INSTANCE_H +#include "item_data.h" +#include +#include +#include + namespace EQEmu { class ItemInstance { public: + ItemInstance(); + ItemInstance(const ItemData* idata); + ItemInstance(const ItemData* idata, int16 charges); + ~ItemInstance(); + + std::shared_ptr GetItem(int index); private: + const ItemData *base_item_; + ItemData *modified_item_; + int16 charges_; + uint32 color_; + bool attuned_; + std::string custom_data_; + uint32 ornament_idfile_; + uint32 ornament_icon_; + uint32 ornament_hero_model_; + uint64 tracking_id_; + std::map> contents_; }; } // EQEmu diff --git a/common/shareddb.cpp b/common/shareddb.cpp index c1766b5c0..7b0863bca 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -151,74 +151,77 @@ bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const Ite bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 slot_id) { - // If we never save tribute slots..how are we to ever benefit from them!!? The client - // object is destroyed upon zoning - including its inventory object..and if tributes - // don't exist in the database, then they will never be loaded when the new client - // object is created in the new zone object... Something to consider... -U + return true; + //// If we never save tribute slots..how are we to ever benefit from them!!? The client + //// object is destroyed upon zoning - including its inventory object..and if tributes + //// don't exist in the database, then they will never be loaded when the new client + //// object is created in the new zone object... Something to consider... -U + //// + //// (we could add them to the 'NoRent' checks and dispose of after 30 minutes offline) // - // (we could add them to the 'NoRent' checks and dispose of after 30 minutes offline) - - //never save tribute slots: - if(slot_id >= EmuConstants::TRIBUTE_BEGIN && slot_id <= EmuConstants::TRIBUTE_END) - return true; - - if (slot_id >= EmuConstants::SHARED_BANK_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) { - // Shared bank inventory - if (!inst) - return DeleteSharedBankSlot(char_id, slot_id); - else - return UpdateSharedBankSlot(char_id, inst, slot_id); - } - else if (!inst) { // All other inventory - return DeleteInventorySlot(char_id, slot_id); - } - - return UpdateInventorySlot(char_id, inst, slot_id); + ////never save tribute slots: + //if(slot_id >= EmuConstants::TRIBUTE_BEGIN && slot_id <= EmuConstants::TRIBUTE_END) + // return true; + // + //if (slot_id >= EmuConstants::SHARED_BANK_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) { + // // Shared bank inventory + // if (!inst) + // return DeleteSharedBankSlot(char_id, slot_id); + // else + // return UpdateSharedBankSlot(char_id, inst, slot_id); + //} + //else if (!inst) { // All other inventory + // return DeleteInventorySlot(char_id, slot_id); + //} + // + //return UpdateInventorySlot(char_id, inst, slot_id); } bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id) { - // need to check 'inst' argument for valid pointer - - uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM }; - if (inst->IsType(ItemClassCommon)) { - for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - ItemInst *auginst = inst->GetItem(i); - augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM; - } - } - - uint16 charges = 0; - if(inst->GetCharges() >= 0) - charges = inst->GetCharges(); - else - charges = 0x7FFF; - - // Update/Insert item - std::string query = StringFormat("REPLACE INTO inventory " - "(charid, slotid, itemid, charges, instnodrop, custom_data, color, " - "augslot1, augslot2, augslot3, augslot4, augslot5, augslot6, ornamenticon, ornamentidfile, ornament_hero_model) " - "VALUES( %lu, %lu, %lu, %lu, %lu, '%s', %lu, " - "%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu)", - (unsigned long)char_id, (unsigned long)slot_id, (unsigned long)inst->GetItem()->ID, - (unsigned long)charges, (unsigned long)(inst->IsAttuned()? 1: 0), - inst->GetCustomDataString().c_str(), (unsigned long)inst->GetColor(), - (unsigned long)augslot[0], (unsigned long)augslot[1], (unsigned long)augslot[2], - (unsigned long)augslot[3], (unsigned long)augslot[4], (unsigned long)augslot[5], (unsigned long)inst->GetOrnamentationIcon(), - (unsigned long)inst->GetOrnamentationIDFile(), (unsigned long)inst->GetOrnamentHeroModel()); - auto results = QueryDatabase(query); - - // Save bag contents, if slot supports bag contents - if (inst->IsType(ItemClassContainer) && InventoryOld::SupportsContainers(slot_id)) - for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) { - const ItemInst* baginst = inst->GetItem(idx); - SaveInventory(char_id, baginst, InventoryOld::CalcSlotId(slot_id, idx)); - } - - if (!results.Success()) { - return false; - } - return true; + + // need to check 'inst' argument for valid pointer + // + //uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM }; + //if (inst->IsType(ItemClassCommon)) { + // for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { + // ItemInst *auginst = inst->GetItem(i); + // augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM; + // } + //} + // + //uint16 charges = 0; + //if(inst->GetCharges() >= 0) + // charges = inst->GetCharges(); + //else + // charges = 0x7FFF; + // + //// Update/Insert item + //std::string query = StringFormat("REPLACE INTO inventory " + // "(charid, slotid, itemid, charges, instnodrop, custom_data, color, " + // "augslot1, augslot2, augslot3, augslot4, augslot5, augslot6, ornamenticon, ornamentidfile, ornament_hero_model) " + // "VALUES( %lu, %lu, %lu, %lu, %lu, '%s', %lu, " + // "%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu)", + // (unsigned long)char_id, (unsigned long)slot_id, (unsigned long)inst->GetItem()->ID, + // (unsigned long)charges, (unsigned long)(inst->IsAttuned()? 1: 0), + // inst->GetCustomDataString().c_str(), (unsigned long)inst->GetColor(), + // (unsigned long)augslot[0], (unsigned long)augslot[1], (unsigned long)augslot[2], + // (unsigned long)augslot[3], (unsigned long)augslot[4], (unsigned long)augslot[5], (unsigned long)inst->GetOrnamentationIcon(), + // (unsigned long)inst->GetOrnamentationIDFile(), (unsigned long)inst->GetOrnamentHeroModel()); + //auto results = QueryDatabase(query); + // + //// Save bag contents, if slot supports bag contents + //if (inst->IsType(ItemClassContainer) && InventoryOld::SupportsContainers(slot_id)) + // for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) { + // const ItemInst* baginst = inst->GetItem(idx); + // SaveInventory(char_id, baginst, InventoryOld::CalcSlotId(slot_id, idx)); + // } + // + //if (!results.Success()) { + // return false; + //} + // + //return true; } bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id) { @@ -482,146 +485,147 @@ bool SharedDatabase::GetSharedBank(uint32 id, InventoryOld *inv, bool is_charid) } // Overloaded: Retrieve character inventory based on character id -bool SharedDatabase::GetInventory(uint32 char_id, InventoryOld *inv) +bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::Inventory *inv) { - // Retrieve character inventory - std::string query = - StringFormat("SELECT slotid, itemid, charges, color, augslot1, augslot2, augslot3, augslot4, augslot5, " - "augslot6, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model FROM " - "inventory WHERE charid = %i ORDER BY slotid", - char_id); - auto results = QueryDatabase(query); - if (!results.Success()) { - Log.Out(Logs::General, Logs::Error, "If you got an error related to the 'instnodrop' field, run the " - "following SQL Queries:\nalter table inventory add instnodrop " - "tinyint(1) unsigned default 0 not null;\n"); - return false; - } - - auto timestamps = GetItemRecastTimestamps(char_id); - - for (auto row = results.begin(); row != results.end(); ++row) { - int16 slot_id = atoi(row[0]); - uint32 item_id = atoi(row[1]); - uint16 charges = atoi(row[2]); - uint32 color = atoul(row[3]); - - uint32 aug[EmuConstants::ITEM_COMMON_SIZE]; - - aug[0] = (uint32)atoul(row[4]); - aug[1] = (uint32)atoul(row[5]); - aug[2] = (uint32)atoul(row[6]); - aug[3] = (uint32)atoul(row[7]); - aug[4] = (uint32)atoul(row[8]); - aug[5] = (uint32)atoul(row[9]); - - bool instnodrop = (row[10] && (uint16)atoi(row[10])) ? true : false; - - uint32 ornament_icon = (uint32)atoul(row[12]); - uint32 ornament_idfile = (uint32)atoul(row[13]); - uint32 ornament_hero_model = (uint32)atoul(row[14]); - - const ItemData *item = GetItem(item_id); - - if (!item) { - Log.Out(Logs::General, Logs::Error, - "Warning: charid %i has an invalid item_id %i in inventory slot %i", char_id, item_id, - slot_id); - continue; - } - - int16 put_slot_id = INVALID_INDEX; - - ItemInst *inst = CreateBaseItem(item, charges); - - if (inst == nullptr) - continue; - - if (row[11]) { - std::string data_str(row[11]); - std::string idAsString; - std::string value; - bool use_id = true; - - for (int i = 0; i < data_str.length(); ++i) { - if (data_str[i] == '^') { - if (!use_id) { - inst->SetCustomData(idAsString, value); - idAsString.clear(); - value.clear(); - } - - use_id = !use_id; - continue; - } - - char v = data_str[i]; - if (use_id) - idAsString.push_back(v); - else - value.push_back(v); - } - } - - inst->SetOrnamentIcon(ornament_icon); - inst->SetOrnamentationIDFile(ornament_idfile); - inst->SetOrnamentHeroModel(ornament_hero_model); - - if (instnodrop || - (((slot_id >= EmuConstants::EQUIPMENT_BEGIN && slot_id <= EmuConstants::EQUIPMENT_END) || - slot_id == MainPowerSource) && - inst->GetItem()->Attuneable)) - inst->SetAttuned(true); - - if (color > 0) - inst->SetColor(color); - - if (charges == 0x7FFF) - inst->SetCharges(-1); - else if (charges == 0 && - inst->IsStackable()) // Stackable items need a minimum charge of 1 remain moveable. - inst->SetCharges(1); - else - inst->SetCharges(charges); - - if (item->RecastDelay) { - if (timestamps.count(item->RecastType)) - inst->SetRecastTimestamp(timestamps.at(item->RecastType)); - else - inst->SetRecastTimestamp(0); - } - - if (item->ItemClass == ItemClassCommon) { - for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - if (aug[i]) - inst->PutAugment(this, i, aug[i]); - } - } - - if (slot_id >= 8000 && slot_id <= 8999) { - put_slot_id = inv->PushCursor(*inst); - } else if (slot_id >= 3111 && slot_id <= 3179) { - // Admins: please report any occurrences of this error - Log.Out(Logs::General, Logs::Error, "Warning: Defunct location for item in inventory: " - "charid=%i, item_id=%i, slot_id=%i .. pushing to cursor...", - char_id, item_id, slot_id); - put_slot_id = inv->PushCursor(*inst); - } else { - put_slot_id = inv->PutItem(slot_id, *inst); - } - - safe_delete(inst); - - // Save ptr to item in inventory - if (put_slot_id == INVALID_INDEX) { - Log.Out(Logs::General, Logs::Error, - "Warning: Invalid slot_id for item in inventory: charid=%i, item_id=%i, slot_id=%i", - char_id, item_id, slot_id); - } - } - - // Retrieve shared inventory - return GetSharedBank(char_id, inv, true); + return false; + //// Retrieve character inventory + //std::string query = + // StringFormat("SELECT slotid, itemid, charges, color, augslot1, augslot2, augslot3, augslot4, augslot5, " + // "augslot6, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model FROM " + // "inventory WHERE charid = %i ORDER BY slotid", + // char_id); + //auto results = QueryDatabase(query); + //if (!results.Success()) { + // Log.Out(Logs::General, Logs::Error, "If you got an error related to the 'instnodrop' field, run the " + // "following SQL Queries:\nalter table inventory add instnodrop " + // "tinyint(1) unsigned default 0 not null;\n"); + // return false; + //} + // + //auto timestamps = GetItemRecastTimestamps(char_id); + // + //for (auto row = results.begin(); row != results.end(); ++row) { + // int16 slot_id = atoi(row[0]); + // uint32 item_id = atoi(row[1]); + // uint16 charges = atoi(row[2]); + // uint32 color = atoul(row[3]); + // + // uint32 aug[EmuConstants::ITEM_COMMON_SIZE]; + // + // aug[0] = (uint32)atoul(row[4]); + // aug[1] = (uint32)atoul(row[5]); + // aug[2] = (uint32)atoul(row[6]); + // aug[3] = (uint32)atoul(row[7]); + // aug[4] = (uint32)atoul(row[8]); + // aug[5] = (uint32)atoul(row[9]); + // + // bool instnodrop = (row[10] && (uint16)atoi(row[10])) ? true : false; + // + // uint32 ornament_icon = (uint32)atoul(row[12]); + // uint32 ornament_idfile = (uint32)atoul(row[13]); + // uint32 ornament_hero_model = (uint32)atoul(row[14]); + // + // const ItemData *item = GetItem(item_id); + // + // if (!item) { + // Log.Out(Logs::General, Logs::Error, + // "Warning: charid %i has an invalid item_id %i in inventory slot %i", char_id, item_id, + // slot_id); + // continue; + // } + // + // int16 put_slot_id = INVALID_INDEX; + // + // ItemInst *inst = CreateBaseItem(item, charges); + // + // if (inst == nullptr) + // continue; + // + // if (row[11]) { + // std::string data_str(row[11]); + // std::string idAsString; + // std::string value; + // bool use_id = true; + // + // for (int i = 0; i < data_str.length(); ++i) { + // if (data_str[i] == '^') { + // if (!use_id) { + // inst->SetCustomData(idAsString, value); + // idAsString.clear(); + // value.clear(); + // } + // + // use_id = !use_id; + // continue; + // } + // + // char v = data_str[i]; + // if (use_id) + // idAsString.push_back(v); + // else + // value.push_back(v); + // } + // } + // + // inst->SetOrnamentIcon(ornament_icon); + // inst->SetOrnamentationIDFile(ornament_idfile); + // inst->SetOrnamentHeroModel(ornament_hero_model); + // + // if (instnodrop || + // (((slot_id >= EmuConstants::EQUIPMENT_BEGIN && slot_id <= EmuConstants::EQUIPMENT_END) || + // slot_id == MainPowerSource) && + // inst->GetItem()->Attuneable)) + // inst->SetAttuned(true); + // + // if (color > 0) + // inst->SetColor(color); + // + // if (charges == 0x7FFF) + // inst->SetCharges(-1); + // else if (charges == 0 && + // inst->IsStackable()) // Stackable items need a minimum charge of 1 remain moveable. + // inst->SetCharges(1); + // else + // inst->SetCharges(charges); + // + // if (item->RecastDelay) { + // if (timestamps.count(item->RecastType)) + // inst->SetRecastTimestamp(timestamps.at(item->RecastType)); + // else + // inst->SetRecastTimestamp(0); + // } + // + // if (item->ItemClass == ItemClassCommon) { + // for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { + // if (aug[i]) + // inst->PutAugment(this, i, aug[i]); + // } + // } + // + // if (slot_id >= 8000 && slot_id <= 8999) { + // put_slot_id = inv->PushCursor(*inst); + // } else if (slot_id >= 3111 && slot_id <= 3179) { + // // Admins: please report any occurrences of this error + // Log.Out(Logs::General, Logs::Error, "Warning: Defunct location for item in inventory: " + // "charid=%i, item_id=%i, slot_id=%i .. pushing to cursor...", + // char_id, item_id, slot_id); + // put_slot_id = inv->PushCursor(*inst); + // } else { + // put_slot_id = inv->PutItem(slot_id, *inst); + // } + // + // safe_delete(inst); + // + // // Save ptr to item in inventory + // if (put_slot_id == INVALID_INDEX) { + // Log.Out(Logs::General, Logs::Error, + // "Warning: Invalid slot_id for item in inventory: charid=%i, item_id=%i, slot_id=%i", + // char_id, item_id, slot_id); + // } + //} + // + //// Retrieve shared inventory + //return GetSharedBank(char_id, inv, true); } // Overloaded: Retrieve character inventory based on account_id and character name diff --git a/common/shareddb.h b/common/shareddb.h index 9f7708919..1eb64fdd9 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -9,6 +9,7 @@ #include "base_data.h" #include "fixed_memory_hash_set.h" #include "fixed_memory_variable_hash_set.h" +#include "inventory.h" #include #include @@ -68,7 +69,7 @@ class SharedDatabase : public Database bool GetSharedBank(uint32 id, InventoryOld* inv, bool is_charid); int32 GetSharedPlatinum(uint32 account_id); bool SetSharedPlatinum(uint32 account_id, int32 amount_to_add); - bool GetInventory(uint32 char_id, InventoryOld* inv); + bool GetInventory(uint32 char_id, EQEmu::Inventory* inv); bool GetInventory(uint32 account_id, char* name, InventoryOld* inv); std::map GetItemRecastTimestamps(uint32 char_id); uint32 GetItemRecastTimestamp(uint32 char_id, uint32 recast_type); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 92c025734..e8ec515b5 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1271,7 +1271,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) m_pp.platinum_shared = database.GetSharedPlatinum(this->AccountID()); database.ClearOldRecastTimestamps(cid); /* Clear out our old recast timestamps to keep the DB clean */ - loaditems = database.GetInventory(cid, &m_inv); /* Load Character Inventory */ + loaditems = database.GetInventory(cid, &m_inventory); /* Load Character Inventory */ database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */ database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */ database.LoadCharacterMaterialColor(cid, &m_pp); /* Load Character Material */ diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 3f8e818e3..ac3d27e94 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -814,11 +814,6 @@ void Client::OnDisconnect(bool hard_disconnect) { Disconnect(); } -// Sends the client complete inventory used in character login - -// DO WE STILL NEED THE 'ITEMCOMBINED' CONDITIONAL CODE? -U - -//#ifdef ITEMCOMBINED void Client::BulkSendInventoryItems() { int16 slot_id = 0; @@ -919,51 +914,6 @@ void Client::BulkSendInventoryItems() { QueuePacket(outapp); safe_delete(outapp); } -/*#else -void Client::BulkSendInventoryItems() -{ - // Search all inventory buckets for items - bool deletenorent=database.NoRentExpired(GetName()); - // Worn items and Inventory items - int16 slot_id = 0; - if(deletenorent){//client was offline for more than 30 minutes, delete no rent items - RemoveNoRent(); - } - for (slot_id=EmuConstants::POSSESSIONS_BEGIN; slot_id<=EmuConstants::POSSESSIONS_END; slot_id++) { - const ItemInst* inst = m_inv[slot_id]; - if (inst){ - SendItemPacket(slot_id, inst, ItemPacketCharInventory); - } - } - // Bank items - for (slot_id=EmuConstants::BANK_BEGIN; slot_id<=EmuConstants::BANK_END; slot_id++) { // 2015... - const ItemInst* inst = m_inv[slot_id]; - if (inst){ - SendItemPacket(slot_id, inst, ItemPacketCharInventory); - } - } - - // Shared Bank items - for (slot_id=EmuConstants::SHARED_BANK_BEGIN; slot_id<=EmuConstants::SHARED_BANK_END; slot_id++) { - const ItemInst* inst = m_inv[slot_id]; - if (inst){ - SendItemPacket(slot_id, inst, ItemPacketCharInventory); - } - } - - // LINKDEAD TRADE ITEMS - // If player went LD during a trade, they have items in the trade inventory - // slots. These items are now being put into their inventory (then queue up on cursor) - for (int16 trade_slot_id=EmuConstants::TRADE_BEGIN; trade_slot_id<=EmuConstants::TRADE_END; trade_slot_id++) { - const ItemInst* inst = m_inv[slot_id]; - if (inst) { - int16 free_slot_id = m_inv.FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size); - DeleteItemInInventory(trade_slot_id, 0, false); - PutItemInInventory(free_slot_id, *inst, true); - } - } -} -#endif*/ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { const ItemData* handyitem = nullptr; diff --git a/zone/mob.h b/zone/mob.h index 09b8d9d4a..862963794 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -18,6 +18,7 @@ #ifndef MOB_H #define MOB_H +#include "../common/inventory.h" #include "common.h" #include "entity.h" #include "hate_list.h" @@ -940,6 +941,9 @@ public: void Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int avoid_override, int Msg = 0); void Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int acc_override, int Msg = 0); + inline EQEmu::Inventory& GetInventory() { return m_inventory; } + inline const EQEmu::Inventory& GetInventory() const { return m_inventory; } + protected: void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic); static uint16 GetProcID(uint16 spell_id, uint8 effect_index); @@ -1273,6 +1277,8 @@ protected: bool bEnraged; bool destructibleobject; + EQEmu::Inventory m_inventory; + private: void _StopSong(); //this is not what you think it is Mob* target; From 551c0ef368d44b53f8a14785e815c4103f991637 Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 19 Feb 2015 23:34:43 -0800 Subject: [PATCH 04/27] Basic arch work, doesn't make a ton of sense yet but it will --- common/CMakeLists.txt | 4 ++ common/inventory.cpp | 13 ------ common/inventory.h | 15 +++---- common/inventory_database_controller.cpp | 0 common/inventory_database_controller.h | 24 +++++++++++ common/item_container.cpp | 52 ++++++++++++++++++++++++ common/item_container.h | 42 +++++++++++++++++++ common/item_instance.h | 4 ++ 8 files changed, 132 insertions(+), 22 deletions(-) create mode 100644 common/inventory_database_controller.cpp create mode 100644 common/inventory_database_controller.h create mode 100644 common/item_container.cpp create mode 100644 common/item_container.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index a992b8feb..49828d082 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -31,8 +31,10 @@ SET(common_sources guild_base.cpp guilds.cpp inventory.cpp + inventory_database_controller.cpp ipc_mutex.cpp item.cpp + item_container.cpp item_instance.cpp md5.cpp memory_mapped_file.cpp @@ -138,8 +140,10 @@ SET(common_headers guild_base.h guilds.h inventory.h + inventory_database_controller.h ipc_mutex.h item.h + item_container.h item_data.h item_fieldlist.h item_instance.h diff --git a/common/inventory.cpp b/common/inventory.cpp index 5ca07becf..01d8474ad 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -23,16 +23,3 @@ EQEmu::Inventory::Inventory() { EQEmu::Inventory::~Inventory() { } - -std::shared_ptr EQEmu::Inventory::GetItem(InventoryType type, int16 slot) { - auto area = items_.find(type); - - if(area != items_.end()) { - auto item = area->second.find(slot); - if(item != area->second.end()) { - return item->second; - } - } - - return std::shared_ptr(nullptr); -} \ No newline at end of file diff --git a/common/inventory.h b/common/inventory.h index 163a5be57..edb252308 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -19,16 +19,15 @@ #ifndef COMMON_INVENTORY_H #define COMMON_INVENTORY_H -#include "item_instance.h" -#include -#include -#include +#include "item_container.h" + +#include namespace EQEmu { - enum InventoryType : int16 + enum InventoryType : int { - InvTypePersonal, + InvTypePersonal = 0, InvTypeBank, InvTypeSharedBank, InvTypeTrade, @@ -45,10 +44,8 @@ namespace EQEmu Inventory(); ~Inventory(); - std::shared_ptr GetItem(InventoryType type, int16 slot); - private: - std::map>> items_; + std::map containers_; }; } // EQEmu diff --git a/common/inventory_database_controller.cpp b/common/inventory_database_controller.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/common/inventory_database_controller.h b/common/inventory_database_controller.h new file mode 100644 index 000000000..d3337dd75 --- /dev/null +++ b/common/inventory_database_controller.h @@ -0,0 +1,24 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 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 +*/ + +#ifndef COMMON_INVENTORY_DATABASE_CONTROLLER_H +#define COMMON_INVENTORY_DATABASE_CONTROLLER_H + + + +#endif diff --git a/common/item_container.cpp b/common/item_container.cpp new file mode 100644 index 000000000..3349c7c7b --- /dev/null +++ b/common/item_container.cpp @@ -0,0 +1,52 @@ +#include "item_container.h" +#include +#include + +struct EQEmu::ItemContainer::impl +{ + std::map> items; +}; + +EQEmu::ItemContainer::ItemContainer() +{ + impl_ = new impl; +} + +EQEmu::ItemContainer::~ItemContainer() +{ + delete impl_; +} + +std::shared_ptr EQEmu::ItemContainer::Get(int slot_id) { + auto iter = impl_->items.find(slot_id); + if(iter != impl_->items.end()) { + return iter->second; + } + + return std::shared_ptr(nullptr); +} + +bool EQEmu::ItemContainer::Put(int slot_id, std::shared_ptr inst) { + if(!inst) + return false; + + auto iter = impl_->items.find(slot_id); + if(iter == impl_->items.end()) { + impl_->items[slot_id] = inst; + //trigger put in slot_id + return true; + } + + return false; +} + +bool EQEmu::ItemContainer::Delete(int slot_id) { + auto iter = impl_->items.find(slot_id); + if(iter == impl_->items.end()) { + return false; + } else { + impl_->items.erase(iter); + //trigger delete in slotid + return true; + } +} diff --git a/common/item_container.h b/common/item_container.h new file mode 100644 index 000000000..5a58b46c2 --- /dev/null +++ b/common/item_container.h @@ -0,0 +1,42 @@ +/* EQEMu: Everquest Server Emulator +Copyright (C) 2001-2015 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 +*/ + +#ifndef COMMON_ITEM_CONTAINER_H +#define COMMON_ITEM_CONTAINER_H + +#include "item_instance.h" +#include + +namespace EQEmu +{ + class ItemContainer + { + public: + ItemContainer(); + ~ItemContainer(); + + std::shared_ptr Get(int slot_id); + bool Put(int slot_id, std::shared_ptr inst); + bool Delete(int slot_id); + private: + struct impl; + impl *impl_; + }; +} // EQEmu + +#endif diff --git a/common/item_instance.h b/common/item_instance.h index 582e80164..abae938ad 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -26,6 +26,7 @@ namespace EQEmu { + class ItemContainer; class ItemInstance { public: @@ -35,6 +36,7 @@ namespace EQEmu ~ItemInstance(); std::shared_ptr GetItem(int index); + void SetContainer(ItemContainer *parent) { parent_ = parent; } private: const ItemData *base_item_; ItemData *modified_item_; @@ -46,7 +48,9 @@ namespace EQEmu uint32 ornament_icon_; uint32 ornament_hero_model_; uint64 tracking_id_; + std::map> contents_; + ItemContainer *parent_; }; } // EQEmu From 2d617f0ea77b8abb27ec824f90f8464a1e855c75 Mon Sep 17 00:00:00 2001 From: KimLS Date: Fri, 20 Feb 2015 16:24:32 -0800 Subject: [PATCH 05/27] Get/Put item implementation + tests --- common/inventory.cpp | 43 +++++++++ common/inventory.h | 8 +- common/item_container.cpp | 2 +- common/item_instance.cpp | 124 +++++++++++++++++++------- common/item_instance.h | 21 +---- tests/CMakeLists.txt | 1 + tests/inventory_test.h | 180 ++++++++++++++++++++++++++++++++++++++ tests/main.cpp | 4 +- 8 files changed, 328 insertions(+), 55 deletions(-) create mode 100644 tests/inventory_test.h diff --git a/common/inventory.cpp b/common/inventory.cpp index 01d8474ad..60e8f10b2 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -17,9 +17,52 @@ */ #include "inventory.h" +#include "data_verification.h" +#include + +struct EQEmu::Inventory::impl +{ + std::map containers_; +}; EQEmu::Inventory::Inventory() { + impl_ = new impl; } EQEmu::Inventory::~Inventory() { + delete impl_; +} + +std::shared_ptr EQEmu::Inventory::Get(int container_id, int slot_id) { + auto iter = impl_->containers_.find(container_id); + if(iter != impl_->containers_.end()) { + return iter->second.Get(slot_id); + } + + return std::shared_ptr(nullptr); +} + +std::shared_ptr EQEmu::Inventory::Get(int container_id, int slot_id, int bag_idx) { + auto iter = impl_->containers_.find(container_id); + if(iter != impl_->containers_.end()) { + auto item = iter->second.Get(slot_id); + if(item) { + return item->GetItem(bag_idx); + } + } + + return std::shared_ptr(nullptr); +} + +bool EQEmu::Inventory::Put(int container_id, int slot_id, std::shared_ptr inst) { + if(impl_->containers_.count(container_id) == 0) { + auto &container = impl_->containers_[container_id]; + return container.Put(slot_id, inst); + } else { + ItemContainer container; + bool v = container.Put(slot_id, inst); + impl_->containers_[container_id] = container; + + return v; + } } diff --git a/common/inventory.h b/common/inventory.h index edb252308..8fe19cb5c 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -21,8 +21,6 @@ #include "item_container.h" -#include - namespace EQEmu { enum InventoryType : int @@ -44,8 +42,12 @@ namespace EQEmu Inventory(); ~Inventory(); + std::shared_ptr Get(int container_id, int slot_id); + std::shared_ptr Get(int container_id, int slot_id, int bag_idx); + bool Put(int container_id, int slot_id, std::shared_ptr inst); private: - std::map containers_; + struct impl; + impl *impl_; }; } // EQEmu diff --git a/common/item_container.cpp b/common/item_container.cpp index 3349c7c7b..ebfc10df0 100644 --- a/common/item_container.cpp +++ b/common/item_container.cpp @@ -33,7 +33,7 @@ bool EQEmu::ItemContainer::Put(int slot_id, std::shared_ptr inst) auto iter = impl_->items.find(slot_id); if(iter == impl_->items.end()) { impl_->items[slot_id] = inst; - //trigger put in slot_id + //trigger insert in slot_id return true; } diff --git a/common/item_instance.cpp b/common/item_instance.cpp index 9427ec890..faa95bcb4 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -18,53 +18,111 @@ #include "item_instance.h" #include "data_verification.h" +#include "item_container.h" + +struct EQEmu::ItemInstance::impl { + const ItemData *base_item_; + ItemData *modified_item_; + int16 charges_; + uint32 color_; + bool attuned_; + std::string custom_data_; + uint32 ornament_idfile_; + uint32 ornament_icon_; + uint32 ornament_hero_model_; + uint64 tracking_id_; + ItemContainer contents_; +}; EQEmu::ItemInstance::ItemInstance() { - base_item_ = nullptr; - modified_item_ = nullptr; - charges_ = -1; - color_ = 0; - attuned_ = false; - ornament_idfile_ = 0; - ornament_icon_ = 0; - ornament_hero_model_ = 0; - tracking_id_ = 0; + impl_ = new impl; + impl_->base_item_ = nullptr; + impl_->modified_item_ = nullptr; + impl_->charges_ = -1; + impl_->color_ = 0; + impl_->attuned_ = false; + impl_->ornament_idfile_ = 0; + impl_->ornament_icon_ = 0; + impl_->ornament_hero_model_ = 0; + impl_->tracking_id_ = 0; } EQEmu::ItemInstance::ItemInstance(const ItemData* idata) { - base_item_ = idata; - modified_item_ = nullptr; - charges_ = -1; - color_ = 0; - attuned_ = false; - ornament_idfile_ = 0; - ornament_icon_ = 0; - ornament_hero_model_ = 0; - tracking_id_ = 0; + impl_ = new impl; + impl_->base_item_ = idata; + impl_->modified_item_ = nullptr; + impl_->charges_ = -1; + impl_->color_ = 0; + impl_->attuned_ = false; + impl_->ornament_idfile_ = 0; + impl_->ornament_icon_ = 0; + impl_->ornament_hero_model_ = 0; + impl_->tracking_id_ = 0; } EQEmu::ItemInstance::ItemInstance(const ItemData* idata, int16 charges) { - base_item_ = idata; - modified_item_ = nullptr; - charges_ = charges; - color_ = 0; - attuned_ = false; - ornament_idfile_ = 0; - ornament_icon_ = 0; - ornament_hero_model_ = 0; - tracking_id_ = 0; + impl_ = new impl; + impl_->base_item_ = idata; + impl_->modified_item_ = nullptr; + impl_->charges_ = charges; + impl_->color_ = 0; + impl_->attuned_ = false; + impl_->ornament_idfile_ = 0; + impl_->ornament_icon_ = 0; + impl_->ornament_hero_model_ = 0; + impl_->tracking_id_ = 0; } EQEmu::ItemInstance::~ItemInstance() { + delete impl_; +} + +const ItemData *EQEmu::ItemInstance::GetItem() { + return impl_->modified_item_ ? impl_->modified_item_ : impl_->base_item_; } std::shared_ptr EQEmu::ItemInstance::GetItem(int index) { - if(EQEmu::ValueWithin(index, 0, 200)) { - auto iter = contents_.find(index); - if(iter != contents_.end()) { - return iter->second; - } + if(EQEmu::ValueWithin(index, 0, 255)) { + return impl_->contents_.Get(index); } - + return std::shared_ptr(nullptr); } + +bool EQEmu::ItemInstance::PutItem(int index, std::shared_ptr inst) { + if(!inst || !inst->GetItem()) { + return false; + } + + if(!impl_->base_item_) { + return false; + } + + auto *item = impl_->base_item_; + if(item->ItemClass == ItemClassContainer) { // Bag + if(!EQEmu::ValueWithin(index, 0, (int)item->BagSlots)) { + return false; + } + + return impl_->contents_.Put(index, inst); + } + else if(item->ItemClass == ItemClassCommon) { // Augment + if(!EQEmu::ValueWithin(index, 0, (int)EmuConstants::ITEM_COMMON_SIZE)) { + return false; + } + + if(!item->AugSlotVisible[index]) { + return false; + } + + auto *aug_item = inst->GetItem(); + int aug_type = aug_item->AugType; + if(aug_type == -1 || (1 << (item->AugSlotType[index] - 1)) & aug_type) { + return impl_->contents_.Put(index, inst); + } + + return false; + } + + return false; +} diff --git a/common/item_instance.h b/common/item_instance.h index abae938ad..64344a4e5 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -20,13 +20,10 @@ #define COMMON_ITEM_INSTANCE_H #include "item_data.h" -#include #include -#include namespace EQEmu { - class ItemContainer; class ItemInstance { public: @@ -35,22 +32,12 @@ namespace EQEmu ItemInstance(const ItemData* idata, int16 charges); ~ItemInstance(); + const ItemData *GetItem(); std::shared_ptr GetItem(int index); - void SetContainer(ItemContainer *parent) { parent_ = parent; } + bool PutItem(int index, std::shared_ptr inst); private: - const ItemData *base_item_; - ItemData *modified_item_; - int16 charges_; - uint32 color_; - bool attuned_; - std::string custom_data_; - uint32 ornament_idfile_; - uint32 ornament_icon_; - uint32 ornament_hero_model_; - uint64 tracking_id_; - - std::map> contents_; - ItemContainer *parent_; + struct impl; + impl *impl_; }; } // EQEmu diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1c13ae26c..8d0a733b7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,6 +12,7 @@ SET(tests_headers fixed_memory_test.h fixed_memory_variable_test.h hextoi_32_64_test.h + inventory_test.h ipc_mutex_test.h memory_mapped_file_test.h string_util_test.h diff --git a/tests/inventory_test.h b/tests/inventory_test.h new file mode 100644 index 000000000..72d9987a7 --- /dev/null +++ b/tests/inventory_test.h @@ -0,0 +1,180 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 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 +*/ + +#ifndef __EQEMU_TESTS_INVENTORY_H +#define __EQEMU_TESTS_INVENTORY_H + +#include "cppunit/cpptest.h" +#include "../common/inventory.h" +#include + +class InventoryTest : public Test::Suite { + typedef void(InventoryTest::*TestFunction)(void); +public: + InventoryTest() { + InitContainer(); + InitArmor(); + InitAugment(); + InitStackable(); + InitInventory(); + TEST_ADD(InventoryTest::InventoryVerifyInitialItemsTest); + } + + ~InventoryTest() { + } + + void InitContainer() { + memset(&container, 0, sizeof(container)); + strcpy(container.Name, "Backpack"); + strcpy(container.IDFile, "IT64"); + container.ID = 1000; + container.BagSize = 3; + container.BagSlots = 8; + container.BagType = 5; + container.BagWR = 50; + container.ItemClass = 1; + container.Classes = 65535U; + container.Focus.Effect = -1; + container.ItemType = 11; + container.NoDrop = 1; + container.NoRent = 1; + container.Races = 131071U; + container.Size = 3; + container.SkillModType = -1; + container.Click.Effect = -1; + container.Weight = 30; + container.StackSize = 1; + container.Proc.Effect = -1; + container.Worn.Effect = -1; + container.Scroll.Effect = -1; + } + + void InitArmor() { + memset(&armor, 0, sizeof(armor)); + strcpy(armor.Name, "Cloth Shirt"); + strcpy(armor.IDFile, "IT64"); + armor.ID = 1001; + armor.AC = 4; + armor.AugSlotType[0] = 7; + for(int i = 0; i < 6; ++i) + armor.AugSlotVisible[i] = 1; + armor.Size = 2; + armor.Slots = 131072; + armor.Classes = 65535U; + armor.Focus.Effect = -1; + armor.ItemType = 10; + armor.NoDrop = 1; + armor.NoRent = 1; + armor.Races = 131071U; + armor.SkillModType = -1; + armor.Click.Effect = -1; + armor.Weight = 8; + armor.StackSize = 1; + armor.Proc.Effect = -1; + armor.Worn.Effect = -1; + armor.Scroll.Effect = -1; + } + + void InitAugment() { + memset(&augment, 0, sizeof(augment)); + strcpy(augment.Name, "Cloth Augment"); + strcpy(augment.IDFile, "IT64"); + augment.ID = 1002; + augment.AWis = 10; + augment.AInt = 10; + augment.AugType = 64; + augment.Slots = 2072574; + augment.Classes = 65535U; + augment.Focus.Effect = -1; + augment.ItemType = 54; + augment.NoDrop = 1; + augment.NoRent = 1; + augment.Races = 131071U; + augment.SkillModType = -1; + augment.Click.Effect = -1; + augment.Weight = 5; + augment.StackSize = 1; + augment.Size = 1; + augment.Proc.Effect = -1; + augment.Worn.Effect = -1; + augment.Scroll.Effect = -1; + } + + void InitStackable() { + memset(&stackable, 0, sizeof(stackable)); + strcpy(stackable.Name, "Stackable Item"); + strcpy(stackable.IDFile, "IT64"); + stackable.ID = 1003; + stackable.Classes = 65535U; + stackable.Focus.Effect = -1; + stackable.ItemType = 54; + stackable.NoDrop = 1; + stackable.NoRent = 1; + stackable.Races = 131071U; + stackable.SkillModType = -1; + stackable.Click.Effect = -1; + stackable.Weight = 5; + stackable.StackSize = 100; + stackable.Stackable = 1; + stackable.Size = 1; + stackable.Proc.Effect = -1; + stackable.Worn.Effect = -1; + stackable.Scroll.Effect = -1; + } + + void InitInventory() + { + std::shared_ptr bag(new EQEmu::ItemInstance(&container)); + bag->PutItem(0, std::shared_ptr(new EQEmu::ItemInstance(&armor))); + bag->PutItem(1, std::shared_ptr(new EQEmu::ItemInstance(&augment))); + bag->PutItem(7, std::shared_ptr(new EQEmu::ItemInstance(&stackable, 45))); + inv.Put(0, 23, bag); //23 first inv slot + } + + void InventoryVerifyInitialItemsTest() + { + auto m_bag = inv.Get(0, 23); + TEST_ASSERT(m_bag); + TEST_ASSERT(m_bag->GetItem()); + TEST_ASSERT(m_bag->GetItem()->ID == 1000); + + auto m_armor = m_bag->GetItem(0); + TEST_ASSERT(m_armor); + TEST_ASSERT(m_armor->GetItem()); + TEST_ASSERT(m_armor->GetItem()->ID == 1001); + + auto m_augment = m_bag->GetItem(1); + TEST_ASSERT(m_augment); + TEST_ASSERT(m_augment->GetItem()); + TEST_ASSERT(m_augment->GetItem()->ID == 1002); + + auto m_stackable = m_bag->GetItem(7); + TEST_ASSERT(m_stackable); + TEST_ASSERT(m_stackable->GetItem()); + TEST_ASSERT(m_stackable->GetItem()->ID == 1003); + } + + private: + EQEmu::Inventory inv; + ItemData container; + ItemData armor; + ItemData augment; + ItemData stackable; +}; + +#endif diff --git a/tests/main.cpp b/tests/main.cpp index d64dfead4..165ab8d82 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -29,6 +29,7 @@ #include "string_util_test.h" #include "data_verification_test.h" #include "skills_util_test.h" +#include "inventory_test.h" int main() { try { @@ -44,7 +45,8 @@ int main() { tests.add(new StringUtilTest()); tests.add(new DataVerificationTest()); tests.add(new SkillsUtilsTest()); - tests.run(*output, true); + tests.add(new InventoryTest()); + tests.run(*output, false); } catch(...) { return -1; } From a90e9cf4c6dd9f5d4f641e3d3b2299c3129c44b0 Mon Sep 17 00:00:00 2001 From: KimLS Date: Fri, 20 Feb 2015 20:15:58 -0800 Subject: [PATCH 06/27] Refactoring --- common/inventory.cpp | 72 ++++++++++++++++++++++++++------------- common/inventory.h | 21 ++++++++++-- common/item.cpp | 2 +- common/item_container.cpp | 10 ++++-- common/item_container.h | 4 +++ common/item_instance.cpp | 4 +-- common/item_instance.h | 4 +-- common/shareddb.cpp | 39 +++++++++++++++------ common/shareddb.h | 7 ++-- tests/inventory_test.h | 31 ++++++++++------- zone/bot.cpp | 2 +- zone/client.cpp | 4 +-- zone/client_packet.cpp | 16 ++++----- zone/client_process.cpp | 4 +-- zone/command.cpp | 2 +- zone/corpse.cpp | 8 ++--- zone/forage.cpp | 4 +-- zone/guild_mgr.cpp | 4 +-- zone/inventory.cpp | 14 ++++---- zone/lua_iteminst.cpp | 4 +-- zone/mob.cpp | 2 +- zone/npc.cpp | 4 +-- zone/object.cpp | 2 +- zone/spell_effects.cpp | 4 +-- zone/trading.cpp | 8 ++--- zone/tribute.cpp | 2 +- zone/zone.cpp | 4 +-- zone/zonedb.cpp | 4 +-- 28 files changed, 181 insertions(+), 105 deletions(-) diff --git a/common/inventory.cpp b/common/inventory.cpp index 60e8f10b2..09f6e11a5 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -33,36 +33,62 @@ EQEmu::Inventory::~Inventory() { delete impl_; } -std::shared_ptr EQEmu::Inventory::Get(int container_id, int slot_id) { - auto iter = impl_->containers_.find(container_id); +std::shared_ptr EQEmu::Inventory::Get(const InventorySlot &slot) { + auto iter = impl_->containers_.find(slot.type_); if(iter != impl_->containers_.end()) { - return iter->second.Get(slot_id); - } - - return std::shared_ptr(nullptr); -} - -std::shared_ptr EQEmu::Inventory::Get(int container_id, int slot_id, int bag_idx) { - auto iter = impl_->containers_.find(container_id); - if(iter != impl_->containers_.end()) { - auto item = iter->second.Get(slot_id); + auto item = iter->second.Get(slot.slot_); if(item) { - return item->GetItem(bag_idx); + if(slot.bag_index_ > -1) { + auto sub_item = item->Get(slot.bag_index_); + if(sub_item) { + if(slot.aug_index_ > -1) { + return sub_item->Get(slot.aug_index_); + } else { + return sub_item; + } + } + } else { + return item; + } } } return std::shared_ptr(nullptr); } -bool EQEmu::Inventory::Put(int container_id, int slot_id, std::shared_ptr inst) { - if(impl_->containers_.count(container_id) == 0) { - auto &container = impl_->containers_[container_id]; - return container.Put(slot_id, inst); - } else { - ItemContainer container; - bool v = container.Put(slot_id, inst); - impl_->containers_[container_id] = container; - - return v; +bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr inst) { + if(impl_->containers_.count(slot.type_) == 0) { + impl_->containers_.insert(std::pair(slot.type_, ItemContainer())); } + + auto &container = impl_->containers_[slot.type_]; + if(slot.bag_index_ > -1) { + auto item = container.Get(slot.slot_); + if(!item) + return false; + + if(slot.aug_index_ > -1) { + auto bag_item = item->Get(slot.bag_index_); + if(!bag_item) { + return false; + } + + return bag_item->Put(slot.aug_index_, inst); + } else { + return item->Put(slot.bag_index_, inst); + } + } else { + if(slot.aug_index_ > -1) { + auto item = container.Get(slot.slot_); + if(!item) + return false; + + return item->Put(slot.aug_index_, inst); + } + + return container.Put(slot.slot_, inst); + } + + + return false; } diff --git a/common/inventory.h b/common/inventory.h index 8fe19cb5c..f268ac466 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -23,6 +23,21 @@ namespace EQEmu { + struct InventorySlot + { + InventorySlot(int type, int slot) + : type_(type), slot_(slot), bag_index_(-1), aug_index_(-1) { } + InventorySlot(int type, int slot, int bag_index) + : type_(type), slot_(slot), bag_index_(bag_index), aug_index_(-1) { } + InventorySlot(int type, int slot, int bag_index, int aug_index) + : type_(type), slot_(slot), bag_index_(bag_index), aug_index_(aug_index) { } + + int type_; + int slot_; + int bag_index_; + int aug_index_; + }; + enum InventoryType : int { InvTypePersonal = 0, @@ -42,9 +57,9 @@ namespace EQEmu Inventory(); ~Inventory(); - std::shared_ptr Get(int container_id, int slot_id); - std::shared_ptr Get(int container_id, int slot_id, int bag_idx); - bool Put(int container_id, int slot_id, std::shared_ptr inst); + std::shared_ptr Get(const InventorySlot &slot); + bool Put(const InventorySlot &slot, std::shared_ptr inst); + bool Swap(const InventorySlot &src, const InventorySlot &dest); private: struct impl; impl *impl_; diff --git a/common/item.cpp b/common/item.cpp index ca3af8066..edb191f17 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -1994,7 +1994,7 @@ void ItemInst::PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id) if (item_id == NO_ITEM) { return; } if (db == nullptr) { return; /* TODO: add log message for nullptr */ } - const ItemInst* aug = db->CreateItem(item_id); + const ItemInst* aug = db->CreateItemOld(item_id); if (aug) { PutAugment(slot, *aug); safe_delete(aug); diff --git a/common/item_container.cpp b/common/item_container.cpp index ebfc10df0..d13efbc4f 100644 --- a/common/item_container.cpp +++ b/common/item_container.cpp @@ -9,12 +9,18 @@ struct EQEmu::ItemContainer::impl EQEmu::ItemContainer::ItemContainer() { - impl_ = new impl; + impl_ = new impl(); } EQEmu::ItemContainer::~ItemContainer() { - delete impl_; + if(impl_) + delete impl_; +} + +EQEmu::ItemContainer::ItemContainer(ItemContainer &&other) { + impl_ = other.impl_; + other.impl_ = nullptr; } std::shared_ptr EQEmu::ItemContainer::Get(int slot_id) { diff --git a/common/item_container.h b/common/item_container.h index 5a58b46c2..d02a99dbe 100644 --- a/common/item_container.h +++ b/common/item_container.h @@ -29,11 +29,15 @@ namespace EQEmu public: ItemContainer(); ~ItemContainer(); + ItemContainer(ItemContainer &&other); std::shared_ptr Get(int slot_id); bool Put(int slot_id, std::shared_ptr inst); bool Delete(int slot_id); private: + ItemContainer(const ItemContainer &other); + ItemContainer& operator=(const ItemContainer &other); + struct impl; impl *impl_; }; diff --git a/common/item_instance.cpp b/common/item_instance.cpp index faa95bcb4..62eb8325e 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -81,7 +81,7 @@ const ItemData *EQEmu::ItemInstance::GetItem() { return impl_->modified_item_ ? impl_->modified_item_ : impl_->base_item_; } -std::shared_ptr EQEmu::ItemInstance::GetItem(int index) { +std::shared_ptr EQEmu::ItemInstance::Get(int index) { if(EQEmu::ValueWithin(index, 0, 255)) { return impl_->contents_.Get(index); } @@ -89,7 +89,7 @@ std::shared_ptr EQEmu::ItemInstance::GetItem(int index) { return std::shared_ptr(nullptr); } -bool EQEmu::ItemInstance::PutItem(int index, std::shared_ptr inst) { +bool EQEmu::ItemInstance::Put(int index, std::shared_ptr inst) { if(!inst || !inst->GetItem()) { return false; } diff --git a/common/item_instance.h b/common/item_instance.h index 64344a4e5..261414753 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -33,8 +33,8 @@ namespace EQEmu ~ItemInstance(); const ItemData *GetItem(); - std::shared_ptr GetItem(int index); - bool PutItem(int index, std::shared_ptr inst); + std::shared_ptr Get(int index); + bool Put(int index, std::shared_ptr inst); private: struct impl; impl *impl_; diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 7b0863bca..5a05ca366 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -371,7 +371,7 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, InventoryOld* in if(!myitem) continue; - ItemInst* myinst = CreateBaseItem(myitem, charges); + ItemInst* myinst = CreateBaseItemOld(myitem, charges); if(slot < 0) slot = inv->FindFreeSlot(0, 0); @@ -433,7 +433,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, InventoryOld *inv, bool is_charid) int16 put_slot_id = INVALID_INDEX; - ItemInst *inst = CreateBaseItem(item, charges); + ItemInst *inst = CreateBaseItemOld(item, charges); if (inst && item->ItemClass == ItemClassCommon) { for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { if (aug[i]) @@ -536,7 +536,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::Inventory *inv) // // int16 put_slot_id = INVALID_INDEX; // - // ItemInst *inst = CreateBaseItem(item, charges); + // ItemInst *inst = CreateBaseItemOld(item, charges); // // if (inst == nullptr) // continue; @@ -671,7 +671,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, InventoryOld *i if (!item) continue; - ItemInst *inst = CreateBaseItem(item, charges); + ItemInst *inst = CreateBaseItemOld(item, charges); if (inst == nullptr) continue; @@ -1257,14 +1257,14 @@ bool SharedDatabase::LoadNPCFactionLists() { } // Create appropriate ItemInst class -ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned) +ItemInst* SharedDatabase::CreateItemOld(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned) { const ItemData* item = nullptr; ItemInst* inst = nullptr; item = GetItem(item_id); if (item) { - inst = CreateBaseItem(item, charges); + inst = CreateBaseItemOld(item, charges); if (inst == nullptr) { Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItem()"); @@ -1286,14 +1286,14 @@ ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1, // Create appropriate ItemInst class -ItemInst* SharedDatabase::CreateItem(const ItemData* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned) +ItemInst* SharedDatabase::CreateItemOld(const ItemData* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned) { ItemInst* inst = nullptr; if (item) { - inst = CreateBaseItem(item, charges); + inst = CreateBaseItemOld(item, charges); if (inst == nullptr) { - Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItem()"); + Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItemOld()"); Log.Out(Logs::General, Logs::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges); return nullptr; } @@ -1310,7 +1310,7 @@ ItemInst* SharedDatabase::CreateItem(const ItemData* item, int16 charges, uint32 return inst; } -ItemInst* SharedDatabase::CreateBaseItem(const ItemData* item, int16 charges) { +ItemInst* SharedDatabase::CreateBaseItemOld(const ItemData* item, int16 charges) { ItemInst* inst = nullptr; if (item) { // if maxcharges is -1 that means it is an unlimited use item. @@ -1324,7 +1324,7 @@ ItemInst* SharedDatabase::CreateBaseItem(const ItemData* item, int16 charges) { inst = new ItemInst(item, charges); if (inst == nullptr) { - Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateBaseItem()"); + Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateBaseItemOld()"); Log.Out(Logs::General, Logs::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges); return nullptr; } @@ -1336,6 +1336,23 @@ ItemInst* SharedDatabase::CreateBaseItem(const ItemData* item, int16 charges) { return inst; } +std::shared_ptr SharedDatabase::CreateItem(uint32 item_id, int16 charges) { + const ItemData* item = GetItem(item_id); + if(item) { + if(charges == 0 && item->MaxCharges == -1) { + charges = 1; + } + + if(charges <= 0 && item->Stackable) { + charges = 1; + } + + return std::shared_ptr(new EQEmu::ItemInstance(item, charges)); + } + + return std::shared_ptr(nullptr); +} + int32 SharedDatabase::DeleteStalePlayerCorpses() { if(RuleB(Zone, EnableShadowrest)) { std::string query = StringFormat( diff --git a/common/shareddb.h b/common/shareddb.h index 1eb64fdd9..506f62eef 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -82,9 +82,10 @@ class SharedDatabase : public Database /* Item Methods */ - ItemInst* CreateItem(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); - ItemInst* CreateItem(const ItemData* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); - ItemInst* CreateBaseItem(const ItemData* item, int16 charges = 0); + ItemInst* CreateItemOld(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); + ItemInst* CreateItemOld(const ItemData* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); + ItemInst* CreateBaseItemOld(const ItemData* item, int16 charges = 0); + std::shared_ptr CreateItem(uint32 item_id, int16 charges = 0); /* Shared Memory crap diff --git a/tests/inventory_test.h b/tests/inventory_test.h index 72d9987a7..14c9d9581 100644 --- a/tests/inventory_test.h +++ b/tests/inventory_test.h @@ -139,36 +139,43 @@ public: void InitInventory() { - std::shared_ptr bag(new EQEmu::ItemInstance(&container)); - bag->PutItem(0, std::shared_ptr(new EQEmu::ItemInstance(&armor))); - bag->PutItem(1, std::shared_ptr(new EQEmu::ItemInstance(&augment))); - bag->PutItem(7, std::shared_ptr(new EQEmu::ItemInstance(&stackable, 45))); - inv.Put(0, 23, bag); //23 first inv slot + std::shared_ptr m_bag(new EQEmu::ItemInstance(&container)); + std::shared_ptr m_armor(new EQEmu::ItemInstance(&armor)); + std::shared_ptr m_augment(new EQEmu::ItemInstance(&augment)); + std::shared_ptr m_stackable(new EQEmu::ItemInstance(&stackable, 45)); + inv.Put(EQEmu::InventorySlot(0, 23), m_bag); + inv.Put(EQEmu::InventorySlot(0, 23, 0), m_armor); + inv.Put(EQEmu::InventorySlot(0, 23, 1), m_augment); + inv.Put(EQEmu::InventorySlot(0, 23, 7), m_stackable); } void InventoryVerifyInitialItemsTest() { - auto m_bag = inv.Get(0, 23); + auto m_bag = inv.Get(EQEmu::InventorySlot(0, 23)); TEST_ASSERT(m_bag); TEST_ASSERT(m_bag->GetItem()); TEST_ASSERT(m_bag->GetItem()->ID == 1000); - - auto m_armor = m_bag->GetItem(0); + + auto m_armor = m_bag->Get(0); TEST_ASSERT(m_armor); TEST_ASSERT(m_armor->GetItem()); TEST_ASSERT(m_armor->GetItem()->ID == 1001); - - auto m_augment = m_bag->GetItem(1); + + auto m_augment = m_bag->Get(1); TEST_ASSERT(m_augment); TEST_ASSERT(m_augment->GetItem()); TEST_ASSERT(m_augment->GetItem()->ID == 1002); - - auto m_stackable = m_bag->GetItem(7); + + auto m_stackable = m_bag->Get(7); TEST_ASSERT(m_stackable); TEST_ASSERT(m_stackable->GetItem()); TEST_ASSERT(m_stackable->GetItem()->ID == 1003); } + void InventorySwapItemsTest() + { + } + private: EQEmu::Inventory inv; ItemData container; diff --git a/zone/bot.cpp b/zone/bot.cpp index 3dd95441c..6d1fdc657 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -4219,7 +4219,7 @@ void Bot::GetBotItems(std::string* errorMessage, InventoryOld &inv) { aug[4] = (uint32)atoul(row[8]); bool instnodrop = (row[9] && (uint16)atoi(row[9])) ? true : false; - ItemInst* inst = database.CreateItem(item_id, charges, aug[0], aug[1], aug[2], aug[3], aug[4]); + ItemInst* inst = database.CreateItemOld(item_id, charges, aug[0], aug[1], aug[2], aug[3], aug[4]); if (!inst) { Log.Out(Logs::General, Logs::Error, "Warning: botid %i has an invalid item_id %i in inventory slot %i", this->GetBotID(), item_id, slot_id); continue; diff --git a/zone/client.cpp b/zone/client.cpp index a8943a860..9db2e7919 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -5423,7 +5423,7 @@ bool Client::TryReward(uint32 claim_id) { } InternalVeteranReward ivr = (*iter); - ItemInst *claim = database.CreateItem(ivr.items[0].item_id, ivr.items[0].charges); + ItemInst *claim = database.CreateItemOld(ivr.items[0].item_id, ivr.items[0].charges); if(!claim) { Save(); return true; @@ -5433,7 +5433,7 @@ bool Client::TryReward(uint32 claim_id) { for(int y = 1; y < 8; y++) if(ivr.items[y].item_id && claim->GetItem()->ItemClass == 1) { - ItemInst *item_temp = database.CreateItem(ivr.items[y].item_id, ivr.items[y].charges); + ItemInst *item_temp = database.CreateItemOld(ivr.items[y].item_id, ivr.items[y].charges); if(item_temp) { if(CheckLoreConflict(item_temp->GetItem())) { lore_conflict = true; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index e8ec515b5..09368e7c1 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -2056,7 +2056,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) if (item->MaxCharges != 0) charges = item->MaxCharges; - ItemInst *inst = database.CreateItem(item, charges); + ItemInst *inst = database.CreateItemOld(item, charges); if (!AutoPutLootInInventory(*inst, true, true)) { PutLootInInventory(MainCursor, *inst); @@ -2579,7 +2579,7 @@ void Client::Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app) if (item->MaxCharges != 0) charges = item->MaxCharges; - ItemInst *inst = database.CreateItem(item, charges); + ItemInst *inst = database.CreateItemOld(item, charges); if (!AutoPutLootInInventory(*inst, true, true)) { PutLootInInventory(MainCursor, *inst); @@ -3383,7 +3383,7 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app) Message(13, "Error: This item does not exist!"); else { - ItemInst* inst = database.CreateItem(item); + ItemInst* inst = database.CreateItemOld(item); if (inst) { SendItemPacket(0, inst, ItemPacketViewLink); @@ -3416,7 +3416,7 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app) Message(13, "Error: This item does not exist!"); else { - ItemInst* inst = database.CreateItem(item); + ItemInst* inst = database.CreateItemOld(item); if (inst) { SendItemPacket(0, inst, ItemPacketViewLink); @@ -3456,7 +3456,7 @@ void Client::Handle_OP_BazaarInspect(const EQApplicationPacket *app) return; } - ItemInst* inst = database.CreateItem(item); + ItemInst* inst = database.CreateItemOld(item); if (inst) { SendItemPacket(0, inst, ItemPacketViewLink); @@ -8081,7 +8081,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) } - ItemInst* inst = database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], ivrs->augments[3], ivrs->augments[4], ivrs->augments[5]); + ItemInst* inst = database.CreateItemOld(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], ivrs->augments[3], ivrs->augments[4], ivrs->augments[5]); if (inst) { SendItemPacket(0, inst, ItemPacketViewLink); safe_delete(inst); @@ -8096,7 +8096,7 @@ void Client::Handle_OP_ItemLinkResponse(const EQApplicationPacket *app) return; } LDONItemViewRequest_Struct* item = (LDONItemViewRequest_Struct*)app->pBuffer; - ItemInst* inst = database.CreateItem(item->item_id); + ItemInst* inst = database.CreateItemOld(item->item_id); if (inst) { SendItemPacket(0, inst, ItemPacketViewLink); safe_delete(inst); @@ -12064,7 +12064,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) else charges = item->MaxCharges; - ItemInst* inst = database.CreateItem(item, charges); + ItemInst* inst = database.CreateItemOld(item, charges); int SinglePrice = 0; if (RuleB(Merchant, UsePriceMod)) diff --git a/zone/client_process.cpp b/zone/client_process.cpp index ac3d27e94..92f784e2e 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -962,7 +962,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { int charges = 1; if (item->ItemClass == ItemClassCommon) charges = item->MaxCharges; - ItemInst* inst = database.CreateItem(item, charges); + ItemInst* inst = database.CreateItemOld(item, charges); if (inst) { if (RuleB(Merchant, UsePriceMod)) { inst->SetPrice((item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(merch, false))); @@ -1003,7 +1003,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { // charges=ml.charges; //else charges = item->MaxCharges; - ItemInst* inst = database.CreateItem(item, charges); + ItemInst* inst = database.CreateItemOld(item, charges); if (inst) { if (RuleB(Merchant, UsePriceMod)) { inst->SetPrice((item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(merch, false))); diff --git a/zone/command.cpp b/zone/command.cpp index 5b2914b94..8581e36a9 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -10201,7 +10201,7 @@ void command_zopp(Client *c, const Seperator *sep) c->Message(0, "Processing request..results may cause unpredictable behavior."); } - ItemInst* FakeItemInst = database.CreateItem(FakeItem, charges); + ItemInst* FakeItemInst = database.CreateItemOld(FakeItem, charges); c->SendItemPacket(slotid, FakeItemInst, packettype); c->Message(0, "Sending zephyr op packet to client - [%s] %s (%u) with %i %s to slot %i.", packettype == ItemPacketTrade ? "Trade" : "Summon", FakeItem->Name, itemid, charges, diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 80fee6f18..e18e6f0e1 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -972,7 +972,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a if(Loot_Request_Type == 5) { int pkitem = GetPlayerKillItem(); const ItemData* item = database.GetItem(pkitem); - ItemInst* inst = database.CreateItem(item, item->MaxCharges); + ItemInst* inst = database.CreateItemOld(item, item->MaxCharges); if(inst) { if (item->RecastDelay) inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0); @@ -1005,7 +1005,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a if(i < corpselootlimit) { item = database.GetItem(item_data->item_id); if(client && item) { - ItemInst* inst = database.CreateItem(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned); + ItemInst* inst = database.CreateItemOld(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned); if(inst) { if (item->RecastDelay) inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0); @@ -1122,10 +1122,10 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) { if (item != 0) { if (item_data){ - inst = database.CreateItem(item, item_data ? item_data->charges : 0, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned); + inst = database.CreateItemOld(item, item_data ? item_data->charges : 0, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned); } else { - inst = database.CreateItem(item); + inst = database.CreateItemOld(item); } } diff --git a/zone/forage.cpp b/zone/forage.cpp index e77ef64c2..0ffb61121 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -298,7 +298,7 @@ void Client::GoFish() const ItemData* food_item = database.GetItem(food_id); Message_StringID(MT_Skills, FISHING_SUCCESS); - ItemInst* inst = database.CreateItem(food_item, 1); + ItemInst* inst = database.CreateItemOld(food_item, 1); if(inst != nullptr) { if(CheckLoreConflict(inst->GetItem())) { @@ -414,7 +414,7 @@ void Client::ForageItem(bool guarantee) { } Message_StringID(MT_Skills, stringid); - ItemInst* inst = database.CreateItem(food_item, 1); + ItemInst* inst = database.CreateItemOld(food_item, 1); if(inst != nullptr) { // check to make sure it isn't a foraged lore item if(CheckLoreConflict(inst->GetItem())) diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index 97834ab17..e5d79c621 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -1021,7 +1021,7 @@ ItemInst* GuildBankManager::GetItem(uint32 GuildID, uint16 Area, uint16 SlotID, if((SlotID > (GUILD_BANK_DEPOSIT_AREA_SIZE - 1))) return nullptr; - inst = database.CreateItem((*Iterator)->Items.DepositArea[SlotID].ItemID); + inst = database.CreateItemOld((*Iterator)->Items.DepositArea[SlotID].ItemID); if(!inst) return nullptr; @@ -1034,7 +1034,7 @@ ItemInst* GuildBankManager::GetItem(uint32 GuildID, uint16 Area, uint16 SlotID, if((SlotID > (GUILD_BANK_MAIN_AREA_SIZE - 1))) return nullptr; - inst = database.CreateItem((*Iterator)->Items.MainArea[SlotID].ItemID); + inst = database.CreateItemOld((*Iterator)->Items.MainArea[SlotID].ItemID); if(!inst) return nullptr; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 886dff767..06eccd9c6 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -528,7 +528,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, // in any other situation just use charges as passed - ItemInst* inst = database.CreateItem(item, charges); + ItemInst* inst = database.CreateItemOld(item, charges); if(inst == nullptr) { Message(13, "An unknown server error has occurred and your item was not created."); @@ -900,7 +900,7 @@ void Client::PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootI for(int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) { if(bag_item_data[i] == nullptr) continue; - const ItemInst *bagitem = database.CreateItem(bag_item_data[i]->item_id, bag_item_data[i]->charges, bag_item_data[i]->aug_1, bag_item_data[i]->aug_2, bag_item_data[i]->aug_3, bag_item_data[i]->aug_4, bag_item_data[i]->aug_5, bag_item_data[i]->aug_6, bag_item_data[i]->attuned); + const ItemInst *bagitem = database.CreateItemOld(bag_item_data[i]->item_id, bag_item_data[i]->charges, bag_item_data[i]->aug_1, bag_item_data[i]->aug_2, bag_item_data[i]->aug_3, bag_item_data[i]->aug_4, bag_item_data[i]->aug_5, bag_item_data[i]->aug_6, bag_item_data[i]->attuned); interior_slot = InventoryOld::CalcSlotId(slot_id, i); Log.Out(Logs::Detail, Logs::Inventory, "Putting bag loot item %s (%d) into slot %d (bag slot %d)", inst.GetItem()->Name, inst.GetItem()->ID, interior_slot, i); PutLootInInventory(interior_slot, *bagitem); @@ -1707,7 +1707,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { // Split into two src_inst->SetCharges(src_inst->GetCharges() - move_in->number_in_stack); Log.Out(Logs::Detail, Logs::Inventory, "Split stack of %s (%d) from slot %d to %d with stack size %d. Src keeps %d.", src_inst->GetItem()->Name, src_inst->GetItem()->ID, src_slot_id, dst_slot_id, move_in->number_in_stack, src_inst->GetCharges()); - ItemInst* inst = database.CreateItem(src_inst->GetItem(), move_in->number_in_stack); + ItemInst* inst = database.CreateItemOld(src_inst->GetItem(), move_in->number_in_stack); m_inv.PutItem(dst_slot_id, *inst); safe_delete(inst); } @@ -1802,7 +1802,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { // This prevents the client from crashing when closing any 'phantom' bags -U const ItemData* token_struct = database.GetItem(22292); // 'Copper Coin' - ItemInst* token_inst = database.CreateItem(token_struct, 1); + ItemInst* token_inst = database.CreateItemOld(token_struct, 1); SendItemPacket(resync_slot, token_inst, ItemPacketTrade); @@ -1827,7 +1827,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { if(m_inv[resync_slot]) { const ItemData* token_struct = database.GetItem(22292); // 'Copper Coin' - ItemInst* token_inst = database.CreateItem(token_struct, 1); + ItemInst* token_inst = database.CreateItemOld(token_struct, 1); SendItemPacket(resync_slot, token_inst, ItemPacketTrade); SendItemPacket(resync_slot, m_inv[resync_slot], ItemPacketTrade); @@ -1844,7 +1844,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { int16 resync_slot = (InventoryOld::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : InventoryOld::CalcSlotId(move_slots->to_slot); if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { const ItemData* token_struct = database.GetItem(22292); // 'Copper Coin' - ItemInst* token_inst = database.CreateItem(token_struct, 1); + ItemInst* token_inst = database.CreateItemOld(token_struct, 1); SendItemPacket(resync_slot, token_inst, ItemPacketTrade); @@ -1869,7 +1869,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) { if(m_inv[resync_slot]) { const ItemData* token_struct = database.GetItem(22292); // 'Copper Coin' - ItemInst* token_inst = database.CreateItem(token_struct, 1); + ItemInst* token_inst = database.CreateItemOld(token_struct, 1); SendItemPacket(resync_slot, token_inst, ItemPacketTrade); SendItemPacket(resync_slot, m_inv[resync_slot], ItemPacketTrade); diff --git a/zone/lua_iteminst.cpp b/zone/lua_iteminst.cpp index 4ebc6908f..44a1b7ffa 100644 --- a/zone/lua_iteminst.cpp +++ b/zone/lua_iteminst.cpp @@ -9,12 +9,12 @@ #include "lua_item.h" Lua_ItemInst::Lua_ItemInst(int item_id) { - SetLuaPtrData(database.CreateItem(item_id)); + SetLuaPtrData(database.CreateItemOld(item_id)); cloned_ = true; } Lua_ItemInst::Lua_ItemInst(int item_id, int charges) { - SetLuaPtrData(database.CreateItem(item_id, charges)); + SetLuaPtrData(database.CreateItemOld(item_id, charges)); cloned_ = true; } diff --git a/zone/mob.cpp b/zone/mob.cpp index ea37e8759..909db26c8 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -3665,7 +3665,7 @@ void Mob::TrySympatheticProc(Mob *target, uint32 spell_id) int32 Mob::GetItemStat(uint32 itemid, const char *identifier) { - const ItemInst* inst = database.CreateItem(itemid); + const ItemInst* inst = database.CreateItemOld(itemid); if (!inst) return 0; diff --git a/zone/npc.cpp b/zone/npc.cpp index a7c22ffed..3322d7083 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -1378,7 +1378,7 @@ void NPC::PickPocket(Client* thief) { const ItemData* item = database.GetItem(citem->item_id); if (item) { - inst = database.CreateItem(item, citem->charges); + inst = database.CreateItemOld(item, citem->charges); bool is_arrow = (item->ItemType == ItemTypeArrow) ? true : false; int slot_id = thief->GetInv().FindFreeSlot(false, true, inst->GetItem()->Size, is_arrow); if (/*!Equipped(item->ID) &&*/ @@ -1398,7 +1398,7 @@ void NPC::PickPocket(Client* thief) { if (x > 0) { int random = zone->random.Int(0, x-1); - inst = database.CreateItem(steal_items[random], charges[random]); + inst = database.CreateItemOld(steal_items[random], charges[random]); if (inst) { const ItemData* item = inst->GetItem(); diff --git a/zone/object.cpp b/zone/object.cpp index 4cdf1b0ad..53f206acd 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -876,7 +876,7 @@ void Object::SetItemID(uint32 itemid) if (itemid) { - this->m_inst = database.CreateItem(itemid); + this->m_inst = database.CreateItemOld(itemid); } } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index d4a03949d..aa3051ef1 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -1171,7 +1171,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) c->SendItemPacket(MainCursor, SummonedItem, ItemPacketSummonItem); safe_delete(SummonedItem); } - SummonedItem = database.CreateItem(spell.base[i], charges); + SummonedItem = database.CreateItemOld(spell.base[i], charges); } } @@ -1208,7 +1208,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) if (charges < 1) charges = 1; - ItemInst *SubItem = database.CreateItem(spell.base[i], charges); + ItemInst *SubItem = database.CreateItemOld(spell.base[i], charges); if (SubItem != nullptr) { SummonedItem->PutItem(slot, *SubItem); safe_delete(SubItem); diff --git a/zone/trading.cpp b/zone/trading.cpp index 5a41e7b74..81a70740e 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -1165,7 +1165,7 @@ void Client::SendTraderItem(uint32 ItemID, uint16 Quantity) { return; } - ItemInst* inst = database.CreateItem(item, Quantity); + ItemInst* inst = database.CreateItemOld(item, Quantity); if (inst) { @@ -1204,7 +1204,7 @@ void Client::BulkSendTraderInventory(uint32 char_id) { item=database.GetItem(TraderItems->ItemID[i]); if (item && (item->NoDrop!=0)) { - ItemInst* inst = database.CreateItem(item); + ItemInst* inst = database.CreateItemOld(item); if (inst) { inst->SetSerialNumber(TraderItems->SerialNumber[i]); if(TraderItems->Charges[i] > 0) @@ -2025,7 +2025,7 @@ static void UpdateTraderCustomerItemsAdded(uint32 CustomerID, TraderCharges_Stru if(!item) return; - ItemInst* inst = database.CreateItem(item); + ItemInst* inst = database.CreateItemOld(item); if(!inst) return; @@ -2106,7 +2106,7 @@ static void UpdateTraderCustomerPriceChanged(uint32 CustomerID, TraderCharges_St Log.Out(Logs::Detail, Logs::Trading, "Sending price updates to customer %s", Customer->GetName()); - ItemInst* inst = database.CreateItem(item); + ItemInst* inst = database.CreateItemOld(item); if(!inst) return; diff --git a/zone/tribute.cpp b/zone/tribute.cpp index df01f843e..f6a7df4c9 100644 --- a/zone/tribute.cpp +++ b/zone/tribute.cpp @@ -161,7 +161,7 @@ void Client::DoTributeUpdate() { uint32 item_id = tier.tribute_item_id; //summon the item for them - const ItemInst* inst = database.CreateItem(item_id, 1); + const ItemInst* inst = database.CreateItemOld(item_id, 1); if(inst == nullptr) continue; diff --git a/zone/zone.cpp b/zone/zone.cpp index 25a8488f8..d5fd2a0ab 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -257,7 +257,7 @@ bool Zone::LoadZoneObjects() { } else { // Groundspawn object - inst = database.CreateItem(itemid); + inst = database.CreateItemOld(itemid); } //Father Nitwit's fix... not perfect... @@ -295,7 +295,7 @@ bool Zone::LoadGroundSpawns() { for(gsindex=0;gsindex<50;gsindex++){ if(groundspawn.spawn[gsindex].item>0 && groundspawn.spawn[gsindex].item<500000){ ItemInst* inst = nullptr; - inst = database.CreateItem(groundspawn.spawn[gsindex].item); + inst = database.CreateItemOld(groundspawn.spawn[gsindex].item); gsnumber=groundspawn.spawn[gsindex].max_allowed; ix=0; if(inst){ diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index ba0fa4233..70c02344c 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -495,7 +495,7 @@ void ZoneDatabase::LoadWorldContainer(uint32 parentid, ItemInst* container) aug[4] = (uint32)atoi(row[7]); aug[5] = (uint32)atoi(row[8]); - ItemInst* inst = database.CreateItem(item_id, charges); + ItemInst* inst = database.CreateItemOld(item_id, charges); if (inst && inst->GetItem()->ItemClass == ItemClassCommon) { for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) if (aug[i]) @@ -640,7 +640,7 @@ ItemInst* ZoneDatabase::LoadSingleTraderItem(uint32 CharID, int SerialNumber) { if (item->NoDrop == 0) return nullptr; - ItemInst* inst = database.CreateItem(item); + ItemInst* inst = database.CreateItemOld(item); if(!inst) { Log.Out(Logs::Detail, Logs::Trading, "Unable to create item instance\n"); fflush(stdout); From f5118620043b941f5346fd5ba075cc78925cf567 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 21 Feb 2015 15:21:45 -0800 Subject: [PATCH 07/27] Working working working on getting the basics setup --- common/inventory.cpp | 4 + common/inventory.h | 4 +- common/item_container.cpp | 6 +- common/item_container.h | 6 +- common/item_instance.cpp | 45 ++++++++- common/item_instance.h | 16 +++- common/shareddb.cpp | 196 +++++++++++--------------------------- tests/inventory_test.h | 34 +++++-- zone/client_packet.cpp | 16 ++-- zone/client_process.cpp | 196 +++++++++++++++++++------------------- 10 files changed, 260 insertions(+), 263 deletions(-) diff --git a/common/inventory.cpp b/common/inventory.cpp index 09f6e11a5..96203fda3 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -92,3 +92,7 @@ bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr Get(const InventorySlot &slot); bool Put(const InventorySlot &slot, std::shared_ptr inst); - bool Swap(const InventorySlot &src, const InventorySlot &dest); + bool Swap(const InventorySlot &src, const InventorySlot &dest); + + void Serialize(); private: struct impl; impl *impl_; diff --git a/common/item_container.cpp b/common/item_container.cpp index d13efbc4f..38923a8cb 100644 --- a/common/item_container.cpp +++ b/common/item_container.cpp @@ -23,7 +23,7 @@ EQEmu::ItemContainer::ItemContainer(ItemContainer &&other) { other.impl_ = nullptr; } -std::shared_ptr EQEmu::ItemContainer::Get(int slot_id) { +std::shared_ptr EQEmu::ItemContainer::Get(const int slot_id) { auto iter = impl_->items.find(slot_id); if(iter != impl_->items.end()) { return iter->second; @@ -32,7 +32,7 @@ std::shared_ptr EQEmu::ItemContainer::Get(int slot_id) { return std::shared_ptr(nullptr); } -bool EQEmu::ItemContainer::Put(int slot_id, std::shared_ptr inst) { +bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr inst) { if(!inst) return false; @@ -46,7 +46,7 @@ bool EQEmu::ItemContainer::Put(int slot_id, std::shared_ptr inst) return false; } -bool EQEmu::ItemContainer::Delete(int slot_id) { +bool EQEmu::ItemContainer::Delete(const int slot_id) { auto iter = impl_->items.find(slot_id); if(iter == impl_->items.end()) { return false; diff --git a/common/item_container.h b/common/item_container.h index d02a99dbe..2847b940b 100644 --- a/common/item_container.h +++ b/common/item_container.h @@ -31,9 +31,9 @@ namespace EQEmu ~ItemContainer(); ItemContainer(ItemContainer &&other); - std::shared_ptr Get(int slot_id); - bool Put(int slot_id, std::shared_ptr inst); - bool Delete(int slot_id); + std::shared_ptr Get(const int slot_id); + bool Put(const int slot_id, std::shared_ptr inst); + bool Delete(const int slot_id); private: ItemContainer(const ItemContainer &other); ItemContainer& operator=(const ItemContainer &other); diff --git a/common/item_instance.cpp b/common/item_instance.cpp index 62eb8325e..8a26b7b3c 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -31,6 +31,7 @@ struct EQEmu::ItemInstance::impl { uint32 ornament_icon_; uint32 ornament_hero_model_; uint64 tracking_id_; + uint32 recast_timestamp_; ItemContainer contents_; }; @@ -44,6 +45,7 @@ EQEmu::ItemInstance::ItemInstance() { impl_->ornament_idfile_ = 0; impl_->ornament_icon_ = 0; impl_->ornament_hero_model_ = 0; + impl_->recast_timestamp_ = 0; impl_->tracking_id_ = 0; } @@ -57,6 +59,7 @@ EQEmu::ItemInstance::ItemInstance(const ItemData* idata) { impl_->ornament_idfile_ = 0; impl_->ornament_icon_ = 0; impl_->ornament_hero_model_ = 0; + impl_->recast_timestamp_ = 0; impl_->tracking_id_ = 0; } @@ -70,6 +73,7 @@ EQEmu::ItemInstance::ItemInstance(const ItemData* idata, int16 charges) { impl_->ornament_idfile_ = 0; impl_->ornament_icon_ = 0; impl_->ornament_hero_model_ = 0; + impl_->recast_timestamp_ = 0; impl_->tracking_id_ = 0; } @@ -81,7 +85,7 @@ const ItemData *EQEmu::ItemInstance::GetItem() { return impl_->modified_item_ ? impl_->modified_item_ : impl_->base_item_; } -std::shared_ptr EQEmu::ItemInstance::Get(int index) { +std::shared_ptr EQEmu::ItemInstance::Get(const int index) { if(EQEmu::ValueWithin(index, 0, 255)) { return impl_->contents_.Get(index); } @@ -89,7 +93,7 @@ std::shared_ptr EQEmu::ItemInstance::Get(int index) { return std::shared_ptr(nullptr); } -bool EQEmu::ItemInstance::Put(int index, std::shared_ptr inst) { +bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr inst) { if(!inst || !inst->GetItem()) { return false; } @@ -126,3 +130,40 @@ bool EQEmu::ItemInstance::Put(int index, std::shared_ptr inst) { return false; } + +void EQEmu::ItemInstance::SetCharges(const int16 charges) { + impl_->charges_ = charges; +} + +void EQEmu::ItemInstance::SetColor(const uint32 color) { + impl_->color_ = color; +} + +void EQEmu::ItemInstance::SetAttuned(const bool attuned) { + impl_->attuned_ = attuned; +} + +void EQEmu::ItemInstance::SetCustomData(const std::string &custom_data) { + //We need to actually set the custom data stuff based on this string + impl_->custom_data_ = custom_data; +} + +void EQEmu::ItemInstance::SetOrnamentIDFile(const uint32 ornament_idfile) { + impl_->ornament_idfile_ = ornament_idfile; +} + +void EQEmu::ItemInstance::SetOrnamentIcon(const uint32 ornament_icon) { + impl_->ornament_icon_ = ornament_icon; +} + +void EQEmu::ItemInstance::SetOrnamentHeroModel(const uint32 ornament_hero_model) { + impl_->ornament_hero_model_ = ornament_hero_model; +} + +void EQEmu::ItemInstance::SetTrackingID(const uint64 tracking_id) { + impl_->tracking_id_ = tracking_id; +} + +void EQEmu::ItemInstance::SetRecastTimestamp(const uint32 recast_timestamp) { + impl_->recast_timestamp_ = recast_timestamp; +} diff --git a/common/item_instance.h b/common/item_instance.h index 261414753..34eeb7384 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -29,12 +29,22 @@ namespace EQEmu public: ItemInstance(); ItemInstance(const ItemData* idata); - ItemInstance(const ItemData* idata, int16 charges); + ItemInstance(const ItemData* idata, const int16 charges); ~ItemInstance(); const ItemData *GetItem(); - std::shared_ptr Get(int index); - bool Put(int index, std::shared_ptr inst); + std::shared_ptr Get(const int index); + bool Put(const int index, std::shared_ptr inst); + + void SetCharges(const int16 charges); + void SetColor(const uint32 color); + void SetAttuned(const bool attuned); + void SetCustomData(const std::string &custom_data); + void SetOrnamentIDFile(const uint32 ornament_idfile); + void SetOrnamentIcon(const uint32 ornament_icon); + void SetOrnamentHeroModel(const uint32 ornament_hero_model); + void SetTrackingID(const uint64 tracking_id); + void SetRecastTimestamp(const uint32 recast_timestamp); private: struct impl; impl *impl_; diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 5a05ca366..e86135fbb 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -487,145 +487,63 @@ bool SharedDatabase::GetSharedBank(uint32 id, InventoryOld *inv, bool is_charid) // Overloaded: Retrieve character inventory based on character id bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::Inventory *inv) { - return false; - //// Retrieve character inventory - //std::string query = - // StringFormat("SELECT slotid, itemid, charges, color, augslot1, augslot2, augslot3, augslot4, augslot5, " - // "augslot6, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model FROM " - // "inventory WHERE charid = %i ORDER BY slotid", - // char_id); - //auto results = QueryDatabase(query); - //if (!results.Success()) { - // Log.Out(Logs::General, Logs::Error, "If you got an error related to the 'instnodrop' field, run the " - // "following SQL Queries:\nalter table inventory add instnodrop " - // "tinyint(1) unsigned default 0 not null;\n"); - // return false; - //} - // - //auto timestamps = GetItemRecastTimestamps(char_id); - // - //for (auto row = results.begin(); row != results.end(); ++row) { - // int16 slot_id = atoi(row[0]); - // uint32 item_id = atoi(row[1]); - // uint16 charges = atoi(row[2]); - // uint32 color = atoul(row[3]); - // - // uint32 aug[EmuConstants::ITEM_COMMON_SIZE]; - // - // aug[0] = (uint32)atoul(row[4]); - // aug[1] = (uint32)atoul(row[5]); - // aug[2] = (uint32)atoul(row[6]); - // aug[3] = (uint32)atoul(row[7]); - // aug[4] = (uint32)atoul(row[8]); - // aug[5] = (uint32)atoul(row[9]); - // - // bool instnodrop = (row[10] && (uint16)atoi(row[10])) ? true : false; - // - // uint32 ornament_icon = (uint32)atoul(row[12]); - // uint32 ornament_idfile = (uint32)atoul(row[13]); - // uint32 ornament_hero_model = (uint32)atoul(row[14]); - // - // const ItemData *item = GetItem(item_id); - // - // if (!item) { - // Log.Out(Logs::General, Logs::Error, - // "Warning: charid %i has an invalid item_id %i in inventory slot %i", char_id, item_id, - // slot_id); - // continue; - // } - // - // int16 put_slot_id = INVALID_INDEX; - // - // ItemInst *inst = CreateBaseItemOld(item, charges); - // - // if (inst == nullptr) - // continue; - // - // if (row[11]) { - // std::string data_str(row[11]); - // std::string idAsString; - // std::string value; - // bool use_id = true; - // - // for (int i = 0; i < data_str.length(); ++i) { - // if (data_str[i] == '^') { - // if (!use_id) { - // inst->SetCustomData(idAsString, value); - // idAsString.clear(); - // value.clear(); - // } - // - // use_id = !use_id; - // continue; - // } - // - // char v = data_str[i]; - // if (use_id) - // idAsString.push_back(v); - // else - // value.push_back(v); - // } - // } - // - // inst->SetOrnamentIcon(ornament_icon); - // inst->SetOrnamentationIDFile(ornament_idfile); - // inst->SetOrnamentHeroModel(ornament_hero_model); - // - // if (instnodrop || - // (((slot_id >= EmuConstants::EQUIPMENT_BEGIN && slot_id <= EmuConstants::EQUIPMENT_END) || - // slot_id == MainPowerSource) && - // inst->GetItem()->Attuneable)) - // inst->SetAttuned(true); - // - // if (color > 0) - // inst->SetColor(color); - // - // if (charges == 0x7FFF) - // inst->SetCharges(-1); - // else if (charges == 0 && - // inst->IsStackable()) // Stackable items need a minimum charge of 1 remain moveable. - // inst->SetCharges(1); - // else - // inst->SetCharges(charges); - // - // if (item->RecastDelay) { - // if (timestamps.count(item->RecastType)) - // inst->SetRecastTimestamp(timestamps.at(item->RecastType)); - // else - // inst->SetRecastTimestamp(0); - // } - // - // if (item->ItemClass == ItemClassCommon) { - // for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - // if (aug[i]) - // inst->PutAugment(this, i, aug[i]); - // } - // } - // - // if (slot_id >= 8000 && slot_id <= 8999) { - // put_slot_id = inv->PushCursor(*inst); - // } else if (slot_id >= 3111 && slot_id <= 3179) { - // // Admins: please report any occurrences of this error - // Log.Out(Logs::General, Logs::Error, "Warning: Defunct location for item in inventory: " - // "charid=%i, item_id=%i, slot_id=%i .. pushing to cursor...", - // char_id, item_id, slot_id); - // put_slot_id = inv->PushCursor(*inst); - // } else { - // put_slot_id = inv->PutItem(slot_id, *inst); - // } - // - // safe_delete(inst); - // - // // Save ptr to item in inventory - // if (put_slot_id == INVALID_INDEX) { - // Log.Out(Logs::General, Logs::Error, - // "Warning: Invalid slot_id for item in inventory: charid=%i, item_id=%i, slot_id=%i", - // char_id, item_id, slot_id); - // } - //} - // - //// Retrieve shared inventory - //return GetSharedBank(char_id, inv, true); + std::string query = StringFormat("SELECT type, slot, bag_index, aug_index, item_id, charges, color, attuned, " + "custom_data, ornament_icon, ornament_idfile, ornament_hero_model, tracking_id " + "FROM character_inventory WHERE id=%u ORDER BY type, slot, bag_index, aug_index", + char_id); + + auto results = QueryDatabase(query); + + if (!results.Success()) { + Log.Out(Logs::General, Logs::Error, "Error with query in SharedDatabase::GetInventory, could not get inventory" + " for character %u", char_id); + return false; + } + + auto timestamps = GetItemRecastTimestamps(char_id); + for(auto row : results) { + int type = atoi(row[0]); + int slot = atoi(row[1]); + int bag_index = atoi(row[2]); + int aug_index = atoi(row[3]); + int item_id = atoi(row[4]); + int charges = atoi(row[5]); + + auto inst = CreateItem(item_id, charges); + if(inst) { + uint32 color = (uint32)std::stoul(row[6]); + int attuned = atoi(row[7]); + uint32 ornament_icon = (uint32)std::stoul(row[9]); + uint32 ornament_idfile = (uint32)std::stoul(row[10]); + uint32 ornament_hero_model = (uint32)std::stoul(row[11]); + uint64 tracking_id = (uint64)std::stoull(row[12]); + + inst->SetColor(color); + inst->SetAttuned(attuned ? true : false); + inst->SetCustomData(row[8]); + inst->SetOrnamentIcon(ornament_icon); + inst->SetOrnamentIDFile(ornament_idfile); + inst->SetOrnamentHeroModel(ornament_hero_model); + inst->SetTrackingID(tracking_id); + + auto *item = inst->GetItem(); + if(item->RecastDelay) { + if(timestamps.count(item->RecastType)) { + inst->SetRecastTimestamp(timestamps.at(item->RecastType)); + } + } + + if(!inv->Put(EQEmu::InventorySlot(type, slot, bag_index, aug_index), inst)) { + Log.Out(Logs::General, Logs::Error, "Error putting item %u into (%d, %d, %d, %d) for char %u.", + item_id, type, slot, bag_index, aug_index, char_id); + } + } else { + Log.Out(Logs::General, Logs::Error, "Error putting item %u into (%d, %d, %d, %d) for char %u. Item does not exist.", + item_id, type, slot, bag_index, aug_index, char_id); + } + } + + return true; } // Overloaded: Retrieve character inventory based on account_id and character name diff --git a/tests/inventory_test.h b/tests/inventory_test.h index 14c9d9581..3e25c1748 100644 --- a/tests/inventory_test.h +++ b/tests/inventory_test.h @@ -38,6 +38,7 @@ public: ~InventoryTest() { } +private: void InitContainer() { memset(&container, 0, sizeof(container)); strcpy(container.Name, "Backpack"); @@ -174,14 +175,35 @@ public: void InventorySwapItemsTest() { + auto swap_result = inv.Swap(EQEmu::InventorySlot(0, 23), EQEmu::InventorySlot(0, 24)); + TEST_ASSERT(swap_result == true); + + auto m_bag = inv.Get(EQEmu::InventorySlot(0, 24)); + TEST_ASSERT(m_bag); + TEST_ASSERT(m_bag->GetItem()); + TEST_ASSERT(m_bag->GetItem()->ID == 1000); + + auto m_armor = m_bag->Get(0); + TEST_ASSERT(m_armor); + TEST_ASSERT(m_armor->GetItem()); + TEST_ASSERT(m_armor->GetItem()->ID == 1001); + + auto m_augment = m_bag->Get(1); + TEST_ASSERT(m_augment); + TEST_ASSERT(m_augment->GetItem()); + TEST_ASSERT(m_augment->GetItem()->ID == 1002); + + auto m_stackable = m_bag->Get(7); + TEST_ASSERT(m_stackable); + TEST_ASSERT(m_stackable->GetItem()); + TEST_ASSERT(m_stackable->GetItem()->ID == 1003); } - private: - EQEmu::Inventory inv; - ItemData container; - ItemData armor; - ItemData augment; - ItemData stackable; + EQEmu::Inventory inv; + ItemData container; + ItemData armor; + ItemData augment; + ItemData stackable; }; #endif diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 09368e7c1..83bcebc28 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1716,14 +1716,14 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) */ if (loaditems) { /* Dont load if a length error occurs */ BulkSendInventoryItems(); - /* Send stuff on the cursor which isnt sent in bulk */ - for (auto iter = m_inv.cursor_cbegin(); iter != m_inv.cursor_cend(); ++iter) { - /* First item cursor is sent in bulk inventory packet */ - if (iter == m_inv.cursor_cbegin()) - continue; - const ItemInst *inst = *iter; - SendItemPacket(MainCursor, inst, ItemPacketSummonItem); - } + // /* Send stuff on the cursor which isnt sent in bulk */ + // for (auto iter = m_inv.cursor_cbegin(); iter != m_inv.cursor_cend(); ++iter) { + // /* First item cursor is sent in bulk inventory packet */ + // if (iter == m_inv.cursor_cbegin()) + // continue; + // const ItemInst *inst = *iter; + // SendItemPacket(MainCursor, inst, ItemPacketSummonItem); + // } } /* Task Packets */ diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 92f784e2e..fe748d5b3 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -815,104 +815,104 @@ void Client::OnDisconnect(bool hard_disconnect) { } void Client::BulkSendInventoryItems() { - int16 slot_id = 0; - - // LINKDEAD TRADE ITEMS - // Move trade slot items back into normal inventory..need them there now for the proceeding validity checks -U - for(slot_id = EmuConstants::TRADE_BEGIN; slot_id <= EmuConstants::TRADE_END; slot_id++) { - ItemInst* inst = m_inv.PopItem(slot_id); - if(inst) { - bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false; - int16 free_slot_id = m_inv.FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size, is_arrow); - Log.Out(Logs::Detail, Logs::Inventory, "Incomplete Trade Transaction: Moving %s from slot %i to %i", inst->GetItem()->Name, slot_id, free_slot_id); - PutItemInInventory(free_slot_id, *inst, false); - database.SaveInventory(character_id, nullptr, slot_id); - safe_delete(inst); - } - } - - bool deletenorent = database.NoRentExpired(GetName()); - if(deletenorent){ RemoveNoRent(false); } //client was offline for more than 30 minutes, delete no rent items - - RemoveDuplicateLore(false); - MoveSlotNotAllowed(false); - - // The previous three method calls took care of moving/removing expired/illegal item placements -U - - //TODO: this function is just retarded... it re-allocates the buffer for every - //new item. It should be changed to loop through once, gather the - //lengths, and item packet pointers into an array (fixed length), and - //then loop again to build the packet. - //EQApplicationPacket *packets[50]; - //unsigned long buflen = 0; - //unsigned long pos = 0; - //memset(packets, 0, sizeof(packets)); - //foreach item in the invendor sections - // packets[pos++] = ReturnItemPacket(...) - // buflen += temp->size - //... - //allocat the buffer - //for r from 0 to pos - // put pos[r]->pBuffer into the buffer - //for r from 0 to pos - // safe_delete(pos[r]); - - uint32 size = 0; - uint16 i = 0; - std::map ser_items; - std::map::iterator itr; - - //Inventory items - for(slot_id = MAIN_BEGIN; slot_id < EmuConstants::MAP_POSSESSIONS_SIZE; slot_id++) { - const ItemInst* inst = m_inv[slot_id]; - if(inst) { - std::string packet = inst->Serialize(slot_id); - ser_items[i++] = packet; - size += packet.length(); - } - } - - // Power Source - if(GetClientVersion() >= ClientVersion::SoF) { - const ItemInst* inst = m_inv[MainPowerSource]; - if(inst) { - std::string packet = inst->Serialize(MainPowerSource); - ser_items[i++] = packet; - size += packet.length(); - } - } - - // Bank items - for(slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; slot_id++) { - const ItemInst* inst = m_inv[slot_id]; - if(inst) { - std::string packet = inst->Serialize(slot_id); - ser_items[i++] = packet; - size += packet.length(); - } - } - - // Shared Bank items - for(slot_id = EmuConstants::SHARED_BANK_BEGIN; slot_id <= EmuConstants::SHARED_BANK_END; slot_id++) { - const ItemInst* inst = m_inv[slot_id]; - if(inst) { - std::string packet = inst->Serialize(slot_id); - ser_items[i++] = packet; - size += packet.length(); - } - } - - EQApplicationPacket* outapp = new EQApplicationPacket(OP_CharInventory, size); - uchar* ptr = outapp->pBuffer; - for(itr = ser_items.begin(); itr != ser_items.end(); ++itr){ - int length = itr->second.length(); - if(length > 5) { - memcpy(ptr, itr->second.c_str(), length); - ptr += length; - } - } - QueuePacket(outapp); - safe_delete(outapp); + //int16 slot_id = 0; + // + //// LINKDEAD TRADE ITEMS + //// Move trade slot items back into normal inventory..need them there now for the proceeding validity checks -U + //for(slot_id = EmuConstants::TRADE_BEGIN; slot_id <= EmuConstants::TRADE_END; slot_id++) { + // ItemInst* inst = m_inv.PopItem(slot_id); + // if(inst) { + // bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false; + // int16 free_slot_id = m_inv.FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size, is_arrow); + // Log.Out(Logs::Detail, Logs::Inventory, "Incomplete Trade Transaction: Moving %s from slot %i to %i", inst->GetItem()->Name, slot_id, free_slot_id); + // PutItemInInventory(free_slot_id, *inst, false); + // database.SaveInventory(character_id, nullptr, slot_id); + // safe_delete(inst); + // } + //} + // + //bool deletenorent = database.NoRentExpired(GetName()); + //if(deletenorent){ RemoveNoRent(false); } //client was offline for more than 30 minutes, delete no rent items + // + //RemoveDuplicateLore(false); + //MoveSlotNotAllowed(false); + // + //// The previous three method calls took care of moving/removing expired/illegal item placements -U + // + ////TODO: this function is just retarded... it re-allocates the buffer for every + ////new item. It should be changed to loop through once, gather the + ////lengths, and item packet pointers into an array (fixed length), and + ////then loop again to build the packet. + ////EQApplicationPacket *packets[50]; + ////unsigned long buflen = 0; + ////unsigned long pos = 0; + ////memset(packets, 0, sizeof(packets)); + ////foreach item in the invendor sections + //// packets[pos++] = ReturnItemPacket(...) + //// buflen += temp->size + ////... + ////allocat the buffer + ////for r from 0 to pos + //// put pos[r]->pBuffer into the buffer + ////for r from 0 to pos + //// safe_delete(pos[r]); + // + //uint32 size = 0; + //uint16 i = 0; + //std::map ser_items; + //std::map::iterator itr; + // + ////Inventory items + //for(slot_id = MAIN_BEGIN; slot_id < EmuConstants::MAP_POSSESSIONS_SIZE; slot_id++) { + // const ItemInst* inst = m_inv[slot_id]; + // if(inst) { + // std::string packet = inst->Serialize(slot_id); + // ser_items[i++] = packet; + // size += packet.length(); + // } + //} + // + //// Power Source + //if(GetClientVersion() >= ClientVersion::SoF) { + // const ItemInst* inst = m_inv[MainPowerSource]; + // if(inst) { + // std::string packet = inst->Serialize(MainPowerSource); + // ser_items[i++] = packet; + // size += packet.length(); + // } + //} + // + //// Bank items + //for(slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; slot_id++) { + // const ItemInst* inst = m_inv[slot_id]; + // if(inst) { + // std::string packet = inst->Serialize(slot_id); + // ser_items[i++] = packet; + // size += packet.length(); + // } + //} + // + //// Shared Bank items + //for(slot_id = EmuConstants::SHARED_BANK_BEGIN; slot_id <= EmuConstants::SHARED_BANK_END; slot_id++) { + // const ItemInst* inst = m_inv[slot_id]; + // if(inst) { + // std::string packet = inst->Serialize(slot_id); + // ser_items[i++] = packet; + // size += packet.length(); + // } + //} + // + //EQApplicationPacket* outapp = new EQApplicationPacket(OP_CharInventory, size); + //uchar* ptr = outapp->pBuffer; + //for(itr = ser_items.begin(); itr != ser_items.end(); ++itr){ + // int length = itr->second.length(); + // if(length > 5) { + // memcpy(ptr, itr->second.c_str(), length); + // ptr += length; + // } + //} + //QueuePacket(outapp); + //safe_delete(outapp); } void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { From 273574d4dbdb442bc69e144fac556ff11613f0ca Mon Sep 17 00:00:00 2001 From: KimLS Date: Sun, 22 Feb 2015 15:37:11 -0800 Subject: [PATCH 08/27] Added memory buffer plus tests to project, going to use it for item serialization --- common/CMakeLists.txt | 2 + common/memory_buffer.cpp | 171 +++++++++++++ common/memory_buffer.h | 131 ++++++++++ tests/CMakeLists.txt | 1 + tests/main.cpp | 2 + tests/memory_buffer_test.h | 510 +++++++++++++++++++++++++++++++++++++ 6 files changed, 817 insertions(+) create mode 100644 common/memory_buffer.cpp create mode 100644 common/memory_buffer.h create mode 100644 tests/memory_buffer_test.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 49828d082..243553bff 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -37,6 +37,7 @@ SET(common_sources item_container.cpp item_instance.cpp md5.cpp + memory_buffer.cpp memory_mapped_file.cpp misc.cpp misc_functions.cpp @@ -152,6 +153,7 @@ SET(common_headers loottable.h mail_oplist.h md5.h + memory_buffer.h memory_mapped_file.h misc.h misc_functions.h diff --git a/common/memory_buffer.cpp b/common/memory_buffer.cpp new file mode 100644 index 000000000..cd10fe0c2 --- /dev/null +++ b/common/memory_buffer.cpp @@ -0,0 +1,171 @@ +#include "memory_buffer.h" + +EQEmu::MemoryBuffer::MemoryBuffer() { + buffer_ = nullptr; + size_ = 0; + capacity_ = 0; + read_pos_ = 0; + write_pos_ = 0; +} + +EQEmu::MemoryBuffer::MemoryBuffer(size_t sz) { + buffer_ = nullptr; + size_ = 0; + capacity_ = 0; + read_pos_ = 0; + write_pos_ = 0; + Resize(sz); +} + +EQEmu::MemoryBuffer::MemoryBuffer(const MemoryBuffer &other) { + if(other.capacity_) { + buffer_ = new uchar[other.capacity_]; + memcpy(buffer_, other.buffer_, other.capacity_); + } else { + buffer_ = nullptr; + } + + size_ = other.size_; + capacity_ = other.capacity_; + write_pos_ = other.write_pos_; + read_pos_ = other.read_pos_; +} + +EQEmu::MemoryBuffer::MemoryBuffer(MemoryBuffer &&other) { + buffer_ = other.buffer_; + size_ = other.size_; + capacity_ = other.capacity_; + write_pos_ = other.write_pos_; + read_pos_ = other.read_pos_; + + other.buffer_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; + other.read_pos_ = 0; + other.write_pos_ = 0; +} + +EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(const MemoryBuffer &other) { + if(other.capacity_) { + buffer_ = new uchar[other.capacity_]; + memcpy(buffer_, other.buffer_, other.capacity_); + } + else { + buffer_ = nullptr; + } + + size_ = other.size_; + capacity_ = other.capacity_; + write_pos_ = other.write_pos_; + read_pos_ = other.read_pos_; + return *this; +} + +EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(MemoryBuffer &&other) { + buffer_ = other.buffer_; + size_ = other.size_; + capacity_ = other.capacity_; + write_pos_ = other.write_pos_; + read_pos_ = other.read_pos_; + + other.buffer_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; + other.read_pos_ = 0; + other.write_pos_ = 0; + return *this; +} + +EQEmu::MemoryBuffer::~MemoryBuffer() { Clear(); } + +uchar& EQEmu::MemoryBuffer::operator[](size_t pos) { + return buffer_[pos]; +} + +const uchar& EQEmu::MemoryBuffer::operator[](size_t pos) const { + return buffer_[pos]; +} + +bool EQEmu::MemoryBuffer::Empty() { + return size_ == 0; +} + +bool EQEmu::MemoryBuffer::Empty() const { + return size_ == 0; +} + +size_t EQEmu::MemoryBuffer::Size() { + return size_; +} + +size_t EQEmu::MemoryBuffer::Size() const { + return size_; +} + +size_t EQEmu::MemoryBuffer::Capacity() { + return capacity_; +} + +size_t EQEmu::MemoryBuffer::Capacity() const { + return capacity_; +} + +void EQEmu::MemoryBuffer::Resize(size_t sz) { + if(!buffer_) { + size_t new_size = sz + 32; + buffer_ = new uchar[new_size]; + capacity_ = new_size; + size_ = sz; + memset(buffer_, 0, capacity_); + return; + } + + if(sz > capacity_) { + size_t new_size = sz + 32; + uchar *temp = new uchar[new_size]; + memcpy(temp, buffer_, new_size); + delete[] buffer_; + buffer_ = temp; + + capacity_ = new_size; + size_ = sz; + } + else { + size_ = sz; + } +} + +void EQEmu::MemoryBuffer::Clear() { + if(buffer_) { + delete[] buffer_; + buffer_ = nullptr; + } + + size_ = 0; + capacity_ = 0; +} + +void EQEmu::MemoryBuffer::Zero() { + if(buffer_) { + memset(buffer_, 0, capacity_); + } +} + +void EQEmu::MemoryBuffer::Write(const char *val, size_t len) { + size_t size_needed = write_pos_ + len; + Resize(size_needed); + + memcpy(&buffer_[write_pos_], val, len); + write_pos_ += len; +} + +void EQEmu::MemoryBuffer::Read(uchar *buf, size_t len) { + memcpy(buf, &buffer_[read_pos_], len); + read_pos_ += len; +} + +void EQEmu::MemoryBuffer::Read(char *str) { + size_t len = strlen((const char*)&buffer_[read_pos_]); + memcpy(str, &buffer_[read_pos_], len); + read_pos_ += len; +} diff --git a/common/memory_buffer.h b/common/memory_buffer.h new file mode 100644 index 000000000..beec6b809 --- /dev/null +++ b/common/memory_buffer.h @@ -0,0 +1,131 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 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 +*/ + +#ifndef COMMON_MEMORY_BUFFER_H +#define COMMON_MEMORY_BUFFER_H + +#include "types.h" +#include +#include +#include + +namespace EQEmu +{ + class MemoryBuffer + { + public: + MemoryBuffer(); + MemoryBuffer(size_t sz); + MemoryBuffer(const MemoryBuffer &other); + MemoryBuffer(MemoryBuffer &&other); + MemoryBuffer& operator=(const MemoryBuffer &other); + MemoryBuffer& operator=(MemoryBuffer &&other); + ~MemoryBuffer(); + + uchar& operator[](size_t pos); + const uchar& operator[](size_t pos) const; + + template + operator T*() { + return reinterpret_cast(buffer_); + } + + template + operator T*() const { + return reinterpret_cast(buffer_); + } + + operator bool() { return buffer_ != nullptr; } + operator bool() const { return buffer_ != nullptr; } + + bool Empty(); + bool Empty() const; + size_t Size(); + size_t Size() const; + size_t Capacity(); + size_t Capacity() const; + + void Resize(size_t sz); + void Clear(); + void Zero(); + + template + void Write(T val) { + static_assert(std::is_pod::value, "MemoryBuffer::Write(T val) only works on pod and string types."); + Write((const char*)&val, sizeof(T)); + } + + template + T Read() { + static_assert(std::is_pod::value, "MemoryBuffer::Read() only works on pod and string types."); + T temp; + Read((uchar*)&temp, sizeof(T)); + return temp; + } + + template<> + void Write(std::string val) { + Write(val.c_str(), val.length()); + Write((uint8)0); + } + + template<> + void Write(const std::string &val) { + Write(val.c_str(), val.length()); + Write((uint8)0); + } + + template<> + void Write(const char *val) { + size_t len = strlen(val); + Write(val, len); + Write((uint8)0); + } + + template<> + std::string Read() { + std::string ret; + size_t len = strlen((const char*)&buffer_[read_pos_]); + ret.resize(len); + memcpy(&ret[0], &buffer_[read_pos_], len); + read_pos_ += len + 1; + return ret; + } + + void Write(const char *val, size_t len); + void Read(uchar *buf, size_t len); + void Read(char *str); + + inline size_t GetWritePosition() { return write_pos_; } + inline void SetWritePosition(size_t wp) { write_pos_ = wp; } + inline void WriteSkipBytes(size_t skip) { write_pos_ += skip; } + inline size_t GetReadPosition() { return read_pos_; } + inline void SetReadPosition(size_t wp) { read_pos_ = wp; } + inline void ReadSkipBytes(size_t skip) { read_pos_ += skip; } + + private: + uchar *buffer_; + size_t size_; + size_t capacity_; + size_t write_pos_; + size_t read_pos_; + }; + +} // EQEmu + +#endif \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8d0a733b7..5e10cddba 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -14,6 +14,7 @@ SET(tests_headers hextoi_32_64_test.h inventory_test.h ipc_mutex_test.h + memory_buffer_test.h memory_mapped_file_test.h string_util_test.h skills_util_test.h diff --git a/tests/main.cpp b/tests/main.cpp index 165ab8d82..420280f30 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -30,6 +30,7 @@ #include "data_verification_test.h" #include "skills_util_test.h" #include "inventory_test.h" +#include "memory_buffer_test.h" int main() { try { @@ -46,6 +47,7 @@ int main() { tests.add(new DataVerificationTest()); tests.add(new SkillsUtilsTest()); tests.add(new InventoryTest()); + tests.add(new MemoryBufferTest()); tests.run(*output, false); } catch(...) { return -1; diff --git a/tests/memory_buffer_test.h b/tests/memory_buffer_test.h new file mode 100644 index 000000000..366795bab --- /dev/null +++ b/tests/memory_buffer_test.h @@ -0,0 +1,510 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2013 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 +*/ + +#ifndef __EQEMU_TESTS_MEMORY_BUFFER_H +#define __EQEMU_TESTS_MEMORY_BUFFER_H + +#include "cppunit/cpptest.h" +#include "../common/memory_buffer.h" + +class MemoryBufferTest : public Test::Suite { + typedef void(MemoryBufferTest::*TestFunction)(void); +public: + MemoryBufferTest() { + TEST_ADD(MemoryBufferTest::WriteTest); + TEST_ADD(MemoryBufferTest::ReadTest); + TEST_ADD(MemoryBufferTest::ConvertTest); + TEST_ADD(MemoryBufferTest::ResizeTest); + TEST_ADD(MemoryBufferTest::CopyTest); + TEST_ADD(MemoryBufferTest::AssignTest); + TEST_ADD(MemoryBufferTest::MoveTest); + TEST_ADD(MemoryBufferTest::ZeroTest); + TEST_ADD(MemoryBufferTest::ClearTest); + } + + ~MemoryBufferTest() { + } + +private: + void WriteTest() { + uint8 a = 0; + uint16 b = 5 ; + uint32 c = 10; + uint64 d = 15; + std::string s2 = "test2"; + + mb.Write(a); + mb.Write(b); + mb.Write(c); + mb.Write(d); + mb.Write("test1"); + mb.Write(s2); + + TEST_ASSERT(mb.Size() == 27); + + uchar *data = (uchar*)mb; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + } + + void ReadTest() { + uint8 a = mb.Read(); + uint16 b = mb.Read(); + uint32 c = mb.Read(); + uint64 d = mb.Read(); + std::string s1 = mb.Read(); + std::string s2 = mb.Read(); + + TEST_ASSERT(a == 0); + TEST_ASSERT(b == 5); + TEST_ASSERT(c == 10); + TEST_ASSERT(d == 15); + TEST_ASSERT(s1.compare("test1") == 0); + TEST_ASSERT(s2.compare("test2") == 0); + } + +#pragma pack(1) + struct ConvertStruct + { + uint8 a; + uint16 b; + uint32 c; + uint64 d; + char test1[6]; + char test2[6]; + }; +#pragma pack() + + void ConvertTest() + { + uchar *v1 = mb; + char *v2 = mb; + ConvertStruct *cs = (ConvertStruct*)mb; + + TEST_ASSERT(v1 != nullptr); + TEST_ASSERT(v1[0] == 0); + TEST_ASSERT(v1[1] == 5); + TEST_ASSERT(v1[2] == 0); + TEST_ASSERT(v1[3] == 10); + TEST_ASSERT(v1[4] == 0); + TEST_ASSERT(v1[5] == 0); + TEST_ASSERT(v1[6] == 0); + TEST_ASSERT(v1[7] == 15); + TEST_ASSERT(v1[8] == 0); + TEST_ASSERT(v1[9] == 0); + TEST_ASSERT(v1[10] == 0); + TEST_ASSERT(v1[11] == 0); + TEST_ASSERT(v1[12] == 0); + TEST_ASSERT(v1[13] == 0); + TEST_ASSERT(v1[14] == 0); + TEST_ASSERT(v1[15] == 't'); + TEST_ASSERT(v1[16] == 'e'); + TEST_ASSERT(v1[17] == 's'); + TEST_ASSERT(v1[18] == 't'); + TEST_ASSERT(v1[19] == '1'); + TEST_ASSERT(v1[20] == 0); + TEST_ASSERT(v1[21] == 't'); + TEST_ASSERT(v1[22] == 'e'); + TEST_ASSERT(v1[23] == 's'); + TEST_ASSERT(v1[24] == 't'); + TEST_ASSERT(v1[25] == '2'); + TEST_ASSERT(v1[26] == 0); + + TEST_ASSERT(v2 != nullptr); + TEST_ASSERT(v2[0] == 0); + TEST_ASSERT(v2[1] == 5); + TEST_ASSERT(v2[2] == 0); + TEST_ASSERT(v2[3] == 10); + TEST_ASSERT(v2[4] == 0); + TEST_ASSERT(v2[5] == 0); + TEST_ASSERT(v2[6] == 0); + TEST_ASSERT(v2[7] == 15); + TEST_ASSERT(v2[8] == 0); + TEST_ASSERT(v2[9] == 0); + TEST_ASSERT(v2[10] == 0); + TEST_ASSERT(v2[11] == 0); + TEST_ASSERT(v2[12] == 0); + TEST_ASSERT(v2[13] == 0); + TEST_ASSERT(v2[14] == 0); + TEST_ASSERT(v2[15] == 't'); + TEST_ASSERT(v2[16] == 'e'); + TEST_ASSERT(v2[17] == 's'); + TEST_ASSERT(v2[18] == 't'); + TEST_ASSERT(v2[19] == '1'); + TEST_ASSERT(v2[20] == 0); + TEST_ASSERT(v2[21] == 't'); + TEST_ASSERT(v2[22] == 'e'); + TEST_ASSERT(v2[23] == 's'); + TEST_ASSERT(v2[24] == 't'); + TEST_ASSERT(v2[25] == '2'); + TEST_ASSERT(v2[26] == 0); + + TEST_ASSERT(cs != nullptr); + TEST_ASSERT(cs->a == 0); + TEST_ASSERT(cs->b == 5); + TEST_ASSERT(cs->c == 10); + TEST_ASSERT(cs->d == 15); + TEST_ASSERT(strcmp(cs->test1, "test1") == 0); + TEST_ASSERT(strcmp(cs->test2, "test2") == 0); + } + + void ResizeTest() + { + mb.Resize(21); + TEST_ASSERT(mb.Size() == 21); + + mb.Resize(27); + uchar *data = (uchar*)mb; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + + mb.Resize(40); + data = (uchar*)mb; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(mb.Capacity() >= 40); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + } + + void CopyTest() + { + EQEmu::MemoryBuffer mb2(mb); + + uchar *data = (uchar*)mb2; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + + data = (uchar*)mb; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + TEST_ASSERT((void*)mb != (void*)mb2); + } + + void AssignTest() + { + EQEmu::MemoryBuffer mb2 = mb; + + uchar *data = (uchar*)mb2; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + + data = (uchar*)mb; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + TEST_ASSERT((void*)mb != (void*)mb2); + } + + void MoveTest() + { + EQEmu::MemoryBuffer mb2 = std::move(mb); + uchar *data = (uchar*)mb; + uchar *data2 = (uchar*)mb2; + TEST_ASSERT(data == nullptr); + TEST_ASSERT(data2 != nullptr); + TEST_ASSERT(mb.Size() == 0); + TEST_ASSERT(mb2.Size() == 40); + TEST_ASSERT(data2[0] == 0); + TEST_ASSERT(data2[1] == 5); + TEST_ASSERT(data2[2] == 0); + TEST_ASSERT(data2[3] == 10); + TEST_ASSERT(data2[4] == 0); + TEST_ASSERT(data2[5] == 0); + TEST_ASSERT(data2[6] == 0); + TEST_ASSERT(data2[7] == 15); + TEST_ASSERT(data2[8] == 0); + TEST_ASSERT(data2[9] == 0); + TEST_ASSERT(data2[10] == 0); + TEST_ASSERT(data2[11] == 0); + TEST_ASSERT(data2[12] == 0); + TEST_ASSERT(data2[13] == 0); + TEST_ASSERT(data2[14] == 0); + TEST_ASSERT(data2[15] == 't'); + TEST_ASSERT(data2[16] == 'e'); + TEST_ASSERT(data2[17] == 's'); + TEST_ASSERT(data2[18] == 't'); + TEST_ASSERT(data2[19] == '1'); + TEST_ASSERT(data2[20] == 0); + TEST_ASSERT(data2[21] == 't'); + TEST_ASSERT(data2[22] == 'e'); + TEST_ASSERT(data2[23] == 's'); + TEST_ASSERT(data2[24] == 't'); + TEST_ASSERT(data2[25] == '2'); + TEST_ASSERT(data2[26] == 0); + + mb = std::move(mb2); + + data = (uchar*)mb; + data2 = (uchar*)mb2; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(data2 == nullptr); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(mb2.Size() == 0); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 5); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 10); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 15); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 't'); + TEST_ASSERT(data[16] == 'e'); + TEST_ASSERT(data[17] == 's'); + TEST_ASSERT(data[18] == 't'); + TEST_ASSERT(data[19] == '1'); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 't'); + TEST_ASSERT(data[22] == 'e'); + TEST_ASSERT(data[23] == 's'); + TEST_ASSERT(data[24] == 't'); + TEST_ASSERT(data[25] == '2'); + TEST_ASSERT(data[26] == 0); + } + + void ZeroTest() + { + mb.Zero(); + uchar *data = (uchar*)mb; + TEST_ASSERT(data != nullptr); + TEST_ASSERT(mb.Size() == 40); + TEST_ASSERT(data[0] == 0); + TEST_ASSERT(data[1] == 0); + TEST_ASSERT(data[2] == 0); + TEST_ASSERT(data[3] == 0); + TEST_ASSERT(data[4] == 0); + TEST_ASSERT(data[5] == 0); + TEST_ASSERT(data[6] == 0); + TEST_ASSERT(data[7] == 0); + TEST_ASSERT(data[8] == 0); + TEST_ASSERT(data[9] == 0); + TEST_ASSERT(data[10] == 0); + TEST_ASSERT(data[11] == 0); + TEST_ASSERT(data[12] == 0); + TEST_ASSERT(data[13] == 0); + TEST_ASSERT(data[14] == 0); + TEST_ASSERT(data[15] == 0); + TEST_ASSERT(data[16] == 0); + TEST_ASSERT(data[17] == 0); + TEST_ASSERT(data[18] == 0); + TEST_ASSERT(data[19] == 0); + TEST_ASSERT(data[20] == 0); + TEST_ASSERT(data[21] == 0); + TEST_ASSERT(data[22] == 0); + TEST_ASSERT(data[23] == 0); + TEST_ASSERT(data[24] == 0); + TEST_ASSERT(data[25] == 0); + TEST_ASSERT(data[26] == 0); + TEST_ASSERT(data[27] == 0); + TEST_ASSERT(data[28] == 0); + TEST_ASSERT(data[29] == 0); + TEST_ASSERT(data[30] == 0); + TEST_ASSERT(data[31] == 0); + TEST_ASSERT(data[32] == 0); + TEST_ASSERT(data[33] == 0); + TEST_ASSERT(data[34] == 0); + TEST_ASSERT(data[35] == 0); + TEST_ASSERT(data[36] == 0); + TEST_ASSERT(data[37] == 0); + TEST_ASSERT(data[38] == 0); + TEST_ASSERT(data[39] == 0); + } + + void ClearTest() + { + mb.Clear(); + TEST_ASSERT(!mb); + uchar *data = (uchar*)mb; + TEST_ASSERT(data == nullptr); + } + + EQEmu::MemoryBuffer mb; +}; + +#endif From ca278d029e5fec57bdca650dd72f150484ce77a8 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sun, 22 Feb 2015 19:38:44 -0800 Subject: [PATCH 09/27] Fix for Memory Buffer stuff, have yet to compile so not sure if that's enough. Partial work on RoF inventory bulk send --- common/inventory.cpp | 19 +++++- common/inventory.h | 2 +- common/item_container.cpp | 14 ++++ common/item_container.h | 3 + common/item_data.h | 6 ++ common/memory_buffer.cpp | 23 ++++++- common/memory_buffer.h | 17 ++--- common/patches/rof2.cpp | 132 +++++++++++++++++++++---------------- tests/memory_buffer_test.h | 82 ++++++++++++++++++++++- zone/client_process.cpp | 9 +++ 10 files changed, 233 insertions(+), 74 deletions(-) diff --git a/common/inventory.cpp b/common/inventory.cpp index 96203fda3..05ae27690 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -89,10 +89,25 @@ bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptrcontainers_) { + bool v = iter.second.Serialize(buf, iter.first); + if(v && !value) { + value = true; + } + } + + return value; +} diff --git a/common/inventory.h b/common/inventory.h index b40253e48..27ace1ff5 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -61,7 +61,7 @@ namespace EQEmu bool Put(const InventorySlot &slot, std::shared_ptr inst); bool Swap(const InventorySlot &src, const InventorySlot &dest); - void Serialize(); + bool Serialize(MemoryBuffer &buf); private: struct impl; impl *impl_; diff --git a/common/item_container.cpp b/common/item_container.cpp index 38923a8cb..e84d193e3 100644 --- a/common/item_container.cpp +++ b/common/item_container.cpp @@ -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(container_number); + buf.Write(iter.first); + buf.Write(iter.second.get()); + } + + return true; +} \ No newline at end of file diff --git a/common/item_container.h b/common/item_container.h index 2847b940b..549611858 100644 --- a/common/item_container.h +++ b/common/item_container.h @@ -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 namespace EQEmu @@ -34,6 +35,8 @@ namespace EQEmu std::shared_ptr Get(const int slot_id); bool Put(const int slot_id, std::shared_ptr inst); bool Delete(const int slot_id); + + bool Serialize(MemoryBuffer &buf, int container_number); private: ItemContainer(const ItemContainer &other); ItemContainer& operator=(const ItemContainer &other); diff --git a/common/item_data.h b/common/item_data.h index e5a8fb395..0df9a86a0 100644 --- a/common/item_data.h +++ b/common/item_data.h @@ -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 diff --git a/common/memory_buffer.cpp b/common/memory_buffer.cpp index cd10fe0c2..c8ebaf5b8 100644 --- a/common/memory_buffer.cpp +++ b/common/memory_buffer.cpp @@ -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() { diff --git a/common/memory_buffer.h b/common/memory_buffer.h index beec6b809..26a5897df 100644 --- a/common/memory_buffer.h +++ b/common/memory_buffer.h @@ -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 val) { + void Write(const std::string &val) { Write(val.c_str(), val.length()); Write((uint8)0); } - template<> - void Write(const std::string &val) { - Write(val.c_str(), val.length()); - Write((uint8)0); - } - - template<> - void Write(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 ReadString() { std::string ret; size_t len = strlen((const char*)&buffer_[read_pos_]); ret.resize(len); diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 63a015ab7..3126f13ce 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -12,6 +12,7 @@ #include "../item.h" #include "rof2_structs.h" #include "../rulesys.h" +#include "../memory_buffer.h" #include #include @@ -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(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) diff --git a/tests/memory_buffer_test.h b/tests/memory_buffer_test.h index 366795bab..db5df217e 100644 --- a/tests/memory_buffer_test.h +++ b/tests/memory_buffer_test.h @@ -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(); uint32 c = mb.Read(); uint64 d = mb.Read(); - std::string s1 = mb.Read(); - std::string s2 = mb.Read(); + 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; }; diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 938bfbc87..5adf4bb6f 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -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 From 4e4168852b3c8802fa8f8a7de33d38034b69cdfc Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 23 Feb 2015 01:50:50 -0800 Subject: [PATCH 10/27] Going to start work on SerializingItems for bulk inv sends --- common/patches/rof.cpp | 129 ++++++++++++++++++------------------ common/patches/rof2.cpp | 24 +++++-- common/patches/sod.cpp | 129 ++++++++++++++++++------------------ common/patches/sof.cpp | 125 +++++++++++++++++----------------- common/patches/titanium.cpp | 68 ++++++++++--------- common/patches/uf.cpp | 125 +++++++++++++++++----------------- zone/client_process.cpp | 5 +- 7 files changed, 311 insertions(+), 294 deletions(-) diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 0304dc1d7..a54f0872c 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -532,71 +532,72 @@ namespace RoF { //consume the packet EQApplicationPacket *in = *p; + delete in; - *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) { - - 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); - - 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); + //*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) { + // + // 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); + // + // 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) diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 3126f13ce..60f439777 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -13,6 +13,7 @@ #include "rof2_structs.h" #include "../rulesys.h" #include "../memory_buffer.h" +#include "../item_instance.h" #include #include @@ -26,7 +27,7 @@ namespace RoF2 static Strategy struct_strategy; char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth, ItemPacketType packet_type); - + void SerializeItem(EQEmu::MemoryBuffer &packet_data, EQEmu::ItemInstance *inst, int container_id, int slot_id, int bag_id, int aug_id); // server to client inventory location converters static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType = ItemPacketInvalid); static inline structs::MainInvItemSlotStruct ServerToRoF2MainInvSlot(uint32 serverSlot); @@ -612,14 +613,23 @@ namespace RoF2 return; } - //SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)in->pBuffer; - //EQEmu::MemoryBuffer packet_data; - //packet_data.Write(entries); - // - //for(size_t i = 0; i < entries; ++i) { + SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)in->pBuffer; + EQEmu::MemoryBuffer packet_data; + packet_data.Write(entries); + + for(size_t i = 0; i < entries; ++i) { + EQEmu::ItemInstance *inst = (EQEmu::ItemInstance*)sis[i].inst; + + if(!inst) { + continue; + } + + //SerializeItem(packet_data, inst, sis[i].container_id, sis[i].slot_id, -1, -1, ItemPacketCharInventory); // //SerializeItem((const EQEmu::ItemInstance*) // //char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0, ItemPacketCharInventory); - //} + } + + delete in; //if (in->size == 0) { // diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index a46946c93..f67198b26 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -336,71 +336,72 @@ namespace SoD { //consume the packet EQApplicationPacket *in = *p; + delete in; - *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) { - - 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); - - 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); + //*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) { + // + // 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); + // + // 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_ClientUpdate) diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index ba1bf74cf..e6cf7e83d 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -318,69 +318,70 @@ namespace SoF { //consume the packet EQApplicationPacket *in = *p; + delete in; - *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) { - - 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); - - 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); + //*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) { + // + // 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); + // + // 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_ClientUpdate) diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index 87d091dd3..8c3367697 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -263,40 +263,42 @@ namespace Titanium EQApplicationPacket *in = *p; *p = nullptr; - //store away the emu struct - unsigned char *__emu_buffer = in->pBuffer; + delete in; - 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; - - //do the transform... - int r; - std::string serial_string; - for (r = 0; r < itemcount; r++, eq++) { - uint32 length; - char *serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &length, 0); - if (serialized) { - serial_string.append(serialized, length + 1); - safe_delete_array(serialized); - } - else { - Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id); - } - - } - - in->size = serial_string.length(); - in->pBuffer = new unsigned char[in->size]; - memcpy(in->pBuffer, serial_string.c_str(), serial_string.length()); - - delete[] __emu_buffer; - - dest->FastQueuePacket(&in, ack_req); + ////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; + // + ////do the transform... + //int r; + //std::string serial_string; + //for (r = 0; r < itemcount; r++, eq++) { + // uint32 length; + // char *serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &length, 0); + // if (serialized) { + // serial_string.append(serialized, length + 1); + // safe_delete_array(serialized); + // } + // else { + // Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id); + // } + // + //} + // + //in->size = serial_string.length(); + //in->pBuffer = new unsigned char[in->size]; + //memcpy(in->pBuffer, serial_string.c_str(), serial_string.length()); + // + //delete[] __emu_buffer; + // + //dest->FastQueuePacket(&in, ack_req); } ENCODE(OP_DeleteCharge) { ENCODE_FORWARD(OP_MoveItem); } diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index eb525b1ec..8a1754992 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -474,68 +474,69 @@ namespace UF { //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) { - - 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); - - 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); + delete in; + + //*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) { + // + // 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); + // + // 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_ClientUpdate) diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 5adf4bb6f..901793df2 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -820,8 +820,9 @@ void Client::BulkSendInventoryItems() { return; } - EQApplicationPacket* outapp = new EQApplicationPacket(OP_CharInventory, items.Size()); - memcpy(outapp->pBuffer, items, items.Size()); + EQApplicationPacket outapp(OP_CharInventory, items.Size()); + memcpy(outapp.pBuffer, items, items.Size()); + QueuePacket(&outapp); //int16 slot_id = 0; From 8bce7893ed6073d9138536fdbb5d0e94c8711496 Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 23 Feb 2015 17:33:21 -0800 Subject: [PATCH 11/27] BulkSendItems now works on RoF2 --- common/item_container.cpp | 8 + common/item_container.h | 2 + common/item_instance.cpp | 133 +++++++- common/item_instance.h | 43 ++- common/patches/rof2.cpp | 623 +++++++++++++++++++++++++++++----- common/patches/rof2_structs.h | 2 +- common/shareddb.cpp | 15 +- 7 files changed, 722 insertions(+), 104 deletions(-) diff --git a/common/item_container.cpp b/common/item_container.cpp index e84d193e3..92823fc20 100644 --- a/common/item_container.cpp +++ b/common/item_container.cpp @@ -46,6 +46,14 @@ bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr return false; } +uint32 EQEmu::ItemContainer::Size() { + return impl_->items.size(); +} + +uint32 EQEmu::ItemContainer::Size() const { + return impl_->items.size(); +} + bool EQEmu::ItemContainer::Delete(const int slot_id) { auto iter = impl_->items.find(slot_id); if(iter == impl_->items.end()) { diff --git a/common/item_container.h b/common/item_container.h index 549611858..cc650a19b 100644 --- a/common/item_container.h +++ b/common/item_container.h @@ -35,6 +35,8 @@ namespace EQEmu std::shared_ptr Get(const int slot_id); bool Put(const int slot_id, std::shared_ptr inst); bool Delete(const int slot_id); + uint32 Size(); + uint32 Size() const; bool Serialize(MemoryBuffer &buf, int container_number); private: diff --git a/common/item_instance.cpp b/common/item_instance.cpp index 8a26b7b3c..34f9e9cbf 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -30,8 +30,12 @@ struct EQEmu::ItemInstance::impl { uint32 ornament_idfile_; uint32 ornament_icon_; uint32 ornament_hero_model_; - uint64 tracking_id_; + char tracking_id_[17]; + uint32 serial_id_; uint32 recast_timestamp_; + uint32 merchant_slot_; + uint32 merchant_count_; + uint32 price_; ItemContainer contents_; }; @@ -45,8 +49,12 @@ EQEmu::ItemInstance::ItemInstance() { impl_->ornament_idfile_ = 0; impl_->ornament_icon_ = 0; impl_->ornament_hero_model_ = 0; + impl_->serial_id_ = 0; impl_->recast_timestamp_ = 0; - impl_->tracking_id_ = 0; + impl_->merchant_slot_ = 0; + impl_->merchant_count_ = 0; + impl_->price_ = 0; + memset(impl_->tracking_id_, 0, 17); } EQEmu::ItemInstance::ItemInstance(const ItemData* idata) { @@ -59,8 +67,12 @@ EQEmu::ItemInstance::ItemInstance(const ItemData* idata) { impl_->ornament_idfile_ = 0; impl_->ornament_icon_ = 0; impl_->ornament_hero_model_ = 0; + impl_->serial_id_ = 0; impl_->recast_timestamp_ = 0; - impl_->tracking_id_ = 0; + impl_->merchant_slot_ = 0; + impl_->merchant_count_ = 0; + impl_->price_ = 0; + memset(impl_->tracking_id_, 0, 17); } EQEmu::ItemInstance::ItemInstance(const ItemData* idata, int16 charges) { @@ -74,7 +86,11 @@ EQEmu::ItemInstance::ItemInstance(const ItemData* idata, int16 charges) { impl_->ornament_icon_ = 0; impl_->ornament_hero_model_ = 0; impl_->recast_timestamp_ = 0; - impl_->tracking_id_ = 0; + impl_->serial_id_ = 0; + impl_->merchant_slot_ = 0; + impl_->merchant_count_ = 0; + impl_->price_ = 0; + memset(impl_->tracking_id_, 0, 17); } EQEmu::ItemInstance::~ItemInstance() { @@ -85,6 +101,10 @@ const ItemData *EQEmu::ItemInstance::GetItem() { return impl_->modified_item_ ? impl_->modified_item_ : impl_->base_item_; } +const ItemData *EQEmu::ItemInstance::GetBaseItem() { + return impl_->base_item_; +} + std::shared_ptr EQEmu::ItemInstance::Get(const int index) { if(EQEmu::ValueWithin(index, 0, 255)) { return impl_->contents_.Get(index); @@ -131,6 +151,22 @@ bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr ins return false; } +uint32 EQEmu::ItemInstance::GetSubItemCount() { + return impl_->contents_.Size(); +} + +uint32 EQEmu::ItemInstance::GetSubItemCount() const { + return impl_->contents_.Size(); +} + +int16 EQEmu::ItemInstance::GetCharges() { + return impl_->charges_; +} + +int16 EQEmu::ItemInstance::GetCharges() const { + return impl_->charges_; +} + void EQEmu::ItemInstance::SetCharges(const int16 charges) { impl_->charges_ = charges; } @@ -139,6 +175,14 @@ void EQEmu::ItemInstance::SetColor(const uint32 color) { impl_->color_ = color; } +bool EQEmu::ItemInstance::GetAttuned() { + return impl_->attuned_; +} + +bool EQEmu::ItemInstance::GetAttuned() const { + return impl_->attuned_; +} + void EQEmu::ItemInstance::SetAttuned(const bool attuned) { impl_->attuned_ = attuned; } @@ -160,10 +204,87 @@ void EQEmu::ItemInstance::SetOrnamentHeroModel(const uint32 ornament_hero_model) impl_->ornament_hero_model_ = ornament_hero_model; } -void EQEmu::ItemInstance::SetTrackingID(const uint64 tracking_id) { - impl_->tracking_id_ = tracking_id; +const char* EQEmu::ItemInstance::GetTrackingID() { + return impl_->tracking_id_; +} + +const char* EQEmu::ItemInstance::GetTrackingID() const { + return impl_->tracking_id_; +} + +void EQEmu::ItemInstance::SetTrackingID(const char *tracking_id) { + size_t len = strlen(tracking_id); + if(len > 16) { + return; + } + + strncpy(impl_->tracking_id_, tracking_id, 16); +} + +uint32 EQEmu::ItemInstance::GetRecastTimestamp() { + return impl_->recast_timestamp_; +} + +uint32 EQEmu::ItemInstance::GetRecastTimestamp() const { + return impl_->recast_timestamp_; } void EQEmu::ItemInstance::SetRecastTimestamp(const uint32 recast_timestamp) { impl_->recast_timestamp_ = recast_timestamp; } + +uint32 EQEmu::ItemInstance::GetMerchantSlot() { + return impl_->merchant_slot_; +} + +uint32 EQEmu::ItemInstance::GetMerchantSlot() const { + return impl_->merchant_slot_; +} + +void EQEmu::ItemInstance::SetMerchantSlot(uint32 slot) { + impl_->merchant_slot_ = slot; +} + +uint32 EQEmu::ItemInstance::GetMerchantCount() { + return impl_->merchant_count_; +} + +uint32 EQEmu::ItemInstance::GetMerchantCount() const { + return impl_->merchant_count_; +} + +void EQEmu::ItemInstance::SetMerchantCount(const uint32 cnt) { + impl_->merchant_count_ = cnt; +} + +uint32 EQEmu::ItemInstance::GetPrice() { + return impl_->price_; +} + +uint32 EQEmu::ItemInstance::GetPrice() const { + return impl_->price_; +} + +void EQEmu::ItemInstance::SetPrice(const uint32 p) { + impl_->price_ = p; +} + +uint32 EQEmu::ItemInstance::GetSerialNumber() { + return impl_->serial_id_; +} + +uint32 EQEmu::ItemInstance::GetSerialNumber() const { + return impl_->serial_id_; +} + +void EQEmu::ItemInstance::SetSerialNumber(const uint32 sn) { + impl_->serial_id_ = sn; +} + +bool EQEmu::ItemInstance::IsStackable() { + return impl_->base_item_->Stackable; +} + +bool EQEmu::ItemInstance::IsStackable() const { + return impl_->base_item_->Stackable; +} diff --git a/common/item_instance.h b/common/item_instance.h index 34eeb7384..4fffaf7ee 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -33,18 +33,59 @@ namespace EQEmu ~ItemInstance(); const ItemData *GetItem(); + const ItemData *GetBaseItem(); + + //Container std::shared_ptr Get(const int index); bool Put(const int index, std::shared_ptr inst); + uint32 GetSubItemCount(); + uint32 GetSubItemCount() const; + //Persistent State + int16 GetCharges(); + int16 GetCharges() const; void SetCharges(const int16 charges); + void SetColor(const uint32 color); + + bool GetAttuned(); + bool GetAttuned() const; void SetAttuned(const bool attuned); + void SetCustomData(const std::string &custom_data); void SetOrnamentIDFile(const uint32 ornament_idfile); void SetOrnamentIcon(const uint32 ornament_icon); void SetOrnamentHeroModel(const uint32 ornament_hero_model); - void SetTrackingID(const uint64 tracking_id); + + const char* GetTrackingID(); + const char* GetTrackingID() const; + void SetTrackingID(const char *tracking_id); + + uint32 GetRecastTimestamp(); + uint32 GetRecastTimestamp() const; void SetRecastTimestamp(const uint32 recast_timestamp); + + //Merchant + uint32 GetMerchantSlot(); + uint32 GetMerchantSlot() const; + void SetMerchantSlot(const uint32 slot); + + uint32 GetMerchantCount(); + uint32 GetMerchantCount() const; + void SetMerchantCount(const uint32 cnt); + + uint32 GetPrice(); + uint32 GetPrice() const; + void SetPrice(const uint32 p); + + //Serial Number + uint32 GetSerialNumber(); + uint32 GetSerialNumber() const; + void SetSerialNumber(uint32 sn); + + //Basic Stats + bool IsStackable(); + bool IsStackable() const; private: struct impl; impl *impl_; diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 60f439777..561b40234 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -28,6 +28,7 @@ namespace RoF2 char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth, ItemPacketType packet_type); void SerializeItem(EQEmu::MemoryBuffer &packet_data, EQEmu::ItemInstance *inst, int container_id, int slot_id, int bag_id, int aug_id); + // server to client inventory location converters static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType = ItemPacketInvalid); static inline structs::MainInvItemSlotStruct ServerToRoF2MainInvSlot(uint32 serverSlot); @@ -602,7 +603,6 @@ namespace RoF2 EQApplicationPacket *in = *p; *p = nullptr; - in->SetReadPosition(0); size_t entry_size = sizeof(int32) * 2 + sizeof(void*); size_t entries = in->size / entry_size; @@ -613,7 +613,8 @@ namespace RoF2 return; } - SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)in->pBuffer; + unsigned char *__emu_buffer = in->pBuffer; + SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)__emu_buffer; EQEmu::MemoryBuffer packet_data; packet_data.Write(entries); @@ -624,75 +625,16 @@ namespace RoF2 continue; } - //SerializeItem(packet_data, inst, sis[i].container_id, sis[i].slot_id, -1, -1, ItemPacketCharInventory); - // //SerializeItem((const EQEmu::ItemInstance*) - // //char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0, ItemPacketCharInventory); + SerializeItem(packet_data, inst, sis[i].container_id, sis[i].slot_id, -1, -1); } - delete in; + in->pBuffer = new uchar[packet_data.Size()]; + in->size = packet_data.Size(); + memcpy(in->pBuffer, packet_data, in->size); - //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); + + delete[] __emu_buffer; + dest->FastQueuePacket(&in, ack_req); } ENCODE(OP_ClickObjectAction) @@ -1549,31 +1491,33 @@ namespace RoF2 ENCODE(OP_ItemPacket) { - //consume the packet - EQApplicationPacket *in = *p; - *p = nullptr; + delete *p; - 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); - - uint32 length; - char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0, old_item_pkt->PacketType); - - if (!serialized) { - 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); - - delete[] __emu_buffer; - safe_delete_array(serialized); - dest->FastQueuePacket(&in, ack_req); + ////consume the packet + //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); + // + //uint32 length; + //char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0, old_item_pkt->PacketType); + // + //if (!serialized) { + // 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); + // + //delete[] __emu_buffer; + //safe_delete_array(serialized); + //dest->FastQueuePacket(&in, ack_req); } ENCODE(OP_ItemVerifyReply) @@ -5258,7 +5202,7 @@ namespace RoF2 //sprintf(hdr.unknown000, "06e0002Y1W00"); - snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%016d", item->ID); + snprintf(hdr.tracking_id, sizeof(hdr.tracking_id), "%016d", item->ID); hdr.stacksize = stackable ? charges : 1; hdr.unknown004 = 0; @@ -5794,6 +5738,499 @@ namespace RoF2 return item_serial; } + void SerializeItem(EQEmu::MemoryBuffer &packet_data, EQEmu::ItemInstance *inst, int container_id, int slot_id, int bag_id, int aug_id) { + int ornamentation_augtype = RuleI(Character, OrnamentationAugmentType); + uint8 null_term = 0; + bool stackable = inst->IsStackable(); + uint32 merchant_slot = inst->GetMerchantSlot(); + uint32 charges = inst->GetCharges(); + + const ItemData *item = inst->GetBaseItem(); + RoF2::structs::ItemSerializationHeader hdr; + + snprintf(hdr.tracking_id, sizeof(hdr.tracking_id), "%016d", inst->GetSerialNumber()); + + hdr.stacksize = stackable ? charges : 1; + hdr.unknown004 = 0; + + hdr.slot_type = (merchant_slot == 0) ? container_id : 9; // 9 is merchant 20 is reclaim items? + hdr.main_slot = (merchant_slot == 0) ? slot_id : merchant_slot; + hdr.sub_slot = (merchant_slot == 0) ? bag_id : 0xffff; + hdr.aug_slot = (merchant_slot == 0) ? aug_id : 0xffff; + + hdr.price = inst->GetPrice(); + hdr.merchant_slot = (merchant_slot == 0) ? 1 : inst->GetMerchantCount(); + //hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0; + hdr.scaled_value = 0; + + hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot; + hdr.unknown028 = 0; + hdr.last_cast_time = inst->GetRecastTimestamp(); + hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges); + hdr.inst_nodrop = inst->GetAttuned() ? 1 : 0; + hdr.unknown044 = 0; + hdr.unknown048 = 0; + hdr.unknown052 = 0; + hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0; + packet_data.Write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader)); + + if(item->EvolvingLevel > 0) { + RoF2::structs::EvolvingItem evotop; + evotop.unknown001 = 0; + evotop.unknown002 = 0; + evotop.unknown003 = 0; + evotop.unknown004 = 0; + evotop.evoLevel = item->EvolvingLevel; + evotop.progress = 95.512; + evotop.Activated = 1; + evotop.evomaxlevel = 7; + packet_data.Write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem)); + } + + uint32 orn_icon = 0; + uint32 hero_model = 0; + + //if(inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) + //{ + // char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile()); + // //Mainhand + // packet_data.Write(tmp, strlen(tmp)); + // packet_data.Write((const char*)&null_term, sizeof(uint8)); + // //Offhand + // ss.write(tmp, strlen(tmp)); + // ss.write((const char*)&null_term, sizeof(uint8)); + // orn_icon = inst->GetOrnamentationIcon(); + // hero_model = inst->GetOrnamentHeroModel(InventoryOld::CalcMaterialFromSlot(slot_id_in)); + //} + //else + //{ + packet_data.Write((const char*)&null_term, sizeof(uint8)); // no main hand Ornamentation + packet_data.Write((const char*)&null_term, sizeof(uint8)); // no off hand Ornamentation + //} + + RoF2::structs::ItemSerializationHeaderFinish hdrf; + hdrf.ornamentIcon = orn_icon; + hdrf.unknowna1 = 0xffffffff; + hdrf.ornamentHeroModel = hero_model; + hdrf.unknown063 = 0; + hdrf.Copied = 0; + hdrf.unknowna4 = 0xffffffff; + hdrf.unknowna5 = 0; + hdrf.ItemClass = item->ItemClass; + + packet_data.Write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish)); + + if(strlen(item->Name) > 0) + { + packet_data.Write(item->Name, strlen(item->Name)); + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + else + { + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + + if(strlen(item->Lore) > 0) + { + packet_data.Write(item->Lore, strlen(item->Lore)); + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + else + { + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + + if(strlen(item->IDFile) > 0) + { + packet_data.Write(item->IDFile, strlen(item->IDFile)); + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + else + { + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + + packet_data.Write((const char*)&null_term, sizeof(uint8)); + + RoF2::structs::ItemBodyStruct ibs; + memset(&ibs, 0, sizeof(RoF2::structs::ItemBodyStruct)); + + ibs.id = item->ID; + ibs.weight = item->Weight; + ibs.norent = item->NoRent; + ibs.nodrop = item->NoDrop; + ibs.attune = item->Attuneable; + ibs.size = item->Size; + ibs.slots = SwapBits21and22(item->Slots); + ibs.price = item->Price; + ibs.icon = item->Icon; + ibs.unknown1 = 1; + ibs.unknown2 = 1; + ibs.BenefitFlag = item->BenefitFlag; + ibs.tradeskills = item->Tradeskills; + ibs.CR = item->CR; + ibs.DR = item->DR; + ibs.PR = item->PR; + ibs.MR = item->MR; + ibs.FR = item->FR; + ibs.SVCorruption = item->SVCorruption; + ibs.AStr = item->AStr; + ibs.ASta = item->ASta; + ibs.AAgi = item->AAgi; + ibs.ADex = item->ADex; + ibs.ACha = item->ACha; + ibs.AInt = item->AInt; + ibs.AWis = item->AWis; + + ibs.HP = item->HP; + ibs.Mana = item->Mana; + ibs.Endur = item->Endur; + ibs.AC = item->AC; + ibs.regen = item->Regen; + ibs.mana_regen = item->ManaRegen; + ibs.end_regen = item->EnduranceRegen; + ibs.Classes = item->Classes; + ibs.Races = item->Races; + ibs.Deity = item->Deity; + ibs.SkillModValue = item->SkillModValue; + ibs.SkillModMax = 0xffffffff; + ibs.SkillModType = (int8)(item->SkillModType); + ibs.SkillModExtra = 0; + ibs.BaneDmgRace = item->BaneDmgRace; + ibs.BaneDmgBody = item->BaneDmgBody; + ibs.BaneDmgRaceAmt = item->BaneDmgRaceAmt; + ibs.BaneDmgAmt = item->BaneDmgAmt; + ibs.Magic = item->Magic; + ibs.CastTime_ = item->CastTime_; + ibs.ReqLevel = item->ReqLevel; + if(item->ReqLevel > 100) + ibs.ReqLevel = 100; + ibs.RecLevel = item->RecLevel; + if(item->RecLevel > 100) + ibs.RecLevel = 100; + ibs.RecSkill = item->RecSkill; + ibs.BardType = item->BardType; + ibs.BardValue = item->BardValue; + ibs.Light = item->Light; + ibs.Delay = item->Delay; + ibs.ElemDmgType = item->ElemDmgType; + ibs.ElemDmgAmt = item->ElemDmgAmt; + ibs.Range = item->Range; + ibs.Damage = item->Damage; + ibs.Color = item->Color; + ibs.Prestige = 0; + ibs.ItemType = item->ItemType; + ibs.Material = item->Material; + ibs.MaterialUnknown1 = 0; + ibs.EliteMaterial = item->EliteMaterial; + ibs.HerosForgeModel = item->HerosForgeModel; + ibs.MaterialUnknown2 = 0; + ibs.SellRate = item->SellRate; + ibs.CombatEffects = item->CombatEffects; + ibs.Shielding = item->Shielding; + ibs.StunResist = item->StunResist; + ibs.StrikeThrough = item->StrikeThrough; + ibs.ExtraDmgSkill = item->ExtraDmgSkill; + ibs.ExtraDmgAmt = item->ExtraDmgAmt; + ibs.SpellShield = item->SpellShield; + ibs.Avoidance = item->Avoidance; + ibs.Accuracy = item->Accuracy; + ibs.CharmFileID = item->CharmFileID; + ibs.FactionAmt1 = item->FactionAmt1; + ibs.FactionMod1 = item->FactionMod1; + ibs.FactionAmt2 = item->FactionAmt2; + ibs.FactionMod2 = item->FactionMod2; + ibs.FactionAmt3 = item->FactionAmt3; + ibs.FactionMod3 = item->FactionMod3; + ibs.FactionAmt4 = item->FactionAmt4; + ibs.FactionMod4 = item->FactionMod4; + + packet_data.Write((const char*)&ibs, sizeof(RoF2::structs::ItemBodyStruct)); + + //charm text + if(strlen(item->CharmFile) > 0) + { + packet_data.Write((const char*)item->CharmFile, strlen(item->CharmFile)); + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + else + { + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody secondary struct is %i bytes", sizeof(RoF2::structs::ItemSecondaryBodyStruct)); + RoF2::structs::ItemSecondaryBodyStruct isbs; + memset(&isbs, 0, sizeof(RoF2::structs::ItemSecondaryBodyStruct)); + + isbs.augtype = item->AugType; + isbs.augrestrict2 = -1; + isbs.augrestrict = item->AugRestrict; + + for(int x = AUG_BEGIN; 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]; + } + + isbs.ldonpoint_type = item->PointType; + isbs.ldontheme = item->LDoNTheme; + isbs.ldonprice = item->LDoNPrice; + isbs.ldonsellbackrate = item->LDoNSellBackRate; + isbs.ldonsold = item->LDoNSold; + + isbs.bagtype = item->BagType; + isbs.bagslots = item->BagSlots; + isbs.bagsize = item->BagSize; + isbs.wreduction = item->BagWR; + + isbs.book = item->Book; + isbs.booktype = item->BookType; + + packet_data.Write((const char*)&isbs, sizeof(RoF2::structs::ItemSecondaryBodyStruct)); + + if(strlen(item->Filename) > 0) + { + packet_data.Write((const char*)item->Filename, strlen(item->Filename)); + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + else + { + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody tertiary struct is %i bytes", sizeof(RoF2::structs::ItemTertiaryBodyStruct)); + RoF2::structs::ItemTertiaryBodyStruct itbs; + memset(&itbs, 0, sizeof(RoF2::structs::ItemTertiaryBodyStruct)); + + itbs.loregroup = item->LoreGroup; + itbs.artifact = item->ArtifactFlag; + itbs.summonedflag = item->SummonedFlag; + itbs.favor = item->Favor; + itbs.fvnodrop = item->FVNoDrop; + itbs.dotshield = item->DotShielding; + itbs.atk = item->Attack; + itbs.haste = item->Haste; + itbs.damage_shield = item->DamageShield; + itbs.guildfavor = item->GuildFavor; + itbs.augdistil = item->AugDistiller; + itbs.unknown3 = 0xffffffff; + itbs.unknown4 = 0; + itbs.no_pet = item->NoPet; + itbs.unknown5 = 0; + + itbs.potion_belt_enabled = item->PotionBelt; + itbs.potion_belt_slots = item->PotionBeltSlots; + itbs.stacksize = stackable ? item->StackSize : 0; + itbs.no_transfer = item->NoTransfer; + itbs.expendablearrow = item->ExpendableArrow; + + itbs.unknown8 = 0; + itbs.unknown9 = 0; + itbs.unknown10 = 0; + itbs.unknown11 = 0; + itbs.unknown12 = 0; + itbs.unknown13 = 0; + itbs.unknown14 = 0; + + packet_data.Write((const char*)&itbs, sizeof(RoF2::structs::ItemTertiaryBodyStruct)); + + // Effect Structures Broken down to allow variable length strings for effect names + int32 effect_unknown = 0; + + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Click effect struct is %i bytes", sizeof(RoF2::structs::ClickEffectStruct)); + RoF2::structs::ClickEffectStruct ices; + memset(&ices, 0, sizeof(RoF2::structs::ClickEffectStruct)); + + ices.effect = item->Click.Effect; + ices.level2 = item->Click.Level2; + ices.type = item->Click.Type; + ices.level = item->Click.Level; + ices.max_charges = item->MaxCharges; + ices.cast_time = item->CastTime; + ices.recast = item->RecastDelay; + ices.recast_type = item->RecastType; + + packet_data.Write((const char*)&ices, sizeof(RoF2::structs::ClickEffectStruct)); + + if(strlen(item->ClickName) > 0) + { + packet_data.Write((const char*)item->ClickName, strlen(item->ClickName)); + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + else + { + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + + packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // clickunk7 + + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody proc effect struct is %i bytes", sizeof(RoF2::structs::ProcEffectStruct)); + RoF2::structs::ProcEffectStruct ipes; + memset(&ipes, 0, sizeof(RoF2::structs::ProcEffectStruct)); + + ipes.effect = item->Proc.Effect; + ipes.level2 = item->Proc.Level2; + ipes.type = item->Proc.Type; + ipes.level = item->Proc.Level; + ipes.procrate = item->ProcRate; + + packet_data.Write((const char*)&ipes, sizeof(RoF2::structs::ProcEffectStruct)); + + if(strlen(item->ProcName) > 0) + { + packet_data.Write((const char*)item->ProcName, strlen(item->ProcName)); + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + else + { + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + + packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown5 + + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody worn effect struct is %i bytes", sizeof(RoF2::structs::WornEffectStruct)); + RoF2::structs::WornEffectStruct iwes; + memset(&iwes, 0, sizeof(RoF2::structs::WornEffectStruct)); + + iwes.effect = item->Worn.Effect; + iwes.level2 = item->Worn.Level2; + iwes.type = item->Worn.Type; + iwes.level = item->Worn.Level; + + packet_data.Write((const char*)&iwes, sizeof(RoF2::structs::WornEffectStruct)); + + if(strlen(item->WornName) > 0) + { + packet_data.Write((const char*)item->WornName, strlen(item->WornName)); + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + else + { + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + + packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6 + + RoF2::structs::WornEffectStruct ifes; + memset(&ifes, 0, sizeof(RoF2::structs::WornEffectStruct)); + + ifes.effect = item->Focus.Effect; + ifes.level2 = item->Focus.Level2; + ifes.type = item->Focus.Type; + ifes.level = item->Focus.Level; + + packet_data.Write((const char*)&ifes, sizeof(RoF2::structs::WornEffectStruct)); + + if(strlen(item->FocusName) > 0) + { + packet_data.Write((const char*)item->FocusName, strlen(item->FocusName)); + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + else + { + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + + packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6 + + RoF2::structs::WornEffectStruct ises; + memset(&ises, 0, sizeof(RoF2::structs::WornEffectStruct)); + + ises.effect = item->Scroll.Effect; + ises.level2 = item->Scroll.Level2; + ises.type = item->Scroll.Type; + ises.level = item->Scroll.Level; + + packet_data.Write((const char*)&ises, sizeof(RoF2::structs::WornEffectStruct)); + + if(strlen(item->ScrollName) > 0) + { + packet_data.Write((const char*)item->ScrollName, strlen(item->ScrollName)); + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + else + { + packet_data.Write((const char*)&null_term, sizeof(uint8)); + } + + packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6 + + // Bard Effect? + RoF2::structs::WornEffectStruct ibes; + memset(&ibes, 0, sizeof(RoF2::structs::WornEffectStruct)); + + ibes.effect = item->Bard.Effect; + ibes.level2 = item->Bard.Level2; + ibes.type = item->Bard.Type; + ibes.level = item->Bard.Level; + //ibes.unknown6 = 0xffffffff; + + packet_data.Write((const char*)&ibes, sizeof(RoF2::structs::WornEffectStruct)); + + packet_data.Write((const char*)&null_term, sizeof(uint8)); + + packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6 + // End of Effects + + //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Quaternary effect struct is %i bytes", sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); + RoF2::structs::ItemQuaternaryBodyStruct iqbs; + memset(&iqbs, 0, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); + + iqbs.scriptfileid = item->ScriptFileID; + iqbs.quest_item = item->QuestItemFlag; + iqbs.Power = 0; + iqbs.Purity = item->Purity; + iqbs.unknown16 = 0; + iqbs.BackstabDmg = item->BackstabDmg; + iqbs.DSMitigation = item->DSMitigation; + iqbs.HeroicStr = item->HeroicStr; + iqbs.HeroicInt = item->HeroicInt; + iqbs.HeroicWis = item->HeroicWis; + iqbs.HeroicAgi = item->HeroicAgi; + iqbs.HeroicDex = item->HeroicDex; + iqbs.HeroicSta = item->HeroicSta; + iqbs.HeroicCha = item->HeroicCha; + iqbs.HeroicMR = item->HeroicMR; + iqbs.HeroicFR = item->HeroicFR; + iqbs.HeroicCR = item->HeroicCR; + iqbs.HeroicDR = item->HeroicDR; + iqbs.HeroicPR = item->HeroicPR; + iqbs.HeroicSVCorrup = item->HeroicSVCorrup; + iqbs.HealAmt = item->HealAmt; + iqbs.SpellDmg = item->SpellDmg; + iqbs.clairvoyance = item->Clairvoyance; + + //unknown18; //Power Source Capacity or evolve filename? + //evolve_string; // Some String, but being evolution related is just a guess + + iqbs.Heirloom = 0; + iqbs.Placeable = 0; + + iqbs.unknown28 = -1; + iqbs.unknown30 = -1; + + iqbs.NoZone = 0; + iqbs.NoGround = 0; + iqbs.unknown37a = 0; // (guessed position) New to RoF2 + iqbs.unknown38 = 0; + + iqbs.unknown39 = 1; + + iqbs.subitem_count = inst->GetSubItemCount(); + + packet_data.Write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); + + for(int x = 0; x < 255; ++x) { + auto sub_inst = inst->Get(x); + + if(sub_inst) { + packet_data.Write((const char*)&x, sizeof(uint32)); + SerializeItem(packet_data, sub_inst.get(), container_id, slot_id, x, -1); + } + } + } + static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType) { structs::ItemSlotStruct RoF2Slot; diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index dd5b95863..bb53f7d7c 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -4407,7 +4407,7 @@ struct RoF2SlotStruct struct ItemSerializationHeader { -/*000*/ char unknown000[17]; // New for HoT. Looks like a string. +/*000*/ char tracking_id[17]; // New for HoT. Looks like a string. /*017*/ uint32 stacksize; /*021*/ uint32 unknown004; /*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ? diff --git a/common/shareddb.cpp b/common/shareddb.cpp index e86135fbb..f7f18aeb8 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -15,6 +15,14 @@ #include "shareddb.h" #include "string_util.h" +uint32 ItemInstanceSerial = 1; +static inline uint32 GetNextItemInstanceSerial() { + ItemInstanceSerial++; + return ItemInstanceSerial; +} + + + SharedDatabase::SharedDatabase() : Database(), skill_caps_mmf(nullptr), items_mmf(nullptr), items_hash(nullptr), faction_mmf(nullptr), faction_hash(nullptr), loot_table_mmf(nullptr), loot_table_hash(nullptr), loot_drop_mmf(nullptr), loot_drop_hash(nullptr), base_data_mmf(nullptr) @@ -516,7 +524,6 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::Inventory *inv) uint32 ornament_icon = (uint32)std::stoul(row[9]); uint32 ornament_idfile = (uint32)std::stoul(row[10]); uint32 ornament_hero_model = (uint32)std::stoul(row[11]); - uint64 tracking_id = (uint64)std::stoull(row[12]); inst->SetColor(color); inst->SetAttuned(attuned ? true : false); @@ -524,7 +531,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::Inventory *inv) inst->SetOrnamentIcon(ornament_icon); inst->SetOrnamentIDFile(ornament_idfile); inst->SetOrnamentHeroModel(ornament_hero_model); - inst->SetTrackingID(tracking_id); + inst->SetTrackingID(row[12]); auto *item = inst->GetItem(); if(item->RecastDelay) { @@ -1265,7 +1272,9 @@ std::shared_ptr SharedDatabase::CreateItem(uint32 item_id, charges = 1; } - return std::shared_ptr(new EQEmu::ItemInstance(item, charges)); + std::shared_ptr inst = std::shared_ptr(new EQEmu::ItemInstance(item, charges)); + inst->SetSerialNumber(GetNextItemInstanceSerial()); + return inst; } return std::shared_ptr(nullptr); From 69612b44d48652cc3758938c523d1eb8ff5b1f82 Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 23 Feb 2015 22:45:50 -0800 Subject: [PATCH 12/27] OP_MoveItem encode/decode for RoF2, disabled other patches for now (until i get rof2 packets and mechanics working well enough to go back and fix those) --- common/eq_packet_structs.h | 15 +- common/inventory.cpp | 58 +- common/inventory.h | 43 +- common/item_instance.cpp | 42 ++ common/item_instance.h | 9 + common/memory_buffer.cpp | 36 +- common/patches/patches.cpp | 20 +- common/patches/rof.cpp | 36 +- common/patches/rof2.cpp | 1179 ++++++++++++++++++----------------- common/patches/sod.cpp | 36 +- common/patches/sof.cpp | 36 +- common/patches/titanium.cpp | 36 +- common/patches/uf.cpp | 36 +- tests/inventory_test.h | 2 +- tests/memory_buffer_test.h | 17 + zone/client.h | 6 +- zone/client_packet.cpp | 119 ++-- zone/command.cpp | 142 ++--- zone/inventory.cpp | 238 +++---- zone/trading.cpp | 806 ++++++++++++------------ 20 files changed, 1560 insertions(+), 1352 deletions(-) diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index eec3ecba9..1301b8996 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -1556,7 +1556,7 @@ struct DeleteItem_Struct { /*0012*/ }; -struct MoveItem_Struct +struct MoveItemOld_Struct { /*0000*/ uint32 from_slot; /*0004*/ uint32 to_slot; @@ -1564,6 +1564,19 @@ struct MoveItem_Struct /*0012*/ }; +struct MoveItem_Struct +{ + int16 from_type; + int16 from_slot; + int16 from_bag_slot; + int16 from_aug_slot; + int16 to_type; + int16 to_slot; + int16 to_bag_slot; + int16 to_aug_slot; + uint32 number_in_stack; +}; + // both MoveItem_Struct/DeleteItem_Struct server structures will be changing to a structure-based slot format..this will // be used for handling SoF/SoD/etc... time stamps sent using the MoveItem_Struct format. (nothing will be done with this // info at the moment..but, it is forwarded on to the server for handling/future use) diff --git a/common/inventory.cpp b/common/inventory.cpp index 05ae27690..72b6bc59d 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -61,6 +61,8 @@ bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptrcontainers_.insert(std::pair(slot.type_, ItemContainer())); } + //Verify item can be put into the slot requested + auto &container = impl_->containers_[slot.type_]; if(slot.bag_index_ > -1) { auto item = container.Get(slot.slot_); @@ -92,10 +94,64 @@ bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr Get(const InventorySlot &slot); bool Put(const InventorySlot &slot, std::shared_ptr inst); - bool Swap(const InventorySlot &src, const InventorySlot &dest); + bool Swap(const InventorySlot &src, const InventorySlot &dest, int charges); + //utility + static int CalcMaterialFromSlot(const InventorySlot &slot); + static InventorySlot CalcSlotFromMaterial(int material); bool Serialize(MemoryBuffer &buf); private: struct impl; diff --git a/common/item_instance.cpp b/common/item_instance.cpp index 34f9e9cbf..c95c8e72d 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -192,14 +192,56 @@ void EQEmu::ItemInstance::SetCustomData(const std::string &custom_data) { impl_->custom_data_ = custom_data; } +uint32 EQEmu::ItemInstance::GetOrnamentIDFile() { + return impl_->ornament_idfile_; +} + +uint32 EQEmu::ItemInstance::GetOrnamentIDFile() const { + return impl_->ornament_idfile_; +} + void EQEmu::ItemInstance::SetOrnamentIDFile(const uint32 ornament_idfile) { impl_->ornament_idfile_ = ornament_idfile; } +uint32 EQEmu::ItemInstance::GetOrnamentIcon() { + return impl_->ornament_icon_; +} + +uint32 EQEmu::ItemInstance::GetOrnamentIcon() const { + return impl_->ornament_icon_; +} + void EQEmu::ItemInstance::SetOrnamentIcon(const uint32 ornament_icon) { impl_->ornament_icon_ = ornament_icon; } +uint32 EQEmu::ItemInstance::GetOrnamentHeroModel(int material_slot) { + uint32 hero_model = 0; + if(impl_->ornament_hero_model_ > 0) + { + hero_model = impl_->ornament_hero_model_; + if(material_slot >= 0) + { + hero_model = (impl_->ornament_hero_model_ * 100) + material_slot; + } + } + return hero_model; +} + +uint32 EQEmu::ItemInstance::GetOrnamentHeroModel(int material_slot) const { + uint32 hero_model = 0; + if(impl_->ornament_hero_model_ > 0) + { + hero_model = impl_->ornament_hero_model_; + if(material_slot >= 0) + { + hero_model = (impl_->ornament_hero_model_ * 100) + material_slot; + } + } + return hero_model; +} + void EQEmu::ItemInstance::SetOrnamentHeroModel(const uint32 ornament_hero_model) { impl_->ornament_hero_model_ = ornament_hero_model; } diff --git a/common/item_instance.h b/common/item_instance.h index 4fffaf7ee..595bff390 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -53,8 +53,17 @@ namespace EQEmu void SetAttuned(const bool attuned); void SetCustomData(const std::string &custom_data); + + uint32 GetOrnamentIDFile(); + uint32 GetOrnamentIDFile() const; void SetOrnamentIDFile(const uint32 ornament_idfile); + + uint32 GetOrnamentIcon(); + uint32 GetOrnamentIcon() const; void SetOrnamentIcon(const uint32 ornament_icon); + + uint32 GetOrnamentHeroModel(int material_slot); + uint32 GetOrnamentHeroModel(int material_slot) const; void SetOrnamentHeroModel(const uint32 ornament_hero_model); const char* GetTrackingID(); diff --git a/common/memory_buffer.cpp b/common/memory_buffer.cpp index c8ebaf5b8..0910289e2 100644 --- a/common/memory_buffer.cpp +++ b/common/memory_buffer.cpp @@ -32,20 +32,30 @@ EQEmu::MemoryBuffer::MemoryBuffer(const MemoryBuffer &other) { } EQEmu::MemoryBuffer::MemoryBuffer(MemoryBuffer &&other) { - buffer_ = other.buffer_; - size_ = other.size_; - capacity_ = other.capacity_; - write_pos_ = other.write_pos_; - read_pos_ = other.read_pos_; + uchar *tbuf = other.buffer_; + size_t tsz = other.size_; + size_t tcapacity = other.capacity_; + size_t twrite_pos = other.write_pos_; + size_t tread_pos = other.read_pos_; other.buffer_ = nullptr; other.size_ = 0; other.capacity_ = 0; other.read_pos_ = 0; other.write_pos_ = 0; + + buffer_ = tbuf; + size_ = tsz; + capacity_ = tcapacity; + write_pos_ = twrite_pos; + read_pos_ = tread_pos; } EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(const MemoryBuffer &other) { + if(buffer_) { + delete[] buffer_; + } + if(other.capacity_) { buffer_ = new uchar[other.capacity_]; memcpy(buffer_, other.buffer_, other.capacity_); @@ -62,17 +72,23 @@ EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(const MemoryBuffer &other) { } EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(MemoryBuffer &&other) { - buffer_ = other.buffer_; - size_ = other.size_; - capacity_ = other.capacity_; - write_pos_ = other.write_pos_; - read_pos_ = other.read_pos_; + uchar *tbuf = other.buffer_; + size_t tsz = other.size_; + size_t tcapacity = other.capacity_; + size_t twrite_pos = other.write_pos_; + size_t tread_pos = other.read_pos_; other.buffer_ = nullptr; other.size_ = 0; other.capacity_ = 0; other.read_pos_ = 0; other.write_pos_ = 0; + + buffer_ = tbuf; + size_ = tsz; + capacity_ = tcapacity; + write_pos_ = twrite_pos; + read_pos_ = tread_pos; return *this; } diff --git a/common/patches/patches.cpp b/common/patches/patches.cpp index 3147b89f6..37ff776bc 100644 --- a/common/patches/patches.cpp +++ b/common/patches/patches.cpp @@ -10,19 +10,19 @@ #include "rof2.h" void RegisterAllPatches(EQStreamIdentifier &into) { - Titanium::Register(into); - SoF::Register(into); - SoD::Register(into); - UF::Register(into); - RoF::Register(into); + //Titanium::Register(into); + //SoF::Register(into); + //SoD::Register(into); + //UF::Register(into); + //RoF::Register(into); RoF2::Register(into); } void ReloadAllPatches() { - Titanium::Reload(); - SoF::Reload(); - SoD::Reload(); - UF::Reload(); - RoF::Reload(); + //Titanium::Reload(); + //SoF::Reload(); + //SoD::Reload(); + //UF::Reload(); + //RoF::Reload(); RoF2::Reload(); } diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index a54f0872c..339dd5e2b 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -1707,14 +1707,14 @@ namespace RoF ENCODE(OP_MoveItem) { - ENCODE_LENGTH_EXACT(MoveItem_Struct); - SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct); - - eq->from_slot = ServerToRoFSlot(emu->from_slot); - eq->to_slot = ServerToRoFSlot(emu->to_slot); - OUT(number_in_stack); - - FINISH_ENCODE(); + //ENCODE_LENGTH_EXACT(MoveItem_Struct); + //SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct); + // + //eq->from_slot = ServerToRoFSlot(emu->from_slot); + //eq->to_slot = ServerToRoFSlot(emu->to_slot); + //OUT(number_in_stack); + // + //FINISH_ENCODE(); } ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); } @@ -4684,16 +4684,16 @@ namespace RoF DECODE(OP_MoveItem) { - DECODE_LENGTH_EXACT(structs::MoveItem_Struct); - SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); - - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Moved item from %u to %u", eq->from_slot.MainSlot, eq->to_slot.MainSlot); - Log.Out(Logs::General, Logs::Netcode, "[RoF] MoveItem SlotType from %i to %i, MainSlot from %i to %i, SubSlot from %i to %i, AugSlot from %i to %i, Unknown01 from %i to %i, Number %u", eq->from_slot.SlotType, eq->to_slot.SlotType, eq->from_slot.MainSlot, eq->to_slot.MainSlot, eq->from_slot.SubSlot, eq->to_slot.SubSlot, eq->from_slot.AugSlot, eq->to_slot.AugSlot, eq->from_slot.Unknown01, eq->to_slot.Unknown01, eq->number_in_stack); - emu->from_slot = RoFToServerSlot(eq->from_slot); - emu->to_slot = RoFToServerSlot(eq->to_slot); - IN(number_in_stack); - - FINISH_DIRECT_DECODE(); + //DECODE_LENGTH_EXACT(structs::MoveItem_Struct); + //SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); + // + ////Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Moved item from %u to %u", eq->from_slot.MainSlot, eq->to_slot.MainSlot); + //Log.Out(Logs::General, Logs::Netcode, "[RoF] MoveItem SlotType from %i to %i, MainSlot from %i to %i, SubSlot from %i to %i, AugSlot from %i to %i, Unknown01 from %i to %i, Number %u", eq->from_slot.SlotType, eq->to_slot.SlotType, eq->from_slot.MainSlot, eq->to_slot.MainSlot, eq->from_slot.SubSlot, eq->to_slot.SubSlot, eq->from_slot.AugSlot, eq->to_slot.AugSlot, eq->from_slot.Unknown01, eq->to_slot.Unknown01, eq->number_in_stack); + //emu->from_slot = RoFToServerSlot(eq->from_slot); + //emu->to_slot = RoFToServerSlot(eq->to_slot); + //IN(number_in_stack); + // + //FINISH_DIRECT_DECODE(); } DECODE(OP_PetCommands) diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 561b40234..c3a1fd0f4 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -13,7 +13,7 @@ #include "rof2_structs.h" #include "../rulesys.h" #include "../memory_buffer.h" -#include "../item_instance.h" +#include "../inventory.h" #include #include @@ -26,7 +26,6 @@ namespace RoF2 static OpcodeManager *opcodes = nullptr; static Strategy struct_strategy; - char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth, ItemPacketType packet_type); void SerializeItem(EQEmu::MemoryBuffer &packet_data, EQEmu::ItemInstance *inst, int container_id, int slot_id, int bag_id, int aug_id); // server to client inventory location converters @@ -1749,9 +1748,15 @@ namespace RoF2 ENCODE_LENGTH_EXACT(MoveItem_Struct); SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct); - eq->from_slot = ServerToRoF2Slot(emu->from_slot); - eq->to_slot = ServerToRoF2Slot(emu->to_slot); - OUT(number_in_stack); + eq->from_slot.SlotType = emu->from_type; + eq->from_slot.MainSlot = emu->from_slot; + eq->from_slot.SubSlot = emu->from_bag_slot; + eq->from_slot.AugSlot = emu->from_aug_slot; + eq->to_slot.SlotType = emu->to_type; + eq->to_slot.MainSlot = emu->to_slot; + eq->to_slot.SubSlot = emu->to_bag_slot; + eq->to_slot.AugSlot = emu->to_aug_slot; + eq->number_in_stack = emu->number_in_stack; FINISH_ENCODE(); } @@ -4804,11 +4809,16 @@ namespace RoF2 DECODE_LENGTH_EXACT(structs::MoveItem_Struct); SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); - Log.Out(Logs::General, Logs::Netcode, "[RoF2] MoveItem SlotType from %i to %i, MainSlot from %i to %i, SubSlot from %i to %i, AugSlot from %i to %i, Unknown01 from %i to %i, Number %u", eq->from_slot.SlotType, eq->to_slot.SlotType, eq->from_slot.MainSlot, eq->to_slot.MainSlot, eq->from_slot.SubSlot, eq->to_slot.SubSlot, eq->from_slot.AugSlot, eq->to_slot.AugSlot, eq->from_slot.Unknown01, eq->to_slot.Unknown01, eq->number_in_stack); - emu->from_slot = RoF2ToServerSlot(eq->from_slot); - emu->to_slot = RoF2ToServerSlot(eq->to_slot); - IN(number_in_stack); - + emu->from_type = eq->from_slot.SlotType; + emu->from_slot = eq->from_slot.MainSlot; + emu->from_bag_slot = eq->from_slot.SubSlot; + emu->from_aug_slot = eq->from_slot.AugSlot; + emu->to_type = eq->to_slot.SlotType; + emu->to_slot = eq->to_slot.MainSlot; + emu->to_bag_slot = eq->to_slot.SubSlot; + emu->to_aug_slot = eq->to_slot.AugSlot; + emu->number_in_stack = eq->number_in_stack; + FINISH_DIRECT_DECODE(); } @@ -5183,560 +5193,560 @@ namespace RoF2 return NextItemInstSerialNumber; } - char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth, ItemPacketType packet_type) - { - int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); - 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 ItemData *item = inst->GetUnscaledItem(); - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name); - - RoF2::structs::ItemSerializationHeader hdr; - - //sprintf(hdr.unknown000, "06e0002Y1W00"); - - snprintf(hdr.tracking_id, sizeof(hdr.tracking_id), "%016d", item->ID); - - hdr.stacksize = stackable ? charges : 1; - hdr.unknown004 = 0; - - structs::ItemSlotStruct slot_id = ServerToRoF2Slot(slot_id_in, packet_type); - - hdr.slot_type = (merchant_slot == 0) ? slot_id.SlotType : 9; // 9 is merchant 20 is reclaim items? - hdr.main_slot = (merchant_slot == 0) ? slot_id.MainSlot : merchant_slot; - hdr.sub_slot = (merchant_slot == 0) ? slot_id.SubSlot : 0xffff; - hdr.aug_slot = (merchant_slot == 0) ? slot_id.AugSlot : 0xffff; - 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.unknown028 = 0; - hdr.last_cast_time = inst->GetRecastTimestamp(); - hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges); - hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0; - hdr.unknown044 = 0; - hdr.unknown048 = 0; - hdr.unknown052 = 0; - hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0; - ss.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader)); - - if (item->EvolvingLevel > 0) { - RoF2::structs::EvolvingItem evotop; - evotop.unknown001 = 0; - evotop.unknown002 = 0; - evotop.unknown003 = 0; - evotop.unknown004 = 0; - evotop.evoLevel = item->EvolvingLevel; - evotop.progress = 95.512; - evotop.Activated = 1; - evotop.evomaxlevel = 7; - ss.write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem)); - } - //ORNAMENT IDFILE / ICON - uint32 ornaIcon = 0; - uint32 heroModel = 0; - - if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) - { - char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile()); - //Mainhand - ss.write(tmp, strlen(tmp)); - ss.write((const char*)&null_term, sizeof(uint8)); - //Offhand - ss.write(tmp, strlen(tmp)); - ss.write((const char*)&null_term, sizeof(uint8)); - ornaIcon = inst->GetOrnamentationIcon(); - heroModel = inst->GetOrnamentHeroModel(InventoryOld::CalcMaterialFromSlot(slot_id_in)); - } - else - { - ss.write((const char*)&null_term, sizeof(uint8)); // no main hand Ornamentation - ss.write((const char*)&null_term, sizeof(uint8)); // no off hand Ornamentation - } - - RoF2::structs::ItemSerializationHeaderFinish hdrf; - hdrf.ornamentIcon = ornaIcon; - hdrf.unknowna1 = 0xffffffff; - hdrf.ornamentHeroModel = heroModel; - hdrf.unknown063 = 0; - hdrf.Copied = 0; - hdrf.unknowna4 = 0xffffffff; - hdrf.unknowna5 = 0; - hdrf.ItemClass = item->ItemClass; - - ss.write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish)); - - 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)); - } - - 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)); - } - - 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((const char*)&null_term, sizeof(uint8)); - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody struct is %i bytes", sizeof(RoF2::structs::ItemBodyStruct)); - RoF2::structs::ItemBodyStruct ibs; - memset(&ibs, 0, sizeof(RoF2::structs::ItemBodyStruct)); - - ibs.id = item->ID; - ibs.weight = item->Weight; - ibs.norent = item->NoRent; - ibs.nodrop = item->NoDrop; - ibs.attune = item->Attuneable; - ibs.size = item->Size; - ibs.slots = SwapBits21and22(item->Slots); - ibs.price = item->Price; - ibs.icon = item->Icon; - ibs.unknown1 = 1; - ibs.unknown2 = 1; - ibs.BenefitFlag = item->BenefitFlag; - ibs.tradeskills = item->Tradeskills; - ibs.CR = item->CR; - ibs.DR = item->DR; - ibs.PR = item->PR; - ibs.MR = item->MR; - ibs.FR = item->FR; - ibs.SVCorruption = item->SVCorruption; - ibs.AStr = item->AStr; - ibs.ASta = item->ASta; - ibs.AAgi = item->AAgi; - ibs.ADex = item->ADex; - ibs.ACha = item->ACha; - ibs.AInt = item->AInt; - ibs.AWis = item->AWis; - - ibs.HP = item->HP; - ibs.Mana = item->Mana; - ibs.Endur = item->Endur; - ibs.AC = item->AC; - ibs.regen = item->Regen; - ibs.mana_regen = item->ManaRegen; - ibs.end_regen = item->EnduranceRegen; - ibs.Classes = item->Classes; - ibs.Races = item->Races; - ibs.Deity = item->Deity; - ibs.SkillModValue = item->SkillModValue; - ibs.SkillModMax = 0xffffffff; - ibs.SkillModType = (int8)(item->SkillModType); - ibs.SkillModExtra = 0; - ibs.BaneDmgRace = item->BaneDmgRace; - ibs.BaneDmgBody = item->BaneDmgBody; - ibs.BaneDmgRaceAmt = item->BaneDmgRaceAmt; - ibs.BaneDmgAmt = item->BaneDmgAmt; - ibs.Magic = item->Magic; - ibs.CastTime_ = item->CastTime_; - ibs.ReqLevel = item->ReqLevel; - if (item->ReqLevel > 100) - ibs.ReqLevel = 100; - ibs.RecLevel = item->RecLevel; - if (item->RecLevel > 100) - ibs.RecLevel = 100; - ibs.RecSkill = item->RecSkill; - ibs.BardType = item->BardType; - ibs.BardValue = item->BardValue; - ibs.Light = item->Light; - ibs.Delay = item->Delay; - ibs.ElemDmgType = item->ElemDmgType; - ibs.ElemDmgAmt = item->ElemDmgAmt; - ibs.Range = item->Range; - ibs.Damage = item->Damage; - ibs.Color = item->Color; - ibs.Prestige = 0; - ibs.ItemType = item->ItemType; - ibs.Material = item->Material; - ibs.MaterialUnknown1 = 0; - ibs.EliteMaterial = item->EliteMaterial; - ibs.HerosForgeModel = item->HerosForgeModel; - ibs.MaterialUnknown2 = 0; - ibs.SellRate = item->SellRate; - ibs.CombatEffects = item->CombatEffects; - ibs.Shielding = item->Shielding; - ibs.StunResist = item->StunResist; - ibs.StrikeThrough = item->StrikeThrough; - ibs.ExtraDmgSkill = item->ExtraDmgSkill; - ibs.ExtraDmgAmt = item->ExtraDmgAmt; - ibs.SpellShield = item->SpellShield; - ibs.Avoidance = item->Avoidance; - ibs.Accuracy = item->Accuracy; - ibs.CharmFileID = item->CharmFileID; - ibs.FactionAmt1 = item->FactionAmt1; - ibs.FactionMod1 = item->FactionMod1; - ibs.FactionAmt2 = item->FactionAmt2; - ibs.FactionMod2 = item->FactionMod2; - ibs.FactionAmt3 = item->FactionAmt3; - ibs.FactionMod3 = item->FactionMod3; - ibs.FactionAmt4 = item->FactionAmt4; - ibs.FactionMod4 = item->FactionMod4; - - ss.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((const char*)&null_term, sizeof(uint8)); - } - else - { - ss.write((const char*)&null_term, sizeof(uint8)); - } - - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody secondary struct is %i bytes", sizeof(RoF2::structs::ItemSecondaryBodyStruct)); - RoF2::structs::ItemSecondaryBodyStruct isbs; - memset(&isbs, 0, sizeof(RoF2::structs::ItemSecondaryBodyStruct)); - - isbs.augtype = item->AugType; - isbs.augrestrict2 = -1; - isbs.augrestrict = item->AugRestrict; - - for (int x = AUG_BEGIN; 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]; - } - - isbs.ldonpoint_type = item->PointType; - isbs.ldontheme = item->LDoNTheme; - isbs.ldonprice = item->LDoNPrice; - isbs.ldonsellbackrate = item->LDoNSellBackRate; - isbs.ldonsold = item->LDoNSold; - - isbs.bagtype = item->BagType; - isbs.bagslots = item->BagSlots; - isbs.bagsize = item->BagSize; - isbs.wreduction = item->BagWR; - - isbs.book = item->Book; - isbs.booktype = item->BookType; - - ss.write((const char*)&isbs, sizeof(RoF2::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)); - } - - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody tertiary struct is %i bytes", sizeof(RoF2::structs::ItemTertiaryBodyStruct)); - RoF2::structs::ItemTertiaryBodyStruct itbs; - memset(&itbs, 0, sizeof(RoF2::structs::ItemTertiaryBodyStruct)); - - itbs.loregroup = item->LoreGroup; - itbs.artifact = item->ArtifactFlag; - itbs.summonedflag = item->SummonedFlag; - itbs.favor = item->Favor; - itbs.fvnodrop = item->FVNoDrop; - itbs.dotshield = item->DotShielding; - itbs.atk = item->Attack; - itbs.haste = item->Haste; - itbs.damage_shield = item->DamageShield; - itbs.guildfavor = item->GuildFavor; - itbs.augdistil = item->AugDistiller; - itbs.unknown3 = 0xffffffff; - itbs.unknown4 = 0; - itbs.no_pet = item->NoPet; - itbs.unknown5 = 0; - - itbs.potion_belt_enabled = item->PotionBelt; - itbs.potion_belt_slots = item->PotionBeltSlots; - itbs.stacksize = stackable ? item->StackSize : 0; - itbs.no_transfer = item->NoTransfer; - itbs.expendablearrow = item->ExpendableArrow; - - itbs.unknown8 = 0; - itbs.unknown9 = 0; - itbs.unknown10 = 0; - itbs.unknown11 = 0; - itbs.unknown12 = 0; - itbs.unknown13 = 0; - itbs.unknown14 = 0; - - ss.write((const char*)&itbs, sizeof(RoF2::structs::ItemTertiaryBodyStruct)); - - // Effect Structures Broken down to allow variable length strings for effect names - int32 effect_unknown = 0; - - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Click effect struct is %i bytes", sizeof(RoF2::structs::ClickEffectStruct)); - RoF2::structs::ClickEffectStruct ices; - memset(&ices, 0, sizeof(RoF2::structs::ClickEffectStruct)); - - ices.effect = item->Click.Effect; - ices.level2 = item->Click.Level2; - ices.type = item->Click.Type; - ices.level = item->Click.Level; - ices.max_charges = item->MaxCharges; - ices.cast_time = item->CastTime; - ices.recast = item->RecastDelay; - ices.recast_type = item->RecastType; - - ss.write((const char*)&ices, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // clickunk7 - - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody proc effect struct is %i bytes", sizeof(RoF2::structs::ProcEffectStruct)); - RoF2::structs::ProcEffectStruct ipes; - memset(&ipes, 0, sizeof(RoF2::structs::ProcEffectStruct)); - - ipes.effect = item->Proc.Effect; - ipes.level2 = item->Proc.Level2; - ipes.type = item->Proc.Type; - ipes.level = item->Proc.Level; - ipes.procrate = item->ProcRate; - - ss.write((const char*)&ipes, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // unknown5 - - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody worn effect struct is %i bytes", sizeof(RoF2::structs::WornEffectStruct)); - RoF2::structs::WornEffectStruct iwes; - memset(&iwes, 0, sizeof(RoF2::structs::WornEffectStruct)); - - iwes.effect = item->Worn.Effect; - iwes.level2 = item->Worn.Level2; - iwes.type = item->Worn.Type; - iwes.level = item->Worn.Level; - - ss.write((const char*)&iwes, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // unknown6 - - RoF2::structs::WornEffectStruct ifes; - memset(&ifes, 0, sizeof(RoF2::structs::WornEffectStruct)); - - ifes.effect = item->Focus.Effect; - ifes.level2 = item->Focus.Level2; - ifes.type = item->Focus.Type; - ifes.level = item->Focus.Level; - - ss.write((const char*)&ifes, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // unknown6 - - RoF2::structs::WornEffectStruct ises; - memset(&ises, 0, sizeof(RoF2::structs::WornEffectStruct)); - - ises.effect = item->Scroll.Effect; - ises.level2 = item->Scroll.Level2; - ises.type = item->Scroll.Type; - ises.level = item->Scroll.Level; - - ss.write((const char*)&ises, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // unknown6 - - // Bard Effect? - RoF2::structs::WornEffectStruct ibes; - memset(&ibes, 0, sizeof(RoF2::structs::WornEffectStruct)); - - ibes.effect = item->Bard.Effect; - ibes.level2 = item->Bard.Level2; - ibes.type = item->Bard.Type; - ibes.level = item->Bard.Level; - //ibes.unknown6 = 0xffffffff; - - ss.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)); - } - else */ - ss.write((const char*)&null_term, sizeof(uint8)); - - ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 - // End of Effects - - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Quaternary effect struct is %i bytes", sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); - RoF2::structs::ItemQuaternaryBodyStruct iqbs; - memset(&iqbs, 0, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); - - iqbs.scriptfileid = item->ScriptFileID; - iqbs.quest_item = item->QuestItemFlag; - iqbs.Power = 0; - iqbs.Purity = item->Purity; - iqbs.unknown16 = 0; - iqbs.BackstabDmg = item->BackstabDmg; - iqbs.DSMitigation = item->DSMitigation; - iqbs.HeroicStr = item->HeroicStr; - iqbs.HeroicInt = item->HeroicInt; - iqbs.HeroicWis = item->HeroicWis; - iqbs.HeroicAgi = item->HeroicAgi; - iqbs.HeroicDex = item->HeroicDex; - iqbs.HeroicSta = item->HeroicSta; - iqbs.HeroicCha = item->HeroicCha; - iqbs.HeroicMR = item->HeroicMR; - iqbs.HeroicFR = item->HeroicFR; - iqbs.HeroicCR = item->HeroicCR; - iqbs.HeroicDR = item->HeroicDR; - iqbs.HeroicPR = item->HeroicPR; - iqbs.HeroicSVCorrup = item->HeroicSVCorrup; - iqbs.HealAmt = item->HealAmt; - iqbs.SpellDmg = item->SpellDmg; - iqbs.clairvoyance = item->Clairvoyance; - - //unknown18; //Power Source Capacity or evolve filename? - //evolve_string; // Some String, but being evolution related is just a guess - - iqbs.Heirloom = 0; - iqbs.Placeable = 0; - - iqbs.unknown28 = -1; - iqbs.unknown30 = -1; - - iqbs.NoZone = 0; - iqbs.NoGround = 0; - iqbs.unknown37a = 0; // (guessed position) New to RoF2 - iqbs.unknown38 = 0; - - iqbs.unknown39 = 1; - - iqbs.subitem_count = 0; - - char *SubSerializations[10]; // - - uint32 SubLengths[10]; - - for (int x = SUB_BEGIN; x < EmuConstants::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 >= EmuConstants::GENERAL_BEGIN && slot_id_in <= EmuConstants::GENERAL_END) // (< 30) - no cursor? - //SubSlotNumber = (((slot_id_in + 3) * 10) + x + 1); - SubSlotNumber = (((slot_id_in + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + x + 1); - else if (slot_id_in >= EmuConstants::BANK_BEGIN && slot_id_in <= EmuConstants::BANK_END) - //SubSlotNumber = (((slot_id_in - 2000) * 10) + 2030 + x + 1); - SubSlotNumber = (((slot_id_in - EmuConstants::BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE) + EmuConstants::BANK_BAGS_BEGIN + x); - else if (slot_id_in >= EmuConstants::SHARED_BANK_BEGIN && slot_id_in <= EmuConstants::SHARED_BANK_END) - //SubSlotNumber = (((slot_id_in - 2500) * 10) + 2530 + x + 1); - SubSlotNumber = (((slot_id_in - EmuConstants::SHARED_BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE) + EmuConstants::SHARED_BANK_BAGS_BEGIN + x); - else - SubSlotNumber = slot_id_in; // ??????? - - /* - // TEST CODE: - SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x); - */ - - SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1, packet_type); - } - } - - ss.write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); - - for (int x = SUB_BEGIN; x < EmuConstants::ITEM_CONTAINER_SIZE; ++x) { - - if (SubSerializations[x]) { - - ss.write((const char*)&x, sizeof(uint32)); - - ss.write(SubSerializations[x], SubLengths[x]); - - safe_delete_array(SubSerializations[x]); - } - } - - char* item_serial = new char[ss.tellp()]; - memset(item_serial, 0, ss.tellp()); - memcpy(item_serial, ss.str().c_str(), ss.tellp()); - - *length = ss.tellp(); - return item_serial; - } + //char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth, ItemPacketType packet_type) + //{ + // int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); + // 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 ItemData *item = inst->GetUnscaledItem(); + // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name); + // + // RoF2::structs::ItemSerializationHeader hdr; + // + // //sprintf(hdr.unknown000, "06e0002Y1W00"); + // + // snprintf(hdr.tracking_id, sizeof(hdr.tracking_id), "%016d", item->ID); + // + // hdr.stacksize = stackable ? charges : 1; + // hdr.unknown004 = 0; + // + // structs::ItemSlotStruct slot_id = ServerToRoF2Slot(slot_id_in, packet_type); + // + // hdr.slot_type = (merchant_slot == 0) ? slot_id.SlotType : 9; // 9 is merchant 20 is reclaim items? + // hdr.main_slot = (merchant_slot == 0) ? slot_id.MainSlot : merchant_slot; + // hdr.sub_slot = (merchant_slot == 0) ? slot_id.SubSlot : 0xffff; + // hdr.aug_slot = (merchant_slot == 0) ? slot_id.AugSlot : 0xffff; + // 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.unknown028 = 0; + // hdr.last_cast_time = inst->GetRecastTimestamp(); + // hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges); + // hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0; + // hdr.unknown044 = 0; + // hdr.unknown048 = 0; + // hdr.unknown052 = 0; + // hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0; + // ss.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader)); + // + // if (item->EvolvingLevel > 0) { + // RoF2::structs::EvolvingItem evotop; + // evotop.unknown001 = 0; + // evotop.unknown002 = 0; + // evotop.unknown003 = 0; + // evotop.unknown004 = 0; + // evotop.evoLevel = item->EvolvingLevel; + // evotop.progress = 95.512; + // evotop.Activated = 1; + // evotop.evomaxlevel = 7; + // ss.write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem)); + // } + // //ORNAMENT IDFILE / ICON + // uint32 ornaIcon = 0; + // uint32 heroModel = 0; + // + // if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) + // { + // char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile()); + // //Mainhand + // ss.write(tmp, strlen(tmp)); + // ss.write((const char*)&null_term, sizeof(uint8)); + // //Offhand + // ss.write(tmp, strlen(tmp)); + // ss.write((const char*)&null_term, sizeof(uint8)); + // ornaIcon = inst->GetOrnamentationIcon(); + // heroModel = inst->GetOrnamentHeroModel(InventoryOld::CalcMaterialFromSlot(slot_id_in)); + // } + // else + // { + // ss.write((const char*)&null_term, sizeof(uint8)); // no main hand Ornamentation + // ss.write((const char*)&null_term, sizeof(uint8)); // no off hand Ornamentation + // } + // + // RoF2::structs::ItemSerializationHeaderFinish hdrf; + // hdrf.ornamentIcon = ornaIcon; + // hdrf.unknowna1 = 0xffffffff; + // hdrf.ornamentHeroModel = heroModel; + // hdrf.unknown063 = 0; + // hdrf.Copied = 0; + // hdrf.unknowna4 = 0xffffffff; + // hdrf.unknowna5 = 0; + // hdrf.ItemClass = item->ItemClass; + // + // ss.write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish)); + // + // 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)); + // } + // + // 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)); + // } + // + // 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((const char*)&null_term, sizeof(uint8)); + // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody struct is %i bytes", sizeof(RoF2::structs::ItemBodyStruct)); + // RoF2::structs::ItemBodyStruct ibs; + // memset(&ibs, 0, sizeof(RoF2::structs::ItemBodyStruct)); + // + // ibs.id = item->ID; + // ibs.weight = item->Weight; + // ibs.norent = item->NoRent; + // ibs.nodrop = item->NoDrop; + // ibs.attune = item->Attuneable; + // ibs.size = item->Size; + // ibs.slots = SwapBits21and22(item->Slots); + // ibs.price = item->Price; + // ibs.icon = item->Icon; + // ibs.unknown1 = 1; + // ibs.unknown2 = 1; + // ibs.BenefitFlag = item->BenefitFlag; + // ibs.tradeskills = item->Tradeskills; + // ibs.CR = item->CR; + // ibs.DR = item->DR; + // ibs.PR = item->PR; + // ibs.MR = item->MR; + // ibs.FR = item->FR; + // ibs.SVCorruption = item->SVCorruption; + // ibs.AStr = item->AStr; + // ibs.ASta = item->ASta; + // ibs.AAgi = item->AAgi; + // ibs.ADex = item->ADex; + // ibs.ACha = item->ACha; + // ibs.AInt = item->AInt; + // ibs.AWis = item->AWis; + // + // ibs.HP = item->HP; + // ibs.Mana = item->Mana; + // ibs.Endur = item->Endur; + // ibs.AC = item->AC; + // ibs.regen = item->Regen; + // ibs.mana_regen = item->ManaRegen; + // ibs.end_regen = item->EnduranceRegen; + // ibs.Classes = item->Classes; + // ibs.Races = item->Races; + // ibs.Deity = item->Deity; + // ibs.SkillModValue = item->SkillModValue; + // ibs.SkillModMax = 0xffffffff; + // ibs.SkillModType = (int8)(item->SkillModType); + // ibs.SkillModExtra = 0; + // ibs.BaneDmgRace = item->BaneDmgRace; + // ibs.BaneDmgBody = item->BaneDmgBody; + // ibs.BaneDmgRaceAmt = item->BaneDmgRaceAmt; + // ibs.BaneDmgAmt = item->BaneDmgAmt; + // ibs.Magic = item->Magic; + // ibs.CastTime_ = item->CastTime_; + // ibs.ReqLevel = item->ReqLevel; + // if (item->ReqLevel > 100) + // ibs.ReqLevel = 100; + // ibs.RecLevel = item->RecLevel; + // if (item->RecLevel > 100) + // ibs.RecLevel = 100; + // ibs.RecSkill = item->RecSkill; + // ibs.BardType = item->BardType; + // ibs.BardValue = item->BardValue; + // ibs.Light = item->Light; + // ibs.Delay = item->Delay; + // ibs.ElemDmgType = item->ElemDmgType; + // ibs.ElemDmgAmt = item->ElemDmgAmt; + // ibs.Range = item->Range; + // ibs.Damage = item->Damage; + // ibs.Color = item->Color; + // ibs.Prestige = 0; + // ibs.ItemType = item->ItemType; + // ibs.Material = item->Material; + // ibs.MaterialUnknown1 = 0; + // ibs.EliteMaterial = item->EliteMaterial; + // ibs.HerosForgeModel = item->HerosForgeModel; + // ibs.MaterialUnknown2 = 0; + // ibs.SellRate = item->SellRate; + // ibs.CombatEffects = item->CombatEffects; + // ibs.Shielding = item->Shielding; + // ibs.StunResist = item->StunResist; + // ibs.StrikeThrough = item->StrikeThrough; + // ibs.ExtraDmgSkill = item->ExtraDmgSkill; + // ibs.ExtraDmgAmt = item->ExtraDmgAmt; + // ibs.SpellShield = item->SpellShield; + // ibs.Avoidance = item->Avoidance; + // ibs.Accuracy = item->Accuracy; + // ibs.CharmFileID = item->CharmFileID; + // ibs.FactionAmt1 = item->FactionAmt1; + // ibs.FactionMod1 = item->FactionMod1; + // ibs.FactionAmt2 = item->FactionAmt2; + // ibs.FactionMod2 = item->FactionMod2; + // ibs.FactionAmt3 = item->FactionAmt3; + // ibs.FactionMod3 = item->FactionMod3; + // ibs.FactionAmt4 = item->FactionAmt4; + // ibs.FactionMod4 = item->FactionMod4; + // + // ss.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((const char*)&null_term, sizeof(uint8)); + // } + // else + // { + // ss.write((const char*)&null_term, sizeof(uint8)); + // } + // + // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody secondary struct is %i bytes", sizeof(RoF2::structs::ItemSecondaryBodyStruct)); + // RoF2::structs::ItemSecondaryBodyStruct isbs; + // memset(&isbs, 0, sizeof(RoF2::structs::ItemSecondaryBodyStruct)); + // + // isbs.augtype = item->AugType; + // isbs.augrestrict2 = -1; + // isbs.augrestrict = item->AugRestrict; + // + // for (int x = AUG_BEGIN; 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]; + // } + // + // isbs.ldonpoint_type = item->PointType; + // isbs.ldontheme = item->LDoNTheme; + // isbs.ldonprice = item->LDoNPrice; + // isbs.ldonsellbackrate = item->LDoNSellBackRate; + // isbs.ldonsold = item->LDoNSold; + // + // isbs.bagtype = item->BagType; + // isbs.bagslots = item->BagSlots; + // isbs.bagsize = item->BagSize; + // isbs.wreduction = item->BagWR; + // + // isbs.book = item->Book; + // isbs.booktype = item->BookType; + // + // ss.write((const char*)&isbs, sizeof(RoF2::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)); + // } + // + // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody tertiary struct is %i bytes", sizeof(RoF2::structs::ItemTertiaryBodyStruct)); + // RoF2::structs::ItemTertiaryBodyStruct itbs; + // memset(&itbs, 0, sizeof(RoF2::structs::ItemTertiaryBodyStruct)); + // + // itbs.loregroup = item->LoreGroup; + // itbs.artifact = item->ArtifactFlag; + // itbs.summonedflag = item->SummonedFlag; + // itbs.favor = item->Favor; + // itbs.fvnodrop = item->FVNoDrop; + // itbs.dotshield = item->DotShielding; + // itbs.atk = item->Attack; + // itbs.haste = item->Haste; + // itbs.damage_shield = item->DamageShield; + // itbs.guildfavor = item->GuildFavor; + // itbs.augdistil = item->AugDistiller; + // itbs.unknown3 = 0xffffffff; + // itbs.unknown4 = 0; + // itbs.no_pet = item->NoPet; + // itbs.unknown5 = 0; + // + // itbs.potion_belt_enabled = item->PotionBelt; + // itbs.potion_belt_slots = item->PotionBeltSlots; + // itbs.stacksize = stackable ? item->StackSize : 0; + // itbs.no_transfer = item->NoTransfer; + // itbs.expendablearrow = item->ExpendableArrow; + // + // itbs.unknown8 = 0; + // itbs.unknown9 = 0; + // itbs.unknown10 = 0; + // itbs.unknown11 = 0; + // itbs.unknown12 = 0; + // itbs.unknown13 = 0; + // itbs.unknown14 = 0; + // + // ss.write((const char*)&itbs, sizeof(RoF2::structs::ItemTertiaryBodyStruct)); + // + // // Effect Structures Broken down to allow variable length strings for effect names + // int32 effect_unknown = 0; + // + // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Click effect struct is %i bytes", sizeof(RoF2::structs::ClickEffectStruct)); + // RoF2::structs::ClickEffectStruct ices; + // memset(&ices, 0, sizeof(RoF2::structs::ClickEffectStruct)); + // + // ices.effect = item->Click.Effect; + // ices.level2 = item->Click.Level2; + // ices.type = item->Click.Type; + // ices.level = item->Click.Level; + // ices.max_charges = item->MaxCharges; + // ices.cast_time = item->CastTime; + // ices.recast = item->RecastDelay; + // ices.recast_type = item->RecastType; + // + // ss.write((const char*)&ices, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // clickunk7 + // + // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody proc effect struct is %i bytes", sizeof(RoF2::structs::ProcEffectStruct)); + // RoF2::structs::ProcEffectStruct ipes; + // memset(&ipes, 0, sizeof(RoF2::structs::ProcEffectStruct)); + // + // ipes.effect = item->Proc.Effect; + // ipes.level2 = item->Proc.Level2; + // ipes.type = item->Proc.Type; + // ipes.level = item->Proc.Level; + // ipes.procrate = item->ProcRate; + // + // ss.write((const char*)&ipes, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // unknown5 + // + // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody worn effect struct is %i bytes", sizeof(RoF2::structs::WornEffectStruct)); + // RoF2::structs::WornEffectStruct iwes; + // memset(&iwes, 0, sizeof(RoF2::structs::WornEffectStruct)); + // + // iwes.effect = item->Worn.Effect; + // iwes.level2 = item->Worn.Level2; + // iwes.type = item->Worn.Type; + // iwes.level = item->Worn.Level; + // + // ss.write((const char*)&iwes, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // unknown6 + // + // RoF2::structs::WornEffectStruct ifes; + // memset(&ifes, 0, sizeof(RoF2::structs::WornEffectStruct)); + // + // ifes.effect = item->Focus.Effect; + // ifes.level2 = item->Focus.Level2; + // ifes.type = item->Focus.Type; + // ifes.level = item->Focus.Level; + // + // ss.write((const char*)&ifes, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // unknown6 + // + // RoF2::structs::WornEffectStruct ises; + // memset(&ises, 0, sizeof(RoF2::structs::WornEffectStruct)); + // + // ises.effect = item->Scroll.Effect; + // ises.level2 = item->Scroll.Level2; + // ises.type = item->Scroll.Type; + // ises.level = item->Scroll.Level; + // + // ss.write((const char*)&ises, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // unknown6 + // + // // Bard Effect? + // RoF2::structs::WornEffectStruct ibes; + // memset(&ibes, 0, sizeof(RoF2::structs::WornEffectStruct)); + // + // ibes.effect = item->Bard.Effect; + // ibes.level2 = item->Bard.Level2; + // ibes.type = item->Bard.Type; + // ibes.level = item->Bard.Level; + // //ibes.unknown6 = 0xffffffff; + // + // ss.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)); + // } + // else */ + // ss.write((const char*)&null_term, sizeof(uint8)); + // + // ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 + // // End of Effects + // + // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Quaternary effect struct is %i bytes", sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); + // RoF2::structs::ItemQuaternaryBodyStruct iqbs; + // memset(&iqbs, 0, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); + // + // iqbs.scriptfileid = item->ScriptFileID; + // iqbs.quest_item = item->QuestItemFlag; + // iqbs.Power = 0; + // iqbs.Purity = item->Purity; + // iqbs.unknown16 = 0; + // iqbs.BackstabDmg = item->BackstabDmg; + // iqbs.DSMitigation = item->DSMitigation; + // iqbs.HeroicStr = item->HeroicStr; + // iqbs.HeroicInt = item->HeroicInt; + // iqbs.HeroicWis = item->HeroicWis; + // iqbs.HeroicAgi = item->HeroicAgi; + // iqbs.HeroicDex = item->HeroicDex; + // iqbs.HeroicSta = item->HeroicSta; + // iqbs.HeroicCha = item->HeroicCha; + // iqbs.HeroicMR = item->HeroicMR; + // iqbs.HeroicFR = item->HeroicFR; + // iqbs.HeroicCR = item->HeroicCR; + // iqbs.HeroicDR = item->HeroicDR; + // iqbs.HeroicPR = item->HeroicPR; + // iqbs.HeroicSVCorrup = item->HeroicSVCorrup; + // iqbs.HealAmt = item->HealAmt; + // iqbs.SpellDmg = item->SpellDmg; + // iqbs.clairvoyance = item->Clairvoyance; + // + // //unknown18; //Power Source Capacity or evolve filename? + // //evolve_string; // Some String, but being evolution related is just a guess + // + // iqbs.Heirloom = 0; + // iqbs.Placeable = 0; + // + // iqbs.unknown28 = -1; + // iqbs.unknown30 = -1; + // + // iqbs.NoZone = 0; + // iqbs.NoGround = 0; + // iqbs.unknown37a = 0; // (guessed position) New to RoF2 + // iqbs.unknown38 = 0; + // + // iqbs.unknown39 = 1; + // + // iqbs.subitem_count = 0; + // + // char *SubSerializations[10]; // + // + // uint32 SubLengths[10]; + // + // for (int x = SUB_BEGIN; x < EmuConstants::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 >= EmuConstants::GENERAL_BEGIN && slot_id_in <= EmuConstants::GENERAL_END) // (< 30) - no cursor? + // //SubSlotNumber = (((slot_id_in + 3) * 10) + x + 1); + // SubSlotNumber = (((slot_id_in + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + x + 1); + // else if (slot_id_in >= EmuConstants::BANK_BEGIN && slot_id_in <= EmuConstants::BANK_END) + // //SubSlotNumber = (((slot_id_in - 2000) * 10) + 2030 + x + 1); + // SubSlotNumber = (((slot_id_in - EmuConstants::BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE) + EmuConstants::BANK_BAGS_BEGIN + x); + // else if (slot_id_in >= EmuConstants::SHARED_BANK_BEGIN && slot_id_in <= EmuConstants::SHARED_BANK_END) + // //SubSlotNumber = (((slot_id_in - 2500) * 10) + 2530 + x + 1); + // SubSlotNumber = (((slot_id_in - EmuConstants::SHARED_BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE) + EmuConstants::SHARED_BANK_BAGS_BEGIN + x); + // else + // SubSlotNumber = slot_id_in; // ??????? + // + // /* + // // TEST CODE: + // SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x); + // */ + // + // SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1, packet_type); + // } + // } + // + // ss.write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); + // + // for (int x = SUB_BEGIN; x < EmuConstants::ITEM_CONTAINER_SIZE; ++x) { + // + // if (SubSerializations[x]) { + // + // ss.write((const char*)&x, sizeof(uint32)); + // + // ss.write(SubSerializations[x], SubLengths[x]); + // + // safe_delete_array(SubSerializations[x]); + // } + // } + // + // char* item_serial = new char[ss.tellp()]; + // memset(item_serial, 0, ss.tellp()); + // memcpy(item_serial, ss.str().c_str(), ss.tellp()); + // + // *length = ss.tellp(); + // return item_serial; + //} void SerializeItem(EQEmu::MemoryBuffer &packet_data, EQEmu::ItemInstance *inst, int container_id, int slot_id, int bag_id, int aug_id) { int ornamentation_augtype = RuleI(Character, OrnamentationAugmentType); @@ -5790,23 +5800,24 @@ namespace RoF2 uint32 orn_icon = 0; uint32 hero_model = 0; - //if(inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) - //{ - // char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile()); - // //Mainhand - // packet_data.Write(tmp, strlen(tmp)); - // packet_data.Write((const char*)&null_term, sizeof(uint8)); - // //Offhand - // ss.write(tmp, strlen(tmp)); - // ss.write((const char*)&null_term, sizeof(uint8)); - // orn_icon = inst->GetOrnamentationIcon(); - // hero_model = inst->GetOrnamentHeroModel(InventoryOld::CalcMaterialFromSlot(slot_id_in)); - //} - //else - //{ - packet_data.Write((const char*)&null_term, sizeof(uint8)); // no main hand Ornamentation - packet_data.Write((const char*)&null_term, sizeof(uint8)); // no off hand Ornamentation - //} + if(inst->GetOrnamentIDFile() && inst->GetOrnamentIcon()) + { + char tmp[30] = { 0 }; + sprintf(tmp, "IT%d", inst->GetOrnamentIDFile()); + //Mainhand + packet_data.Write(tmp, strlen(tmp)); + packet_data.Write((const char*)&null_term, sizeof(uint8)); + //Offhand + packet_data.Write(tmp, strlen(tmp)); + packet_data.Write((const char*)&null_term, sizeof(uint8)); + orn_icon = inst->GetOrnamentIcon(); + hero_model = inst->GetOrnamentHeroModel(EQEmu::Inventory::CalcMaterialFromSlot(EQEmu::InventorySlot(container_id, slot_id))); + } + else + { + packet_data.Write((const char*)&null_term, sizeof(uint8)); // no main hand Ornamentation + packet_data.Write((const char*)&null_term, sizeof(uint8)); // no off hand Ornamentation + } RoF2::structs::ItemSerializationHeaderFinish hdrf; hdrf.ornamentIcon = orn_icon; @@ -5958,7 +5969,6 @@ namespace RoF2 packet_data.Write((const char*)&null_term, sizeof(uint8)); } - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody secondary struct is %i bytes", sizeof(RoF2::structs::ItemSecondaryBodyStruct)); RoF2::structs::ItemSecondaryBodyStruct isbs; memset(&isbs, 0, sizeof(RoF2::structs::ItemSecondaryBodyStruct)); @@ -5999,7 +6009,6 @@ namespace RoF2 packet_data.Write((const char*)&null_term, sizeof(uint8)); } - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody tertiary struct is %i bytes", sizeof(RoF2::structs::ItemTertiaryBodyStruct)); RoF2::structs::ItemTertiaryBodyStruct itbs; memset(&itbs, 0, sizeof(RoF2::structs::ItemTertiaryBodyStruct)); @@ -6038,7 +6047,6 @@ namespace RoF2 // Effect Structures Broken down to allow variable length strings for effect names int32 effect_unknown = 0; - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Click effect struct is %i bytes", sizeof(RoF2::structs::ClickEffectStruct)); RoF2::structs::ClickEffectStruct ices; memset(&ices, 0, sizeof(RoF2::structs::ClickEffectStruct)); @@ -6065,7 +6073,6 @@ namespace RoF2 packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // clickunk7 - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody proc effect struct is %i bytes", sizeof(RoF2::structs::ProcEffectStruct)); RoF2::structs::ProcEffectStruct ipes; memset(&ipes, 0, sizeof(RoF2::structs::ProcEffectStruct)); @@ -6089,7 +6096,6 @@ namespace RoF2 packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown5 - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody worn effect struct is %i bytes", sizeof(RoF2::structs::WornEffectStruct)); RoF2::structs::WornEffectStruct iwes; memset(&iwes, 0, sizeof(RoF2::structs::WornEffectStruct)); @@ -6173,7 +6179,6 @@ namespace RoF2 packet_data.Write((const char*)&effect_unknown, sizeof(int32)); // unknown6 // End of Effects - //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Quaternary effect struct is %i bytes", sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); RoF2::structs::ItemQuaternaryBodyStruct iqbs; memset(&iqbs, 0, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index f67198b26..1c0abf90a 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -1265,14 +1265,14 @@ namespace SoD ENCODE(OP_MoveItem) { - ENCODE_LENGTH_EXACT(MoveItem_Struct); - SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct); - - eq->from_slot = ServerToSoDSlot(emu->from_slot); - eq->to_slot = ServerToSoDSlot(emu->to_slot); - OUT(number_in_stack); - - FINISH_ENCODE(); + //ENCODE_LENGTH_EXACT(MoveItem_Struct); + //SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct); + // + //eq->from_slot = ServerToSoDSlot(emu->from_slot); + //eq->to_slot = ServerToSoDSlot(emu->to_slot); + //OUT(number_in_stack); + // + //FINISH_ENCODE(); } ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); } @@ -3260,16 +3260,16 @@ namespace SoD DECODE(OP_MoveItem) { - DECODE_LENGTH_EXACT(structs::MoveItem_Struct); - SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); - - Log.Out(Logs::General, Logs::Netcode, "[SoD] Moved item from %u to %u", eq->from_slot, eq->to_slot); - - emu->from_slot = SoDToServerSlot(eq->from_slot); - emu->to_slot = SoDToServerSlot(eq->to_slot); - IN(number_in_stack); - - FINISH_DIRECT_DECODE(); + //DECODE_LENGTH_EXACT(structs::MoveItem_Struct); + //SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); + // + //Log.Out(Logs::General, Logs::Netcode, "[SoD] Moved item from %u to %u", eq->from_slot, eq->to_slot); + // + //emu->from_slot = SoDToServerSlot(eq->from_slot); + //emu->to_slot = SoDToServerSlot(eq->to_slot); + //IN(number_in_stack); + // + //FINISH_DIRECT_DECODE(); } DECODE(OP_PetCommands) diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index e6cf7e83d..47a45809f 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -930,14 +930,14 @@ namespace SoF ENCODE(OP_MoveItem) { - ENCODE_LENGTH_EXACT(MoveItem_Struct); - SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct); - - eq->from_slot = ServerToSoFSlot(emu->from_slot); - eq->to_slot = ServerToSoFSlot(emu->to_slot); - OUT(number_in_stack); - - FINISH_ENCODE(); + //ENCODE_LENGTH_EXACT(MoveItem_Struct); + //SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct); + // + //eq->from_slot = ServerToSoFSlot(emu->from_slot); + //eq->to_slot = ServerToSoFSlot(emu->to_slot); + //OUT(number_in_stack); + // + //FINISH_ENCODE(); } ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); } @@ -2598,16 +2598,16 @@ namespace SoF DECODE(OP_MoveItem) { - DECODE_LENGTH_EXACT(structs::MoveItem_Struct); - SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); - - Log.Out(Logs::General, Logs::Netcode, "[SoF] Moved item from %u to %u", eq->from_slot, eq->to_slot); - - emu->from_slot = SoFToServerSlot(eq->from_slot); - emu->to_slot = SoFToServerSlot(eq->to_slot); - IN(number_in_stack); - - FINISH_DIRECT_DECODE(); + //DECODE_LENGTH_EXACT(structs::MoveItem_Struct); + //SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); + // + //Log.Out(Logs::General, Logs::Netcode, "[SoF] Moved item from %u to %u", eq->from_slot, eq->to_slot); + // + //emu->from_slot = SoFToServerSlot(eq->from_slot); + //emu->to_slot = SoFToServerSlot(eq->to_slot); + //IN(number_in_stack); + // + //FINISH_DIRECT_DECODE(); } DECODE(OP_PetCommands) diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index 8c3367697..fe7ab2067 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -778,14 +778,14 @@ namespace Titanium ENCODE(OP_MoveItem) { - ENCODE_LENGTH_EXACT(MoveItem_Struct); - SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct); - - eq->from_slot = ServerToTitaniumSlot(emu->from_slot); - eq->to_slot = ServerToTitaniumSlot(emu->to_slot); - OUT(number_in_stack); - - FINISH_ENCODE(); + //ENCODE_LENGTH_EXACT(MoveItem_Struct); + //SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct); + // + //eq->from_slot = ServerToTitaniumSlot(emu->from_slot); + //eq->to_slot = ServerToTitaniumSlot(emu->to_slot); + //OUT(number_in_stack); + // + //FINISH_ENCODE(); } ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); } @@ -1854,16 +1854,16 @@ namespace Titanium DECODE(OP_MoveItem) { - DECODE_LENGTH_EXACT(structs::MoveItem_Struct); - SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); - - Log.Out(Logs::General, Logs::Netcode, "[Titanium] Moved item from %u to %u", eq->from_slot, eq->to_slot); - - emu->from_slot = TitaniumToServerSlot(eq->from_slot); - emu->to_slot = TitaniumToServerSlot(eq->to_slot); - IN(number_in_stack); - - FINISH_DIRECT_DECODE(); + //DECODE_LENGTH_EXACT(structs::MoveItem_Struct); + //SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); + // + //Log.Out(Logs::General, Logs::Netcode, "[Titanium] Moved item from %u to %u", eq->from_slot, eq->to_slot); + // + //emu->from_slot = TitaniumToServerSlot(eq->from_slot); + //emu->to_slot = TitaniumToServerSlot(eq->to_slot); + //IN(number_in_stack); + // + //FINISH_DIRECT_DECODE(); } DECODE(OP_PetCommands) diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index 8a1754992..421a48d6a 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -1504,14 +1504,14 @@ namespace UF ENCODE(OP_MoveItem) { - ENCODE_LENGTH_EXACT(MoveItem_Struct); - SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct); - - eq->from_slot = ServerToUFSlot(emu->from_slot); - eq->to_slot = ServerToUFSlot(emu->to_slot); - OUT(number_in_stack); - - FINISH_ENCODE(); + //ENCODE_LENGTH_EXACT(MoveItem_Struct); + //SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct); + // + //eq->from_slot = ServerToUFSlot(emu->from_slot); + //eq->to_slot = ServerToUFSlot(emu->to_slot); + //OUT(number_in_stack); + // + //FINISH_ENCODE(); } ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); } @@ -3582,16 +3582,16 @@ namespace UF DECODE(OP_MoveItem) { - DECODE_LENGTH_EXACT(structs::MoveItem_Struct); - SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); - - Log.Out(Logs::General, Logs::Netcode, "[UF] Moved item from %u to %u", eq->from_slot, eq->to_slot); - - emu->from_slot = UFToServerSlot(eq->from_slot); - emu->to_slot = UFToServerSlot(eq->to_slot); - IN(number_in_stack); - - FINISH_DIRECT_DECODE(); + //DECODE_LENGTH_EXACT(structs::MoveItem_Struct); + //SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); + // + //Log.Out(Logs::General, Logs::Netcode, "[UF] Moved item from %u to %u", eq->from_slot, eq->to_slot); + // + //emu->from_slot = UFToServerSlot(eq->from_slot); + //emu->to_slot = UFToServerSlot(eq->to_slot); + //IN(number_in_stack); + // + //FINISH_DIRECT_DECODE(); } DECODE(OP_PetCommands) diff --git a/tests/inventory_test.h b/tests/inventory_test.h index 3e25c1748..55ff1f655 100644 --- a/tests/inventory_test.h +++ b/tests/inventory_test.h @@ -175,7 +175,7 @@ private: void InventorySwapItemsTest() { - auto swap_result = inv.Swap(EQEmu::InventorySlot(0, 23), EQEmu::InventorySlot(0, 24)); + auto swap_result = inv.Swap(EQEmu::InventorySlot(0, 23), EQEmu::InventorySlot(0, 24), 0); TEST_ASSERT(swap_result == true); auto m_bag = inv.Get(EQEmu::InventorySlot(0, 24)); diff --git a/tests/memory_buffer_test.h b/tests/memory_buffer_test.h index db5df217e..9d6c0cec7 100644 --- a/tests/memory_buffer_test.h +++ b/tests/memory_buffer_test.h @@ -33,6 +33,7 @@ public: TEST_ADD(MemoryBufferTest::CopyTest); TEST_ADD(MemoryBufferTest::AssignTest); TEST_ADD(MemoryBufferTest::MoveTest); + TEST_ADD(MemoryBufferTest::SelfTest); TEST_ADD(MemoryBufferTest::ZeroTest); TEST_ADD(MemoryBufferTest::ClearTest); TEST_ADD(MemoryBufferTest::AddTest) @@ -449,6 +450,22 @@ private: TEST_ASSERT(data[26] == 0); } + void SelfTest() + { + EQEmu::MemoryBuffer mb2(mb); + void *addr = (void*)mb2; + + mb2 = mb2; + void *addr2 = (void*)mb2; + + TEST_ASSERT(addr != addr2); + + mb2 = std::move(mb2); + addr2 = (void*)mb2; + + TEST_ASSERT(addr2 != nullptr); + } + void ZeroTest() { mb.Zero(); diff --git a/zone/client.h b/zone/client.h index f17d99720..3d4e1c8d0 100644 --- a/zone/client.h +++ b/zone/client.h @@ -813,9 +813,9 @@ public: bool PushItemOnCursor(const ItemInst& inst, bool client_update = false); void SendCursorBuffer(); void DeleteItemInInventory(int16 slot_id, int8 quantity = 0, bool client_update = false, bool update_db = true); - bool SwapItem(MoveItem_Struct* move_in); - void SwapItemResync(MoveItem_Struct* move_slots); - void QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call = false); + bool SwapItem(MoveItemOld_Struct* move_in); + void SwapItemResync(MoveItemOld_Struct* move_slots); + void QSSwapItemAuditor(MoveItemOld_Struct* move_in, bool postaction_call = false); 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 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); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 190a3e272..c49f3e035 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -9586,68 +9586,77 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app) { return; } - + if (app->size != sizeof(MoveItem_Struct)) { Log.Out(Logs::General, Logs::Error, "Wrong size: OP_MoveItem, size=%i, expected %i", app->size, sizeof(MoveItem_Struct)); return; } - + MoveItem_Struct* mi = (MoveItem_Struct*)app->pBuffer; - if (spellend_timer.Enabled() && casting_spell_id && !IsBardSong(casting_spell_id)) - { - if (mi->from_slot != mi->to_slot && (mi->from_slot <= EmuConstants::GENERAL_END || mi->from_slot > 39) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) - { - char *detect = nullptr; - const ItemInst *itm_from = GetInv().GetItem(mi->from_slot); - const ItemInst *itm_to = GetInv().GetItem(mi->to_slot); - MakeAnyLenString(&detect, "Player issued a move item from %u(item id %u) to %u(item id %u) while casting %u.", - mi->from_slot, - itm_from ? itm_from->GetID() : 0, - mi->to_slot, - itm_to ? itm_to->GetID() : 0, - casting_spell_id); - database.SetMQDetectionFlag(AccountName(), GetName(), detect, zone->GetShortName()); - safe_delete_array(detect); - Kick(); // Kick client to prevent client and server from getting out-of-sync inventory slots - return; - } - } + auto res = m_inventory.Swap(EQEmu::InventorySlot(mi->from_type, mi->from_slot, mi->from_bag_slot, mi->from_aug_slot), + EQEmu::InventorySlot(mi->to_type, mi->to_slot, mi->to_bag_slot, mi->to_aug_slot), + mi->number_in_stack); - // Illegal bagslot usage checks. Currently, user only receives a message if this check is triggered. - bool mi_hack = false; + //printf("%i %i %i %i --> %i %i %i %i (%u)\n", + // mi->from_type, mi->from_slot, mi->from_bag_slot, mi->from_aug_slot, + // mi->to_type, mi->to_slot, mi->to_bag_slot, mi->to_aug_slot, + // mi->number_in_stack); - if (mi->from_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->from_slot <= EmuConstants::CURSOR_BAG_END) { - if (mi->from_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; } - else { - int16 from_parent = m_inv.CalcSlotId(mi->from_slot); - if (!m_inv[from_parent]) { mi_hack = true; } - else if (!m_inv[from_parent]->IsType(ItemClassContainer)) { mi_hack = true; } - else if (m_inv.CalcBagIdx(mi->from_slot) >= m_inv[from_parent]->GetItem()->BagSlots) { mi_hack = true; } - } - } - - if (mi->to_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->to_slot <= EmuConstants::CURSOR_BAG_END) { - if (mi->to_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; } - else { - int16 to_parent = m_inv.CalcSlotId(mi->to_slot); - if (!m_inv[to_parent]) { mi_hack = true; } - else if (!m_inv[to_parent]->IsType(ItemClassContainer)) { mi_hack = true; } - else if (m_inv.CalcBagIdx(mi->to_slot) >= m_inv[to_parent]->GetItem()->BagSlots) { mi_hack = true; } - } - } - - if (mi_hack) { Message(15, "Caution: Illegal use of inaccessible bag slots!"); } - - if (!SwapItem(mi) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) { - SwapItemResync(mi); - - bool error = false; - InterrogateInventory(this, false, true, false, error, false); - if (error) - InterrogateInventory(this, true, false, true, error); - } - - return; + //if (spellend_timer.Enabled() && casting_spell_id && !IsBardSong(casting_spell_id)) + //{ + // if (mi->from_slot != mi->to_slot && (mi->from_slot <= EmuConstants::GENERAL_END || mi->from_slot > 39) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) + // { + // char *detect = nullptr; + // const ItemInst *itm_from = GetInv().GetItem(mi->from_slot); + // const ItemInst *itm_to = GetInv().GetItem(mi->to_slot); + // MakeAnyLenString(&detect, "Player issued a move item from %u(item id %u) to %u(item id %u) while casting %u.", + // mi->from_slot, + // itm_from ? itm_from->GetID() : 0, + // mi->to_slot, + // itm_to ? itm_to->GetID() : 0, + // casting_spell_id); + // database.SetMQDetectionFlag(AccountName(), GetName(), detect, zone->GetShortName()); + // safe_delete_array(detect); + // Kick(); // Kick client to prevent client and server from getting out-of-sync inventory slots + // return; + // } + //} + // + //// Illegal bagslot usage checks. Currently, user only receives a message if this check is triggered. + //bool mi_hack = false; + // + //if (mi->from_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->from_slot <= EmuConstants::CURSOR_BAG_END) { + // if (mi->from_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; } + // else { + // int16 from_parent = m_inv.CalcSlotId(mi->from_slot); + // if (!m_inv[from_parent]) { mi_hack = true; } + // else if (!m_inv[from_parent]->IsType(ItemClassContainer)) { mi_hack = true; } + // else if (m_inv.CalcBagIdx(mi->from_slot) >= m_inv[from_parent]->GetItem()->BagSlots) { mi_hack = true; } + // } + //} + // + //if (mi->to_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->to_slot <= EmuConstants::CURSOR_BAG_END) { + // if (mi->to_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; } + // else { + // int16 to_parent = m_inv.CalcSlotId(mi->to_slot); + // if (!m_inv[to_parent]) { mi_hack = true; } + // else if (!m_inv[to_parent]->IsType(ItemClassContainer)) { mi_hack = true; } + // else if (m_inv.CalcBagIdx(mi->to_slot) >= m_inv[to_parent]->GetItem()->BagSlots) { mi_hack = true; } + // } + //} + // + //if (mi_hack) { Message(15, "Caution: Illegal use of inaccessible bag slots!"); } + // + //if (!SwapItem(mi) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) { + // SwapItemResync(mi); + // + // bool error = false; + // InterrogateInventory(this, false, true, false, error, false); + // if (error) + // InterrogateInventory(this, true, false, true, error); + //} + // + //return; } void Client::Handle_OP_OpenContainer(const EQApplicationPacket *app) diff --git a/zone/command.cpp b/zone/command.cpp index 8581e36a9..fed5c7807 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -3119,77 +3119,77 @@ void command_listpetition(Client *c, const Seperator *sep) void command_equipitem(Client *c, const Seperator *sep) { - uint32 slot_id = atoi(sep->arg[1]); - if (sep->IsNumber(1) && ((slot_id >= EmuConstants::EQUIPMENT_BEGIN) && (slot_id <= EmuConstants::EQUIPMENT_END) || (slot_id == MainPowerSource))) { - const ItemInst* from_inst = c->GetInv().GetItem(MainCursor); - const ItemInst* to_inst = c->GetInv().GetItem(slot_id); // added (desync issue when forcing stack to stack) - bool partialmove = false; - int16 movecount; - - if (from_inst && from_inst->IsType(ItemClassCommon)) { - EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct)); - MoveItem_Struct* mi = (MoveItem_Struct*)outapp->pBuffer; - mi->from_slot = MainCursor; - mi->to_slot = slot_id; - // mi->number_in_stack = from_inst->GetCharges(); // replaced with con check for stacking - - // crude stackable check to only 'move' the difference count on client instead of entire stack when applicable - if (to_inst && to_inst->IsStackable() && - (to_inst->GetItem()->ID == from_inst->GetItem()->ID) && - (to_inst->GetCharges() < to_inst->GetItem()->StackSize) && - (from_inst->GetCharges() > to_inst->GetItem()->StackSize - to_inst->GetCharges())) { - movecount = to_inst->GetItem()->StackSize - to_inst->GetCharges(); - mi->number_in_stack = (uint32)movecount; - partialmove = true; - } - else - mi->number_in_stack = from_inst->GetCharges(); - - // Save move changes - // Added conditional check to packet send..would have sent change even on a swap failure..whoops! - - if (partialmove) { // remove this con check if someone can figure out removing charges from cursor stack issue below - // mi->number_in_stack is always from_inst->GetCharges() when partialmove is false - c->Message(13, "Error: Partial stack added to existing stack exceeds allowable stacksize"); - return; - } - else if(c->SwapItem(mi)) { - c->FastQueuePacket(&outapp); - - // if the below code is still needed..just send an an item trade packet to each slot..it should overwrite the client instance - - // below code has proper logic, but client does not like to have cursor charges changed - // (we could delete the cursor item and resend, but issues would arise if there are queued items) - //if (partialmove) { - // EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct)); - // DeleteItem_Struct* di = (DeleteItem_Struct*)outapp2->pBuffer; - // di->from_slot = SLOT_CURSOR; - // di->to_slot = 0xFFFFFFFF; - // di->number_in_stack = 0xFFFFFFFF; - - // c->Message(0, "Deleting %i charges from stack", movecount); // debug line..delete - - // for (int16 deletecount=0; deletecount < movecount; deletecount++) - // have to use 'movecount' because mi->number_in_stack is 'ENCODED' at this point (i.e., 99 charges returns 22...) - // c->QueuePacket(outapp2); - - // safe_delete(outapp2); - //} - } - else { - c->Message(13, "Error: Unable to equip current item"); - } - safe_delete(outapp); - - // also send out a wear change packet? - } - else if (from_inst == nullptr) - c->Message(13, "Error: There is no item on your cursor"); - else - c->Message(13, "Error: Item on your cursor cannot be equipped"); - } - else - c->Message(0, "Usage: #equipitem slotid[0-21] - equips the item on your cursor to the position"); +// uint32 slot_id = atoi(sep->arg[1]); +// if (sep->IsNumber(1) && ((slot_id >= EmuConstants::EQUIPMENT_BEGIN) && (slot_id <= EmuConstants::EQUIPMENT_END) || (slot_id == MainPowerSource))) { +// const ItemInst* from_inst = c->GetInv().GetItem(MainCursor); +// const ItemInst* to_inst = c->GetInv().GetItem(slot_id); // added (desync issue when forcing stack to stack) +// bool partialmove = false; +// int16 movecount; +// +// if (from_inst && from_inst->IsType(ItemClassCommon)) { +// EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct)); +// MoveItem_Struct* mi = (MoveItem_Struct*)outapp->pBuffer; +// mi->from_slot = MainCursor; +// mi->to_slot = slot_id; +// // mi->number_in_stack = from_inst->GetCharges(); // replaced with con check for stacking +// +// // crude stackable check to only 'move' the difference count on client instead of entire stack when applicable +// if (to_inst && to_inst->IsStackable() && +// (to_inst->GetItem()->ID == from_inst->GetItem()->ID) && +// (to_inst->GetCharges() < to_inst->GetItem()->StackSize) && +// (from_inst->GetCharges() > to_inst->GetItem()->StackSize - to_inst->GetCharges())) { +// movecount = to_inst->GetItem()->StackSize - to_inst->GetCharges(); +// mi->number_in_stack = (uint32)movecount; +// partialmove = true; +// } +// else +// mi->number_in_stack = from_inst->GetCharges(); +// +// // Save move changes +// // Added conditional check to packet send..would have sent change even on a swap failure..whoops! +// +// if (partialmove) { // remove this con check if someone can figure out removing charges from cursor stack issue below +// // mi->number_in_stack is always from_inst->GetCharges() when partialmove is false +// c->Message(13, "Error: Partial stack added to existing stack exceeds allowable stacksize"); +// return; +// } +// else if(c->SwapItem(mi)) { +// c->FastQueuePacket(&outapp); +// +// // if the below code is still needed..just send an an item trade packet to each slot..it should overwrite the client instance +// +// // below code has proper logic, but client does not like to have cursor charges changed +// // (we could delete the cursor item and resend, but issues would arise if there are queued items) +// //if (partialmove) { +// // EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct)); +// // DeleteItem_Struct* di = (DeleteItem_Struct*)outapp2->pBuffer; +// // di->from_slot = SLOT_CURSOR; +// // di->to_slot = 0xFFFFFFFF; +// // di->number_in_stack = 0xFFFFFFFF; +// +// // c->Message(0, "Deleting %i charges from stack", movecount); // debug line..delete +// +// // for (int16 deletecount=0; deletecount < movecount; deletecount++) +// // have to use 'movecount' because mi->number_in_stack is 'ENCODED' at this point (i.e., 99 charges returns 22...) +// // c->QueuePacket(outapp2); +// +// // safe_delete(outapp2); +// //} +// } +// else { +// c->Message(13, "Error: Unable to equip current item"); +// } +// safe_delete(outapp); +// +// // also send out a wear change packet? +// } +// else if (from_inst == nullptr) +// c->Message(13, "Error: There is no item on your cursor"); +// else +// c->Message(13, "Error: Item on your cursor cannot be equipped"); +// } +// else +// c->Message(0, "Usage: #equipitem slotid[0-21] - equips the item on your cursor to the position"); } void command_zonelock(Client *c, const Seperator *sep) diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 06eccd9c6..a23bd198e 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -716,122 +716,122 @@ void Client::SendCursorBuffer() // Remove item from inventory void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_update, bool update_db) { - #if (EQDEBUG >= 5) - Log.Out(Logs::General, Logs::None, "DeleteItemInInventory(%i, %i, %s)", slot_id, quantity, (client_update) ? "true":"false"); - #endif - - // Added 'IsSlotValid(slot_id)' check to both segments of client packet processing. - // - cursor queue slots were slipping through and crashing client - if(!m_inv[slot_id]) { - // Make sure the client deletes anything in this slot to match the server. - if(client_update && IsValidSlot(slot_id)) { - EQApplicationPacket* outapp; - outapp = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct)); - DeleteItem_Struct* delitem = (DeleteItem_Struct*)outapp->pBuffer; - delitem->from_slot = slot_id; - delitem->to_slot = 0xFFFFFFFF; - delitem->number_in_stack = 0xFFFFFFFF; - QueuePacket(outapp); - safe_delete(outapp); - } - return; - } - - // start QS code - if(RuleB(QueryServ, PlayerLogDeletes)) { - uint16 delete_count = 0; - - if(m_inv[slot_id]) { delete_count += m_inv.GetItem(slot_id)->GetTotalItemCount(); } - - ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogDeletes, sizeof(QSPlayerLogDelete_Struct) + (sizeof(QSDeleteItems_Struct) * delete_count)); - QSPlayerLogDelete_Struct* qsaudit = (QSPlayerLogDelete_Struct*)qspack->pBuffer; - uint16 parent_offset = 0; - - qsaudit->char_id = character_id; - qsaudit->stack_size = quantity; - qsaudit->char_count = delete_count; - - qsaudit->items[parent_offset].char_slot = slot_id; - qsaudit->items[parent_offset].item_id = m_inv[slot_id]->GetID(); - qsaudit->items[parent_offset].charges = m_inv[slot_id]->GetCharges(); - qsaudit->items[parent_offset].aug_1 = m_inv[slot_id]->GetAugmentItemID(1); - qsaudit->items[parent_offset].aug_2 = m_inv[slot_id]->GetAugmentItemID(2); - qsaudit->items[parent_offset].aug_3 = m_inv[slot_id]->GetAugmentItemID(3); - qsaudit->items[parent_offset].aug_4 = m_inv[slot_id]->GetAugmentItemID(4); - qsaudit->items[parent_offset].aug_5 = m_inv[slot_id]->GetAugmentItemID(5); - - if(m_inv[slot_id]->IsType(ItemClassContainer)) { - for(uint8 bag_idx = SUB_BEGIN; bag_idx < m_inv[slot_id]->GetItem()->BagSlots; bag_idx++) { - ItemInst* bagitem = m_inv[slot_id]->GetItem(bag_idx); - - if(bagitem) { - int16 bagslot_id = InventoryOld::CalcSlotId(slot_id, bag_idx); - - qsaudit->items[++parent_offset].char_slot = bagslot_id; - qsaudit->items[parent_offset].item_id = bagitem->GetID(); - qsaudit->items[parent_offset].charges = bagitem->GetCharges(); - qsaudit->items[parent_offset].aug_1 = bagitem->GetAugmentItemID(1); - qsaudit->items[parent_offset].aug_2 = bagitem->GetAugmentItemID(2); - qsaudit->items[parent_offset].aug_3 = bagitem->GetAugmentItemID(3); - qsaudit->items[parent_offset].aug_4 = bagitem->GetAugmentItemID(4); - qsaudit->items[parent_offset].aug_5 = bagitem->GetAugmentItemID(5); - } - } - } - - qspack->Deflate(); - if(worldserver.Connected()) { worldserver.SendPacket(qspack); } - safe_delete(qspack); - } - // end QS code - - bool isDeleted = m_inv.DeleteItem(slot_id, quantity); - - const ItemInst* inst = nullptr; - if (slot_id == MainCursor) { - auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); - if(update_db) - database.SaveCursor(character_id, s, e); - } - else { - // Save change to database - inst = m_inv[slot_id]; - if(update_db) - database.SaveInventory(character_id, inst, slot_id); - } - - if(client_update && IsValidSlot(slot_id)) { - EQApplicationPacket* outapp = nullptr; - if(inst) { - if (!inst->IsStackable() && !isDeleted) { - // Non stackable item with charges = Item with clicky spell effect ? Delete a charge. - outapp = new EQApplicationPacket(OP_DeleteCharge, sizeof(MoveItem_Struct)); - } - else { - // Stackable, arrows, etc ? Delete one from the stack - outapp = new EQApplicationPacket(OP_DeleteItem, sizeof(MoveItem_Struct)); - } - - DeleteItem_Struct* delitem = (DeleteItem_Struct*)outapp->pBuffer; - delitem->from_slot = slot_id; - delitem->to_slot = 0xFFFFFFFF; - delitem->number_in_stack = 0xFFFFFFFF; - - for(int loop=0;looppBuffer; - delitem->from_slot = slot_id; - delitem->to_slot = 0xFFFFFFFF; - delitem->number_in_stack = 0xFFFFFFFF; - - QueuePacket(outapp); - safe_delete(outapp); - } - } +// #if (EQDEBUG >= 5) +// Log.Out(Logs::General, Logs::None, "DeleteItemInInventory(%i, %i, %s)", slot_id, quantity, (client_update) ? "true":"false"); +// #endif +// +// // Added 'IsSlotValid(slot_id)' check to both segments of client packet processing. +// // - cursor queue slots were slipping through and crashing client +// if(!m_inv[slot_id]) { +// // Make sure the client deletes anything in this slot to match the server. +// if(client_update && IsValidSlot(slot_id)) { +// EQApplicationPacket* outapp; +// outapp = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct)); +// DeleteItem_Struct* delitem = (DeleteItem_Struct*)outapp->pBuffer; +// delitem->from_slot = slot_id; +// delitem->to_slot = 0xFFFFFFFF; +// delitem->number_in_stack = 0xFFFFFFFF; +// QueuePacket(outapp); +// safe_delete(outapp); +// } +// return; +// } +// +// // start QS code +// if(RuleB(QueryServ, PlayerLogDeletes)) { +// uint16 delete_count = 0; +// +// if(m_inv[slot_id]) { delete_count += m_inv.GetItem(slot_id)->GetTotalItemCount(); } +// +// ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogDeletes, sizeof(QSPlayerLogDelete_Struct) + (sizeof(QSDeleteItems_Struct) * delete_count)); +// QSPlayerLogDelete_Struct* qsaudit = (QSPlayerLogDelete_Struct*)qspack->pBuffer; +// uint16 parent_offset = 0; +// +// qsaudit->char_id = character_id; +// qsaudit->stack_size = quantity; +// qsaudit->char_count = delete_count; +// +// qsaudit->items[parent_offset].char_slot = slot_id; +// qsaudit->items[parent_offset].item_id = m_inv[slot_id]->GetID(); +// qsaudit->items[parent_offset].charges = m_inv[slot_id]->GetCharges(); +// qsaudit->items[parent_offset].aug_1 = m_inv[slot_id]->GetAugmentItemID(1); +// qsaudit->items[parent_offset].aug_2 = m_inv[slot_id]->GetAugmentItemID(2); +// qsaudit->items[parent_offset].aug_3 = m_inv[slot_id]->GetAugmentItemID(3); +// qsaudit->items[parent_offset].aug_4 = m_inv[slot_id]->GetAugmentItemID(4); +// qsaudit->items[parent_offset].aug_5 = m_inv[slot_id]->GetAugmentItemID(5); +// +// if(m_inv[slot_id]->IsType(ItemClassContainer)) { +// for(uint8 bag_idx = SUB_BEGIN; bag_idx < m_inv[slot_id]->GetItem()->BagSlots; bag_idx++) { +// ItemInst* bagitem = m_inv[slot_id]->GetItem(bag_idx); +// +// if(bagitem) { +// int16 bagslot_id = InventoryOld::CalcSlotId(slot_id, bag_idx); +// +// qsaudit->items[++parent_offset].char_slot = bagslot_id; +// qsaudit->items[parent_offset].item_id = bagitem->GetID(); +// qsaudit->items[parent_offset].charges = bagitem->GetCharges(); +// qsaudit->items[parent_offset].aug_1 = bagitem->GetAugmentItemID(1); +// qsaudit->items[parent_offset].aug_2 = bagitem->GetAugmentItemID(2); +// qsaudit->items[parent_offset].aug_3 = bagitem->GetAugmentItemID(3); +// qsaudit->items[parent_offset].aug_4 = bagitem->GetAugmentItemID(4); +// qsaudit->items[parent_offset].aug_5 = bagitem->GetAugmentItemID(5); +// } +// } +// } +// +// qspack->Deflate(); +// if(worldserver.Connected()) { worldserver.SendPacket(qspack); } +// safe_delete(qspack); +// } +// // end QS code +// +// bool isDeleted = m_inv.DeleteItem(slot_id, quantity); +// +// const ItemInst* inst = nullptr; +// if (slot_id == MainCursor) { +// auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); +// if(update_db) +// database.SaveCursor(character_id, s, e); +// } +// else { +// // Save change to database +// inst = m_inv[slot_id]; +// if(update_db) +// database.SaveInventory(character_id, inst, slot_id); +// } +// +// if(client_update && IsValidSlot(slot_id)) { +// EQApplicationPacket* outapp = nullptr; +// if(inst) { +// if (!inst->IsStackable() && !isDeleted) { +// // Non stackable item with charges = Item with clicky spell effect ? Delete a charge. +// outapp = new EQApplicationPacket(OP_DeleteCharge, sizeof(MoveItem_Struct)); +// } +// else { +// // Stackable, arrows, etc ? Delete one from the stack +// outapp = new EQApplicationPacket(OP_DeleteItem, sizeof(MoveItem_Struct)); +// } +// +// DeleteItem_Struct* delitem = (DeleteItem_Struct*)outapp->pBuffer; +// delitem->from_slot = slot_id; +// delitem->to_slot = 0xFFFFFFFF; +// delitem->number_in_stack = 0xFFFFFFFF; +// +// for(int loop=0;looppBuffer; +// delitem->from_slot = slot_id; +// delitem->to_slot = 0xFFFFFFFF; +// delitem->number_in_stack = 0xFFFFFFFF; +// +// QueuePacket(outapp); +// safe_delete(outapp); +// } +// } } bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update) @@ -1315,7 +1315,7 @@ bool Client::IsBankSlot(uint32 slot) // Moves items around both internally and in the database // In the future, this can be optimized by pushing all changes through one database REPLACE call -bool Client::SwapItem(MoveItem_Struct* move_in) { +bool Client::SwapItem(MoveItemOld_Struct* move_in) { uint32 src_slot_check = move_in->from_slot; uint32 dst_slot_check = move_in->to_slot; @@ -1788,7 +1788,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { return true; } -void Client::SwapItemResync(MoveItem_Struct* move_slots) { +void Client::SwapItemResync(MoveItemOld_Struct* move_slots) { // wow..this thing created a helluva memory leak... // with any luck..this won't be needed in the future @@ -1883,7 +1883,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { } } -void Client::QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call) { +void Client::QSSwapItemAuditor(MoveItemOld_Struct* move_in, bool postaction_call) { int16 from_slot_id = static_cast(move_in->from_slot); int16 to_slot_id = static_cast(move_in->to_slot); int16 move_amount = static_cast(move_in->number_in_stack); diff --git a/zone/trading.cpp b/zone/trading.cpp index b5bb3e42f..0af87625f 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -1333,68 +1333,68 @@ uint16 Client::FindTraderItem(int32 SerialNumber, uint16 Quantity){ } void Client::NukeTraderItem(uint16 Slot,int16 Charges,uint16 Quantity,Client* Customer,uint16 TraderSlot, int32 SerialNumber, int32 itemid) { - - if(!Customer) - return; - - Log.Out(Logs::Detail, Logs::Trading, "NukeTraderItem(Slot %i, Charges %i, Quantity %i", Slot, Charges, Quantity); - - if(Quantity < Charges) - { - Customer->SendSingleTraderItem(this->CharacterID(), SerialNumber); - m_inv.DeleteItem(Slot, Quantity); - } - else - { - EQApplicationPacket* outapp = new EQApplicationPacket(OP_TraderDelItem,sizeof(TraderDelItem_Struct)); - TraderDelItem_Struct* tdis = (TraderDelItem_Struct*)outapp->pBuffer; - - tdis->Unknown000 = 0; - tdis->TraderID = Customer->GetID(); - if (Customer->GetClientVersion() >= ClientVersion::RoF) - { - // RoF+ use Item IDs for now - tdis->ItemID = itemid; - } - else - { - tdis->ItemID = SerialNumber; - } - tdis->Unknown012 = 0; - - - Customer->QueuePacket(outapp); - safe_delete(outapp); - - m_inv.DeleteItem(Slot); - } - // This updates the trader. Removes it from his trading bags. - // - const ItemInst* Inst = m_inv[Slot]; - - database.SaveInventory(CharacterID(), Inst, Slot); - - EQApplicationPacket* outapp2; - - if(Quantity < Charges) - outapp2 = new EQApplicationPacket(OP_DeleteItem,sizeof(MoveItem_Struct)); - else - outapp2 = new EQApplicationPacket(OP_MoveItem,sizeof(MoveItem_Struct)); - - MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer; - mis->from_slot = Slot; - mis->to_slot = 0xFFFFFFFF; - mis->number_in_stack = 0xFFFFFFFF; - - if(Quantity >= Charges) - Quantity = 1; - - for(int i = 0; i < Quantity; i++) { - - this->QueuePacket(outapp2); - } - safe_delete(outapp2); - +// +// if(!Customer) +// return; +// +// Log.Out(Logs::Detail, Logs::Trading, "NukeTraderItem(Slot %i, Charges %i, Quantity %i", Slot, Charges, Quantity); +// +// if(Quantity < Charges) +// { +// Customer->SendSingleTraderItem(this->CharacterID(), SerialNumber); +// m_inv.DeleteItem(Slot, Quantity); +// } +// else +// { +// EQApplicationPacket* outapp = new EQApplicationPacket(OP_TraderDelItem,sizeof(TraderDelItem_Struct)); +// TraderDelItem_Struct* tdis = (TraderDelItem_Struct*)outapp->pBuffer; +// +// tdis->Unknown000 = 0; +// tdis->TraderID = Customer->GetID(); +// if (Customer->GetClientVersion() >= ClientVersion::RoF) +// { +// // RoF+ use Item IDs for now +// tdis->ItemID = itemid; +// } +// else +// { +// tdis->ItemID = SerialNumber; +// } +// tdis->Unknown012 = 0; +// +// +// Customer->QueuePacket(outapp); +// safe_delete(outapp); +// +// m_inv.DeleteItem(Slot); +// } +// // This updates the trader. Removes it from his trading bags. +// // +// const ItemInst* Inst = m_inv[Slot]; +// +// database.SaveInventory(CharacterID(), Inst, Slot); +// +// EQApplicationPacket* outapp2; +// +// if(Quantity < Charges) +// outapp2 = new EQApplicationPacket(OP_DeleteItem,sizeof(MoveItem_Struct)); +// else +// outapp2 = new EQApplicationPacket(OP_MoveItem,sizeof(MoveItem_Struct)); +// +// MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer; +// mis->from_slot = Slot; +// mis->to_slot = 0xFFFFFFFF; +// mis->number_in_stack = 0xFFFFFFFF; +// +// if(Quantity >= Charges) +// Quantity = 1; +// +// for(int i = 0; i < Quantity; i++) { +// +// this->QueuePacket(outapp2); +// } +// safe_delete(outapp2); +// } void Client::TraderUpdate(uint16 SlotID,uint32 TraderID){ // This method is no longer used. @@ -2507,347 +2507,347 @@ void Client::ShowBuyLines(const EQApplicationPacket *app) { } void Client::SellToBuyer(const EQApplicationPacket *app) { - - char* Buf = (char *)app->pBuffer; - - char ItemName[64]; - - /*uint32 Action =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused - uint32 Quantity = VARSTRUCT_DECODE_TYPE(uint32, Buf); - uint32 BuyerID = VARSTRUCT_DECODE_TYPE(uint32, Buf); - uint32 BuySlot = VARSTRUCT_DECODE_TYPE(uint32, Buf); - uint32 UnknownByte = VARSTRUCT_DECODE_TYPE(uint8, Buf); - uint32 ItemID = VARSTRUCT_DECODE_TYPE(uint32, Buf); - /* ItemName */ VARSTRUCT_DECODE_STRING(ItemName, Buf); - /*uint32 Unknown2 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused - uint32 QtyBuyerWants = VARSTRUCT_DECODE_TYPE(uint32, Buf); - UnknownByte = VARSTRUCT_DECODE_TYPE(uint8, Buf); - uint32 Price = VARSTRUCT_DECODE_TYPE(uint32, Buf); - /*uint32 BuyerID2 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused - /*uint32 Unknown3 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused - - const ItemData *item = database.GetItem(ItemID); - - if(!item || !Quantity || !Price || !QtyBuyerWants) return; - - if (m_inv.HasItem(ItemID, Quantity, invWhereWorn | invWherePersonal | invWhereCursor) == INVALID_INDEX) { - Message(13, "You do not have %i %s on you.", Quantity, item->Name); - return; - } - - - Client *Buyer = entity_list.GetClientByID(BuyerID); - - if(!Buyer || !Buyer->IsBuyer()) { - Message(13, "The Buyer has gone away."); - return; - } - - // For Stackable items, HasSpaceForItem will try check if there is space to stack with existing stacks in - // the buyer inventory. - if(!(Buyer->GetInv().HasSpaceForItem(item, Quantity))) { - Message(13, "The Buyer does not have space for %i %s", Quantity, item->Name); - return; - } - - if((static_cast(Quantity) * static_cast(Price)) > MAX_TRANSACTION_VALUE) { - Message(13, "That would exceed the single transaction limit of %u platinum.", MAX_TRANSACTION_VALUE / 1000); - return; - } - - if(!Buyer->HasMoney(Quantity * Price)) { - Message(13, "The Buyer does not have sufficient money to purchase that quantity of %s.", item->Name); - Buyer->Message(13, "%s tried to sell you %i %s, but you have insufficient funds.", GetName(), Quantity, item->Name); - return; - } - - if(Buyer->CheckLoreConflict(item)) { - Message(13, "That item is LORE and the Buyer already has one."); - Buyer->Message(13, "%s tried to sell you %s but this item is LORE and you already have one.", - GetName(), item->Name); - return; - } - - if(item->NoDrop == 0) { - Message(13, "That item is NODROP."); - return; - } - - if(!item->Stackable) { - - for(uint32 i = 0; i < Quantity; i++) { - - int16 SellerSlot = m_inv.HasItem(ItemID, 1, invWhereWorn|invWherePersonal|invWhereCursor); - - // This shouldn't happen, as we already checked there was space in the Buyer's inventory - if (SellerSlot == INVALID_INDEX) { - - if(i > 0) { - // Set the Quantity to the actual number we successfully transferred. - Quantity = i; - break; - } - Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); - Message(13, "Internal error while processing transaction."); - return; - } - - ItemInst* ItemToTransfer = m_inv.PopItem(SellerSlot); - - if(!ItemToTransfer || !Buyer->MoveItemToInventory(ItemToTransfer, true)) { - Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); - Message(13, "Internal error while processing transaction."); - - if(ItemToTransfer) - safe_delete(ItemToTransfer); - - return; - } - - database.SaveInventory(CharacterID(), 0, SellerSlot); - - safe_delete(ItemToTransfer); - - // Remove the item from inventory, clientside - // - EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_MoveItem,sizeof(MoveItem_Struct)); - - MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer; - mis->from_slot = SellerSlot; - mis->to_slot = 0xFFFFFFFF; - mis->number_in_stack = 0xFFFFFFFF; - - QueuePacket(outapp2); - safe_delete(outapp2); - - } - } - else { - // Stackable - // - uint32 QuantityMoved = 0; - - while(QuantityMoved < Quantity) { - - // Find the slot on the seller that has a stack of at least 1 of the item - int16 SellerSlot = m_inv.HasItem(ItemID, 1, invWhereWorn|invWherePersonal|invWhereCursor); - - if (SellerSlot == INVALID_INDEX) { - Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); - Message(13, "Internal error while processing transaction."); - return; - } - - ItemInst* ItemToTransfer = m_inv.PopItem(SellerSlot); - - if(!ItemToTransfer) { - Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); - Message(13, "Internal error while processing transaction."); - return; - } - - // If the stack we found has less than the quantity we are selling ... - if(ItemToTransfer->GetCharges() <= (Quantity - QuantityMoved)) { - // Transfer the entire stack - - QuantityMoved += ItemToTransfer->GetCharges(); - - if(!Buyer->MoveItemToInventory(ItemToTransfer, true)) { - Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); - Message(13, "Internal error while processing transaction."); - safe_delete(ItemToTransfer); - return; - } - // Delete the entire stack from the seller's inventory - database.SaveInventory(CharacterID(), 0, SellerSlot); - - safe_delete(ItemToTransfer); - - // and tell the client to do the same. - EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_MoveItem,sizeof(MoveItem_Struct)); - - MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer; - mis->from_slot = SellerSlot; - mis->to_slot = 0xFFFFFFFF; - mis->number_in_stack = 0xFFFFFFFF; - - QueuePacket(outapp2); - safe_delete(outapp2); - } - else { - //Move the amount we need, and put the rest of the stack back in the seller's inventory - // - int QuantityToRemoveFromStack = Quantity - QuantityMoved; - - ItemToTransfer->SetCharges(ItemToTransfer->GetCharges() - QuantityToRemoveFromStack); - - m_inv.PutItem(SellerSlot, *ItemToTransfer); - - database.SaveInventory(CharacterID(), ItemToTransfer, SellerSlot); - - ItemToTransfer->SetCharges(QuantityToRemoveFromStack); - - if(!Buyer->MoveItemToInventory(ItemToTransfer, true)) { - Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); - Message(13, "Internal error while processing transaction."); - safe_delete(ItemToTransfer); - return; - } - - safe_delete(ItemToTransfer); - - EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_DeleteItem,sizeof(MoveItem_Struct)); - - MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer; - mis->from_slot = SellerSlot; - mis->to_slot = 0xFFFFFFFF; - mis->number_in_stack = 0xFFFFFFFF; - - for(int i = 0; i < QuantityToRemoveFromStack; i++) - QueuePacket(outapp2); - - safe_delete(outapp2); - - QuantityMoved = Quantity; - } - } - - } - - Buyer->TakeMoneyFromPP(Quantity * Price); - - AddMoneyToPP(Quantity * Price, false); - - if(RuleB(Bazaar, AuditTrail)) - BazaarAuditTrail(GetName(), Buyer->GetName(), ItemName, Quantity, Quantity * Price, 1); - - // We now send a packet to the Seller, which causes it to display 'You have sold to for ' - // - // The PacketLength of 1016 is from the only instance of this packet I have seen, which is from Live, November 2008 - // The Titanium/6.2 struct is slightly different in that it appears to use fixed length strings instead of variable - // length as used on Live. The extra space in the packet is also likely to be used for Item compensation, if we ever - // implement that. - // - uint32 PacketLength = 1016; - - EQApplicationPacket* outapp = new EQApplicationPacket(OP_Barter, PacketLength); - - Buf = (char *)outapp->pBuffer; - - VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_SellerTransactionComplete); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity * Price); - - if(GetClientVersion() >= ClientVersion::SoD) - { - VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); // Think this is the upper 32 bits of a 64 bit price - } - - sprintf(Buf, "%s", Buyer->GetName()); Buf += 64; - - VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00); - VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0x01); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00); - - sprintf(Buf, "%s", ItemName); Buf += 64; - - QueuePacket(outapp); - - // This next packet goes to the Buyer and produces the 'You've bought from for ' - // - - Buf = (char *)outapp->pBuffer; - - VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerTransactionComplete); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity * Price); - - if(Buyer->GetClientVersion() >= ClientVersion::SoD) - { - VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); // Think this is the upper 32 bits of a 64 bit price - } - - sprintf(Buf, "%s", GetName()); Buf += 64; - - VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00); - VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0x01); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00); - - sprintf(Buf, "%s", ItemName); Buf += 64; - - Buyer->QueuePacket(outapp); - - safe_delete(outapp); - - // Next we update the buyer table in the database to reflect the reduced quantity the Buyer wants to buy. - // - database.UpdateBuyLine(Buyer->CharacterID(), BuySlot, QtyBuyerWants - Quantity); - - // Next we update the Seller's Barter Window to reflect the reduced quantity the Buyer is now looking to buy. - // - EQApplicationPacket* outapp3 = new EQApplicationPacket(OP_Barter, 936); - - Buf = (char *)outapp3->pBuffer; - - VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerInspectWindow); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, BuySlot); - VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // Unknown - VARSTRUCT_ENCODE_TYPE(uint32, Buf,ItemID); - VARSTRUCT_ENCODE_STRING(Buf, ItemName); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, item->Icon); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, QtyBuyerWants - Quantity); - - // If the amount we have just sold completely satisfies the quantity the Buyer was looking for, - // setting the next byte to 0 will remove the item from the Barter Window. - // - if(QtyBuyerWants - Quantity > 0) { - VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // 0 = Toggle Off, 1 = Toggle On - } - else { - VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0); // 0 = Toggle Off, 1 = Toggle On - } - - VARSTRUCT_ENCODE_TYPE(uint32, Buf, Price); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, Buyer->GetID()); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); - - VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName()); - - QueuePacket(outapp3); - safe_delete(outapp3); - - // The next packet updates the /buyer window with the reduced quantity, and toggles the buy line off if the - // quantity they wanted to buy has been met. - // - EQApplicationPacket* outapp4 = new EQApplicationPacket(OP_Barter, 936); - - Buf = (char*)outapp4->pBuffer; - - VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerItemUpdate); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, BuySlot); - VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, ItemID); - VARSTRUCT_ENCODE_STRING(Buf, ItemName); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, item->Icon); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, QtyBuyerWants - Quantity); - - if((QtyBuyerWants - Quantity) > 0) { - - VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // 0 = Toggle Off, 1 = Toggle On - } - else { - VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0); // 0 = Toggle Off, 1 = Toggle On - } - - VARSTRUCT_ENCODE_TYPE(uint32, Buf, Price); - VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x08f4); // Unknown - VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); - VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName()); - - Buyer->QueuePacket(outapp4); - safe_delete(outapp4); - - return; +// +// char* Buf = (char *)app->pBuffer; +// +// char ItemName[64]; +// +// /*uint32 Action =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused +// uint32 Quantity = VARSTRUCT_DECODE_TYPE(uint32, Buf); +// uint32 BuyerID = VARSTRUCT_DECODE_TYPE(uint32, Buf); +// uint32 BuySlot = VARSTRUCT_DECODE_TYPE(uint32, Buf); +// uint32 UnknownByte = VARSTRUCT_DECODE_TYPE(uint8, Buf); +// uint32 ItemID = VARSTRUCT_DECODE_TYPE(uint32, Buf); +// /* ItemName */ VARSTRUCT_DECODE_STRING(ItemName, Buf); +// /*uint32 Unknown2 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused +// uint32 QtyBuyerWants = VARSTRUCT_DECODE_TYPE(uint32, Buf); +// UnknownByte = VARSTRUCT_DECODE_TYPE(uint8, Buf); +// uint32 Price = VARSTRUCT_DECODE_TYPE(uint32, Buf); +// /*uint32 BuyerID2 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused +// /*uint32 Unknown3 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused +// +// const ItemData *item = database.GetItem(ItemID); +// +// if(!item || !Quantity || !Price || !QtyBuyerWants) return; +// +// if (m_inv.HasItem(ItemID, Quantity, invWhereWorn | invWherePersonal | invWhereCursor) == INVALID_INDEX) { +// Message(13, "You do not have %i %s on you.", Quantity, item->Name); +// return; +// } +// +// +// Client *Buyer = entity_list.GetClientByID(BuyerID); +// +// if(!Buyer || !Buyer->IsBuyer()) { +// Message(13, "The Buyer has gone away."); +// return; +// } +// +// // For Stackable items, HasSpaceForItem will try check if there is space to stack with existing stacks in +// // the buyer inventory. +// if(!(Buyer->GetInv().HasSpaceForItem(item, Quantity))) { +// Message(13, "The Buyer does not have space for %i %s", Quantity, item->Name); +// return; +// } +// +// if((static_cast(Quantity) * static_cast(Price)) > MAX_TRANSACTION_VALUE) { +// Message(13, "That would exceed the single transaction limit of %u platinum.", MAX_TRANSACTION_VALUE / 1000); +// return; +// } +// +// if(!Buyer->HasMoney(Quantity * Price)) { +// Message(13, "The Buyer does not have sufficient money to purchase that quantity of %s.", item->Name); +// Buyer->Message(13, "%s tried to sell you %i %s, but you have insufficient funds.", GetName(), Quantity, item->Name); +// return; +// } +// +// if(Buyer->CheckLoreConflict(item)) { +// Message(13, "That item is LORE and the Buyer already has one."); +// Buyer->Message(13, "%s tried to sell you %s but this item is LORE and you already have one.", +// GetName(), item->Name); +// return; +// } +// +// if(item->NoDrop == 0) { +// Message(13, "That item is NODROP."); +// return; +// } +// +// if(!item->Stackable) { +// +// for(uint32 i = 0; i < Quantity; i++) { +// +// int16 SellerSlot = m_inv.HasItem(ItemID, 1, invWhereWorn|invWherePersonal|invWhereCursor); +// +// // This shouldn't happen, as we already checked there was space in the Buyer's inventory +// if (SellerSlot == INVALID_INDEX) { +// +// if(i > 0) { +// // Set the Quantity to the actual number we successfully transferred. +// Quantity = i; +// break; +// } +// Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); +// Message(13, "Internal error while processing transaction."); +// return; +// } +// +// ItemInst* ItemToTransfer = m_inv.PopItem(SellerSlot); +// +// if(!ItemToTransfer || !Buyer->MoveItemToInventory(ItemToTransfer, true)) { +// Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); +// Message(13, "Internal error while processing transaction."); +// +// if(ItemToTransfer) +// safe_delete(ItemToTransfer); +// +// return; +// } +// +// database.SaveInventory(CharacterID(), 0, SellerSlot); +// +// safe_delete(ItemToTransfer); +// +// // Remove the item from inventory, clientside +// // +// EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_MoveItem,sizeof(MoveItem_Struct)); +// +// MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer; +// mis->from_slot = SellerSlot; +// mis->to_slot = 0xFFFFFFFF; +// mis->number_in_stack = 0xFFFFFFFF; +// +// QueuePacket(outapp2); +// safe_delete(outapp2); +// +// } +// } +// else { +// // Stackable +// // +// uint32 QuantityMoved = 0; +// +// while(QuantityMoved < Quantity) { +// +// // Find the slot on the seller that has a stack of at least 1 of the item +// int16 SellerSlot = m_inv.HasItem(ItemID, 1, invWhereWorn|invWherePersonal|invWhereCursor); +// +// if (SellerSlot == INVALID_INDEX) { +// Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); +// Message(13, "Internal error while processing transaction."); +// return; +// } +// +// ItemInst* ItemToTransfer = m_inv.PopItem(SellerSlot); +// +// if(!ItemToTransfer) { +// Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); +// Message(13, "Internal error while processing transaction."); +// return; +// } +// +// // If the stack we found has less than the quantity we are selling ... +// if(ItemToTransfer->GetCharges() <= (Quantity - QuantityMoved)) { +// // Transfer the entire stack +// +// QuantityMoved += ItemToTransfer->GetCharges(); +// +// if(!Buyer->MoveItemToInventory(ItemToTransfer, true)) { +// Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); +// Message(13, "Internal error while processing transaction."); +// safe_delete(ItemToTransfer); +// return; +// } +// // Delete the entire stack from the seller's inventory +// database.SaveInventory(CharacterID(), 0, SellerSlot); +// +// safe_delete(ItemToTransfer); +// +// // and tell the client to do the same. +// EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_MoveItem,sizeof(MoveItem_Struct)); +// +// MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer; +// mis->from_slot = SellerSlot; +// mis->to_slot = 0xFFFFFFFF; +// mis->number_in_stack = 0xFFFFFFFF; +// +// QueuePacket(outapp2); +// safe_delete(outapp2); +// } +// else { +// //Move the amount we need, and put the rest of the stack back in the seller's inventory +// // +// int QuantityToRemoveFromStack = Quantity - QuantityMoved; +// +// ItemToTransfer->SetCharges(ItemToTransfer->GetCharges() - QuantityToRemoveFromStack); +// +// m_inv.PutItem(SellerSlot, *ItemToTransfer); +// +// database.SaveInventory(CharacterID(), ItemToTransfer, SellerSlot); +// +// ItemToTransfer->SetCharges(QuantityToRemoveFromStack); +// +// if(!Buyer->MoveItemToInventory(ItemToTransfer, true)) { +// Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); +// Message(13, "Internal error while processing transaction."); +// safe_delete(ItemToTransfer); +// return; +// } +// +// safe_delete(ItemToTransfer); +// +// EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_DeleteItem,sizeof(MoveItem_Struct)); +// +// MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer; +// mis->from_slot = SellerSlot; +// mis->to_slot = 0xFFFFFFFF; +// mis->number_in_stack = 0xFFFFFFFF; +// +// for(int i = 0; i < QuantityToRemoveFromStack; i++) +// QueuePacket(outapp2); +// +// safe_delete(outapp2); +// +// QuantityMoved = Quantity; +// } +// } +// +// } +// +// Buyer->TakeMoneyFromPP(Quantity * Price); +// +// AddMoneyToPP(Quantity * Price, false); +// +// if(RuleB(Bazaar, AuditTrail)) +// BazaarAuditTrail(GetName(), Buyer->GetName(), ItemName, Quantity, Quantity * Price, 1); +// +// // We now send a packet to the Seller, which causes it to display 'You have sold to for ' +// // +// // The PacketLength of 1016 is from the only instance of this packet I have seen, which is from Live, November 2008 +// // The Titanium/6.2 struct is slightly different in that it appears to use fixed length strings instead of variable +// // length as used on Live. The extra space in the packet is also likely to be used for Item compensation, if we ever +// // implement that. +// // +// uint32 PacketLength = 1016; +// +// EQApplicationPacket* outapp = new EQApplicationPacket(OP_Barter, PacketLength); +// +// Buf = (char *)outapp->pBuffer; +// +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_SellerTransactionComplete); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity * Price); +// +// if(GetClientVersion() >= ClientVersion::SoD) +// { +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); // Think this is the upper 32 bits of a 64 bit price +// } +// +// sprintf(Buf, "%s", Buyer->GetName()); Buf += 64; +// +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00); +// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0x01); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00); +// +// sprintf(Buf, "%s", ItemName); Buf += 64; +// +// QueuePacket(outapp); +// +// // This next packet goes to the Buyer and produces the 'You've bought from for ' +// // +// +// Buf = (char *)outapp->pBuffer; +// +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerTransactionComplete); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity * Price); +// +// if(Buyer->GetClientVersion() >= ClientVersion::SoD) +// { +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); // Think this is the upper 32 bits of a 64 bit price +// } +// +// sprintf(Buf, "%s", GetName()); Buf += 64; +// +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00); +// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0x01); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00); +// +// sprintf(Buf, "%s", ItemName); Buf += 64; +// +// Buyer->QueuePacket(outapp); +// +// safe_delete(outapp); +// +// // Next we update the buyer table in the database to reflect the reduced quantity the Buyer wants to buy. +// // +// database.UpdateBuyLine(Buyer->CharacterID(), BuySlot, QtyBuyerWants - Quantity); +// +// // Next we update the Seller's Barter Window to reflect the reduced quantity the Buyer is now looking to buy. +// // +// EQApplicationPacket* outapp3 = new EQApplicationPacket(OP_Barter, 936); +// +// Buf = (char *)outapp3->pBuffer; +// +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerInspectWindow); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, BuySlot); +// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // Unknown +// VARSTRUCT_ENCODE_TYPE(uint32, Buf,ItemID); +// VARSTRUCT_ENCODE_STRING(Buf, ItemName); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, item->Icon); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, QtyBuyerWants - Quantity); +// +// // If the amount we have just sold completely satisfies the quantity the Buyer was looking for, +// // setting the next byte to 0 will remove the item from the Barter Window. +// // +// if(QtyBuyerWants - Quantity > 0) { +// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // 0 = Toggle Off, 1 = Toggle On +// } +// else { +// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0); // 0 = Toggle Off, 1 = Toggle On +// } +// +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Price); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Buyer->GetID()); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); +// +// VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName()); +// +// QueuePacket(outapp3); +// safe_delete(outapp3); +// +// // The next packet updates the /buyer window with the reduced quantity, and toggles the buy line off if the +// // quantity they wanted to buy has been met. +// // +// EQApplicationPacket* outapp4 = new EQApplicationPacket(OP_Barter, 936); +// +// Buf = (char*)outapp4->pBuffer; +// +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerItemUpdate); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, BuySlot); +// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, ItemID); +// VARSTRUCT_ENCODE_STRING(Buf, ItemName); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, item->Icon); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, QtyBuyerWants - Quantity); +// +// if((QtyBuyerWants - Quantity) > 0) { +// +// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // 0 = Toggle Off, 1 = Toggle On +// } +// else { +// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0); // 0 = Toggle Off, 1 = Toggle On +// } +// +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Price); +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x08f4); // Unknown +// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); +// VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName()); +// +// Buyer->QueuePacket(outapp4); +// safe_delete(outapp4); +// +// return; } void Client::SendBuyerPacket(Client* Buyer) { From c62cff1ce78b88a0165b61c7de5a60bd3306ba77 Mon Sep 17 00:00:00 2001 From: KimLS Date: Tue, 24 Feb 2015 00:38:49 -0800 Subject: [PATCH 13/27] Fixed test again. --- common/memory_buffer.cpp | 4 ++++ tests/memory_buffer_test.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/common/memory_buffer.cpp b/common/memory_buffer.cpp index 0910289e2..4f47867d8 100644 --- a/common/memory_buffer.cpp +++ b/common/memory_buffer.cpp @@ -52,6 +52,10 @@ EQEmu::MemoryBuffer::MemoryBuffer(MemoryBuffer &&other) { } EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(const MemoryBuffer &other) { + if(this == &other) { + return *this; + } + if(buffer_) { delete[] buffer_; } diff --git a/tests/memory_buffer_test.h b/tests/memory_buffer_test.h index 9d6c0cec7..0da7d01be 100644 --- a/tests/memory_buffer_test.h +++ b/tests/memory_buffer_test.h @@ -458,7 +458,7 @@ private: mb2 = mb2; void *addr2 = (void*)mb2; - TEST_ASSERT(addr != addr2); + TEST_ASSERT(addr == addr2); mb2 = std::move(mb2); addr2 = (void*)mb2; From 215861dd86cfada50d70a52ede0ffbfe343a894c Mon Sep 17 00:00:00 2001 From: KimLS Date: Wed, 25 Feb 2015 19:36:10 -0800 Subject: [PATCH 14/27] Added serialization differentiation --- common/CMakeLists.txt | 7 +- common/inventory.cpp | 7 +- common/inventory_database_controller.cpp | 0 common/inventory_database_controller.h | 24 - common/item_container.cpp | 66 +- common/item_container.h | 17 +- .../item_container_default_serialization.cpp | 17 + common/item_container_default_serialization.h | 35 ++ .../item_container_personal_serialization.cpp | 19 + .../item_container_personal_serialization.h | 35 ++ .../item_container_serialization_strategy.h | 37 ++ common/item_instance.cpp | 12 +- common/item_instance.h | 7 +- common/patches/rof2.cpp | 581 +----------------- 14 files changed, 236 insertions(+), 628 deletions(-) delete mode 100644 common/inventory_database_controller.cpp delete mode 100644 common/inventory_database_controller.h create mode 100644 common/item_container_default_serialization.cpp create mode 100644 common/item_container_default_serialization.h create mode 100644 common/item_container_personal_serialization.cpp create mode 100644 common/item_container_personal_serialization.h create mode 100644 common/item_container_serialization_strategy.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 243553bff..9d8dea551 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -31,10 +31,11 @@ SET(common_sources guild_base.cpp guilds.cpp inventory.cpp - inventory_database_controller.cpp ipc_mutex.cpp item.cpp item_container.cpp + item_container_default_serialization.cpp + item_container_personal_serialization.cpp item_instance.cpp md5.cpp memory_buffer.cpp @@ -141,10 +142,12 @@ SET(common_headers guild_base.h guilds.h inventory.h - inventory_database_controller.h ipc_mutex.h item.h item_container.h + item_container_default_serialization.h + item_container_personal_serialization.h + item_container_serialization_strategy.h item_data.h item_fieldlist.h item_instance.h diff --git a/common/inventory.cpp b/common/inventory.cpp index 72b6bc59d..9cd897bed 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -18,6 +18,7 @@ #include "inventory.h" #include "data_verification.h" +#include "item_container_personal_serialization.h" #include struct EQEmu::Inventory::impl @@ -58,7 +59,11 @@ std::shared_ptr EQEmu::Inventory::Get(const InventorySlot & bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr inst) { if(impl_->containers_.count(slot.type_) == 0) { - impl_->containers_.insert(std::pair(slot.type_, ItemContainer())); + if(slot.type_ == 0) { + impl_->containers_.insert(std::pair(slot.type_, ItemContainer(new ItemContainerPersonalSerialization()))); + } else { + impl_->containers_.insert(std::pair(slot.type_, ItemContainer())); + } } //Verify item can be put into the slot requested diff --git a/common/inventory_database_controller.cpp b/common/inventory_database_controller.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/common/inventory_database_controller.h b/common/inventory_database_controller.h deleted file mode 100644 index d3337dd75..000000000 --- a/common/inventory_database_controller.h +++ /dev/null @@ -1,24 +0,0 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2015 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 -*/ - -#ifndef COMMON_INVENTORY_DATABASE_CONTROLLER_H -#define COMMON_INVENTORY_DATABASE_CONTROLLER_H - - - -#endif diff --git a/common/item_container.cpp b/common/item_container.cpp index 92823fc20..6f708051a 100644 --- a/common/item_container.cpp +++ b/common/item_container.cpp @@ -1,21 +1,30 @@ #include "item_container.h" -#include +#include "item_container_default_serialization.h" #include struct EQEmu::ItemContainer::impl { - std::map> items; + std::map> items_; + ItemContainerSerializationStrategy *serialize_strat_; }; EQEmu::ItemContainer::ItemContainer() { impl_ = new impl(); + impl_->serialize_strat_ = new ItemContainerDefaultSerialization(); +} + +EQEmu::ItemContainer::ItemContainer(ItemContainerSerializationStrategy *strategy) { + impl_ = new impl(); + impl_->serialize_strat_ = strategy; } EQEmu::ItemContainer::~ItemContainer() { - if(impl_) + if(impl_) { + delete impl_->serialize_strat_; delete impl_; + } } EQEmu::ItemContainer::ItemContainer(ItemContainer &&other) { @@ -23,9 +32,18 @@ EQEmu::ItemContainer::ItemContainer(ItemContainer &&other) { other.impl_ = nullptr; } +EQEmu::ItemContainer& EQEmu::ItemContainer::operator=(ItemContainer &&other) { + if(this == &other) + return *this; + + impl_ = other.impl_; + other.impl_ = nullptr; + return *this; +} + std::shared_ptr EQEmu::ItemContainer::Get(const int slot_id) { - auto iter = impl_->items.find(slot_id); - if(iter != impl_->items.end()) { + auto iter = impl_->items_.find(slot_id); + if(iter != impl_->items_.end()) { return iter->second; } @@ -36,10 +54,9 @@ bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr if(!inst) return false; - auto iter = impl_->items.find(slot_id); - if(iter == impl_->items.end()) { - impl_->items[slot_id] = inst; - //trigger insert in slot_id + auto iter = impl_->items_.find(slot_id); + if(iter == impl_->items_.end()) { + impl_->items_[slot_id] = inst; return true; } @@ -47,34 +64,35 @@ bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr } uint32 EQEmu::ItemContainer::Size() { - return impl_->items.size(); + return (uint32)impl_->items_.size(); } uint32 EQEmu::ItemContainer::Size() const { - return impl_->items.size(); + return (uint32)impl_->items_.size(); } bool EQEmu::ItemContainer::Delete(const int slot_id) { - auto iter = impl_->items.find(slot_id); - if(iter == impl_->items.end()) { + auto iter = impl_->items_.find(slot_id); + if(iter == impl_->items_.end()) { return false; } else { - impl_->items.erase(iter); - //trigger delete in slotid + impl_->items_.erase(iter); return true; } } bool EQEmu::ItemContainer::Serialize(MemoryBuffer &buf, int container_number) { - if(impl_->items.size() == 0) { - return false; + if(impl_->serialize_strat_) { + return impl_->serialize_strat_->Serialize(buf, container_number, impl_->items_); } - for(auto &iter : impl_->items) { - buf.Write(container_number); - buf.Write(iter.first); - buf.Write(iter.second.get()); - } + return false; +} - return true; -} \ No newline at end of file +EQEmu::ItemContainer::ItemContainerIter EQEmu::ItemContainer::Begin() { + return impl_->items_.begin(); +} + +EQEmu::ItemContainer::ItemContainerIter EQEmu::ItemContainer::End() { + return impl_->items_.end(); +} diff --git a/common/item_container.h b/common/item_container.h index cc650a19b..bde5d3c0d 100644 --- a/common/item_container.h +++ b/common/item_container.h @@ -20,17 +20,24 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define COMMON_ITEM_CONTAINER_H #include "item_instance.h" +#include "item_container_serialization_strategy.h" #include "memory_buffer.h" #include +#include namespace EQEmu { + class ItemContainerSerializationStrategy; class ItemContainer { public: + typedef std::map>::const_iterator ItemContainerIter; + ItemContainer(); + ItemContainer(ItemContainerSerializationStrategy *strategy); ~ItemContainer(); ItemContainer(ItemContainer &&other); + ItemContainer& operator=(ItemContainer &&other); std::shared_ptr Get(const int slot_id); bool Put(const int slot_id, std::shared_ptr inst); @@ -38,13 +45,17 @@ namespace EQEmu uint32 Size(); uint32 Size() const; + //Low level interface for encode/decode bool Serialize(MemoryBuffer &buf, int container_number); + ItemContainerIter Begin(); + ItemContainerIter End(); + protected: + struct impl; + impl *impl_; + private: ItemContainer(const ItemContainer &other); ItemContainer& operator=(const ItemContainer &other); - - struct impl; - impl *impl_; }; } // EQEmu diff --git a/common/item_container_default_serialization.cpp b/common/item_container_default_serialization.cpp new file mode 100644 index 000000000..4bcec1e17 --- /dev/null +++ b/common/item_container_default_serialization.cpp @@ -0,0 +1,17 @@ +#include "item_container_default_serialization.h" + +bool EQEmu::ItemContainerDefaultSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items) { + if(items.size() == 0) { + return false; + } + + bool ret = false; + for(auto &iter : items) { + buf.Write(container_number); + buf.Write(iter.first); + buf.Write(iter.second.get()); + ret = true; + } + + return ret; +} diff --git a/common/item_container_default_serialization.h b/common/item_container_default_serialization.h new file mode 100644 index 000000000..3626eded6 --- /dev/null +++ b/common/item_container_default_serialization.h @@ -0,0 +1,35 @@ +/* EQEMu: Everquest Server Emulator +Copyright (C) 2001-2015 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 +*/ + +#ifndef COMMON_ITEM_CONTAINER_DEFAULT_SERIALIZATION_H +#define COMMON_ITEM_CONTAINER_DEFAULT_SERIALIZATION_H + +#include "item_container_serialization_strategy.h" + +namespace EQEmu +{ + class ItemContainerDefaultSerialization : public ItemContainerSerializationStrategy + { + public: + ItemContainerDefaultSerialization() { } + virtual ~ItemContainerDefaultSerialization() { } + virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items); + }; +} // EQEmu + +#endif diff --git a/common/item_container_personal_serialization.cpp b/common/item_container_personal_serialization.cpp new file mode 100644 index 000000000..eefd8423a --- /dev/null +++ b/common/item_container_personal_serialization.cpp @@ -0,0 +1,19 @@ +#include "item_container_personal_serialization.h" + +bool EQEmu::ItemContainerPersonalSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items) { + if(items.size() == 0) { + return false; + } + + bool ret = false; + for(auto &iter : items) { + if(iter.first < 33) { + buf.Write(container_number); + buf.Write(iter.first); + buf.Write(iter.second.get()); + ret = true; + } + } + + return ret; +} diff --git a/common/item_container_personal_serialization.h b/common/item_container_personal_serialization.h new file mode 100644 index 000000000..0b41d5dc6 --- /dev/null +++ b/common/item_container_personal_serialization.h @@ -0,0 +1,35 @@ +/* EQEMu: Everquest Server Emulator +Copyright (C) 2001-2015 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 +*/ + +#ifndef COMMON_ITEM_CONTAINER_PERSONAL_SERIALIZATION_H +#define COMMON_ITEM_CONTAINER_PERSONAL_SERIALIZATION_H + +#include "item_container_serialization_strategy.h" + +namespace EQEmu +{ + class ItemContainerPersonalSerialization : public ItemContainerSerializationStrategy + { + public: + ItemContainerPersonalSerialization() { } + virtual ~ItemContainerPersonalSerialization() { } + virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items); + }; +} // EQEmu + +#endif diff --git a/common/item_container_serialization_strategy.h b/common/item_container_serialization_strategy.h new file mode 100644 index 000000000..e8fb61bee --- /dev/null +++ b/common/item_container_serialization_strategy.h @@ -0,0 +1,37 @@ +/* EQEMu: Everquest Server Emulator +Copyright (C) 2001-2015 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 +*/ + +#ifndef COMMON_ITEM_CONTAINER_SERIALIZATION_STRATEGY_H +#define COMMON_ITEM_CONTAINER_SERIALIZATION_STRATEGY_H + +#include "item_container.h" +#include "memory_buffer.h" +#include + +namespace EQEmu +{ + class ItemContainerSerializationStrategy + { + public: + ItemContainerSerializationStrategy() { } + virtual ~ItemContainerSerializationStrategy() { } + virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items) = 0; + }; +} // EQEmu + +#endif diff --git a/common/item_instance.cpp b/common/item_instance.cpp index c95c8e72d..4b442dfc2 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -151,14 +151,6 @@ bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr ins return false; } -uint32 EQEmu::ItemInstance::GetSubItemCount() { - return impl_->contents_.Size(); -} - -uint32 EQEmu::ItemInstance::GetSubItemCount() const { - return impl_->contents_.Size(); -} - int16 EQEmu::ItemInstance::GetCharges() { return impl_->charges_; } @@ -330,3 +322,7 @@ bool EQEmu::ItemInstance::IsStackable() { bool EQEmu::ItemInstance::IsStackable() const { return impl_->base_item_->Stackable; } + +EQEmu::ItemContainer *EQEmu::ItemInstance::GetContainer() { + return &(impl_->contents_); +} diff --git a/common/item_instance.h b/common/item_instance.h index 595bff390..72bcc3c16 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -24,6 +24,7 @@ namespace EQEmu { + class ItemContainer; class ItemInstance { public: @@ -38,8 +39,6 @@ namespace EQEmu //Container std::shared_ptr Get(const int index); bool Put(const int index, std::shared_ptr inst); - uint32 GetSubItemCount(); - uint32 GetSubItemCount() const; //Persistent State int16 GetCharges(); @@ -95,6 +94,10 @@ namespace EQEmu //Basic Stats bool IsStackable(); bool IsStackable() const; + + //Internal state + //Used for low level operations such as encode/decode + ItemContainer *GetContainer(); private: struct impl; impl *impl_; diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index c3a1fd0f4..ea0c11b45 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -5193,561 +5193,6 @@ namespace RoF2 return NextItemInstSerialNumber; } - //char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth, ItemPacketType packet_type) - //{ - // int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); - // 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 ItemData *item = inst->GetUnscaledItem(); - // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name); - // - // RoF2::structs::ItemSerializationHeader hdr; - // - // //sprintf(hdr.unknown000, "06e0002Y1W00"); - // - // snprintf(hdr.tracking_id, sizeof(hdr.tracking_id), "%016d", item->ID); - // - // hdr.stacksize = stackable ? charges : 1; - // hdr.unknown004 = 0; - // - // structs::ItemSlotStruct slot_id = ServerToRoF2Slot(slot_id_in, packet_type); - // - // hdr.slot_type = (merchant_slot == 0) ? slot_id.SlotType : 9; // 9 is merchant 20 is reclaim items? - // hdr.main_slot = (merchant_slot == 0) ? slot_id.MainSlot : merchant_slot; - // hdr.sub_slot = (merchant_slot == 0) ? slot_id.SubSlot : 0xffff; - // hdr.aug_slot = (merchant_slot == 0) ? slot_id.AugSlot : 0xffff; - // 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.unknown028 = 0; - // hdr.last_cast_time = inst->GetRecastTimestamp(); - // hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges); - // hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0; - // hdr.unknown044 = 0; - // hdr.unknown048 = 0; - // hdr.unknown052 = 0; - // hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0; - // ss.write((const char*)&hdr, sizeof(RoF2::structs::ItemSerializationHeader)); - // - // if (item->EvolvingLevel > 0) { - // RoF2::structs::EvolvingItem evotop; - // evotop.unknown001 = 0; - // evotop.unknown002 = 0; - // evotop.unknown003 = 0; - // evotop.unknown004 = 0; - // evotop.evoLevel = item->EvolvingLevel; - // evotop.progress = 95.512; - // evotop.Activated = 1; - // evotop.evomaxlevel = 7; - // ss.write((const char*)&evotop, sizeof(RoF2::structs::EvolvingItem)); - // } - // //ORNAMENT IDFILE / ICON - // uint32 ornaIcon = 0; - // uint32 heroModel = 0; - // - // if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) - // { - // char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile()); - // //Mainhand - // ss.write(tmp, strlen(tmp)); - // ss.write((const char*)&null_term, sizeof(uint8)); - // //Offhand - // ss.write(tmp, strlen(tmp)); - // ss.write((const char*)&null_term, sizeof(uint8)); - // ornaIcon = inst->GetOrnamentationIcon(); - // heroModel = inst->GetOrnamentHeroModel(InventoryOld::CalcMaterialFromSlot(slot_id_in)); - // } - // else - // { - // ss.write((const char*)&null_term, sizeof(uint8)); // no main hand Ornamentation - // ss.write((const char*)&null_term, sizeof(uint8)); // no off hand Ornamentation - // } - // - // RoF2::structs::ItemSerializationHeaderFinish hdrf; - // hdrf.ornamentIcon = ornaIcon; - // hdrf.unknowna1 = 0xffffffff; - // hdrf.ornamentHeroModel = heroModel; - // hdrf.unknown063 = 0; - // hdrf.Copied = 0; - // hdrf.unknowna4 = 0xffffffff; - // hdrf.unknowna5 = 0; - // hdrf.ItemClass = item->ItemClass; - // - // ss.write((const char*)&hdrf, sizeof(RoF2::structs::ItemSerializationHeaderFinish)); - // - // 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)); - // } - // - // 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)); - // } - // - // 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((const char*)&null_term, sizeof(uint8)); - // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody struct is %i bytes", sizeof(RoF2::structs::ItemBodyStruct)); - // RoF2::structs::ItemBodyStruct ibs; - // memset(&ibs, 0, sizeof(RoF2::structs::ItemBodyStruct)); - // - // ibs.id = item->ID; - // ibs.weight = item->Weight; - // ibs.norent = item->NoRent; - // ibs.nodrop = item->NoDrop; - // ibs.attune = item->Attuneable; - // ibs.size = item->Size; - // ibs.slots = SwapBits21and22(item->Slots); - // ibs.price = item->Price; - // ibs.icon = item->Icon; - // ibs.unknown1 = 1; - // ibs.unknown2 = 1; - // ibs.BenefitFlag = item->BenefitFlag; - // ibs.tradeskills = item->Tradeskills; - // ibs.CR = item->CR; - // ibs.DR = item->DR; - // ibs.PR = item->PR; - // ibs.MR = item->MR; - // ibs.FR = item->FR; - // ibs.SVCorruption = item->SVCorruption; - // ibs.AStr = item->AStr; - // ibs.ASta = item->ASta; - // ibs.AAgi = item->AAgi; - // ibs.ADex = item->ADex; - // ibs.ACha = item->ACha; - // ibs.AInt = item->AInt; - // ibs.AWis = item->AWis; - // - // ibs.HP = item->HP; - // ibs.Mana = item->Mana; - // ibs.Endur = item->Endur; - // ibs.AC = item->AC; - // ibs.regen = item->Regen; - // ibs.mana_regen = item->ManaRegen; - // ibs.end_regen = item->EnduranceRegen; - // ibs.Classes = item->Classes; - // ibs.Races = item->Races; - // ibs.Deity = item->Deity; - // ibs.SkillModValue = item->SkillModValue; - // ibs.SkillModMax = 0xffffffff; - // ibs.SkillModType = (int8)(item->SkillModType); - // ibs.SkillModExtra = 0; - // ibs.BaneDmgRace = item->BaneDmgRace; - // ibs.BaneDmgBody = item->BaneDmgBody; - // ibs.BaneDmgRaceAmt = item->BaneDmgRaceAmt; - // ibs.BaneDmgAmt = item->BaneDmgAmt; - // ibs.Magic = item->Magic; - // ibs.CastTime_ = item->CastTime_; - // ibs.ReqLevel = item->ReqLevel; - // if (item->ReqLevel > 100) - // ibs.ReqLevel = 100; - // ibs.RecLevel = item->RecLevel; - // if (item->RecLevel > 100) - // ibs.RecLevel = 100; - // ibs.RecSkill = item->RecSkill; - // ibs.BardType = item->BardType; - // ibs.BardValue = item->BardValue; - // ibs.Light = item->Light; - // ibs.Delay = item->Delay; - // ibs.ElemDmgType = item->ElemDmgType; - // ibs.ElemDmgAmt = item->ElemDmgAmt; - // ibs.Range = item->Range; - // ibs.Damage = item->Damage; - // ibs.Color = item->Color; - // ibs.Prestige = 0; - // ibs.ItemType = item->ItemType; - // ibs.Material = item->Material; - // ibs.MaterialUnknown1 = 0; - // ibs.EliteMaterial = item->EliteMaterial; - // ibs.HerosForgeModel = item->HerosForgeModel; - // ibs.MaterialUnknown2 = 0; - // ibs.SellRate = item->SellRate; - // ibs.CombatEffects = item->CombatEffects; - // ibs.Shielding = item->Shielding; - // ibs.StunResist = item->StunResist; - // ibs.StrikeThrough = item->StrikeThrough; - // ibs.ExtraDmgSkill = item->ExtraDmgSkill; - // ibs.ExtraDmgAmt = item->ExtraDmgAmt; - // ibs.SpellShield = item->SpellShield; - // ibs.Avoidance = item->Avoidance; - // ibs.Accuracy = item->Accuracy; - // ibs.CharmFileID = item->CharmFileID; - // ibs.FactionAmt1 = item->FactionAmt1; - // ibs.FactionMod1 = item->FactionMod1; - // ibs.FactionAmt2 = item->FactionAmt2; - // ibs.FactionMod2 = item->FactionMod2; - // ibs.FactionAmt3 = item->FactionAmt3; - // ibs.FactionMod3 = item->FactionMod3; - // ibs.FactionAmt4 = item->FactionAmt4; - // ibs.FactionMod4 = item->FactionMod4; - // - // ss.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((const char*)&null_term, sizeof(uint8)); - // } - // else - // { - // ss.write((const char*)&null_term, sizeof(uint8)); - // } - // - // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody secondary struct is %i bytes", sizeof(RoF2::structs::ItemSecondaryBodyStruct)); - // RoF2::structs::ItemSecondaryBodyStruct isbs; - // memset(&isbs, 0, sizeof(RoF2::structs::ItemSecondaryBodyStruct)); - // - // isbs.augtype = item->AugType; - // isbs.augrestrict2 = -1; - // isbs.augrestrict = item->AugRestrict; - // - // for (int x = AUG_BEGIN; 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]; - // } - // - // isbs.ldonpoint_type = item->PointType; - // isbs.ldontheme = item->LDoNTheme; - // isbs.ldonprice = item->LDoNPrice; - // isbs.ldonsellbackrate = item->LDoNSellBackRate; - // isbs.ldonsold = item->LDoNSold; - // - // isbs.bagtype = item->BagType; - // isbs.bagslots = item->BagSlots; - // isbs.bagsize = item->BagSize; - // isbs.wreduction = item->BagWR; - // - // isbs.book = item->Book; - // isbs.booktype = item->BookType; - // - // ss.write((const char*)&isbs, sizeof(RoF2::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)); - // } - // - // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody tertiary struct is %i bytes", sizeof(RoF2::structs::ItemTertiaryBodyStruct)); - // RoF2::structs::ItemTertiaryBodyStruct itbs; - // memset(&itbs, 0, sizeof(RoF2::structs::ItemTertiaryBodyStruct)); - // - // itbs.loregroup = item->LoreGroup; - // itbs.artifact = item->ArtifactFlag; - // itbs.summonedflag = item->SummonedFlag; - // itbs.favor = item->Favor; - // itbs.fvnodrop = item->FVNoDrop; - // itbs.dotshield = item->DotShielding; - // itbs.atk = item->Attack; - // itbs.haste = item->Haste; - // itbs.damage_shield = item->DamageShield; - // itbs.guildfavor = item->GuildFavor; - // itbs.augdistil = item->AugDistiller; - // itbs.unknown3 = 0xffffffff; - // itbs.unknown4 = 0; - // itbs.no_pet = item->NoPet; - // itbs.unknown5 = 0; - // - // itbs.potion_belt_enabled = item->PotionBelt; - // itbs.potion_belt_slots = item->PotionBeltSlots; - // itbs.stacksize = stackable ? item->StackSize : 0; - // itbs.no_transfer = item->NoTransfer; - // itbs.expendablearrow = item->ExpendableArrow; - // - // itbs.unknown8 = 0; - // itbs.unknown9 = 0; - // itbs.unknown10 = 0; - // itbs.unknown11 = 0; - // itbs.unknown12 = 0; - // itbs.unknown13 = 0; - // itbs.unknown14 = 0; - // - // ss.write((const char*)&itbs, sizeof(RoF2::structs::ItemTertiaryBodyStruct)); - // - // // Effect Structures Broken down to allow variable length strings for effect names - // int32 effect_unknown = 0; - // - // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Click effect struct is %i bytes", sizeof(RoF2::structs::ClickEffectStruct)); - // RoF2::structs::ClickEffectStruct ices; - // memset(&ices, 0, sizeof(RoF2::structs::ClickEffectStruct)); - // - // ices.effect = item->Click.Effect; - // ices.level2 = item->Click.Level2; - // ices.type = item->Click.Type; - // ices.level = item->Click.Level; - // ices.max_charges = item->MaxCharges; - // ices.cast_time = item->CastTime; - // ices.recast = item->RecastDelay; - // ices.recast_type = item->RecastType; - // - // ss.write((const char*)&ices, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // clickunk7 - // - // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody proc effect struct is %i bytes", sizeof(RoF2::structs::ProcEffectStruct)); - // RoF2::structs::ProcEffectStruct ipes; - // memset(&ipes, 0, sizeof(RoF2::structs::ProcEffectStruct)); - // - // ipes.effect = item->Proc.Effect; - // ipes.level2 = item->Proc.Level2; - // ipes.type = item->Proc.Type; - // ipes.level = item->Proc.Level; - // ipes.procrate = item->ProcRate; - // - // ss.write((const char*)&ipes, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // unknown5 - // - // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody worn effect struct is %i bytes", sizeof(RoF2::structs::WornEffectStruct)); - // RoF2::structs::WornEffectStruct iwes; - // memset(&iwes, 0, sizeof(RoF2::structs::WornEffectStruct)); - // - // iwes.effect = item->Worn.Effect; - // iwes.level2 = item->Worn.Level2; - // iwes.type = item->Worn.Type; - // iwes.level = item->Worn.Level; - // - // ss.write((const char*)&iwes, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // unknown6 - // - // RoF2::structs::WornEffectStruct ifes; - // memset(&ifes, 0, sizeof(RoF2::structs::WornEffectStruct)); - // - // ifes.effect = item->Focus.Effect; - // ifes.level2 = item->Focus.Level2; - // ifes.type = item->Focus.Type; - // ifes.level = item->Focus.Level; - // - // ss.write((const char*)&ifes, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // unknown6 - // - // RoF2::structs::WornEffectStruct ises; - // memset(&ises, 0, sizeof(RoF2::structs::WornEffectStruct)); - // - // ises.effect = item->Scroll.Effect; - // ises.level2 = item->Scroll.Level2; - // ises.type = item->Scroll.Type; - // ises.level = item->Scroll.Level; - // - // ss.write((const char*)&ises, sizeof(RoF2::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((const char*)&effect_unknown, sizeof(int32)); // unknown6 - // - // // Bard Effect? - // RoF2::structs::WornEffectStruct ibes; - // memset(&ibes, 0, sizeof(RoF2::structs::WornEffectStruct)); - // - // ibes.effect = item->Bard.Effect; - // ibes.level2 = item->Bard.Level2; - // ibes.type = item->Bard.Type; - // ibes.level = item->Bard.Level; - // //ibes.unknown6 = 0xffffffff; - // - // ss.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)); - // } - // else */ - // ss.write((const char*)&null_term, sizeof(uint8)); - // - // ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 - // // End of Effects - // - // //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] ItemBody Quaternary effect struct is %i bytes", sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); - // RoF2::structs::ItemQuaternaryBodyStruct iqbs; - // memset(&iqbs, 0, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); - // - // iqbs.scriptfileid = item->ScriptFileID; - // iqbs.quest_item = item->QuestItemFlag; - // iqbs.Power = 0; - // iqbs.Purity = item->Purity; - // iqbs.unknown16 = 0; - // iqbs.BackstabDmg = item->BackstabDmg; - // iqbs.DSMitigation = item->DSMitigation; - // iqbs.HeroicStr = item->HeroicStr; - // iqbs.HeroicInt = item->HeroicInt; - // iqbs.HeroicWis = item->HeroicWis; - // iqbs.HeroicAgi = item->HeroicAgi; - // iqbs.HeroicDex = item->HeroicDex; - // iqbs.HeroicSta = item->HeroicSta; - // iqbs.HeroicCha = item->HeroicCha; - // iqbs.HeroicMR = item->HeroicMR; - // iqbs.HeroicFR = item->HeroicFR; - // iqbs.HeroicCR = item->HeroicCR; - // iqbs.HeroicDR = item->HeroicDR; - // iqbs.HeroicPR = item->HeroicPR; - // iqbs.HeroicSVCorrup = item->HeroicSVCorrup; - // iqbs.HealAmt = item->HealAmt; - // iqbs.SpellDmg = item->SpellDmg; - // iqbs.clairvoyance = item->Clairvoyance; - // - // //unknown18; //Power Source Capacity or evolve filename? - // //evolve_string; // Some String, but being evolution related is just a guess - // - // iqbs.Heirloom = 0; - // iqbs.Placeable = 0; - // - // iqbs.unknown28 = -1; - // iqbs.unknown30 = -1; - // - // iqbs.NoZone = 0; - // iqbs.NoGround = 0; - // iqbs.unknown37a = 0; // (guessed position) New to RoF2 - // iqbs.unknown38 = 0; - // - // iqbs.unknown39 = 1; - // - // iqbs.subitem_count = 0; - // - // char *SubSerializations[10]; // - // - // uint32 SubLengths[10]; - // - // for (int x = SUB_BEGIN; x < EmuConstants::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 >= EmuConstants::GENERAL_BEGIN && slot_id_in <= EmuConstants::GENERAL_END) // (< 30) - no cursor? - // //SubSlotNumber = (((slot_id_in + 3) * 10) + x + 1); - // SubSlotNumber = (((slot_id_in + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + x + 1); - // else if (slot_id_in >= EmuConstants::BANK_BEGIN && slot_id_in <= EmuConstants::BANK_END) - // //SubSlotNumber = (((slot_id_in - 2000) * 10) + 2030 + x + 1); - // SubSlotNumber = (((slot_id_in - EmuConstants::BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE) + EmuConstants::BANK_BAGS_BEGIN + x); - // else if (slot_id_in >= EmuConstants::SHARED_BANK_BEGIN && slot_id_in <= EmuConstants::SHARED_BANK_END) - // //SubSlotNumber = (((slot_id_in - 2500) * 10) + 2530 + x + 1); - // SubSlotNumber = (((slot_id_in - EmuConstants::SHARED_BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE) + EmuConstants::SHARED_BANK_BAGS_BEGIN + x); - // else - // SubSlotNumber = slot_id_in; // ??????? - // - // /* - // // TEST CODE: - // SubSlotNumber = InventoryOld::CalcSlotID(slot_id_in, x); - // */ - // - // SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1, packet_type); - // } - // } - // - // ss.write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); - // - // for (int x = SUB_BEGIN; x < EmuConstants::ITEM_CONTAINER_SIZE; ++x) { - // - // if (SubSerializations[x]) { - // - // ss.write((const char*)&x, sizeof(uint32)); - // - // ss.write(SubSerializations[x], SubLengths[x]); - // - // safe_delete_array(SubSerializations[x]); - // } - // } - // - // char* item_serial = new char[ss.tellp()]; - // memset(item_serial, 0, ss.tellp()); - // memcpy(item_serial, ss.str().c_str(), ss.tellp()); - // - // *length = ss.tellp(); - // return item_serial; - //} - void SerializeItem(EQEmu::MemoryBuffer &packet_data, EQEmu::ItemInstance *inst, int container_id, int slot_id, int bag_id, int aug_id) { int ornamentation_augtype = RuleI(Character, OrnamentationAugmentType); uint8 null_term = 0; @@ -6222,17 +5667,25 @@ namespace RoF2 iqbs.unknown39 = 1; - iqbs.subitem_count = inst->GetSubItemCount(); + EQEmu::ItemContainer *container = inst->GetContainer(); + if(container) { + iqbs.subitem_count = container->Size(); + packet_data.Write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); - packet_data.Write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); - - for(int x = 0; x < 255; ++x) { - auto sub_inst = inst->Get(x); - - if(sub_inst) { - packet_data.Write((const char*)&x, sizeof(uint32)); - SerializeItem(packet_data, sub_inst.get(), container_id, slot_id, x, -1); + auto iter = container->Begin(); + auto end = container->End(); + while(iter != end) { + auto sub_inst = inst->Get(iter->first); + if(sub_inst) { + uint32 bag_slot = iter->first; + packet_data.Write((const char*)&bag_slot, sizeof(uint32)); + SerializeItem(packet_data, sub_inst.get(), container_id, slot_id, bag_slot, -1); + } + ++iter; } + } else { + iqbs.subitem_count = 0; + packet_data.Write((const char*)&iqbs, sizeof(RoF2::structs::ItemQuaternaryBodyStruct)); } } From 18b4d068ea653bb37818bf69df37b5ecafc7cd64 Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 26 Feb 2015 22:09:29 -0800 Subject: [PATCH 15/27] Early stages of swapping requirements in, should check for basic validity and equipable status --- common/data_verification.h | 4 +- common/inventory.cpp | 120 ++++++++++++++++++++++++++++++------- common/inventory.h | 58 +++++++++++++----- common/item_instance.cpp | 4 +- zone/client.cpp | 6 +- zone/client.h | 6 +- zone/client_packet.cpp | 69 ++------------------- zone/exp.cpp | 2 +- zone/inventory.cpp | 75 ++++++++++++++++++++++- zone/trading.cpp | 2 +- 10 files changed, 232 insertions(+), 114 deletions(-) diff --git a/common/data_verification.h b/common/data_verification.h index 9da85a579..e0cb055c2 100644 --- a/common/data_verification.h +++ b/common/data_verification.h @@ -38,8 +38,8 @@ T ClampUpper(const T& value, const T& upper) { return std::min(value, upper); } -template -bool ValueWithin(const T& value, const T& lower, const T& upper) { +template +bool ValueWithin(const T& value, const U& lower, const V& upper) { return value >= lower && value <= upper; } diff --git a/common/inventory.cpp b/common/inventory.cpp index 9cd897bed..ecdf35934 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -19,8 +19,82 @@ #include "inventory.h" #include "data_verification.h" #include "item_container_personal_serialization.h" +#include "string_util.h" #include +bool EQEmu::InventorySlot::IsValid() const { + if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotCharm, PersonalSlotCursor)) { + return true; + } + + if(type_ == InvTypeBank && EQEmu::ValueWithin(slot_, 0, 23)) { + return true; + } + + if(type_ == InvTypeSharedBank && EQEmu::ValueWithin(slot_, 0, 1)) { + return true; + } + + if(type_ == InvTypeTribute && EQEmu::ValueWithin(slot_, 0, 4)) { + return true; + } + + if(type_ == InvTypeTrade && EQEmu::ValueWithin(slot_, 0, 7)) { + return true; + } + + if(type_ == InvTypeWorld && EQEmu::ValueWithin(slot_, 0, 255)) { + return true; + } + + + return false; +} + +bool EQEmu::InventorySlot::IsBank() const { + if(type_ == InvTypeBank && EQEmu::ValueWithin(slot_, 0, 23)) { + return true; + } + + if(type_ == InvTypeSharedBank && EQEmu::ValueWithin(slot_, 0, 1)) { + return true; + } + + return false; +} + +bool EQEmu::InventorySlot::IsCursor() const { + if(type_ == InvTypePersonal && slot_ == PersonalSlotCursor) { + return true; + } + + if(type_ == InvTypeCursorBuffer) { + return true; + } + + return false; +} + +bool EQEmu::InventorySlot::IsEquipment() const { + if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotCharm, PersonalSlotAmmo)) { + return true; + } + + return false; +} + +bool EQEmu::InventorySlot::IsGeneral() const { + if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotGeneral1, PersonalSlotGeneral10)) { + return true; + } + + return false; +} + +const std::string EQEmu::InventorySlot::ToString() const { + return StringFormat("(%i, %i, %i, %i)", type_, slot_, bag_index_, aug_index_); +} + struct EQEmu::Inventory::impl { std::map containers_; @@ -35,15 +109,15 @@ EQEmu::Inventory::~Inventory() { } std::shared_ptr EQEmu::Inventory::Get(const InventorySlot &slot) { - auto iter = impl_->containers_.find(slot.type_); + auto iter = impl_->containers_.find(slot.Type()); if(iter != impl_->containers_.end()) { - auto item = iter->second.Get(slot.slot_); + auto item = iter->second.Get(slot.Slot()); if(item) { - if(slot.bag_index_ > -1) { - auto sub_item = item->Get(slot.bag_index_); + if(slot.BagIndex() > -1) { + auto sub_item = item->Get(slot.BagIndex()); if(sub_item) { - if(slot.aug_index_ > -1) { - return sub_item->Get(slot.aug_index_); + if(slot.AugIndex() > -1) { + return sub_item->Get(slot.AugIndex()); } else { return sub_item; } @@ -58,42 +132,42 @@ std::shared_ptr EQEmu::Inventory::Get(const InventorySlot & } bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr inst) { - if(impl_->containers_.count(slot.type_) == 0) { - if(slot.type_ == 0) { - impl_->containers_.insert(std::pair(slot.type_, ItemContainer(new ItemContainerPersonalSerialization()))); + if(impl_->containers_.count(slot.Type()) == 0) { + if(slot.Type() == 0) { + impl_->containers_.insert(std::pair(slot.Type(), ItemContainer(new ItemContainerPersonalSerialization()))); } else { - impl_->containers_.insert(std::pair(slot.type_, ItemContainer())); + impl_->containers_.insert(std::pair(slot.Type(), ItemContainer())); } } //Verify item can be put into the slot requested - auto &container = impl_->containers_[slot.type_]; - if(slot.bag_index_ > -1) { - auto item = container.Get(slot.slot_); + auto &container = impl_->containers_[slot.Type()]; + if(slot.BagIndex() > -1) { + auto item = container.Get(slot.Slot()); if(!item) return false; - if(slot.aug_index_ > -1) { - auto bag_item = item->Get(slot.bag_index_); + if(slot.AugIndex() > -1) { + auto bag_item = item->Get(slot.BagIndex()); if(!bag_item) { return false; } - return bag_item->Put(slot.aug_index_, inst); + return bag_item->Put(slot.AugIndex(), inst); } else { - return item->Put(slot.bag_index_, inst); + return item->Put(slot.BagIndex(), inst); } } else { - if(slot.aug_index_ > -1) { - auto item = container.Get(slot.slot_); + if(slot.AugIndex() > -1) { + auto item = container.Get(slot.Slot()); if(!item) return false; - return item->Put(slot.aug_index_, inst); + return item->Put(slot.AugIndex(), inst); } - return container.Put(slot.slot_, inst); + return container.Put(slot.Slot(), inst); } return false; @@ -104,10 +178,10 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, } int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) { - if(slot.type_ != 0) + if(slot.Type() != 0) return _MaterialInvalid; - switch(slot.slot_) { + switch(slot.Slot()) { case PersonalSlotHead: return MaterialHead; case PersonalSlotChest: diff --git a/common/inventory.h b/common/inventory.h index 15196e622..b50bc7b0a 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -20,24 +20,10 @@ #define COMMON_INVENTORY_H #include "item_container.h" +#include namespace EQEmu { - struct InventorySlot - { - InventorySlot(int type, int slot) - : type_(type), slot_(slot), bag_index_(-1), aug_index_(-1) { } - InventorySlot(int type, int slot, int bag_index) - : type_(type), slot_(slot), bag_index_(bag_index), aug_index_(-1) { } - InventorySlot(int type, int slot, int bag_index, int aug_index) - : type_(type), slot_(slot), bag_index_(bag_index), aug_index_(aug_index) { } - - int type_; - int slot_; - int bag_index_; - int aug_index_; - }; - enum InventoryType : int { InvTypePersonal = 0, @@ -89,6 +75,48 @@ namespace EQEmu PersonalSlotCursor }; + class InventorySlot + { + public: + InventorySlot() : type_(-1), slot_(-1), bag_index_(-1), aug_index_(-1) { } + InventorySlot(int type, int slot) + : type_(type), slot_(slot), bag_index_(-1), aug_index_(-1) { } + InventorySlot(int type, int slot, int bag_index) + : type_(type), slot_(slot), bag_index_(bag_index), aug_index_(-1) { } + InventorySlot(int type, int slot, int bag_index, int aug_index) + : type_(type), slot_(slot), bag_index_(bag_index), aug_index_(aug_index) { } + + bool IsValid() const; + bool IsBank() const; + bool IsCursor() const; + bool IsEquipment() const; + bool IsGeneral() const; + + const std::string ToString() const; + + inline int Type() { return type_; } + inline int Type() const { return type_; } + inline int Slot() { return slot_; } + inline int Slot() const { return slot_; } + inline int BagIndex() { return bag_index_; } + inline int BagIndex() const { return bag_index_; } + inline int AugIndex() { return aug_index_; } + inline int AugIndex() const { return aug_index_; } + + private: + int type_; + int slot_; + int bag_index_; + int aug_index_; + }; + + inline bool operator==(const InventorySlot &lhs, const InventorySlot &rhs) { + return lhs.Type() == rhs.Type() && + lhs.Slot() == rhs.Slot() && + lhs.BagIndex() == rhs.BagIndex() && + lhs.AugIndex() == rhs.AugIndex(); } + inline bool operator!=(const InventorySlot &lhs, const InventorySlot &rhs) { return !(lhs == rhs); } + class Inventory { public: diff --git a/common/item_instance.cpp b/common/item_instance.cpp index 4b442dfc2..b97edbd54 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -124,14 +124,14 @@ bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr ins auto *item = impl_->base_item_; if(item->ItemClass == ItemClassContainer) { // Bag - if(!EQEmu::ValueWithin(index, 0, (int)item->BagSlots)) { + if(!EQEmu::ValueWithin(index, 0, item->BagSlots)) { return false; } return impl_->contents_.Put(index, inst); } else if(item->ItemClass == ItemClassCommon) { // Augment - if(!EQEmu::ValueWithin(index, 0, (int)EmuConstants::ITEM_COMMON_SIZE)) { + if(!EQEmu::ValueWithin(index, 0, EmuConstants::ITEM_COMMON_SIZE)) { return false; } diff --git a/zone/client.cpp b/zone/client.cpp index c3e2b1729..db29aa107 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2167,7 +2167,7 @@ void Client::AddMoneyToPP(uint64 copper, bool updateclient){ Log.Out(Logs::General, Logs::None, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i", GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper); } -void Client::EVENT_ITEM_ScriptStopReturn(){ +void Client::ItemScriptStopReturn(){ /* Set a timestamp in an entity variable for plugin check_handin.pl in return_items This will stopgap players from items being returned if global_npc.pl has a catch all return_items */ @@ -2175,11 +2175,11 @@ void Client::EVENT_ITEM_ScriptStopReturn(){ char buffer[50]; gettimeofday(&read_time, 0); sprintf(buffer, "%li.%li \n", read_time.tv_sec, read_time.tv_usec); - this->SetEntityVariable("Stop_Return", buffer); + SetEntityVariable("Stop_Return", buffer); } void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool updateclient){ - this->EVENT_ITEM_ScriptStopReturn(); + ItemScriptStopReturn(); int32 new_value = m_pp.platinum + platinum; if(new_value >= 0 && new_value > m_pp.platinum) diff --git a/zone/client.h b/zone/client.h index 3d4e1c8d0..f4aa36412 100644 --- a/zone/client.h +++ b/zone/client.h @@ -800,7 +800,7 @@ public: int32 acmod(); // Item methods - void EVENT_ITEM_ScriptStopReturn(); + void ItemScriptStopReturn(); uint32 NukeItem(uint32 itemnum, uint8 where_to_check = (invWhereWorn | invWherePersonal | invWhereBank | invWhereSharedBank | invWhereTrading | invWhereCursor)); void SetTint(int16 slot_id, uint32 color); @@ -823,6 +823,10 @@ public: void IncStats(uint8 type,int16 increase_val); void DropItem(int16 slot_id); + //New Inventory + bool SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlot &dest, int number_in_stack); + bool CanEquipItem(std::shared_ptr inst, const EQEmu::InventorySlot &slot); + // // class Client::TextLink // diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 10f729aa2..4304fc3c4 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -9593,70 +9593,11 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app) } MoveItem_Struct* mi = (MoveItem_Struct*)app->pBuffer; - auto res = m_inventory.Swap(EQEmu::InventorySlot(mi->from_type, mi->from_slot, mi->from_bag_slot, mi->from_aug_slot), - EQEmu::InventorySlot(mi->to_type, mi->to_slot, mi->to_bag_slot, mi->to_aug_slot), - mi->number_in_stack); - - //printf("%i %i %i %i --> %i %i %i %i (%u)\n", - // mi->from_type, mi->from_slot, mi->from_bag_slot, mi->from_aug_slot, - // mi->to_type, mi->to_slot, mi->to_bag_slot, mi->to_aug_slot, - // mi->number_in_stack); - - //if (spellend_timer.Enabled() && casting_spell_id && !IsBardSong(casting_spell_id)) - //{ - // if (mi->from_slot != mi->to_slot && (mi->from_slot <= EmuConstants::GENERAL_END || mi->from_slot > 39) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) - // { - // char *detect = nullptr; - // const ItemInst *itm_from = GetInv().GetItem(mi->from_slot); - // const ItemInst *itm_to = GetInv().GetItem(mi->to_slot); - // MakeAnyLenString(&detect, "Player issued a move item from %u(item id %u) to %u(item id %u) while casting %u.", - // mi->from_slot, - // itm_from ? itm_from->GetID() : 0, - // mi->to_slot, - // itm_to ? itm_to->GetID() : 0, - // casting_spell_id); - // database.SetMQDetectionFlag(AccountName(), GetName(), detect, zone->GetShortName()); - // safe_delete_array(detect); - // Kick(); // Kick client to prevent client and server from getting out-of-sync inventory slots - // return; - // } - //} - // - //// Illegal bagslot usage checks. Currently, user only receives a message if this check is triggered. - //bool mi_hack = false; - // - //if (mi->from_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->from_slot <= EmuConstants::CURSOR_BAG_END) { - // if (mi->from_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; } - // else { - // int16 from_parent = m_inv.CalcSlotId(mi->from_slot); - // if (!m_inv[from_parent]) { mi_hack = true; } - // else if (!m_inv[from_parent]->IsType(ItemClassContainer)) { mi_hack = true; } - // else if (m_inv.CalcBagIdx(mi->from_slot) >= m_inv[from_parent]->GetItem()->BagSlots) { mi_hack = true; } - // } - //} - // - //if (mi->to_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->to_slot <= EmuConstants::CURSOR_BAG_END) { - // if (mi->to_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; } - // else { - // int16 to_parent = m_inv.CalcSlotId(mi->to_slot); - // if (!m_inv[to_parent]) { mi_hack = true; } - // else if (!m_inv[to_parent]->IsType(ItemClassContainer)) { mi_hack = true; } - // else if (m_inv.CalcBagIdx(mi->to_slot) >= m_inv[to_parent]->GetItem()->BagSlots) { mi_hack = true; } - // } - //} - // - //if (mi_hack) { Message(15, "Caution: Illegal use of inaccessible bag slots!"); } - // - //if (!SwapItem(mi) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) { - // SwapItemResync(mi); - // - // bool error = false; - // InterrogateInventory(this, false, true, false, error, false); - // if (error) - // InterrogateInventory(this, true, false, true, error); - //} - // - //return; + EQEmu::InventorySlot src(mi->from_type, mi->from_slot, mi->from_bag_slot, mi->from_aug_slot); + EQEmu::InventorySlot dest(mi->to_type, mi->to_slot, mi->to_bag_slot, mi->to_aug_slot); + if(!SwapItem(src, dest, mi->number_in_stack)) { + //Send Resync Here + } } void Client::Handle_OP_OpenContainer(const EQApplicationPacket *app) diff --git a/zone/exp.cpp b/zone/exp.cpp index 7e878206a..2aa60ce92 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -61,7 +61,7 @@ static uint32 MaxBankedRaidLeadershipPoints(int Level) void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) { - this->EVENT_ITEM_ScriptStopReturn(); + ItemScriptStopReturn(); uint32 add_exp = in_add_exp; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 59901fd85..207124e9e 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -18,8 +18,8 @@ #include "../common/global_define.h" #include "../common/eqemu_logsys.h" - #include "../common/string_util.h" +#include "../common/data_verification.h" #include "quest_parser_collection.h" #include "worldserver.h" #include "zonedb.h" @@ -191,7 +191,7 @@ bool Client::CheckLoreConflict(const ItemData* item) } bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, bool attuned, uint16 to_slot, uint32 ornament_icon, uint32 ornament_idfile, uint32 ornament_hero_model) { - this->EVENT_ITEM_ScriptStopReturn(); + ItemScriptStopReturn(); // TODO: update calling methods and script apis to handle a failure return @@ -3092,3 +3092,74 @@ std::string InventoryOld::GetCustomItemData(int16 slot_id, std::string identifie } return ""; } + +//New Inventory +bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlot &dest, int number_in_stack) { + + if (spellend_timer.Enabled() && casting_spell_id && !IsBardSong(casting_spell_id)) + { + if(src != dest && !src.IsCursor() && src.IsValid() && dest.IsValid()) { + auto i_src = m_inventory.Get(src); + auto i_dest = m_inventory.Get(dest); + std::string detect = StringFormat("Player issued a move item from %s (item id %u) to %s (item id %u) while casting %u.", + src.ToString().c_str(), + i_src ? i_src->GetItem()->ID : 0, + dest.ToString().c_str(), + i_dest ? i_dest->GetItem()->ID : 0, + casting_spell_id); + database.SetMQDetectionFlag(AccountName(), GetName(), detect.c_str(), zone->GetShortName()); + Kick(); + return false; + } + } + + auto i_src = m_inventory.Get(src); + auto i_dest = m_inventory.Get(dest); + + if(dest.IsEquipment() && !CanEquipItem(i_dest, dest)) { + return false; + } + + printf("Equip check passes %s -> %s\n", src.ToString().c_str(), dest.ToString().c_str()); + + bool res = m_inventory.Swap(src, dest, number_in_stack); + + return true; +} + +bool Client::CanEquipItem(std::shared_ptr inst, const EQEmu::InventorySlot &slot) { + if(!inst) { + return false; + } + + if(slot.Type() != 0) { + return false; + } + + if(!EQEmu::ValueWithin(slot.Slot(), EQEmu::PersonalSlotCharm, EQEmu::PersonalSlotAmmo)) { + return false; + } + + auto item = inst->GetItem(); + //check slot + + int use_slot = -1; + if(slot.Slot() == EQEmu::PersonalSlotPowerSource) { + use_slot = EQEmu::PersonalSlotAmmo; + } + else if(slot.Slot() == EQEmu::PersonalSlotAmmo) { + use_slot = EQEmu::PersonalSlotPowerSource; + } else { + use_slot = slot.Slot(); + } + + if(!(item->Slots & (1 << use_slot))) { + return false; + } + + if(!item->IsEquipable(GetBaseRace(), GetBaseClass())) { + return false; + } + + return true; +} diff --git a/zone/trading.cpp b/zone/trading.cpp index 0bcd3da41..f1e7bdc1f 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -923,7 +923,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st if(!tradingWith->IsMoving()) tradingWith->FaceTarget(this); - this->EVENT_ITEM_ScriptStopReturn(); + ItemScriptStopReturn(); } } From 7870bf103afb33e262161094f55c8253c7ec179c Mon Sep 17 00:00:00 2001 From: KimLS Date: Fri, 27 Feb 2015 02:40:44 -0800 Subject: [PATCH 16/27] Working on can equip, putting it in the general inventory class. --- common/inventory.cpp | 44 +++++++++++++++++++++++++++++++++++++++- common/inventory.h | 3 ++- tests/CMakeLists.txt | 2 +- tests/inventory_test.h | 46 ++++++++++++++++++++++++++++++++++-------- tests/main.cpp | 3 +++ zone/client.h | 1 - zone/inventory.cpp | 40 ++---------------------------------- zone/mob.cpp | 3 ++- 8 files changed, 91 insertions(+), 51 deletions(-) diff --git a/common/inventory.cpp b/common/inventory.cpp index ecdf35934..878e9f450 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -98,10 +98,14 @@ const std::string EQEmu::InventorySlot::ToString() const { struct EQEmu::Inventory::impl { std::map containers_; + int race_; + int class_; }; -EQEmu::Inventory::Inventory() { +EQEmu::Inventory::Inventory(int race, int class_) { impl_ = new impl; + impl_->race_ = race; + impl_->class_ = class_; } EQEmu::Inventory::~Inventory() { @@ -231,6 +235,44 @@ EQEmu::InventorySlot EQEmu::Inventory::CalcSlotFromMaterial(int material) { } } +bool EQEmu::Inventory::CanEquip(std::shared_ptr inst, const EQEmu::InventorySlot &slot) { + if(!inst) { + return false; + } + + if(slot.Type() != 0) { + return false; + } + + if(!EQEmu::ValueWithin(slot.Slot(), EQEmu::PersonalSlotCharm, EQEmu::PersonalSlotAmmo)) { + return false; + } + + auto item = inst->GetItem(); + //check slot + + int use_slot = -1; + if(slot.Slot() == EQEmu::PersonalSlotPowerSource) { + use_slot = EQEmu::PersonalSlotAmmo; + } + else if(slot.Slot() == EQEmu::PersonalSlotAmmo) { + use_slot = EQEmu::PersonalSlotPowerSource; + } + else { + use_slot = slot.Slot(); + } + + if(!(item->Slots & (1 << use_slot))) { + return false; + } + + if(!item->IsEquipable(impl_->race_, impl_->class_)) { + return false; + } + + return true; +} + bool EQEmu::Inventory::Serialize(MemoryBuffer &buf) { buf.SetWritePosition(0); buf.SetReadPosition(0); diff --git a/common/inventory.h b/common/inventory.h index b50bc7b0a..c3606949d 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -120,7 +120,7 @@ namespace EQEmu class Inventory { public: - Inventory(); + Inventory(int race, int class_); ~Inventory(); std::shared_ptr Get(const InventorySlot &slot); @@ -130,6 +130,7 @@ namespace EQEmu //utility static int CalcMaterialFromSlot(const InventorySlot &slot); static InventorySlot CalcSlotFromMaterial(int material); + bool CanEquip(std::shared_ptr inst, const EQEmu::InventorySlot &slot); bool Serialize(MemoryBuffer &buf); private: struct impl; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5e10cddba..3738a5719 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -22,7 +22,7 @@ SET(tests_headers ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers}) -TARGET_LINK_LIBRARIES(tests common cppunit) +TARGET_LINK_LIBRARIES(tests common cppunit debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE}) INSTALL(TARGETS tests RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}) diff --git a/tests/inventory_test.h b/tests/inventory_test.h index 55ff1f655..6cb34c6b3 100644 --- a/tests/inventory_test.h +++ b/tests/inventory_test.h @@ -26,13 +26,14 @@ class InventoryTest : public Test::Suite { typedef void(InventoryTest::*TestFunction)(void); public: - InventoryTest() { + InventoryTest() : inv(1, 1) { InitContainer(); InitArmor(); InitAugment(); InitStackable(); InitInventory(); TEST_ADD(InventoryTest::InventoryVerifyInitialItemsTest); + TEST_ADD(InventoryTest::InventoryCanEquipTest); } ~InventoryTest() { @@ -144,15 +145,15 @@ private: std::shared_ptr m_armor(new EQEmu::ItemInstance(&armor)); std::shared_ptr m_augment(new EQEmu::ItemInstance(&augment)); std::shared_ptr m_stackable(new EQEmu::ItemInstance(&stackable, 45)); - inv.Put(EQEmu::InventorySlot(0, 23), m_bag); - inv.Put(EQEmu::InventorySlot(0, 23, 0), m_armor); - inv.Put(EQEmu::InventorySlot(0, 23, 1), m_augment); - inv.Put(EQEmu::InventorySlot(0, 23, 7), m_stackable); + inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1), m_bag); + inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 0), m_armor); + inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 1), m_augment); + inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7), m_stackable); } void InventoryVerifyInitialItemsTest() { - auto m_bag = inv.Get(EQEmu::InventorySlot(0, 23)); + auto m_bag = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1)); TEST_ASSERT(m_bag); TEST_ASSERT(m_bag->GetItem()); TEST_ASSERT(m_bag->GetItem()->ID == 1000); @@ -173,12 +174,41 @@ private: TEST_ASSERT(m_stackable->GetItem()->ID == 1003); } + void InventoryCanEquipTest() { + auto m_bag = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1)); + TEST_ASSERT(m_bag); + TEST_ASSERT(m_bag->GetItem()); + TEST_ASSERT(m_bag->GetItem()->ID == 1000); + + auto m_armor = m_bag->Get(0); + TEST_ASSERT(m_armor); + TEST_ASSERT(m_armor->GetItem()); + TEST_ASSERT(m_armor->GetItem()->ID == 1001); + + auto can_equip = inv.CanEquip(m_armor, EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotChest)); + TEST_ASSERT(can_equip); + + can_equip = inv.CanEquip(m_armor, EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotWaist)); + TEST_ASSERT(!can_equip); + + armor.Classes -= 1; + can_equip = inv.CanEquip(m_armor, EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotChest)); + TEST_ASSERT(!can_equip); + armor.Classes += 1; + + armor.Races -= 1; + can_equip = inv.CanEquip(m_armor, EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotChest)); + TEST_ASSERT(!can_equip); + armor.Races += 1; + } + void InventorySwapItemsTest() { - auto swap_result = inv.Swap(EQEmu::InventorySlot(0, 23), EQEmu::InventorySlot(0, 24), 0); + auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1), + EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2), 0); TEST_ASSERT(swap_result == true); - auto m_bag = inv.Get(EQEmu::InventorySlot(0, 24)); + auto m_bag = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2)); TEST_ASSERT(m_bag); TEST_ASSERT(m_bag->GetItem()); TEST_ASSERT(m_bag->GetItem()->ID == 1000); diff --git a/tests/main.cpp b/tests/main.cpp index 420280f30..d9dad9da6 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -20,6 +20,7 @@ #include #include #include +#include "../common/eqemu_logsys.h" #include "memory_mapped_file_test.h" #include "ipc_mutex_test.h" #include "fixed_memory_test.h" @@ -32,6 +33,8 @@ #include "inventory_test.h" #include "memory_buffer_test.h" +EQEmuLogSys Log; + int main() { try { std::ofstream outfile("test_output.txt"); diff --git a/zone/client.h b/zone/client.h index f4aa36412..2ceadae2a 100644 --- a/zone/client.h +++ b/zone/client.h @@ -825,7 +825,6 @@ public: //New Inventory bool SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlot &dest, int number_in_stack); - bool CanEquipItem(std::shared_ptr inst, const EQEmu::InventorySlot &slot); // // class Client::TextLink diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 207124e9e..55aa08620 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -3116,50 +3116,14 @@ bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlo auto i_src = m_inventory.Get(src); auto i_dest = m_inventory.Get(dest); - if(dest.IsEquipment() && !CanEquipItem(i_dest, dest)) { + if(dest.IsEquipment() && !m_inventory.CanEquip(i_dest, dest)) { return false; } printf("Equip check passes %s -> %s\n", src.ToString().c_str(), dest.ToString().c_str()); - + bool res = m_inventory.Swap(src, dest, number_in_stack); return true; } -bool Client::CanEquipItem(std::shared_ptr inst, const EQEmu::InventorySlot &slot) { - if(!inst) { - return false; - } - - if(slot.Type() != 0) { - return false; - } - - if(!EQEmu::ValueWithin(slot.Slot(), EQEmu::PersonalSlotCharm, EQEmu::PersonalSlotAmmo)) { - return false; - } - - auto item = inst->GetItem(); - //check slot - - int use_slot = -1; - if(slot.Slot() == EQEmu::PersonalSlotPowerSource) { - use_slot = EQEmu::PersonalSlotAmmo; - } - else if(slot.Slot() == EQEmu::PersonalSlotAmmo) { - use_slot = EQEmu::PersonalSlotPowerSource; - } else { - use_slot = slot.Slot(); - } - - if(!(item->Slots & (1 << use_slot))) { - return false; - } - - if(!item->IsEquipable(GetBaseRace(), GetBaseClass())) { - return false; - } - - return true; -} diff --git a/zone/mob.cpp b/zone/mob.cpp index 909db26c8..d7a63f065 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -102,7 +102,8 @@ Mob::Mob(const char* in_name, m_TargetLocation(glm::vec3()), m_TargetV(glm::vec3()), flee_timer(FLEE_CHECK_TIMER), - m_Position(position) + m_Position(position), + m_inventory(in_race, in_class) { targeted = 0; tar_ndx=0; From 20cbe4af44f6239c9eb31df3dec1a729d9a75bc3 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 28 Feb 2015 17:56:01 -0800 Subject: [PATCH 17/27] More work on swapping, almost there just need to write code for stack split/move/combining --- common/inventory.cpp | 99 ++++++++++++++++++++++++++++++++++++++- common/inventory.h | 8 +++- common/item_container.cpp | 14 +++--- common/item_instance.cpp | 22 +++++++-- common/item_instance.h | 4 ++ tests/inventory_test.h | 70 +++++++++++++++++++++++++-- zone/inventory.cpp | 43 +++++++++++++---- zone/mob.cpp | 2 +- 8 files changed, 236 insertions(+), 26 deletions(-) diff --git a/common/inventory.cpp b/common/inventory.cpp index 878e9f450..f2b418ec7 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -51,6 +51,10 @@ bool EQEmu::InventorySlot::IsValid() const { return false; } +bool EQEmu::InventorySlot::IsDelete() const { + return type_ == -1 && slot_ == -1 && bag_index_ == -1 && aug_index_ == -1; +} + bool EQEmu::InventorySlot::IsBank() const { if(type_ == InvTypeBank && EQEmu::ValueWithin(slot_, 0, 23)) { return true; @@ -91,6 +95,24 @@ bool EQEmu::InventorySlot::IsGeneral() const { return false; } +bool EQEmu::InventorySlot::IsWeapon() const { + if(type_ == InvTypePersonal && + (EQEmu::ValueWithin(slot_, PersonalSlotPrimary, PersonalSlotSecondary) || slot_ == PersonalSlotRange)) + { + return true; + } + + return false; +} + +bool EQEmu::InventorySlot::IsTrade() const { + if(type_ == InvTypeTrade) { + return true; + } + + return false; +} + const std::string EQEmu::InventorySlot::ToString() const { return StringFormat("(%i, %i, %i, %i)", type_, slot_, bag_index_, aug_index_); } @@ -100,12 +122,14 @@ struct EQEmu::Inventory::impl std::map containers_; int race_; int class_; + int deity_; }; -EQEmu::Inventory::Inventory(int race, int class_) { +EQEmu::Inventory::Inventory(int race, int class_, int deity) { impl_ = new impl; impl_->race_ = race; impl_->class_ = class_; + impl_->deity_ = deity; } EQEmu::Inventory::~Inventory() { @@ -178,7 +202,45 @@ bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr %s (%i)\n", src.IsCursor() ? "Cursor" : src.ToString().c_str(), dest.IsCursor() ? "Cursor" : dest.ToString().c_str(), charges); + + if(src == dest) { + return true; + } + + if(dest.IsDelete()) { + //return Delete(src); + return false; + } + + if(!src.IsValid() || !dest.IsValid()) { + return false; + } + + auto i_src = Get(src); + auto i_dest = Get(dest); + + if(dest.IsEquipment() && !CanEquip(i_dest, dest)) { + return false; + } + + if(!i_src) { + return false; + } + + //Check this -> trade no drop + if(dest.IsTrade() && i_src->IsNoDrop()) { + return false; + } + + if(i_src->IsStackable()) { + //charges == 0 -> Move entire stack from src to dest + //charges > 0 -> Move charges number of charges from src to dest (may require creating a new item + } else { + return _swap(src, dest); + } + + return true; } int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) { @@ -288,3 +350,36 @@ bool EQEmu::Inventory::Serialize(MemoryBuffer &buf) { return value; } + +bool EQEmu::Inventory::_swap(const InventorySlot &src, const InventorySlot &dest) { + auto src_i = Get(src); + auto dest_i = Get(dest); + + if(src_i) { + if(!_destroy(src)) { + return false; + } + } + + if(dest_i) { + if(!_destroy(dest)) { + return false; + } + + if(!Put(src, dest_i)) { + return false; + } + } + + if(src_i) { + if(!Put(dest, src_i)) { + return false; + } + } + + return true; +} + +bool EQEmu::Inventory::_destroy(const InventorySlot &slot) { + return Put(slot, std::shared_ptr(nullptr)); +} diff --git a/common/inventory.h b/common/inventory.h index c3606949d..fb55b1765 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -87,10 +87,13 @@ namespace EQEmu : type_(type), slot_(slot), bag_index_(bag_index), aug_index_(aug_index) { } bool IsValid() const; + bool IsDelete() const; bool IsBank() const; bool IsCursor() const; bool IsEquipment() const; bool IsGeneral() const; + bool IsWeapon() const; + bool IsTrade() const; const std::string ToString() const; @@ -120,7 +123,7 @@ namespace EQEmu class Inventory { public: - Inventory(int race, int class_); + Inventory(int race, int class_, int deity); ~Inventory(); std::shared_ptr Get(const InventorySlot &slot); @@ -133,6 +136,9 @@ namespace EQEmu bool CanEquip(std::shared_ptr inst, const EQEmu::InventorySlot &slot); bool Serialize(MemoryBuffer &buf); private: + bool _swap(const InventorySlot &src, const InventorySlot &dest); + bool _destroy(const InventorySlot &slot); + struct impl; impl *impl_; }; diff --git a/common/item_container.cpp b/common/item_container.cpp index 6f708051a..f602a1f50 100644 --- a/common/item_container.cpp +++ b/common/item_container.cpp @@ -51,13 +51,15 @@ std::shared_ptr EQEmu::ItemContainer::Get(const int slot_id } bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr inst) { - if(!inst) - return false; - - auto iter = impl_->items_.find(slot_id); - if(iter == impl_->items_.end()) { - impl_->items_[slot_id] = inst; + if(!inst) { + impl_->items_.erase(slot_id); return true; + } else { + auto iter = impl_->items_.find(slot_id); + if(iter == impl_->items_.end()) { + impl_->items_[slot_id] = inst; + return true; + } } return false; diff --git a/common/item_instance.cpp b/common/item_instance.cpp index b97edbd54..d4880d199 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -105,6 +105,10 @@ const ItemData *EQEmu::ItemInstance::GetBaseItem() { return impl_->base_item_; } +const ItemData *EQEmu::ItemInstance::GetBaseItem() const { + return impl_->base_item_; +} + std::shared_ptr EQEmu::ItemInstance::Get(const int index) { if(EQEmu::ValueWithin(index, 0, 255)) { return impl_->contents_.Get(index); @@ -139,9 +143,13 @@ bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr ins return false; } - auto *aug_item = inst->GetItem(); - int aug_type = aug_item->AugType; - if(aug_type == -1 || (1 << (item->AugSlotType[index] - 1)) & aug_type) { + if(inst) { + auto *aug_item = inst->GetItem(); + int aug_type = aug_item->AugType; + if(aug_type == -1 || (1 << (item->AugSlotType[index] - 1)) & aug_type) { + return impl_->contents_.Put(index, inst); + } + } else { return impl_->contents_.Put(index, inst); } @@ -323,6 +331,14 @@ bool EQEmu::ItemInstance::IsStackable() const { return impl_->base_item_->Stackable; } +bool EQEmu::ItemInstance::IsNoDrop() { + return GetAttuned() || GetBaseItem()->NoDrop == 0; +} + +bool EQEmu::ItemInstance::IsNoDrop() const { + return GetAttuned() || GetBaseItem()->NoDrop == 0; +} + EQEmu::ItemContainer *EQEmu::ItemInstance::GetContainer() { return &(impl_->contents_); } diff --git a/common/item_instance.h b/common/item_instance.h index 72bcc3c16..29f2394a2 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -35,6 +35,7 @@ namespace EQEmu const ItemData *GetItem(); const ItemData *GetBaseItem(); + const ItemData *GetBaseItem() const; //Container std::shared_ptr Get(const int index); @@ -95,6 +96,9 @@ namespace EQEmu bool IsStackable(); bool IsStackable() const; + bool IsNoDrop(); + bool IsNoDrop() const; + //Internal state //Used for low level operations such as encode/decode ItemContainer *GetContainer(); diff --git a/tests/inventory_test.h b/tests/inventory_test.h index 6cb34c6b3..f373e9cf0 100644 --- a/tests/inventory_test.h +++ b/tests/inventory_test.h @@ -26,7 +26,7 @@ class InventoryTest : public Test::Suite { typedef void(InventoryTest::*TestFunction)(void); public: - InventoryTest() : inv(1, 1) { + InventoryTest() : inv(1, 1, 1) { InitContainer(); InitArmor(); InitAugment(); @@ -34,6 +34,10 @@ public: InitInventory(); TEST_ADD(InventoryTest::InventoryVerifyInitialItemsTest); TEST_ADD(InventoryTest::InventoryCanEquipTest); + TEST_ADD(InventoryTest::InventorySwapGeneral1ToCursor); + TEST_ADD(InventoryTest::InventorySwapCursorToGeneral2); + TEST_ADD(InventoryTest::InventorySplitStackToCursor); + TEST_ADD(InventoryTest::InventoryStackCombine); } ~InventoryTest() { @@ -144,7 +148,7 @@ private: std::shared_ptr m_bag(new EQEmu::ItemInstance(&container)); std::shared_ptr m_armor(new EQEmu::ItemInstance(&armor)); std::shared_ptr m_augment(new EQEmu::ItemInstance(&augment)); - std::shared_ptr m_stackable(new EQEmu::ItemInstance(&stackable, 45)); + std::shared_ptr m_stackable(new EQEmu::ItemInstance(&stackable, 100)); inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1), m_bag); inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 0), m_armor); inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 1), m_augment); @@ -202,10 +206,37 @@ private: armor.Races += 1; } - void InventorySwapItemsTest() - { + void InventorySwapGeneral1ToCursor() { auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1), + EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), 0); + + TEST_ASSERT(swap_result == true); + + auto m_bag = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor)); + TEST_ASSERT(m_bag); + TEST_ASSERT(m_bag->GetItem()); + TEST_ASSERT(m_bag->GetItem()->ID == 1000); + + auto m_armor = m_bag->Get(0); + TEST_ASSERT(m_armor); + TEST_ASSERT(m_armor->GetItem()); + TEST_ASSERT(m_armor->GetItem()->ID == 1001); + + auto m_augment = m_bag->Get(1); + TEST_ASSERT(m_augment); + TEST_ASSERT(m_augment->GetItem()); + TEST_ASSERT(m_augment->GetItem()->ID == 1002); + + auto m_stackable = m_bag->Get(7); + TEST_ASSERT(m_stackable); + TEST_ASSERT(m_stackable->GetItem()); + TEST_ASSERT(m_stackable->GetItem()->ID == 1003); + } + + void InventorySwapCursorToGeneral2() { + auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2), 0); + TEST_ASSERT(swap_result == true); auto m_bag = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2)); @@ -229,6 +260,37 @@ private: TEST_ASSERT(m_stackable->GetItem()->ID == 1003); } + void InventorySplitStackToCursor() { + auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7), + EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), 10); + + TEST_ASSERT(swap_result == true); + + auto m_stackable_cursor = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor)); + auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7)); + + TEST_ASSERT(m_stackable_cursor); + TEST_ASSERT(m_stackable); + + TEST_ASSERT(m_stackable_cursor->GetCharges() == 10); + TEST_ASSERT(m_stackable->GetCharges() == 90); + } + + void InventoryStackCombine() { + auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), + EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7), 0); + + TEST_ASSERT(swap_result == true); + + auto m_cursor = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor)); + auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7)); + + TEST_ASSERT(!m_cursor); + TEST_ASSERT(m_stackable); + + TEST_ASSERT(m_stackable->GetCharges() == 100); + } + EQEmu::Inventory inv; ItemData container; ItemData armor; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 55aa08620..143b3d18f 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -3113,17 +3113,42 @@ bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlo } } - auto i_src = m_inventory.Get(src); - auto i_dest = m_inventory.Get(dest); - - if(dest.IsEquipment() && !m_inventory.CanEquip(i_dest, dest)) { - return false; + bool recalc_weapon_speed = false; + if(src.IsWeapon() || dest.IsWeapon()) { + recalc_weapon_speed = true; } - - printf("Equip check passes %s -> %s\n", src.ToString().c_str(), dest.ToString().c_str()); - + + if(src.IsBank() || dest.IsBank()) { + uint32 distance = 0; + NPC *banker = entity_list.GetClosestBanker(this, distance); + if(!banker || distance > USE_NPC_RANGE2) + { + std::string hacked = StringFormat("Player tried to make use of a banker(items) but %s is " + "non-existant or too far away (%u units).", + banker ? banker->GetName() : "UNKNOWN NPC", + distance); + database.SetMQDetectionFlag(AccountName(), GetName(), hacked.c_str(), zone->GetShortName()); + Kick(); + return false; + } + } + bool res = m_inventory.Swap(src, dest, number_in_stack); - return true; + if(res) { + printf("Swap success\n"); + } else { + printf("Swap failure!\n"); + } + + if(auto_attack && res && recalc_weapon_speed) { + SetAttackTimer(); + } + + if(res) { + CalcBonuses(); + } + + return res; } diff --git a/zone/mob.cpp b/zone/mob.cpp index d7a63f065..ab4233b4e 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -103,7 +103,7 @@ Mob::Mob(const char* in_name, m_TargetV(glm::vec3()), flee_timer(FLEE_CHECK_TIMER), m_Position(position), - m_inventory(in_race, in_class) + m_inventory(in_race, in_class, in_deity) { targeted = 0; tar_ndx=0; From abc5ddc5f8bf21c077f0e8a18609f46656cc4243 Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 2 Mar 2015 00:44:28 -0800 Subject: [PATCH 18/27] Inventory Swap implemented and passes tests, though still want to verify it a bit more also does not yet save but that's next. Fixed a crash in memory buffer too. --- common/data_verification.h | 18 +++---- common/inventory.cpp | 73 ++++++++++++++++++++++++--- common/inventory.h | 4 ++ common/item.cpp | 2 +- common/item_instance.cpp | 62 +++++++++++++++-------- common/item_instance.h | 5 +- common/memory_buffer.cpp | 2 +- common/memory_buffer.h | 2 +- common/shareddb.cpp | 11 +--- tests/inventory_test.h | 46 +++++++++++++++-- zone/client_packet.cpp | 6 ++- zone/client_process.cpp | 100 ------------------------------------- zone/inventory.cpp | 6 ++- 13 files changed, 177 insertions(+), 160 deletions(-) diff --git a/common/data_verification.h b/common/data_verification.h index e0cb055c2..aa44df7bc 100644 --- a/common/data_verification.h +++ b/common/data_verification.h @@ -23,19 +23,19 @@ namespace EQEmu { -template -T Clamp(const T& value, const T& lower, const T& upper) { - return std::max(lower, std::min(value, upper)); +template +T Clamp(const T& value, const U& lower, const V& upper) { + return std::max(static_cast(lower), std::min(value, static_cast(upper))); } -template -T ClampLower(const T& value, const T& lower) { - return std::max(lower, value); +template +T ClampLower(const T& value, const U& lower) { + return std::max(static_cast(lower), value); } -template -T ClampUpper(const T& value, const T& upper) { - return std::min(value, upper); +template +T ClampUpper(const T& value, const U& upper) { + return std::min(value, static_cast(upper)); } template diff --git a/common/inventory.cpp b/common/inventory.cpp index f2b418ec7..c9124ced6 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -136,6 +136,18 @@ EQEmu::Inventory::~Inventory() { delete impl_; } +void EQEmu::Inventory::SetRace(int race) { + impl_->race_ = race; +} + +void EQEmu::Inventory::SetClass(int class_) { + impl_->class_ = class_; +} + +void EQEmu::Inventory::SetDeity(int deity) { + impl_->deity_ = deity; +} + std::shared_ptr EQEmu::Inventory::Get(const InventorySlot &slot) { auto iter = impl_->containers_.find(slot.Type()); if(iter != impl_->containers_.end()) { @@ -202,15 +214,12 @@ bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr %s (%i)\n", src.IsCursor() ? "Cursor" : src.ToString().c_str(), dest.IsCursor() ? "Cursor" : dest.ToString().c_str(), charges); - if(src == dest) { return true; } if(dest.IsDelete()) { - //return Delete(src); - return false; + return _destroy(src); } if(!src.IsValid() || !dest.IsValid()) { @@ -220,11 +229,11 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, auto i_src = Get(src); auto i_dest = Get(dest); - if(dest.IsEquipment() && !CanEquip(i_dest, dest)) { + if(!i_src) { return false; } - if(!i_src) { + if(dest.IsEquipment() && !CanEquip(i_src, dest)) { return false; } @@ -234,8 +243,56 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, } if(i_src->IsStackable()) { - //charges == 0 -> Move entire stack from src to dest - //charges > 0 -> Move charges number of charges from src to dest (may require creating a new item + //move # charges from src to dest + + //0 means *all* the charges + if(charges == 0) { + charges = i_src->GetCharges(); + } + + //src needs to have that many charges + if(i_src->GetCharges() < charges) { + return false; + } + + //if dest exists it needs to not only be the same item id but also be able to hold enough charges + if(i_dest) { + uint32 src_id = i_src->GetBaseItem()->ID; + uint32 dest_id = i_dest->GetBaseItem()->ID; + if(src_id != dest_id) { + return false; + } + + int charges_avail = i_dest->GetBaseItem()->StackSize - i_dest->GetCharges(); + if(charges_avail < charges) { + return false; + } + + if(i_src->GetCharges() == charges) { + if(!_destroy(src)) { + return false; + } + } else { + i_src->SetCharges(i_src->GetCharges() - charges); + } + + i_dest->SetCharges(i_dest->GetCharges() + charges); + return true; + } else { + //if dest does not exist and src charges > # charges then we need to create a new item with # charges in dest + //if dest does not exist and src charges == # charges then we need to swap src to dest + if(i_src->GetCharges() > charges) { + auto split = i_src->Split(charges); + if(!split) { + return false; + } + + Put(dest, split); + return true; + } else { + return _swap(src, dest); + } + } } else { return _swap(src, dest); } diff --git a/common/inventory.h b/common/inventory.h index fb55b1765..24c5e7881 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -126,6 +126,10 @@ namespace EQEmu Inventory(int race, int class_, int deity); ~Inventory(); + void SetRace(int race); + void SetClass(int class_); + void SetDeity(int deity); + std::shared_ptr Get(const InventorySlot &slot); bool Put(const InventorySlot &slot, std::shared_ptr inst); bool Swap(const InventorySlot &src, const InventorySlot &dest, int charges); diff --git a/common/item.cpp b/common/item.cpp index 0a9bb2dc4..67664ccc5 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -993,7 +993,7 @@ int InventoryOld::GetSlotByItemInst(ItemInst *inst) { return INVALID_INDEX; } -uint8 Inventory::FindBrightestLightType() +uint8 InventoryOld::FindBrightestLightType() { uint8 brightest_light_type = 0; diff --git a/common/item_instance.cpp b/common/item_instance.cpp index d4880d199..f3c24aad5 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -20,6 +20,12 @@ #include "data_verification.h" #include "item_container.h" +uint32 ItemInstanceSerial = 1; +uint32 EQEmu::GetNextItemInstanceSerial() { + ItemInstanceSerial++; + return ItemInstanceSerial; +} + struct EQEmu::ItemInstance::impl { const ItemData *base_item_; ItemData *modified_item_; @@ -39,24 +45,6 @@ struct EQEmu::ItemInstance::impl { ItemContainer contents_; }; -EQEmu::ItemInstance::ItemInstance() { - impl_ = new impl; - impl_->base_item_ = nullptr; - impl_->modified_item_ = nullptr; - impl_->charges_ = -1; - impl_->color_ = 0; - impl_->attuned_ = false; - impl_->ornament_idfile_ = 0; - impl_->ornament_icon_ = 0; - impl_->ornament_hero_model_ = 0; - impl_->serial_id_ = 0; - impl_->recast_timestamp_ = 0; - impl_->merchant_slot_ = 0; - impl_->merchant_count_ = 0; - impl_->price_ = 0; - memset(impl_->tracking_id_, 0, 17); -} - EQEmu::ItemInstance::ItemInstance(const ItemData* idata) { impl_ = new impl; impl_->base_item_ = idata; @@ -97,6 +85,39 @@ EQEmu::ItemInstance::~ItemInstance() { delete impl_; } + +std::shared_ptr EQEmu::ItemInstance::Split(int charges) { + if(!IsStackable()) { + //Can't split non stackable items! + return std::shared_ptr(nullptr); + } + + if(charges >= GetCharges()) { + return std::shared_ptr(nullptr); + } + + if(impl_->contents_.Size() > 0) { + return std::shared_ptr(nullptr); + } + + std::shared_ptr split = std::shared_ptr(new EQEmu::ItemInstance(impl_->base_item_, charges)); + split->SetSerialNumber(EQEmu::GetNextItemInstanceSerial()); + //Set Tracking here + split->impl_->attuned_ = impl_->attuned_; + split->impl_->custom_data_ = impl_->custom_data_; + split->impl_->recast_timestamp_ = impl_->recast_timestamp_; + split->impl_->price_ = impl_->price_; + split->impl_->color_ = impl_->color_; + split->impl_->merchant_count_ = impl_->merchant_count_; + split->impl_->merchant_slot_ = impl_->merchant_slot_; + split->impl_->ornament_hero_model_ = impl_->ornament_hero_model_; + split->impl_->ornament_icon_ = impl_->ornament_icon_; + split->impl_->ornament_idfile_ = impl_->ornament_idfile_; + + SetCharges(GetCharges() - charges); + return split; +} + const ItemData *EQEmu::ItemInstance::GetItem() { return impl_->modified_item_ ? impl_->modified_item_ : impl_->base_item_; } @@ -118,10 +139,6 @@ std::shared_ptr EQEmu::ItemInstance::Get(const int index) { } bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr inst) { - if(!inst || !inst->GetItem()) { - return false; - } - if(!impl_->base_item_) { return false; } @@ -342,3 +359,4 @@ bool EQEmu::ItemInstance::IsNoDrop() const { EQEmu::ItemContainer *EQEmu::ItemInstance::GetContainer() { return &(impl_->contents_); } + diff --git a/common/item_instance.h b/common/item_instance.h index 29f2394a2..18901bff6 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -24,11 +24,12 @@ namespace EQEmu { + uint32 GetNextItemInstanceSerial(); + class ItemContainer; class ItemInstance { public: - ItemInstance(); ItemInstance(const ItemData* idata); ItemInstance(const ItemData* idata, const int16 charges); ~ItemInstance(); @@ -37,6 +38,8 @@ namespace EQEmu const ItemData *GetBaseItem(); const ItemData *GetBaseItem() const; + std::shared_ptr Split(int charges); + //Container std::shared_ptr Get(const int index); bool Put(const int index, std::shared_ptr inst); diff --git a/common/memory_buffer.cpp b/common/memory_buffer.cpp index 4f47867d8..c762a1118 100644 --- a/common/memory_buffer.cpp +++ b/common/memory_buffer.cpp @@ -162,7 +162,7 @@ void EQEmu::MemoryBuffer::Resize(size_t sz) { if(sz > capacity_) { size_t new_size = sz + 32; uchar *temp = new uchar[new_size]; - memcpy(temp, buffer_, new_size); + memcpy(temp, buffer_, capacity_); delete[] buffer_; buffer_ = temp; diff --git a/common/memory_buffer.h b/common/memory_buffer.h index 26a5897df..689ed81bd 100644 --- a/common/memory_buffer.h +++ b/common/memory_buffer.h @@ -121,4 +121,4 @@ namespace EQEmu } // EQEmu -#endif \ No newline at end of file +#endif diff --git a/common/shareddb.cpp b/common/shareddb.cpp index f7f18aeb8..cf18cac55 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -15,14 +15,6 @@ #include "shareddb.h" #include "string_util.h" -uint32 ItemInstanceSerial = 1; -static inline uint32 GetNextItemInstanceSerial() { - ItemInstanceSerial++; - return ItemInstanceSerial; -} - - - SharedDatabase::SharedDatabase() : Database(), skill_caps_mmf(nullptr), items_mmf(nullptr), items_hash(nullptr), faction_mmf(nullptr), faction_hash(nullptr), loot_table_mmf(nullptr), loot_table_hash(nullptr), loot_drop_mmf(nullptr), loot_drop_hash(nullptr), base_data_mmf(nullptr) @@ -1273,7 +1265,8 @@ std::shared_ptr SharedDatabase::CreateItem(uint32 item_id, } std::shared_ptr inst = std::shared_ptr(new EQEmu::ItemInstance(item, charges)); - inst->SetSerialNumber(GetNextItemInstanceSerial()); + inst->SetSerialNumber(EQEmu::GetNextItemInstanceSerial()); + //Set Tracking here return inst; } diff --git a/tests/inventory_test.h b/tests/inventory_test.h index f373e9cf0..11ff2acd0 100644 --- a/tests/inventory_test.h +++ b/tests/inventory_test.h @@ -38,6 +38,8 @@ public: TEST_ADD(InventoryTest::InventorySwapCursorToGeneral2); TEST_ADD(InventoryTest::InventorySplitStackToCursor); TEST_ADD(InventoryTest::InventoryStackCombine); + TEST_ADD(InventoryTest::InventorySplitStackToCursor2); + TEST_ADD(InventoryTest::InventoryStackCombine2); } ~InventoryTest() { @@ -135,7 +137,7 @@ private: stackable.SkillModType = -1; stackable.Click.Effect = -1; stackable.Weight = 5; - stackable.StackSize = 100; + stackable.StackSize = 105; stackable.Stackable = 1; stackable.Size = 1; stackable.Proc.Effect = -1; @@ -261,13 +263,13 @@ private: } void InventorySplitStackToCursor() { - auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7), + auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7), EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), 10); TEST_ASSERT(swap_result == true); auto m_stackable_cursor = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor)); - auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7)); + auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7)); TEST_ASSERT(m_stackable_cursor); TEST_ASSERT(m_stackable); @@ -278,12 +280,12 @@ private: void InventoryStackCombine() { auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), - EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7), 0); + EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7), 0); TEST_ASSERT(swap_result == true); auto m_cursor = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor)); - auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 7)); + auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7)); TEST_ASSERT(!m_cursor); TEST_ASSERT(m_stackable); @@ -291,6 +293,40 @@ private: TEST_ASSERT(m_stackable->GetCharges() == 100); } + void InventorySplitStackToCursor2() { + std::shared_ptr m_stackable_i(new EQEmu::ItemInstance(&stackable, 10)); + inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 8), m_stackable_i); + + auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 8), + EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), 0); + + TEST_ASSERT(swap_result == true); + + auto m_stackable_cursor = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor)); + auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 8)); + + TEST_ASSERT(m_stackable_cursor); + TEST_ASSERT(!m_stackable); + + TEST_ASSERT(m_stackable_cursor->GetCharges() == 10); + } + + void InventoryStackCombine2() { + auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), + EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7), 5); + + TEST_ASSERT(swap_result == true); + + auto m_cursor = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor)); + auto m_stackable = inv.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 7)); + + TEST_ASSERT(m_cursor); + TEST_ASSERT(m_stackable); + + TEST_ASSERT(m_stackable->GetCharges() == 105); + TEST_ASSERT(m_cursor->GetCharges() == 5); + } + EQEmu::Inventory inv; ItemData container; ItemData armor; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index e9343ba0b..84c102817 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1271,7 +1271,6 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) m_pp.platinum_shared = database.GetSharedPlatinum(this->AccountID()); database.ClearOldRecastTimestamps(cid); /* Clear out our old recast timestamps to keep the DB clean */ - loaditems = database.GetInventory(cid, &m_inventory); /* Load Character Inventory */ database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */ database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */ database.LoadCharacterMaterialColor(cid, &m_pp); /* Load Character Material */ @@ -1287,6 +1286,11 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) database.LoadCharacterLeadershipAA(cid, &m_pp); /* Load Character Leadership AA's */ database.LoadCharacterTribute(cid, &m_pp); /* Load CharacterTribute */ + m_inventory.SetRace(GetBaseRace()); + m_inventory.SetClass(GetBaseClass()); + m_inventory.SetDeity(GetDeity()); + loaditems = database.GetInventory(cid, &m_inventory); /* Load Character Inventory */ + /* Load AdventureStats */ AdventureStats_Struct as; if(database.GetAdventureStats(cid, &as)) diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 7d9066930..662264d95 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -824,106 +824,6 @@ void Client::BulkSendInventoryItems() { EQApplicationPacket outapp(OP_CharInventory, items.Size()); memcpy(outapp.pBuffer, items, items.Size()); QueuePacket(&outapp); - - - //int16 slot_id = 0; - // - //// LINKDEAD TRADE ITEMS - //// Move trade slot items back into normal inventory..need them there now for the proceeding validity checks -U - //for(slot_id = EmuConstants::TRADE_BEGIN; slot_id <= EmuConstants::TRADE_END; slot_id++) { - // ItemInst* inst = m_inv.PopItem(slot_id); - // if(inst) { - // bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false; - // int16 free_slot_id = m_inv.FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size, is_arrow); - // Log.Out(Logs::Detail, Logs::Inventory, "Incomplete Trade Transaction: Moving %s from slot %i to %i", inst->GetItem()->Name, slot_id, free_slot_id); - // PutItemInInventory(free_slot_id, *inst, false); - // database.SaveInventory(character_id, nullptr, slot_id); - // safe_delete(inst); - // } - //} - // - //bool deletenorent = database.NoRentExpired(GetName()); - //if(deletenorent){ RemoveNoRent(false); } //client was offline for more than 30 minutes, delete no rent items - // - //RemoveDuplicateLore(false); - //MoveSlotNotAllowed(false); - // - //// The previous three method calls took care of moving/removing expired/illegal item placements -U - // - ////TODO: this function is just retarded... it re-allocates the buffer for every - ////new item. It should be changed to loop through once, gather the - ////lengths, and item packet pointers into an array (fixed length), and - ////then loop again to build the packet. - ////EQApplicationPacket *packets[50]; - ////unsigned long buflen = 0; - ////unsigned long pos = 0; - ////memset(packets, 0, sizeof(packets)); - ////foreach item in the invendor sections - //// packets[pos++] = ReturnItemPacket(...) - //// buflen += temp->size - ////... - ////allocat the buffer - ////for r from 0 to pos - //// put pos[r]->pBuffer into the buffer - ////for r from 0 to pos - //// safe_delete(pos[r]); - // - //uint32 size = 0; - //uint16 i = 0; - //std::map ser_items; - //std::map::iterator itr; - // - ////Inventory items - //for(slot_id = MAIN_BEGIN; slot_id < EmuConstants::MAP_POSSESSIONS_SIZE; slot_id++) { - // const ItemInst* inst = m_inv[slot_id]; - // if(inst) { - // std::string packet = inst->Serialize(slot_id); - // ser_items[i++] = packet; - // size += packet.length(); - // } - //} - // - //// Power Source - //if(GetClientVersion() >= ClientVersion::SoF) { - // const ItemInst* inst = m_inv[MainPowerSource]; - // if(inst) { - // std::string packet = inst->Serialize(MainPowerSource); - // ser_items[i++] = packet; - // size += packet.length(); - // } - //} - // - //// Bank items - //for(slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; slot_id++) { - // const ItemInst* inst = m_inv[slot_id]; - // if(inst) { - // std::string packet = inst->Serialize(slot_id); - // ser_items[i++] = packet; - // size += packet.length(); - // } - //} - // - //// Shared Bank items - //for(slot_id = EmuConstants::SHARED_BANK_BEGIN; slot_id <= EmuConstants::SHARED_BANK_END; slot_id++) { - // const ItemInst* inst = m_inv[slot_id]; - // if(inst) { - // std::string packet = inst->Serialize(slot_id); - // ser_items[i++] = packet; - // size += packet.length(); - // } - //} - // - //EQApplicationPacket* outapp = new EQApplicationPacket(OP_CharInventory, size); - //uchar* ptr = outapp->pBuffer; - //for(itr = ser_items.begin(); itr != ser_items.end(); ++itr){ - // int length = itr->second.length(); - // if(length > 5) { - // memcpy(ptr, itr->second.c_str(), length); - // ptr += length; - // } - //} - //QueuePacket(outapp); - //safe_delete(outapp); } void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 143b3d18f..72ba9984e 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -3133,12 +3133,14 @@ bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlo } } + Message(0, "%s -> %s (%i)\n", src.IsCursor() ? "Cursor" : src.ToString().c_str(), dest.IsCursor() ? "Cursor" : dest.ToString().c_str(), number_in_stack); + bool res = m_inventory.Swap(src, dest, number_in_stack); if(res) { - printf("Swap success\n"); + Message(0, "Swap success\n"); } else { - printf("Swap failure!\n"); + Message(0, "Swap failure!\n"); } if(auto_attack && res && recalc_weapon_speed) { From 972d3d88748c9c4cc9a0d1424371330dd35c177e Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 2 Mar 2015 19:38:57 -0800 Subject: [PATCH 19/27] Fix for swapping a stack with another item that is not of the same stack size. Added some console visualization for testing and added basics of data modeling for inventory, saving soon. --- common/CMakeLists.txt | 2 + common/inventory.cpp | 84 ++++++++++++++++++++++++++---- common/inventory.h | 5 ++ common/inventory_data_model.h | 40 ++++++++++++++ common/inventory_null_data_model.h | 40 ++++++++++++++ common/item_container.cpp | 12 +++++ common/item_container.h | 3 ++ common/item_instance.cpp | 3 ++ common/item_instance.h | 2 + zone/inventory.cpp | 3 ++ 10 files changed, 184 insertions(+), 10 deletions(-) create mode 100644 common/inventory_data_model.h create mode 100644 common/inventory_null_data_model.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 9d8dea551..c66ff5776 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -142,6 +142,8 @@ SET(common_headers guild_base.h guilds.h inventory.h + inventory_data_model.h + inventory_null_data_model.h ipc_mutex.h item.h item_container.h diff --git a/common/inventory.cpp b/common/inventory.cpp index c9124ced6..5d5a2c9ed 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -17,8 +17,9 @@ */ #include "inventory.h" -#include "data_verification.h" +#include "inventory_null_data_model.h" #include "item_container_personal_serialization.h" +#include "data_verification.h" #include "string_util.h" #include @@ -123,6 +124,7 @@ struct EQEmu::Inventory::impl int race_; int class_; int deity_; + std::unique_ptr data_model_; }; EQEmu::Inventory::Inventory(int race, int class_, int deity) { @@ -130,6 +132,7 @@ EQEmu::Inventory::Inventory(int race, int class_, int deity) { impl_->race_ = race; impl_->class_ = class_; impl_->deity_ = deity; + impl_->data_model_ = std::unique_ptr(new InventoryNullDataModel()); } EQEmu::Inventory::~Inventory() { @@ -148,6 +151,10 @@ void EQEmu::Inventory::SetDeity(int deity) { impl_->deity_ = deity; } +void EQEmu::Inventory::SetDataMode(InventoryDataModel *dm) { + impl_->data_model_ = std::unique_ptr(dm); +} + std::shared_ptr EQEmu::Inventory::Get(const InventorySlot &slot) { auto iter = impl_->containers_.find(slot.Type()); if(iter != impl_->containers_.end()) { @@ -218,10 +225,6 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, return true; } - if(dest.IsDelete()) { - return _destroy(src); - } - if(!src.IsValid() || !dest.IsValid()) { return false; } @@ -242,6 +245,18 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, return false; } + 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()) { //move # charges from src to dest @@ -252,31 +267,46 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, //src needs to have that many charges if(i_src->GetCharges() < charges) { + impl_->data_model_->Rollback(); return false; } - //if dest exists it needs to not only be the same item id but also be able to hold enough charges + //if dest exists it needs to not only be the same item id but also be able to hold enough charges to combine + //we can also swap if src id != dest id if(i_dest) { uint32 src_id = i_src->GetBaseItem()->ID; uint32 dest_id = i_dest->GetBaseItem()->ID; if(src_id != dest_id) { - return false; + bool v = _swap(src, dest); + if(v) { + impl_->data_model_->Commit(); + } + else { + impl_->data_model_->Rollback(); + } + + return v; } int charges_avail = i_dest->GetBaseItem()->StackSize - i_dest->GetCharges(); if(charges_avail < charges) { + impl_->data_model_->Rollback(); return false; } if(i_src->GetCharges() == charges) { if(!_destroy(src)) { + impl_->data_model_->Rollback(); return false; } } else { i_src->SetCharges(i_src->GetCharges() - charges); + impl_->data_model_->Insert(src, i_src); } i_dest->SetCharges(i_dest->GetCharges() + charges); + impl_->data_model_->Insert(dest, i_dest); + impl_->data_model_->Commit(); return true; } else { //if dest does not exist and src charges > # charges then we need to create a new item with # charges in dest @@ -284,19 +314,39 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, if(i_src->GetCharges() > charges) { auto split = i_src->Split(charges); if(!split) { + impl_->data_model_->Rollback(); return false; } Put(dest, split); + impl_->data_model_->Insert(src, i_src); + impl_->data_model_->Insert(dest, split); + impl_->data_model_->Commit(); return true; } else { - return _swap(src, dest); + bool v = _swap(src, dest); + if(v) { + impl_->data_model_->Commit(); + } else { + impl_->data_model_->Rollback(); + } + + return v; } } } else { - return _swap(src, dest); + bool v = _swap(src, dest); + if(v) { + impl_->data_model_->Commit(); + } + else { + impl_->data_model_->Rollback(); + } + + return v; } + impl_->data_model_->Commit(); return true; } @@ -408,6 +458,16 @@ bool EQEmu::Inventory::Serialize(MemoryBuffer &buf) { return value; } +void EQEmu::Inventory::Interrogate() { + printf("Inventory:\n"); + printf("Class: %u, Race: %u, Deity: %u\n", impl_->class_, impl_->race_, impl_->deity_); + for(auto &iter : impl_->containers_) { + printf("Container: %u\n", iter.first); + iter.second.Interrogate(1); + } + printf("\n"); +} + bool EQEmu::Inventory::_swap(const InventorySlot &src, const InventorySlot &dest) { auto src_i = Get(src); auto dest_i = Get(dest); @@ -423,12 +483,14 @@ bool EQEmu::Inventory::_swap(const InventorySlot &src, const InventorySlot &dest return false; } + impl_->data_model_->Insert(src, dest_i); if(!Put(src, dest_i)) { return false; } } if(src_i) { + impl_->data_model_->Insert(dest, src_i); if(!Put(dest, src_i)) { return false; } @@ -438,5 +500,7 @@ bool EQEmu::Inventory::_swap(const InventorySlot &src, const InventorySlot &dest } bool EQEmu::Inventory::_destroy(const InventorySlot &slot) { - return Put(slot, std::shared_ptr(nullptr)); + bool v = Put(slot, std::shared_ptr(nullptr)); + impl_->data_model_->Delete(slot); + return v; } diff --git a/common/inventory.h b/common/inventory.h index 24c5e7881..75a33b690 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -120,6 +120,7 @@ namespace EQEmu lhs.AugIndex() == rhs.AugIndex(); } inline bool operator!=(const InventorySlot &lhs, const InventorySlot &rhs) { return !(lhs == rhs); } + class InventoryDataModel; class Inventory { public: @@ -129,6 +130,7 @@ namespace EQEmu void SetRace(int race); void SetClass(int class_); void SetDeity(int deity); + void SetDataMode(InventoryDataModel *dm); std::shared_ptr Get(const InventorySlot &slot); bool Put(const InventorySlot &slot, std::shared_ptr inst); @@ -139,6 +141,9 @@ namespace EQEmu static InventorySlot CalcSlotFromMaterial(int material); bool CanEquip(std::shared_ptr inst, const EQEmu::InventorySlot &slot); bool Serialize(MemoryBuffer &buf); + + //testing + void Interrogate(); private: bool _swap(const InventorySlot &src, const InventorySlot &dest); bool _destroy(const InventorySlot &slot); diff --git a/common/inventory_data_model.h b/common/inventory_data_model.h new file mode 100644 index 000000000..c35922147 --- /dev/null +++ b/common/inventory_data_model.h @@ -0,0 +1,40 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 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 +*/ + +#ifndef COMMON_INVENTORY_DATA_MODEL_H +#define COMMON_INVENTORY_DATA_MODEL_H + +#include "inventory.h" + +namespace EQEmu +{ + class InventoryDataModel + { + public: + InventoryDataModel() { } + virtual ~InventoryDataModel() { } + + virtual void Begin() = 0; + virtual void Commit() = 0; + virtual void Rollback() = 0; + virtual bool Insert(const InventorySlot &slot, std::shared_ptr inst) = 0; + virtual bool Delete(const InventorySlot &slot) = 0; + }; +} // EQEmu + +#endif diff --git a/common/inventory_null_data_model.h b/common/inventory_null_data_model.h new file mode 100644 index 000000000..3f3433df0 --- /dev/null +++ b/common/inventory_null_data_model.h @@ -0,0 +1,40 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 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 +*/ + +#ifndef COMMON_INVENTORY_NULL_DATA_MODEL_H +#define COMMON_INVENTORY_NULL_DATA_MODEL_H + +#include "inventory_data_model.h" + +namespace EQEmu +{ + class InventoryNullDataModel : public InventoryDataModel + { + public: + InventoryNullDataModel() { } + virtual ~InventoryNullDataModel() { } + + virtual void Begin() { printf("NDM: Begin\n"); } + virtual void Commit() { printf("NDM: Commit\n"); } + virtual void Rollback() { printf("NDM: Rollback\n"); } + virtual bool Insert(const InventorySlot &slot, std::shared_ptr inst) { printf("NDM: Insert %s %s\n", slot.ToString().c_str(), inst ? inst->GetBaseItem()->Name : "Null" ); return true; } + virtual bool Delete(const InventorySlot &slot) { printf("NDM: Delete %s\n", slot.ToString().c_str()); return true; } + }; +} // EQEmu + +#endif diff --git a/common/item_container.cpp b/common/item_container.cpp index f602a1f50..f78d28461 100644 --- a/common/item_container.cpp +++ b/common/item_container.cpp @@ -98,3 +98,15 @@ EQEmu::ItemContainer::ItemContainerIter EQEmu::ItemContainer::Begin() { EQEmu::ItemContainer::ItemContainerIter EQEmu::ItemContainer::End() { return impl_->items_.end(); } + +void EQEmu::ItemContainer::Interrogate(int level) { + char buffer[16] = { 0 }; + for(int i = 0; i < level; ++i) { + buffer[i] = '\t'; + } + + for(auto &iter : impl_->items_) { + printf("%s%u: (%u)%s (%u)\n", buffer, iter.first, iter.second->GetBaseItem()->ID, iter.second->GetBaseItem()->Name, iter.second->GetCharges()); + iter.second->Interrogate(level + 1); + } +} \ No newline at end of file diff --git a/common/item_container.h b/common/item_container.h index bde5d3c0d..7900c3840 100644 --- a/common/item_container.h +++ b/common/item_container.h @@ -49,6 +49,9 @@ namespace EQEmu bool Serialize(MemoryBuffer &buf, int container_number); ItemContainerIter Begin(); ItemContainerIter End(); + + //testing + void Interrogate(int level); protected: struct impl; impl *impl_; diff --git a/common/item_instance.cpp b/common/item_instance.cpp index f3c24aad5..afa902404 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -360,3 +360,6 @@ EQEmu::ItemContainer *EQEmu::ItemInstance::GetContainer() { return &(impl_->contents_); } +void EQEmu::ItemInstance::Interrogate(int level) { + impl_->contents_.Interrogate(level); +} diff --git a/common/item_instance.h b/common/item_instance.h index 18901bff6..4b21aaa35 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -105,6 +105,8 @@ namespace EQEmu //Internal state //Used for low level operations such as encode/decode ItemContainer *GetContainer(); + + void Interrogate(int level); private: struct impl; impl *impl_; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 72ba9984e..bdb800add 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -3139,8 +3139,11 @@ bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlo if(res) { Message(0, "Swap success\n"); + m_inventory.Interrogate(); } else { Message(0, "Swap failure!\n"); + //should kick the player here... + } if(auto_attack && res && recalc_weapon_speed) { From 9fcdf5367e77f1c1a7c0169bcb5ebd0c35e9a378 Mon Sep 17 00:00:00 2001 From: KimLS Date: Wed, 4 Mar 2015 19:33:01 -0800 Subject: [PATCH 20/27] Swap saving now works correctly except for cursor items which wont be reloaded correctly as we don't send cursor on login yet. Also added check for bag into another bag src bag needs to have nothing in it first. --- common/CMakeLists.txt | 2 + common/inventory.cpp | 8 +- common/inventory.h | 2 +- common/inventory_data_model.h | 6 +- common/inventory_db_data_model.cpp | 197 +++++++++++++++++++++++++++++ common/inventory_db_data_model.h | 45 +++++++ common/inventory_null_data_model.h | 6 +- common/item_instance.cpp | 24 ++++ common/item_instance.h | 6 + zone/client_packet.cpp | 2 + 10 files changed, 290 insertions(+), 8 deletions(-) create mode 100644 common/inventory_db_data_model.cpp create mode 100644 common/inventory_db_data_model.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index c66ff5776..292d1032b 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -31,6 +31,7 @@ SET(common_sources guild_base.cpp guilds.cpp inventory.cpp + inventory_db_data_model.cpp ipc_mutex.cpp item.cpp item_container.cpp @@ -143,6 +144,7 @@ SET(common_headers guilds.h inventory.h inventory_data_model.h + inventory_db_data_model.h inventory_null_data_model.h ipc_mutex.h item.h diff --git a/common/inventory.cpp b/common/inventory.cpp index 5d5a2c9ed..e90322b93 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -151,7 +151,7 @@ void EQEmu::Inventory::SetDeity(int deity) { impl_->deity_ = deity; } -void EQEmu::Inventory::SetDataMode(InventoryDataModel *dm) { +void EQEmu::Inventory::SetDataModel(InventoryDataModel *dm) { impl_->data_model_ = std::unique_ptr(dm); } @@ -236,6 +236,12 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, return false; } + if(i_src->GetBaseItem()->ItemClass == ItemClassContainer && dest.BagIndex() > -1) { + if(i_src->GetContainer()->Size() > 0) { + return false; + } + } + if(dest.IsEquipment() && !CanEquip(i_src, dest)) { return false; } diff --git a/common/inventory.h b/common/inventory.h index 75a33b690..d4ef2a8cf 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -130,7 +130,7 @@ namespace EQEmu void SetRace(int race); void SetClass(int class_); void SetDeity(int deity); - void SetDataMode(InventoryDataModel *dm); + void SetDataModel(InventoryDataModel *dm); std::shared_ptr Get(const InventorySlot &slot); bool Put(const InventorySlot &slot, std::shared_ptr inst); diff --git a/common/inventory_data_model.h b/common/inventory_data_model.h index c35922147..5bf6a2ec9 100644 --- a/common/inventory_data_model.h +++ b/common/inventory_data_model.h @@ -30,10 +30,10 @@ namespace EQEmu virtual ~InventoryDataModel() { } virtual void Begin() = 0; - virtual void Commit() = 0; + virtual bool Commit() = 0; virtual void Rollback() = 0; - virtual bool Insert(const InventorySlot &slot, std::shared_ptr inst) = 0; - virtual bool Delete(const InventorySlot &slot) = 0; + virtual void Insert(const InventorySlot &slot, std::shared_ptr inst) = 0; + virtual void Delete(const InventorySlot &slot) = 0; }; } // EQEmu diff --git a/common/inventory_db_data_model.cpp b/common/inventory_db_data_model.cpp new file mode 100644 index 000000000..080467341 --- /dev/null +++ b/common/inventory_db_data_model.cpp @@ -0,0 +1,197 @@ +#include "inventory_db_data_model.h" +#include "shareddb.h" +#include "string_util.h" +#include +#include + +enum DataEventTypes +{ + DB_Insert, + DB_Delete +}; + +struct DataEvent +{ + DataEventTypes evt; + EQEmu::InventorySlot slot; + std::shared_ptr inst; +}; + +struct EQEmu::InventoryDatabaseDataModel::impl { + SharedDatabase *db_; + std::list events_; + uint32 char_id_; +}; + +EQEmu::InventoryDatabaseDataModel::InventoryDatabaseDataModel(SharedDatabase *db, uint32 char_id) { + impl_ = new impl; + impl_->db_ = db; + impl_->char_id_ = char_id; +} + +EQEmu::InventoryDatabaseDataModel::~InventoryDatabaseDataModel() { + delete impl_; +} + +void EQEmu::InventoryDatabaseDataModel::Begin() { + impl_->db_->TransactionBegin(); + impl_->events_.clear(); +} + +bool EQEmu::InventoryDatabaseDataModel::Commit() { + std::string base_insert = "INSERT INTO character_inventory(id, type, slot, bag_index, aug_index, " + "item_id, charges, color, attuned, custom_data, ornament_icon, ornament_idfile, ornament_hero_model" + ", tracking_id) VALUES"; + + std::string current_insert = base_insert; + bool insert = false; + for(auto iter : impl_->events_) { + if(iter.evt == DB_Delete) { + if(insert) { + insert = false; + + //commit the current_insert + auto res = impl_->db_->QueryDatabase(current_insert); + if(!res.Success()) { + Rollback(); + return false; + } + + current_insert = base_insert; + } + + std::string current_delete; + if(iter.slot.BagIndex() > -1) { + if(iter.slot.AugIndex() > -1) { + current_delete = StringFormat("DELETE FROM character_inventory WHERE id=%u AND type=%u AND slot=%u AND bag_index=%u AND aug_index=%u", + impl_->char_id_, iter.slot.Type(), iter.slot.Slot(), iter.slot.BagIndex(), iter.slot.AugIndex()); + } + else { + current_delete = StringFormat("DELETE FROM character_inventory WHERE id=%u AND type=%u AND slot=%u AND bag_index=%u", + impl_->char_id_, iter.slot.Type(), iter.slot.Slot(), iter.slot.BagIndex()); + } + } + else if(iter.slot.AugIndex() > -1) { + current_delete = StringFormat("DELETE FROM character_inventory WHERE id=%u AND type=%u AND slot=%u AND aug_index=%u", + impl_->char_id_, iter.slot.Type(), iter.slot.Slot(), iter.slot.AugIndex()); + } + else { + current_delete = StringFormat("DELETE FROM character_inventory WHERE id=%u AND type=%u AND slot=%u", + impl_->char_id_, iter.slot.Type(), iter.slot.Slot()); + } + + auto res = impl_->db_->QueryDatabase(current_delete); + if(!res.Success()) { + Rollback(); + return false; + } + + } else { + //insert + if(!insert) { + insert = true; + } else { + current_insert += ","; + } + + current_insert += StringFormat("(%u, %i, %i, %i, %i, %u, %i, %u, %u, '%s', %u, %u, %u, %llu)", + impl_->char_id_, + iter.slot.Type(), + iter.slot.Slot(), + iter.slot.BagIndex(), + iter.slot.AugIndex(), + iter.inst->GetBaseItem()->ID, + iter.inst->GetCharges(), + iter.inst->GetColor(), + iter.inst->GetAttuned(), + EscapeString(iter.inst->GetCustomData()).c_str(), + iter.inst->GetOrnamentIcon(), + iter.inst->GetOrnamentIDFile(), + iter.inst->GetOrnamentHeroModel(), + iter.inst->GetTrackingID()); + } + } + + if(insert) { + insert = false; + + //commit the current_insert + auto res = impl_->db_->QueryDatabase(current_insert); + if(!res.Success()) { + Rollback(); + return false; + } + + current_insert = base_insert; + } + + impl_->db_->TransactionCommit(); + impl_->events_.clear(); + return true; +} + +void EQEmu::InventoryDatabaseDataModel::Rollback() { + impl_->db_->TransactionRollback(); + impl_->events_.clear(); +} + +void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, std::shared_ptr inst) { + DataEvent evt; + evt.evt = DB_Insert; + evt.inst = inst; + evt.slot = slot; + impl_->events_.push_back(evt); + + //insert current item + if(slot.BagIndex() < 0 && slot.AugIndex() < 0) { + //if bag put all bag contents in + //if common put all augment contents in + if(inst->GetBaseItem()->ItemClass == ItemClassContainer) { + auto container = inst->GetContainer(); + auto iter = container->Begin(); + while(iter != container->End()) { + DataEvent evt; + evt.evt = DB_Insert; + evt.inst = iter->second; + evt.slot = InventorySlot(slot.Type(), slot.Slot(), -1, iter->first); + impl_->events_.push_back(evt); + + ++iter; + } + } + else if(inst->GetBaseItem()->ItemClass == ItemClassCommon) { + auto container = inst->GetContainer(); + auto iter = container->Begin(); + while(iter != container->End()) { + DataEvent evt; + evt.evt = DB_Insert; + evt.inst = iter->second; + evt.slot = InventorySlot(slot.Type(), slot.Slot(), iter->first); + impl_->events_.push_back(evt); + + ++iter; + } + } + } + else if(inst->GetBaseItem()->ItemClass == ItemClassCommon) { + //if common put all augment contents in + auto container = inst->GetContainer(); + auto iter = container->Begin(); + while(iter != container->End()) { + DataEvent evt; + evt.evt = DB_Insert; + evt.inst = iter->second; + evt.slot = InventorySlot(slot.Type(), slot.Slot(), iter->first, slot.BagIndex()); + impl_->events_.push_back(evt); + + ++iter; + } + } +} + +void EQEmu::InventoryDatabaseDataModel::Delete(const InventorySlot &slot) { + DataEvent evt; + evt.evt = DB_Delete; + evt.slot = slot; + impl_->events_.push_back(evt); +} diff --git a/common/inventory_db_data_model.h b/common/inventory_db_data_model.h new file mode 100644 index 000000000..b43ec6412 --- /dev/null +++ b/common/inventory_db_data_model.h @@ -0,0 +1,45 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 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 +*/ + +#ifndef COMMON_INVENTORY_DB_DATA_MODEL_H +#define COMMON_INVENTORY_DB_DATA_MODEL_H + +#include "inventory_data_model.h" + +class SharedDatabase; + +namespace EQEmu +{ + class InventoryDatabaseDataModel : public InventoryDataModel + { + public: + InventoryDatabaseDataModel(SharedDatabase *db, uint32 char_id); + virtual ~InventoryDatabaseDataModel(); + + virtual void Begin(); + virtual bool Commit(); + virtual void Rollback(); + virtual void Insert(const InventorySlot &slot, std::shared_ptr inst); + virtual void Delete(const InventorySlot &slot); + private: + struct impl; + impl *impl_; + }; +} // EQEmu + +#endif diff --git a/common/inventory_null_data_model.h b/common/inventory_null_data_model.h index 3f3433df0..460fe1b3b 100644 --- a/common/inventory_null_data_model.h +++ b/common/inventory_null_data_model.h @@ -30,10 +30,10 @@ namespace EQEmu virtual ~InventoryNullDataModel() { } virtual void Begin() { printf("NDM: Begin\n"); } - virtual void Commit() { printf("NDM: Commit\n"); } + virtual bool Commit() { printf("NDM: Commit\n"); return true; } virtual void Rollback() { printf("NDM: Rollback\n"); } - virtual bool Insert(const InventorySlot &slot, std::shared_ptr inst) { printf("NDM: Insert %s %s\n", slot.ToString().c_str(), inst ? inst->GetBaseItem()->Name : "Null" ); return true; } - virtual bool Delete(const InventorySlot &slot) { printf("NDM: Delete %s\n", slot.ToString().c_str()); return true; } + virtual void Insert(const InventorySlot &slot, std::shared_ptr inst) { printf("NDM: Insert %s %s\n", slot.ToString().c_str(), inst ? inst->GetBaseItem()->Name : "Null" ); } + virtual void Delete(const InventorySlot &slot) { printf("NDM: Delete %s\n", slot.ToString().c_str()); } }; } // EQEmu diff --git a/common/item_instance.cpp b/common/item_instance.cpp index afa902404..f727f0d79 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -188,6 +188,14 @@ void EQEmu::ItemInstance::SetCharges(const int16 charges) { impl_->charges_ = charges; } +uint32 EQEmu::ItemInstance::GetColor() { + return impl_->color_; +} + +uint32 EQEmu::ItemInstance::GetColor() const { + return impl_->color_; +} + void EQEmu::ItemInstance::SetColor(const uint32 color) { impl_->color_ = color; } @@ -204,6 +212,14 @@ void EQEmu::ItemInstance::SetAttuned(const bool attuned) { impl_->attuned_ = attuned; } +std::string EQEmu::ItemInstance::GetCustomData() { + return impl_->custom_data_; +} + +std::string EQEmu::ItemInstance::GetCustomData() const { + return impl_->custom_data_; +} + void EQEmu::ItemInstance::SetCustomData(const std::string &custom_data) { //We need to actually set the custom data stuff based on this string impl_->custom_data_ = custom_data; @@ -233,6 +249,14 @@ void EQEmu::ItemInstance::SetOrnamentIcon(const uint32 ornament_icon) { impl_->ornament_icon_ = ornament_icon; } +uint32 EQEmu::ItemInstance::GetOrnamentHeroModel() { + return impl_->ornament_hero_model_; +} + +uint32 EQEmu::ItemInstance::GetOrnamentHeroModel() const { + return impl_->ornament_hero_model_; +} + uint32 EQEmu::ItemInstance::GetOrnamentHeroModel(int material_slot) { uint32 hero_model = 0; if(impl_->ornament_hero_model_ > 0) diff --git a/common/item_instance.h b/common/item_instance.h index 4b21aaa35..93cbecf6f 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -49,12 +49,16 @@ namespace EQEmu int16 GetCharges() const; void SetCharges(const int16 charges); + uint32 GetColor(); + uint32 GetColor() const; void SetColor(const uint32 color); bool GetAttuned(); bool GetAttuned() const; void SetAttuned(const bool attuned); + std::string GetCustomData(); + std::string GetCustomData() const; void SetCustomData(const std::string &custom_data); uint32 GetOrnamentIDFile(); @@ -65,6 +69,8 @@ namespace EQEmu uint32 GetOrnamentIcon() const; void SetOrnamentIcon(const uint32 ornament_icon); + uint32 GetOrnamentHeroModel(); + uint32 GetOrnamentHeroModel() const; uint32 GetOrnamentHeroModel(int material_slot); uint32 GetOrnamentHeroModel(int material_slot) const; void SetOrnamentHeroModel(const uint32 ornament_hero_model); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 84c102817..09f64e8b2 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -47,6 +47,7 @@ #include "../common/spdat.h" #include "../common/string_util.h" #include "../common/zone_numbers.h" +#include "../common/inventory_db_data_model.h" #include "event_codes.h" #include "guild_mgr.h" #include "merc.h" @@ -1289,6 +1290,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) m_inventory.SetRace(GetBaseRace()); m_inventory.SetClass(GetBaseClass()); m_inventory.SetDeity(GetDeity()); + m_inventory.SetDataModel(new EQEmu::InventoryDatabaseDataModel(&database, CharacterID())); loaditems = database.GetInventory(cid, &m_inventory); /* Load Character Inventory */ /* Load AdventureStats */ From 316aa5ef7370d2149224be88b0ee93a4a58954b5 Mon Sep 17 00:00:00 2001 From: KimLS Date: Wed, 4 Mar 2015 19:35:10 -0800 Subject: [PATCH 21/27] Added current table to utils sql, though not formatted correctly yet since it's heavily wip --- utils/sql/git/required/inv2_wip.sql | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 utils/sql/git/required/inv2_wip.sql diff --git a/utils/sql/git/required/inv2_wip.sql b/utils/sql/git/required/inv2_wip.sql new file mode 100644 index 000000000..43879272d --- /dev/null +++ b/utils/sql/git/required/inv2_wip.sql @@ -0,0 +1,21 @@ +DROP TABLE IF EXISTS `character_inventory`; +CREATE TABLE `character_inventory` ( + `id` INT(10) UNSIGNED NOT NULL, + `type` SMALLINT(6) NOT NULL, + `slot` SMALLINT(6) NOT NULL, + `bag_index` SMALLINT(6) NOT NULL, + `aug_index` SMALLINT(6) NOT NULL, + `item_id` INT(10) UNSIGNED NOT NULL, + `charges` SMALLINT(6) NOT NULL, + `color` INT(10) UNSIGNED NOT NULL, + `attuned` TINYINT(3) UNSIGNED NOT NULL, + `custom_data` TEXT NOT NULL, + `ornament_icon` INT(10) UNSIGNED NOT NULL, + `ornament_idfile` INT(10) UNSIGNED NOT NULL, + `ornament_hero_model` INT(10) UNSIGNED NOT NULL, + `tracking_id` BIGINT(20) UNSIGNED NOT NULL, + PRIMARY KEY (`id`, `type`, `slot`, `bag_index`, `aug_index`), + INDEX `tracking_id` (`tracking_id`) +) +COLLATE='latin1_swedish_ci' +ENGINE=InnoDB; From dda8ae48037a96a96cfcfc2d896149fde3f2ece3 Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 5 Mar 2015 18:03:37 -0800 Subject: [PATCH 22/27] Basic item summoning, fix for saving not working 100 pct, deletion works, cursor queue should work too. --- common/inventory.cpp | 180 ++++++++++++++-- common/inventory.h | 4 + common/inventory_db_data_model.cpp | 25 ++- common/inventory_null_data_model.h | 10 +- common/item_container.cpp | 23 +++ common/item_container.h | 5 + .../item_container_default_serialization.cpp | 2 + .../item_container_personal_serialization.cpp | 2 + common/item_data.h | 2 + common/patches/rof2.cpp | 70 ++++--- zone/client.h | 20 +- zone/client_packet.cpp | 13 +- zone/command.cpp | 17 +- zone/inventory.cpp | 194 ++++++++++++++---- 14 files changed, 459 insertions(+), 108 deletions(-) diff --git a/common/inventory.cpp b/common/inventory.cpp index e90322b93..3c558910c 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -22,6 +22,7 @@ #include "data_verification.h" #include "string_util.h" #include +#include bool EQEmu::InventorySlot::IsValid() const { if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotCharm, PersonalSlotCursor)) { @@ -225,7 +226,28 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, 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; } @@ -252,17 +274,6 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, } 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()) { //move # charges from src to dest @@ -356,6 +367,109 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, return true; } +bool EQEmu::Inventory::Summon(const InventorySlot &slot, std::shared_ptr 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 inst) { + if(impl_->containers_.count(InvTypeCursorBuffer) == 0) { + impl_->containers_.insert(std::pair(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) { if(slot.Type() != 0) return _MaterialInvalid; @@ -441,17 +555,59 @@ bool EQEmu::Inventory::CanEquip(std::shared_ptr inst, const return false; } + //todo: check deity if(!item->IsEquipable(impl_->race_, impl_->class_)) { 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; } +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) { buf.SetWritePosition(0); buf.SetReadPosition(0); buf.Resize(0); + buf.Write(105); bool value = false; for(auto &iter : impl_->containers_) { diff --git a/common/inventory.h b/common/inventory.h index d4ef2a8cf..48b1614bf 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -135,11 +135,15 @@ namespace EQEmu std::shared_ptr Get(const InventorySlot &slot); bool Put(const InventorySlot &slot, std::shared_ptr inst); bool Swap(const InventorySlot &src, const InventorySlot &dest, int charges); + bool Summon(const InventorySlot &slot, std::shared_ptr inst); + bool PushToCursorBuffer(std::shared_ptr inst); + bool PopFromCursorBuffer(); //utility static int CalcMaterialFromSlot(const InventorySlot &slot); static InventorySlot CalcSlotFromMaterial(int material); bool CanEquip(std::shared_ptr inst, const EQEmu::InventorySlot &slot); + bool CheckLoreConflict(const ItemData *item); bool Serialize(MemoryBuffer &buf); //testing diff --git a/common/inventory_db_data_model.cpp b/common/inventory_db_data_model.cpp index 080467341..63035f67c 100644 --- a/common/inventory_db_data_model.cpp +++ b/common/inventory_db_data_model.cpp @@ -153,9 +153,23 @@ void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, std::s DataEvent evt; evt.evt = DB_Insert; 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); + //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; } } @@ -166,14 +180,15 @@ void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, std::s DataEvent evt; evt.evt = DB_Insert; 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); ++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 auto container = inst->GetContainer(); auto iter = container->Begin(); @@ -181,9 +196,9 @@ void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, std::s DataEvent evt; evt.evt = DB_Insert; 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); - + ++iter; } } diff --git a/common/inventory_null_data_model.h b/common/inventory_null_data_model.h index 460fe1b3b..ed1872393 100644 --- a/common/inventory_null_data_model.h +++ b/common/inventory_null_data_model.h @@ -29,11 +29,11 @@ namespace EQEmu InventoryNullDataModel() { } virtual ~InventoryNullDataModel() { } - virtual void Begin() { printf("NDM: Begin\n"); } - virtual bool Commit() { printf("NDM: Commit\n"); return true; } - virtual void Rollback() { printf("NDM: Rollback\n"); } - virtual void Insert(const InventorySlot &slot, std::shared_ptr inst) { printf("NDM: Insert %s %s\n", slot.ToString().c_str(), inst ? inst->GetBaseItem()->Name : "Null" ); } - virtual void Delete(const InventorySlot &slot) { printf("NDM: Delete %s\n", slot.ToString().c_str()); } + virtual void Begin() { } + virtual bool Commit() { return true; } + virtual void Rollback() { } + virtual void Insert(const InventorySlot &slot, std::shared_ptr inst) { } + virtual void Delete(const InventorySlot &slot) { } }; } // EQEmu diff --git a/common/item_container.cpp b/common/item_container.cpp index f78d28461..5a38b009a 100644 --- a/common/item_container.cpp +++ b/common/item_container.cpp @@ -65,6 +65,29 @@ bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr 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() { return (uint32)impl_->items_.size(); } diff --git a/common/item_container.h b/common/item_container.h index 7900c3840..2ea0829ec 100644 --- a/common/item_container.h +++ b/common/item_container.h @@ -42,6 +42,11 @@ namespace EQEmu std::shared_ptr Get(const int slot_id); bool Put(const int slot_id, std::shared_ptr inst); bool Delete(const int slot_id); + + //Utility + bool HasItem(uint32 item_id); + bool HasItemByLoreGroup(uint32 loregroup); + uint32 Size(); uint32 Size() const; diff --git a/common/item_container_default_serialization.cpp b/common/item_container_default_serialization.cpp index 4bcec1e17..0e51896a6 100644 --- a/common/item_container_default_serialization.cpp +++ b/common/item_container_default_serialization.cpp @@ -9,6 +9,8 @@ bool EQEmu::ItemContainerDefaultSerialization::Serialize(MemoryBuffer &buf, cons for(auto &iter : items) { buf.Write(container_number); buf.Write(iter.first); + buf.Write(-1); + buf.Write(-1); buf.Write(iter.second.get()); ret = true; } diff --git a/common/item_container_personal_serialization.cpp b/common/item_container_personal_serialization.cpp index eefd8423a..2a242a645 100644 --- a/common/item_container_personal_serialization.cpp +++ b/common/item_container_personal_serialization.cpp @@ -10,6 +10,8 @@ bool EQEmu::ItemContainerPersonalSerialization::Serialize(MemoryBuffer &buf, con if(iter.first < 33) { buf.Write(container_number); buf.Write(iter.first); + buf.Write(-1); + buf.Write(-1); buf.Write(iter.second.get()); ret = true; } diff --git a/common/item_data.h b/common/item_data.h index 0df9a86a0..ccb6b6411 100644 --- a/common/item_data.h +++ b/common/item_data.h @@ -72,6 +72,8 @@ struct InternalSerializedItem_Struct { struct SerializedItemInstance_Struct { int32 container_id; int32 slot_id; + int32 bag_id; + int32 aug_id; void *inst; }; diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index e2f0c02b3..6bc16c8d5 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -602,18 +602,18 @@ namespace RoF2 EQApplicationPacket *in = *p; *p = nullptr; - size_t entry_size = sizeof(int32) * 2 + sizeof(void*); - size_t entries = in->size / entry_size; + size_t entry_size = sizeof(SerializedItemInstance_Struct); + 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", - opcodes->EmuToName(in->GetOpcode()), in->size, entry_size); + opcodes->EmuToName(in->GetOpcode()), (in->size - sizeof(int32)), entry_size); delete in; return; } 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; packet_data.Write(entries); @@ -1490,33 +1490,41 @@ namespace RoF2 ENCODE(OP_ItemPacket) { - delete *p; + EQApplicationPacket *in = *p; + *p = nullptr; - ////consume the packet - //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); - // - //uint32 length; - //char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0, old_item_pkt->PacketType); - // - //if (!serialized) { - // 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); - // - //delete[] __emu_buffer; - //safe_delete_array(serialized); - //dest->FastQueuePacket(&in, ack_req); + size_t entry_size = sizeof(SerializedItemInstance_Struct); + size_t entries = (in->size - sizeof(int32)) / entry_size; + + if(entries == 0 || entries > 1 || (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", + opcodes->EmuToName(in->GetOpcode()), (in->size - sizeof(int32)), entry_size); + delete in; + return; + } + + unsigned char *__emu_buffer = in->pBuffer; + + int32 *packet_type = (int32*)(__emu_buffer); + SerializedItemInstance_Struct *sis = (SerializedItemInstance_Struct*)(__emu_buffer + sizeof(int32)); + EQEmu::MemoryBuffer packet_data; + packet_data.Write(*packet_type); + + EQEmu::ItemInstance *inst = (EQEmu::ItemInstance*)sis->inst; + if(!inst) { + delete in; + return; + } + + SerializeItem(packet_data, inst, sis->container_id, sis->slot_id, sis->bag_id, sis->slot_id); + + 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) diff --git a/zone/client.h b/zone/client.h index 923401f60..5b6580b1e 100644 --- a/zone/client.h +++ b/zone/client.h @@ -818,13 +818,28 @@ public: void QSSwapItemAuditor(MoveItemOld_Struct* move_in, bool postaction_call = false); 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 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 IncStats(uint8 type,int16 increase_val); void DropItem(int16 slot_id); //New Inventory 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 @@ -881,6 +896,9 @@ public: bool IsValidSlot(uint32 slot); bool IsBankSlot(uint32 slot); + //inv2 + void SendItemPacket(const EQEmu::InventorySlot &slot, std::shared_ptr inst, ItemPacketType packet_type); + inline bool IsTrader() const { return(Trader); } inline bool IsBuyer() const { return(Buyer); } eqFilterMode GetFilter(eqFilterType filter_id) const { return ClientFilters[filter_id]; } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 09f64e8b2..c67c334ab 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1722,14 +1722,11 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) */ if (loaditems) { /* Dont load if a length error occurs */ BulkSendInventoryItems(); - // /* Send stuff on the cursor which isnt sent in bulk */ - // for (auto iter = m_inv.cursor_cbegin(); iter != m_inv.cursor_cend(); ++iter) { - // /* First item cursor is sent in bulk inventory packet */ - // if (iter == m_inv.cursor_cbegin()) - // continue; - // const ItemInst *inst = *iter; - // SendItemPacket(MainCursor, inst, ItemPacketSummonItem); - // } + EQEmu::InventorySlot slot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor); + auto cursor = m_inventory.Get(slot); + if(cursor) { + SendItemPacket(slot, cursor, ItemPacketSummonItem); + } } /* Task Packets */ diff --git a/zone/command.cpp b/zone/command.cpp index fed5c7807..e24e2425b 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -5418,24 +5418,25 @@ void command_summonitem(Client *c, const Seperator *sep) item_status = static_cast(item->MinStatus); } + EQEmu::InventorySlot cursor(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor); if (item_status > c->Admin()) c->Message(13, "Error: Insufficient status to summon this item."); 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) - 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) - 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) - 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) - 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) - 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) - 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 { - c->SummonItem(itemid); + c->SummonItem(itemid, -1, cursor); } } } diff --git a/zone/inventory.cpp b/zone/inventory.cpp index bdb800add..68ee62dc1 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -2427,52 +2427,74 @@ uint32 Client::GetEquipmentColor(uint8 material_slot) const // Send an item packet (including all subitems of the item) 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 inst, ItemPacketType packet_type) { + if(!inst) { return; + } - // Serialize item into |-delimited string - std::string packet = inst->Serialize(slot_id); - + EQEmu::MemoryBuffer item; EmuOpcode opcode = OP_Unknown; - EQApplicationPacket* outapp = nullptr; - ItemPacket_Struct* itempacket = nullptr; + opcode = (packet_type == ItemPacketViewLink) ? OP_ItemLinkResponse : OP_ItemPacket; - // 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); + item.Write((int32)packet_type); + item.Write(slot.Type()); + item.Write(slot.Slot()); + item.Write(slot.BagIndex()); + item.Write(slot.AugIndex()); + item.Write(inst.get()); + + EQApplicationPacket outapp(opcode, item.Size()); + memcpy(outapp.pBuffer, item, item.Size()); + QueuePacket(&outapp); } EQApplicationPacket* Client::ReturnItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type) { - if (!inst) - return nullptr; - - // Serialize item into |-delimited string - std::string packet = inst->Serialize(slot_id); - - EmuOpcode opcode = OP_Unknown; - EQApplicationPacket* outapp = nullptr; - BulkItemPacket_Struct* itempacket = nullptr; - - // Construct packet - opcode = OP_ItemPacket; - outapp = new EQApplicationPacket(opcode, packet.length()+1); - itempacket = (BulkItemPacket_Struct*)outapp->pBuffer; - memcpy(itempacket->SerializedItem, packet.c_str(), packet.length()); - -#if EQDEBUG >= 9 - DumpPacket(outapp); -#endif - - return outapp; + return nullptr; +// if (!inst) +// return nullptr; +// +// // Serialize item into |-delimited string +// std::string packet = inst->Serialize(slot_id); +// +// EmuOpcode opcode = OP_Unknown; +// EQApplicationPacket* outapp = nullptr; +// BulkItemPacket_Struct* itempacket = nullptr; +// +// // Construct packet +// opcode = OP_ItemPacket; +// outapp = new EQApplicationPacket(opcode, packet.length()+1); +// itempacket = (BulkItemPacket_Struct*)outapp->pBuffer; +// memcpy(itempacket->SerializedItem, packet.c_str(), packet.length()); +// +//#if EQDEBUG >= 9 +// DumpPacket(outapp); +//#endif +// +// return outapp; } static int16 BandolierSlotToWeaponSlot(int BandolierSlot) @@ -3143,7 +3165,16 @@ bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlo } else { Message(0, "Swap failure!\n"); //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) { @@ -3157,3 +3188,90 @@ bool Client::SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlo 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 inst = database.CreateItem(item_id, charges); + if(!inst) + return false; + + if(inst->GetBaseItem()->ItemClass == ItemClassCommon) { + if(aug1) { + std::shared_ptr aug = database.CreateItem(aug1); + if(!aug) + return false; + + if(!inst->Put(0, aug)) { + return false; + } + } + + if(aug2) { + std::shared_ptr aug = database.CreateItem(aug2); + if(!aug) + return false; + + if(!inst->Put(1, aug)) { + return false; + } + } + + if(aug3) { + std::shared_ptr aug = database.CreateItem(aug3); + if(!aug) + return false; + + if(!inst->Put(2, aug)) { + return false; + } + } + + if(aug4) { + std::shared_ptr aug = database.CreateItem(aug4); + if(!aug) + return false; + + if(!inst->Put(3, aug)) { + return false; + } + } + + if(aug5) { + std::shared_ptr aug = database.CreateItem(aug5); + if(!aug) + return false; + + if(!inst->Put(4, aug)) { + return false; + } + } + + if(aug6) { + std::shared_ptr 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; +} From 00af95502e6fd070a98d0c23aa21446b3cd56471 Mon Sep 17 00:00:00 2001 From: KimLS Date: Fri, 6 Mar 2015 15:53:15 -0800 Subject: [PATCH 23/27] Wip merchant stuff, summoning should work now. --- common/inventory.cpp | 1 - common/shareddb.cpp | 8 ++++--- common/shareddb.h | 2 +- zone/client.h | 2 +- zone/client_packet.cpp | 15 ++++-------- zone/client_process.cpp | 5 ++-- zone/command.cpp | 51 ++++++++++++++++++++++++++--------------- zone/inventory.cpp | 2 +- zone/lua_client.cpp | 2 +- zone/questmgr.cpp | 2 +- zone/spell_effects.cpp | 2 +- zone/tradeskills.cpp | 6 ++--- 12 files changed, 54 insertions(+), 44 deletions(-) diff --git a/common/inventory.cpp b/common/inventory.cpp index 3c558910c..a0a14f18b 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -22,7 +22,6 @@ #include "data_verification.h" #include "string_util.h" #include -#include bool EQEmu::InventorySlot::IsValid() const { if(type_ == InvTypePersonal && EQEmu::ValueWithin(slot_, PersonalSlotCharm, PersonalSlotCursor)) { diff --git a/common/shareddb.cpp b/common/shareddb.cpp index cf18cac55..3b5170d75 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1253,7 +1253,7 @@ ItemInst* SharedDatabase::CreateBaseItemOld(const ItemData* item, int16 charges) return inst; } -std::shared_ptr SharedDatabase::CreateItem(uint32 item_id, int16 charges) { +std::shared_ptr SharedDatabase::CreateItem(uint32 item_id, int16 charges, bool unique) { const ItemData* item = GetItem(item_id); if(item) { if(charges == 0 && item->MaxCharges == -1) { @@ -1265,8 +1265,10 @@ std::shared_ptr SharedDatabase::CreateItem(uint32 item_id, } std::shared_ptr inst = std::shared_ptr(new EQEmu::ItemInstance(item, charges)); - inst->SetSerialNumber(EQEmu::GetNextItemInstanceSerial()); - //Set Tracking here + if(unique) { + inst->SetSerialNumber(EQEmu::GetNextItemInstanceSerial()); + //Set Tracking here + } return inst; } diff --git a/common/shareddb.h b/common/shareddb.h index 506f62eef..f995bd0df 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -85,7 +85,7 @@ class SharedDatabase : public Database ItemInst* CreateItemOld(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); ItemInst* CreateItemOld(const ItemData* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); ItemInst* CreateBaseItemOld(const ItemData* item, int16 charges = 0); - std::shared_ptr CreateItem(uint32 item_id, int16 charges = 0); + std::shared_ptr CreateItem(uint32 item_id, int16 charges = 0, bool unique = true); /* Shared Memory crap diff --git a/zone/client.h b/zone/client.h index 5b6580b1e..860ac1dc7 100644 --- a/zone/client.h +++ b/zone/client.h @@ -829,7 +829,7 @@ public: 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, + const EQEmu::InventorySlot &slot = EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index c67c334ab..d36207c9e 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -2628,7 +2628,7 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app) /* If you input more than you have currency wise, just give the max of the currency you currently have */ if (reclaim->count > max_currency) { - SummonItem(item_id, max_currency); + SummonItem(item_id, max_currency, 0); SetAlternateCurrencyValue(reclaim->currency_id, 0); } else { @@ -4889,14 +4889,14 @@ void Client::Handle_OP_CrystalCreate(const EQApplicationPacket *app) if (cr->type == 5) { if (cr->amount > GetEbonCrystals()) { - SummonItem(RuleI(Zone, EbonCrystalItemID), GetEbonCrystals()); + SummonItem(RuleI(Zone, EbonCrystalItemID), GetEbonCrystals(), 0); m_pp.currentEbonCrystals = 0; m_pp.careerEbonCrystals = 0; SaveCurrency(); SendCrystalCounts(); } else { - SummonItem(RuleI(Zone, EbonCrystalItemID), cr->amount); + SummonItem(RuleI(Zone, EbonCrystalItemID), cr->amount, 0); m_pp.currentEbonCrystals -= cr->amount; m_pp.careerEbonCrystals -= cr->amount; SaveCurrency(); @@ -4905,14 +4905,14 @@ void Client::Handle_OP_CrystalCreate(const EQApplicationPacket *app) } else if (cr->type == 4) { if (cr->amount > GetRadiantCrystals()) { - SummonItem(RuleI(Zone, RadiantCrystalItemID), GetRadiantCrystals()); + SummonItem(RuleI(Zone, RadiantCrystalItemID), GetRadiantCrystals(), 0); m_pp.currentRadCrystals = 0; m_pp.careerRadCrystals = 0; SaveCurrency(); SendCrystalCounts(); } else { - SummonItem(RuleI(Zone, RadiantCrystalItemID), cr->amount); + SummonItem(RuleI(Zone, RadiantCrystalItemID), cr->amount, 0); m_pp.currentRadCrystals -= cr->amount; m_pp.careerRadCrystals -= cr->amount; SaveCurrency(); @@ -12177,7 +12177,6 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) sizeof(Merchant_Purchase_Struct), app->size); return; } - RDTSC_Timer t1(true); Merchant_Purchase_Struct* mp = (Merchant_Purchase_Struct*)app->pBuffer; Mob* vendor = entity_list.GetMob(mp->npcid); @@ -12206,7 +12205,6 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) } if (!item->NoDrop) { - //Message(13,"%s tells you, 'LOL NOPE'", vendor->GetName()); return; } @@ -12319,10 +12317,7 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) QueuePacket(outapp); safe_delete(outapp); SendMoneyUpdate(); - t1.start(); Save(1); - t1.stop(); - std::cout << "Save took: " << t1.getDuration() << std::endl; return; } diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 662264d95..ba30b7abe 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -873,7 +873,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { int charges = 1; if (item->ItemClass == ItemClassCommon) charges = item->MaxCharges; - ItemInst* inst = database.CreateItemOld(item, charges); + auto inst = database.CreateItem(item->ID, charges, false); if (inst) { if (RuleB(Merchant, UsePriceMod)) { inst->SetPrice((item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(merch, false))); @@ -887,8 +887,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { else inst->SetCharges(1); - SendItemPacket(ml.slot - 1, inst, ItemPacketMerchant); - safe_delete(inst); + SendItemPacket(EQEmu::InventorySlot(EQEmu::InvTypePersonal, ml.slot - 1), inst, ItemPacketMerchant); } } // Account for merchant lists with gaps. diff --git a/zone/command.cpp b/zone/command.cpp index e24e2425b..5aabf6563 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -5419,24 +5419,31 @@ void command_summonitem(Client *c, const Seperator *sep) } EQEmu::InventorySlot cursor(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor); - if (item_status > c->Admin()) + bool v = false; + if (item_status > c->Admin()) { c->Message(13, "Error: Insufficient status to summon this item."); + return; + } else if (sep->argnum==2 && sep->IsNumber(2)) - c->SummonItem(itemid, atoi(sep->arg[2]), cursor); + v = c->SummonItem(itemid, atoi(sep->arg[2]), cursor); else if (sep->argnum==3) - c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3])); + v = c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3])); else if (sep->argnum==4) - c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4])); + v = c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4])); else if (sep->argnum==5) - c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5])); + v = 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) - c->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6])); + v = 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) - 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])); + v = 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) - 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])); + v = 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 { - c->SummonItem(itemid, -1, cursor); + v = c->SummonItem(itemid, -1, cursor); + } + + if(!v) { + c->Message(13, "Error: unable to summon item."); } } } @@ -5458,24 +5465,32 @@ void command_giveitem(Client *c, const Seperator *sep) item_status = static_cast(item->MinStatus); } - if (item_status > c->Admin()) + EQEmu::InventorySlot cursor(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor); + bool v = false; + if (item_status > c->Admin()) { c->Message(13, "Error: Insufficient status to summon this item."); + return; + } else if (sep->argnum==2 && sep->IsNumber(2)) - t->SummonItem(itemid, atoi(sep->arg[2])); + v = t->SummonItem(itemid, atoi(sep->arg[2]), cursor); else if (sep->argnum==3) - t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3])); + v = t->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3])); else if (sep->argnum==4) - t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4])); + v = t->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4])); else if (sep->argnum==5) - t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5])); + v = t->SummonItem(itemid, atoi(sep->arg[2]), cursor, atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5])); else if (sep->argnum==6) - t->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6])); + v = t->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) - t->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])); + v = t->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 == 7) - t->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])); + v = t->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 { - t->SummonItem(itemid); + v = t->SummonItem(itemid, -1, cursor); + } + + if(!v) { + c->Message(13, "Error: Unable to summon item on target."); } } } diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 68ee62dc1..de89acd94 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -1649,7 +1649,7 @@ bool Client::SwapItem(MoveItemOld_Struct* move_in) { } else { if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit - SummonItem(src_inst->GetID(), src_inst->GetCharges()); + SummonItem(src_inst->GetID(), src_inst->GetCharges(), 0); DeleteItemInInventory(MainCursor); return true; diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index ac0ddcf99..400d2a419 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -672,7 +672,7 @@ void Lua_Client::SummonItem(uint32 item_id) { void Lua_Client::SummonItem(uint32 item_id, int charges) { Lua_Safe_Call_Void(); - self->SummonItem(item_id, charges); + self->SummonItem(item_id, charges, 0); } void Lua_Client::SummonItem(uint32 item_id, int charges, uint32 aug1) { diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 38d90b848..b129d00cc 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -189,7 +189,7 @@ void QuestManager::summonitem(uint32 itemid, int16 charges) { QuestManagerCurrentQuestVars(); if(!initiator) return; - initiator->SummonItem(itemid, charges); + initiator->SummonItem(itemid, charges, 0); } void QuestManager::write(const char *file, const char *str) { diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index aa3051ef1..c60923346 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -619,7 +619,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) strstr(transI->GetItem()->Name, "parts") || strstr(transI->GetItem()->Name, "Parts")){ CastToClient()->DeleteItemInInventory(MainCursor, fcharges, true); - CastToClient()->SummonItem(13073, fcharges); + CastToClient()->SummonItem(13073, fcharges, 0); } else{ Message(13, "You can only transmute flesh to bone."); diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 4e3262de1..edd01b4aa 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -1068,7 +1068,7 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { itr = spec->onsuccess.begin(); while(itr != spec->onsuccess.end() && !spec->quest) { //should we check this crap? - SummonItem(itr->first, itr->second); + SummonItem(itr->first, itr->second, 0); item = database.GetItem(itr->first); if (this->GetGroup()) { entity_list.MessageGroup(this, true, MT_Skills, "%s has successfully fashioned %s!", GetName(), item->Name); @@ -1111,7 +1111,7 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { itr = spec->onfail.begin(); while(itr != spec->onfail.end()) { //should we check these arguments? - SummonItem(itr->first, itr->second); + SummonItem(itr->first, itr->second, 0); ++itr; } @@ -1126,7 +1126,7 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { while(itr != spec->salvage.end()) { for(sc = 0; sc < itr->second; sc++) if(zone->random.Roll(SalvageChance)) - SummonItem(itr->first, 1); + SummonItem(itr->first, 1, 0); ++itr; } } From 7341ecc1859ac3de51c0c7f7bea5e3f8467f7c80 Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 6 Apr 2015 16:53:12 -0700 Subject: [PATCH 24/27] Some work on implementing slot selection --- common/inventory.cpp | 44 +++++++++++ common/inventory.h | 4 +- zone/client_packet.cpp | 174 +++++++++++++++-------------------------- 3 files changed, 110 insertions(+), 112 deletions(-) diff --git a/common/inventory.cpp b/common/inventory.cpp index b3fc99a0f..2c10c84ba 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -506,6 +506,50 @@ bool EQEmu::Inventory::PopFromCursorBuffer() { return false; } +EQEmu::InventorySlot EQEmu::Inventory::PutItemInInventory(std::shared_ptr inst, bool try_worn, bool try_cursor) { + return EQEmu::InventorySlot(); +} + +EQEmu::InventorySlot EQEmu::Inventory::FindFreeSlot(bool for_bag, bool try_cursor, int min_size, bool is_arrow) { + //check basic inventory + for(int i = EQEmu::PersonalSlotGeneral1; i < EQEmu::PersonalSlotGeneral10; ++i) { + EQEmu::InventorySlot slot(EQEmu::InvTypePersonal, i); + if(!Get(slot)) { + return slot; + } + } + + if (!for_bag) { + for(int i = EQEmu::PersonalSlotGeneral1; i < EQEmu::PersonalSlotGeneral10; ++i) { + EQEmu::InventorySlot slot(EQEmu::InvTypePersonal, i); + auto inst = Get(slot); + + if(inst && inst->GetBaseItem()->ItemClass == ItemClassContainer && inst->GetBaseItem()->BagSize >= min_size) + { + if(inst->GetBaseItem()->BagType == BagTypeQuiver && !is_arrow) + { + continue; + } + + int slots = inst->GetBaseItem()->BagSlots; + for(int b_i = 0; b_i < slots; ++b_i) { + EQEmu::InventorySlot bag_slot(EQEmu::InvTypePersonal, i, b_i); + + if(!Get(bag_slot)) { + return bag_slot; + } + } + } + } + } + + if(try_cursor) { + EQEmu::InventorySlot slot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor); + } + + return EQEmu::InventorySlot(); +} + int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) { if(slot.Type() != 0) return _MaterialInvalid; diff --git a/common/inventory.h b/common/inventory.h index a85e647bb..2562c1f21 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -37,7 +37,7 @@ namespace EQEmu InvTypeGuildTribute }; - enum PersonaInventorylSlot : int + enum PersonaInventorySlot : int { PersonalSlotCharm = 0, PersonalSlotEar1, @@ -139,8 +139,8 @@ namespace EQEmu bool Summon(const InventorySlot &slot, std::shared_ptr inst); bool PushToCursorBuffer(std::shared_ptr inst); bool PopFromCursorBuffer(); - bool PutStackInInventory(std::shared_ptr inst, bool try_worn, bool try_cursor); InventorySlot PutItemInInventory(std::shared_ptr inst, bool try_worn, bool try_cursor); + InventorySlot FindFreeSlot(bool for_bag, bool try_cursor, int min_size = 0, bool is_arrow = false); //utility static int CalcMaterialFromSlot(const InventorySlot &slot); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 6ec6b1754..f22958575 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -12028,7 +12028,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) mpo->npcid = mp->npcid; mpo->itemslot = mp->itemslot; - int16 freeslotid = INVALID_INDEX; + EQEmu::InventorySlot free_slot; int16 charges = 0; if (item->Stackable || item->MaxCharges > 1) charges = mp->quantity; @@ -12070,115 +12070,69 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) } bool stacked = TryStacking(inst); - //if (!stacked) - // freeslotid = m_inv.FindFreeSlot(false, true, item->Size); - // - //// shouldn't we be reimbursing if these two fail? - // - ////make sure we are not completely full... - //if (freeslotid == MainCursor) { - // if (m_inv.GetItem(MainCursor) != nullptr) { - // Message(13, "You do not have room for any more items."); - // safe_delete(outapp); - // return; - // } - //} - // - //if (!stacked && freeslotid == INVALID_INDEX) - //{ - // Message(13, "You do not have room for any more items."); - // safe_delete(outapp); - // return; - //} - // - //std::string packet; - //if (!stacked && inst) { - // PutItemInInventory(freeslotid, *inst); - // SendItemPacket(freeslotid, inst, ItemPacketTrade); - //} - //else if (!stacked){ - // Log.Out(Logs::General, Logs::Error, "OP_ShopPlayerBuy: item->ItemClass Unknown! Type: %i", item->ItemClass); - //} - //QueuePacket(outapp); - //if (inst && tmpmer_used){ - // int32 new_charges = prevcharges - mp->quantity; - // zone->SaveTempItem(merchantid, tmp->GetNPCTypeID(), item_id, new_charges); - // if (new_charges <= 0){ - // EQApplicationPacket* delitempacket = new EQApplicationPacket(OP_ShopDelItem, sizeof(Merchant_DelItem_Struct)); - // Merchant_DelItem_Struct* delitem = (Merchant_DelItem_Struct*)delitempacket->pBuffer; - // delitem->itemslot = mp->itemslot; - // delitem->npcid = mp->npcid; - // delitem->playerid = mp->playerid; - // delitempacket->priority = 6; - // entity_list.QueueClients(tmp, delitempacket); //que for anyone that could be using the merchant so they see the update - // safe_delete(delitempacket); - // } - // else { - // // Update the charges/quantity in the merchant window - // inst->SetCharges(new_charges); - // inst->SetPrice(SinglePrice); - // inst->SetMerchantSlot(mp->itemslot); - // inst->SetMerchantCount(new_charges); - // - // SendItemPacket(mp->itemslot, inst, ItemPacketMerchant); - // } - //} - //safe_delete(inst); - //safe_delete(outapp); - // - //// start QS code - //// stacking purchases not supported at this time - entire process will need some work to catch them properly - //if (RuleB(QueryServ, PlayerLogMerchantTransactions)) { - // ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogMerchantTransactions, sizeof(QSMerchantLogTransaction_Struct)+sizeof(QSTransactionItems_Struct)); - // QSMerchantLogTransaction_Struct* qsaudit = (QSMerchantLogTransaction_Struct*)qspack->pBuffer; - // - // qsaudit->zone_id = zone->GetZoneID(); - // qsaudit->merchant_id = tmp->CastToNPC()->MerchantType; - // qsaudit->merchant_money.platinum = 0; - // qsaudit->merchant_money.gold = 0; - // qsaudit->merchant_money.silver = 0; - // qsaudit->merchant_money.copper = 0; - // qsaudit->merchant_count = 1; - // qsaudit->char_id = character_id; - // qsaudit->char_money.platinum = (mpo->price / 1000); - // qsaudit->char_money.gold = (mpo->price / 100) % 10; - // qsaudit->char_money.silver = (mpo->price / 10) % 10; - // qsaudit->char_money.copper = mpo->price % 10; - // qsaudit->char_count = 0; - // - // qsaudit->items[0].char_slot = freeslotid == INVALID_INDEX ? 0 : freeslotid; - // qsaudit->items[0].item_id = item->ID; - // qsaudit->items[0].charges = mpo->quantity; - // - // if (freeslotid == INVALID_INDEX) { - // qsaudit->items[0].aug_1 = 0; - // qsaudit->items[0].aug_2 = 0; - // qsaudit->items[0].aug_3 = 0; - // qsaudit->items[0].aug_4 = 0; - // qsaudit->items[0].aug_5 = 0; - // } - // else { - // qsaudit->items[0].aug_1 = m_inv[freeslotid]->GetAugmentItemID(0); - // qsaudit->items[0].aug_2 = m_inv[freeslotid]->GetAugmentItemID(1); - // qsaudit->items[0].aug_3 = m_inv[freeslotid]->GetAugmentItemID(2); - // qsaudit->items[0].aug_4 = m_inv[freeslotid]->GetAugmentItemID(3); - // qsaudit->items[0].aug_5 = m_inv[freeslotid]->GetAugmentItemID(4); - // } - // - // qspack->Deflate(); - // if (worldserver.Connected()) { worldserver.SendPacket(qspack); } - // safe_delete(qspack); - //} - //// end QS code - // - //if (RuleB(EventLog, RecordBuyFromMerchant)) - // LogMerchant(this, tmp, mpo->quantity, mpo->price, item, true); - // - //if ((RuleB(Character, EnableDiscoveredItems))) - //{ - // if (!GetGM() && !IsDiscovered(item_id)) - // DiscoverItem(item_id); - //} + if(!stacked) { + free_slot = m_inventory.FindFreeSlot(false, true, item->Size); + } + + if(free_slot.IsCursor()) { + if(m_inventory.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor))) { + Message(13, "You do not have room for any more items."); + safe_delete(outapp); + return; + } + } + + if(!stacked && !free_slot.IsValid()) + { + Message(13, "You do not have room for any more items."); + safe_delete(outapp); + return; + } + + std::string packet; + if(!stacked && inst) { + //PutItemInInventory(free_slot, inst); + SendItemPacket(free_slot, inst, ItemPacketTrade); + } + else if (!stacked){ + Log.Out(Logs::General, Logs::Error, "OP_ShopPlayerBuy: item->ItemClass Unknown! Type: %i", item->ItemClass); + } + + QueuePacket(outapp); + if (inst && tmpmer_used){ + int32 new_charges = prevcharges - mp->quantity; + zone->SaveTempItem(merchantid, tmp->GetNPCTypeID(), item_id, new_charges); + if (new_charges <= 0){ + EQApplicationPacket* delitempacket = new EQApplicationPacket(OP_ShopDelItem, sizeof(Merchant_DelItem_Struct)); + Merchant_DelItem_Struct* delitem = (Merchant_DelItem_Struct*)delitempacket->pBuffer; + delitem->itemslot = mp->itemslot; + delitem->npcid = mp->npcid; + delitem->playerid = mp->playerid; + delitempacket->priority = 6; + entity_list.QueueClients(tmp, delitempacket); //que for anyone that could be using the merchant so they see the update + safe_delete(delitempacket); + } + else { + // Update the charges/quantity in the merchant window + inst->SetCharges(new_charges); + inst->SetPrice(SinglePrice); + inst->SetMerchantSlot(mp->itemslot); + inst->SetMerchantCount(new_charges); + + //SendItemPacket(mp->itemslot, inst, ItemPacketMerchant); + } + } + safe_delete(outapp); + + + if (RuleB(EventLog, RecordBuyFromMerchant)) + LogMerchant(this, tmp, mpo->quantity, mpo->price, item, true); + + if ((RuleB(Character, EnableDiscoveredItems))) + { + if (!GetGM() && !IsDiscovered(item_id)) + DiscoverItem(item_id); + } } void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) { From 56e7d1b0dcf4110e7d110f460a2e3ce3843fda4c Mon Sep 17 00:00:00 2001 From: KimLS Date: Tue, 7 Apr 2015 16:28:28 -0700 Subject: [PATCH 25/27] Okay finally merchant buying works -.- --- common/inventory.cpp | 4 ---- common/inventory.h | 4 ++-- zone/client.h | 4 +++- zone/client_packet.cpp | 12 +++++------- zone/inventory.cpp | 21 +++++++++++++++++++++ 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/common/inventory.cpp b/common/inventory.cpp index 2c10c84ba..1451bcef5 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -506,10 +506,6 @@ bool EQEmu::Inventory::PopFromCursorBuffer() { return false; } -EQEmu::InventorySlot EQEmu::Inventory::PutItemInInventory(std::shared_ptr inst, bool try_worn, bool try_cursor) { - return EQEmu::InventorySlot(); -} - EQEmu::InventorySlot EQEmu::Inventory::FindFreeSlot(bool for_bag, bool try_cursor, int min_size, bool is_arrow) { //check basic inventory for(int i = EQEmu::PersonalSlotGeneral1; i < EQEmu::PersonalSlotGeneral10; ++i) { diff --git a/common/inventory.h b/common/inventory.h index 2562c1f21..c3d7d11e9 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -34,7 +34,8 @@ namespace EQEmu InvTypeCursorBuffer, InvTypeTribute, InvTypeTrophyTribute, - InvTypeGuildTribute + InvTypeGuildTribute, + InvTypeMerchant }; enum PersonaInventorySlot : int @@ -139,7 +140,6 @@ namespace EQEmu bool Summon(const InventorySlot &slot, std::shared_ptr inst); bool PushToCursorBuffer(std::shared_ptr inst); bool PopFromCursorBuffer(); - InventorySlot PutItemInInventory(std::shared_ptr inst, bool try_worn, bool try_cursor); InventorySlot FindFreeSlot(bool for_bag, bool try_cursor, int min_size = 0, bool is_arrow = false); //utility diff --git a/zone/client.h b/zone/client.h index 0b188dd64..54cf45f12 100644 --- a/zone/client.h +++ b/zone/client.h @@ -827,7 +827,8 @@ public: void IncStats(uint8 type,int16 increase_val); void DropItem(int16 slot_id); - //New Inventory + //inv2: New Inventory methods, will probably move these to Mob in a future update as there's + //little reason for them to be in client except for simplicity of implementation atm bool SwapItem(const EQEmu::InventorySlot &src, const EQEmu::InventorySlot &dest, int number_in_stack); bool SummonItem(uint32 item_id, int16 charges, @@ -842,6 +843,7 @@ public: uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0); + bool PutItemInInventory(const EQEmu::InventorySlot &slot, std::shared_ptr inst, bool client_update = false); // // class Client::TextLink diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index f22958575..697a693ba 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -12075,11 +12075,9 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) } if(free_slot.IsCursor()) { - if(m_inventory.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor))) { - Message(13, "You do not have room for any more items."); - safe_delete(outapp); - return; - } + Message(13, "You do not have room for any more items."); + safe_delete(outapp); + return; } if(!stacked && !free_slot.IsValid()) @@ -12091,7 +12089,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) std::string packet; if(!stacked && inst) { - //PutItemInInventory(free_slot, inst); + PutItemInInventory(free_slot, inst); SendItemPacket(free_slot, inst, ItemPacketTrade); } else if (!stacked){ @@ -12119,7 +12117,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) inst->SetMerchantSlot(mp->itemslot); inst->SetMerchantCount(new_charges); - //SendItemPacket(mp->itemslot, inst, ItemPacketMerchant); + SendItemPacket(EQEmu::InventorySlot(EQEmu::InvTypeMerchant, mp->itemslot), inst, ItemPacketMerchant); } } safe_delete(outapp); diff --git a/zone/inventory.cpp b/zone/inventory.cpp index e3db7047b..95f0f267d 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -3353,3 +3353,24 @@ bool Client::SummonItem(uint32 item_id, return res; } + +bool Client::PutItemInInventory(const EQEmu::InventorySlot &slot, std::shared_ptr inst, bool client_update) { + if(!inst) + return false; + + if(!slot.IsValid()) { + return false; + } + + Log.Out(Logs::Detail, Logs::Inventory, "Putting item %s (%d) into slot %s", inst->GetBaseItem()->Name, inst->GetBaseItem()->ID, slot.ToString().c_str()); + + if(!m_inventory.Summon(slot, inst)) { + return false; + } + + if(client_update) { + SendItemPacket(slot, inst, slot.IsCursor() ? ItemPacketSummonItem : ItemPacketTrade); + } + + CalcBonuses(); +} From bbc3733c3a97ab8c2c57488fd85291f571c10151 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sun, 21 Jun 2015 01:45:42 -0700 Subject: [PATCH 26/27] Compiles again, had to disable a new piece of code though --- zone/bot.cpp | 3 +- zone/inventory.cpp | 215 ++++++++++++++++++++++---------------------- zone/loottables.cpp | 2 +- zone/mob.cpp | 2 +- 4 files changed, 112 insertions(+), 110 deletions(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index 2f02abe12..536b661f8 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -5,6 +5,7 @@ #include "doors.h" #include "quest_parser_collection.h" #include "../common/string_util.h" +#include "../common/item.h" extern volatile bool ZoneLoaded; @@ -9006,7 +9007,7 @@ void Bot::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug, return; } - const Item_Struct *item = inst->GetItem(); + const ItemData *item = inst->GetItem(); if(!isTribute && !inst->IsEquipable(GetBaseRace(),GetClass())) { diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 0cedb9d9a..e1eec88cc 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -2271,113 +2271,114 @@ static bool CopyBagContents(ItemInst* new_bag, const ItemInst* old_bag) void Client::DisenchantSummonedBags(bool client_update) { - for (auto slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; ++slot_id) { - auto inst = m_inv[slot_id]; - if (!inst) { continue; } - if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; } - if (inst->GetItem()->ItemClass != ItemClassContainer) { continue; } - if (inst->GetTotalItemCount() == 1) { continue; } - - auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots); - if (!new_id) { continue; } - auto new_item = database.GetItem(new_id); - if (!new_item) { continue; } - auto new_inst = database.CreateBaseItem(new_item); - if (!new_inst) { continue; } - - if (CopyBagContents(new_inst, inst)) { - Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, slot_id); - PutItemInInventory(slot_id, *new_inst, client_update); - } - safe_delete(new_inst); - } - - for (auto slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; ++slot_id) { - auto inst = m_inv[slot_id]; - if (!inst) { continue; } - if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; } - if (inst->GetItem()->ItemClass != ItemClassContainer) { continue; } - if (inst->GetTotalItemCount() == 1) { continue; } - - auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots); - if (!new_id) { continue; } - auto new_item = database.GetItem(new_id); - if (!new_item) { continue; } - auto new_inst = database.CreateBaseItem(new_item); - if (!new_inst) { continue; } - - if (CopyBagContents(new_inst, inst)) { - Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, slot_id); - PutItemInInventory(slot_id, *new_inst, client_update); - } - safe_delete(new_inst); - } - - for (auto slot_id = EmuConstants::SHARED_BANK_BEGIN; slot_id <= EmuConstants::SHARED_BANK_END; ++slot_id) { - auto inst = m_inv[slot_id]; - if (!inst) { continue; } - if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; } - if (inst->GetItem()->ItemClass != ItemClassContainer) { continue; } - if (inst->GetTotalItemCount() == 1) { continue; } - - auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots); - if (!new_id) { continue; } - auto new_item = database.GetItem(new_id); - if (!new_item) { continue; } - auto new_inst = database.CreateBaseItem(new_item); - if (!new_inst) { continue; } - - if (CopyBagContents(new_inst, inst)) { - Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, slot_id); - PutItemInInventory(slot_id, *new_inst, client_update); - } - safe_delete(new_inst); - } - - while (!m_inv.CursorEmpty()) { - auto inst = m_inv[MainCursor]; - if (!inst) { break; } - if (!IsSummonedBagID(inst->GetItem()->ID)) { break; } - if (inst->GetItem()->ItemClass != ItemClassContainer) { break; } - if (inst->GetTotalItemCount() == 1) { break; } - - auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots); - if (!new_id) { break; } - auto new_item = database.GetItem(new_id); - if (!new_item) { break; } - auto new_inst = database.CreateBaseItem(new_item); - if (!new_inst) { break; } - - if (CopyBagContents(new_inst, inst)) { - Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, MainCursor); - std::list local; - local.push_front(new_inst); - m_inv.PopItem(MainCursor); - safe_delete(inst); - - while (!m_inv.CursorEmpty()) { - auto limbo_inst = m_inv.PopItem(MainCursor); - if (limbo_inst == nullptr) { continue; } - local.push_back(limbo_inst); - } - - for (auto iter = local.begin(); iter != local.end(); ++iter) { - auto cur_inst = *iter; - if (cur_inst == nullptr) { continue; } - m_inv.PushCursor(*cur_inst); - safe_delete(cur_inst); - } - local.clear(); - - auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); - database.SaveCursor(this->CharacterID(), s, e); - } - else { - safe_delete(new_inst); // deletes disenchanted bag if not used - } - - break; - } + //Inv2 todo: uh fix this + //for (auto slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; ++slot_id) { + // auto inst = m_inv[slot_id]; + // if (!inst) { continue; } + // if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; } + // if (inst->GetItem()->ItemClass != ItemClassContainer) { continue; } + // if (inst->GetTotalItemCount() == 1) { continue; } + // + // auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots); + // if (!new_id) { continue; } + // auto new_item = database.GetItem(new_id); + // if (!new_item) { continue; } + // auto new_inst = database.CreateBaseItem(new_item); + // if (!new_inst) { continue; } + // + // if (CopyBagContents(new_inst, inst)) { + // Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, slot_id); + // PutItemInInventory(slot_id, *new_inst, client_update); + // } + // safe_delete(new_inst); + //} + // + //for (auto slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; ++slot_id) { + // auto inst = m_inv[slot_id]; + // if (!inst) { continue; } + // if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; } + // if (inst->GetItem()->ItemClass != ItemClassContainer) { continue; } + // if (inst->GetTotalItemCount() == 1) { continue; } + // + // auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots); + // if (!new_id) { continue; } + // auto new_item = database.GetItem(new_id); + // if (!new_item) { continue; } + // auto new_inst = database.CreateBaseItem(new_item); + // if (!new_inst) { continue; } + // + // if (CopyBagContents(new_inst, inst)) { + // Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, slot_id); + // PutItemInInventory(slot_id, *new_inst, client_update); + // } + // safe_delete(new_inst); + //} + // + //for (auto slot_id = EmuConstants::SHARED_BANK_BEGIN; slot_id <= EmuConstants::SHARED_BANK_END; ++slot_id) { + // auto inst = m_inv[slot_id]; + // if (!inst) { continue; } + // if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; } + // if (inst->GetItem()->ItemClass != ItemClassContainer) { continue; } + // if (inst->GetTotalItemCount() == 1) { continue; } + // + // auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots); + // if (!new_id) { continue; } + // auto new_item = database.GetItem(new_id); + // if (!new_item) { continue; } + // auto new_inst = database.CreateBaseItem(new_item); + // if (!new_inst) { continue; } + // + // if (CopyBagContents(new_inst, inst)) { + // Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, slot_id); + // PutItemInInventory(slot_id, *new_inst, client_update); + // } + // safe_delete(new_inst); + //} + // + //while (!m_inv.CursorEmpty()) { + // auto inst = m_inv[MainCursor]; + // if (!inst) { break; } + // if (!IsSummonedBagID(inst->GetItem()->ID)) { break; } + // if (inst->GetItem()->ItemClass != ItemClassContainer) { break; } + // if (inst->GetTotalItemCount() == 1) { break; } + // + // auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots); + // if (!new_id) { break; } + // auto new_item = database.GetItem(new_id); + // if (!new_item) { break; } + // auto new_inst = database.CreateBaseItem(new_item); + // if (!new_inst) { break; } + // + // if (CopyBagContents(new_inst, inst)) { + // Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, MainCursor); + // std::list local; + // local.push_front(new_inst); + // m_inv.PopItem(MainCursor); + // safe_delete(inst); + // + // while (!m_inv.CursorEmpty()) { + // auto limbo_inst = m_inv.PopItem(MainCursor); + // if (limbo_inst == nullptr) { continue; } + // local.push_back(limbo_inst); + // } + // + // for (auto iter = local.begin(); iter != local.end(); ++iter) { + // auto cur_inst = *iter; + // if (cur_inst == nullptr) { continue; } + // m_inv.PushCursor(*cur_inst); + // safe_delete(cur_inst); + // } + // local.clear(); + // + // auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); + // database.SaveCursor(this->CharacterID(), s, e); + // } + // else { + // safe_delete(new_inst); // deletes disenchanted bag if not used + // } + // + // break; + //} } void Client::RemoveNoRent(bool client_update) diff --git a/zone/loottables.cpp b/zone/loottables.cpp index 5cfd95239..372d7acd3 100644 --- a/zone/loottables.cpp +++ b/zone/loottables.cpp @@ -157,7 +157,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml for(int i = 0; i < mindrop; ++i) { float roll = (float)zone->random.Real(0.0, roll_t_min); for(uint32 j = 0; j < lds->NumEntries; ++j) { - const Item_Struct* db_item = GetItem(lds->Entries[j].item_id); + const ItemData* db_item = GetItem(lds->Entries[j].item_id); if(db_item) { if(roll < lds->Entries[j].chance) { npc->AddLootDrop(db_item, itemlist, lds->Entries[j].item_charges, lds->Entries[j].minlevel, diff --git a/zone/mob.cpp b/zone/mob.cpp index 41ad94d2d..990698e4b 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2729,7 +2729,7 @@ void Mob::SendArmorAppearance(Client *one_client) { if (!IsClient()) { - const Item_Struct *item; + const ItemData *item; for (int i=0; i< 7 ; ++i) { item=database.GetItem(GetEquipment(i)); From 46cb96a02694773403488c43837b94e41d78c908 Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 22 Jun 2015 23:50:39 -0700 Subject: [PATCH 27/27] Merchant buying in flux but it works better now --- common/inventory.cpp | 148 +++--- common/inventory.h | 15 +- common/inventory_data_model.h | 2 +- common/inventory_db_data_model.cpp | 4 +- common/inventory_db_data_model.h | 2 +- common/inventory_null_data_model.h | 2 +- common/item_container.cpp | 8 +- common/item_container.h | 6 +- .../item_container_default_serialization.cpp | 2 +- common/item_container_default_serialization.h | 2 +- .../item_container_personal_serialization.cpp | 2 +- .../item_container_personal_serialization.h | 2 +- .../item_container_serialization_strategy.h | 2 +- common/item_instance.cpp | 18 +- common/item_instance.h | 9 +- common/ruletypes.h | 21 - common/servertalk.h | 135 +----- common/shareddb.cpp | 6 +- common/shareddb.h | 2 +- queryserv/database.cpp | 223 --------- queryserv/database.h | 6 - queryserv/worldserver.cpp | 35 -- tests/inventory_test.h | 10 +- world/zoneserver.cpp | 7 - zone/aa.cpp | 14 +- zone/attack.cpp | 64 --- zone/client.cpp | 150 ++---- zone/client.h | 10 +- zone/client_packet.cpp | 274 ++++------- zone/client_process.cpp | 6 - zone/command.cpp | 73 --- zone/command.h | 1 - zone/embparser_api.cpp | 5 +- zone/exp.cpp | 19 - zone/inventory.cpp | 304 ++++++------ zone/queryserv.cpp | 7 - zone/queryserv.h | 1 - zone/questmgr.cpp | 12 - zone/tasks.cpp | 11 - zone/tradeskills.cpp | 12 - zone/trading.cpp | 442 ++++-------------- zone/zone.cpp | 104 +++-- zone/zone.h | 15 +- zone/zonedb.cpp | 27 -- zone/zonedb.h | 1 - zone/zoning.cpp | 6 - 46 files changed, 606 insertions(+), 1621 deletions(-) diff --git a/common/inventory.cpp b/common/inventory.cpp index 1451bcef5..12dd8840c 100644 --- a/common/inventory.cpp +++ b/common/inventory.cpp @@ -155,7 +155,7 @@ void EQEmu::Inventory::SetDataModel(InventoryDataModel *dm) { impl_->data_model_ = std::unique_ptr(dm); } -std::shared_ptr EQEmu::Inventory::Get(const InventorySlot &slot) { +EQEmu::ItemInstance::pointer EQEmu::Inventory::Get(const InventorySlot &slot) { auto iter = impl_->containers_.find(slot.Type()); if(iter != impl_->containers_.end()) { auto item = iter->second.Get(slot.Slot()); @@ -175,10 +175,10 @@ std::shared_ptr EQEmu::Inventory::Get(const InventorySlot & } } - return std::shared_ptr(nullptr); + return ItemInstance::pointer(nullptr); } -bool EQEmu::Inventory::Put(const InventorySlot &slot, std::shared_ptr inst) { +bool EQEmu::Inventory::Put(const InventorySlot &slot, ItemInstance::pointer &inst) { if(impl_->containers_.count(slot.Type()) == 0) { if(slot.Type() == 0) { impl_->containers_.insert(std::pair(slot.Type(), ItemContainer(new ItemContainerPersonalSerialization()))); @@ -321,6 +321,7 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, } i_dest->SetCharges(i_dest->GetCharges() + charges); + impl_->data_model_->Delete(dest); impl_->data_model_->Insert(dest, i_dest); impl_->data_model_->Commit(); return true; @@ -335,6 +336,8 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, } Put(dest, split); + impl_->data_model_->Delete(src); + impl_->data_model_->Delete(dest); impl_->data_model_->Insert(src, i_src); impl_->data_model_->Insert(dest, split); impl_->data_model_->Commit(); @@ -366,44 +369,7 @@ bool EQEmu::Inventory::Swap(const InventorySlot &src, const InventorySlot &dest, return true; } -bool EQEmu::Inventory::TryStacking(std::shared_ptr inst, const InventorySlot &slot) { - auto target_inst = Get(slot); - - if(!inst || !target_inst || - !inst->IsStackable() || !target_inst->IsStackable()) - { - return false; - } - - if(inst->GetBaseItem()->ID != target_inst->GetBaseItem()->ID) { - return false; - } - - int stack_avail = target_inst->GetBaseItem()->StackSize - target_inst->GetCharges(); - - if(stack_avail <= 0) { - return false; - } - - impl_->data_model_->Begin(); - if(inst->GetCharges() <= stack_avail) { - inst->SetCharges(0); - target_inst->SetCharges(target_inst->GetCharges() + inst->GetCharges()); - impl_->data_model_->Delete(slot); - impl_->data_model_->Insert(slot, target_inst); - } else { - inst->SetCharges(inst->GetCharges() - stack_avail); - target_inst->SetCharges(target_inst->GetCharges() + stack_avail); - impl_->data_model_->Delete(slot); - impl_->data_model_->Insert(slot, target_inst); - } - - impl_->data_model_->Commit(); - - return true; -} - -bool EQEmu::Inventory::Summon(const InventorySlot &slot, std::shared_ptr inst) { +bool EQEmu::Inventory::Summon(const InventorySlot &slot, ItemInstance::pointer &inst) { if(!inst) return false; @@ -432,7 +398,7 @@ bool EQEmu::Inventory::Summon(const InventorySlot &slot, std::shared_ptr inst) { +bool EQEmu::Inventory::PushToCursorBuffer(ItemInstance::pointer &inst) { if(impl_->containers_.count(InvTypeCursorBuffer) == 0) { impl_->containers_.insert(std::pair(InvTypeCursorBuffer, ItemContainer())); } @@ -506,18 +472,23 @@ bool EQEmu::Inventory::PopFromCursorBuffer() { return false; } -EQEmu::InventorySlot EQEmu::Inventory::FindFreeSlot(bool for_bag, bool try_cursor, int min_size, bool is_arrow) { - //check basic inventory - for(int i = EQEmu::PersonalSlotGeneral1; i < EQEmu::PersonalSlotGeneral10; ++i) { - EQEmu::InventorySlot slot(EQEmu::InvTypePersonal, i); +EQEmu::InventorySlot EQEmu::Inventory::FindFreeSlot(ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end) { + bool for_bag = inst->GetItem()->ItemClass == ItemClassContainer; + int min_size = inst->GetItem()->Size; + bool is_arrow = inst->GetItem()->ItemType == ItemTypeArrow; + + //check upper level inventory + for(int i = slot_id_start; i <= slot_id_end; ++i) { + EQEmu::InventorySlot slot(container_id, i); if(!Get(slot)) { return slot; } } + //if not for a bag then check inside bags if (!for_bag) { - for(int i = EQEmu::PersonalSlotGeneral1; i < EQEmu::PersonalSlotGeneral10; ++i) { - EQEmu::InventorySlot slot(EQEmu::InvTypePersonal, i); + for(int i = slot_id_start; i <= slot_id_end; ++i) { + EQEmu::InventorySlot slot(container_id, i); auto inst = Get(slot); if(inst && inst->GetBaseItem()->ItemClass == ItemClassContainer && inst->GetBaseItem()->BagSize >= min_size) @@ -529,7 +500,7 @@ EQEmu::InventorySlot EQEmu::Inventory::FindFreeSlot(bool for_bag, bool try_curso int slots = inst->GetBaseItem()->BagSlots; for(int b_i = 0; b_i < slots; ++b_i) { - EQEmu::InventorySlot bag_slot(EQEmu::InvTypePersonal, i, b_i); + EQEmu::InventorySlot bag_slot(container_id, i, b_i); if(!Get(bag_slot)) { return bag_slot; @@ -539,11 +510,77 @@ EQEmu::InventorySlot EQEmu::Inventory::FindFreeSlot(bool for_bag, bool try_curso } } - if(try_cursor) { - EQEmu::InventorySlot slot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor); + return EQEmu::InventorySlot(); +} + +int EQEmu::Inventory::FindFreeStackSlots(ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end) { + if(!inst->IsStackable()) { + return 0; } - return EQEmu::InventorySlot(); + bool is_arrow = inst->GetItem()->ItemType == ItemTypeArrow; + int item_id = inst->GetItem()->ID; + + int charges_to_check = inst->GetCharges(); + int charges = 0; + + auto iter = impl_->containers_.find(container_id); + if(iter == impl_->containers_.end()) { + return 0; + } + + auto &container = iter->second; + for(int i = slot_id_start; i <= slot_id_end; ++i) { + auto current = container.Get(i); + if(!current) { + continue; + } + + if(current->GetItem()->ID == item_id) { + int free_charges = current->GetItem()->StackSize - current->GetCharges(); + if(free_charges) + charges += free_charges; + + if(charges >= charges_to_check) { + return charges_to_check; + } + } else if(current->GetItem()->ItemClass == ItemClassContainer) { + int sz = current->GetItem()->BagSlots; + for(int i = 0; i < sz; ++i) { + auto sub_item = current->Get(i); + if(!sub_item) { + continue; + } + + if(sub_item->GetItem()->ID == item_id) { + int free_charges = sub_item->GetItem()->StackSize - sub_item->GetCharges(); + if(free_charges) + charges += free_charges; + + if(charges >= charges_to_check) { + return charges_to_check; + } + } + } + } + } + + if(charges >= charges_to_check) { + return charges_to_check; + } + + return charges; +} + +void EQEmu::Inventory::UpdateSlot(const InventorySlot &slot, ItemInstance::pointer &inst) { + impl_->data_model_->Begin(); + + impl_->data_model_->Delete(slot); + if(inst) { + impl_->data_model_->Insert(slot, inst); + } + + impl_->data_model_->Commit(); } int EQEmu::Inventory::CalcMaterialFromSlot(const InventorySlot &slot) { @@ -600,7 +637,7 @@ EQEmu::InventorySlot EQEmu::Inventory::CalcSlotFromMaterial(int material) { } } -bool EQEmu::Inventory::CanEquip(std::shared_ptr inst, const EQEmu::InventorySlot &slot) { +bool EQEmu::Inventory::CanEquip(EQEmu::ItemInstance::pointer &inst, const EQEmu::InventorySlot &slot) { if(!inst) { return false; } @@ -640,7 +677,8 @@ bool EQEmu::Inventory::CanEquip(std::shared_ptr inst, const 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))) { + EQEmu::ItemInstance::pointer itm = iter->second; + if(!CanEquip(itm, InventorySlot(slot.Type(), slot.Slot(), slot.BagIndex(), iter->first))) { return false; } ++iter; @@ -738,7 +776,7 @@ bool EQEmu::Inventory::_swap(const InventorySlot &src, const InventorySlot &dest } bool EQEmu::Inventory::_destroy(const InventorySlot &slot) { - bool v = Put(slot, std::shared_ptr(nullptr)); + bool v = Put(slot, EQEmu::ItemInstance::pointer(nullptr)); impl_->data_model_->Delete(slot); return v; } diff --git a/common/inventory.h b/common/inventory.h index c3d7d11e9..345edb7fb 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -133,19 +133,20 @@ namespace EQEmu void SetDeity(int deity); void SetDataModel(InventoryDataModel *dm); - std::shared_ptr Get(const InventorySlot &slot); - bool Put(const InventorySlot &slot, std::shared_ptr inst); + ItemInstance::pointer Get(const InventorySlot &slot); + bool Put(const InventorySlot &slot, ItemInstance::pointer &inst); bool Swap(const InventorySlot &src, const InventorySlot &dest, int charges); - bool TryStacking(std::shared_ptr inst, const InventorySlot &slot); - bool Summon(const InventorySlot &slot, std::shared_ptr inst); - bool PushToCursorBuffer(std::shared_ptr inst); + bool Summon(const InventorySlot &slot, ItemInstance::pointer &inst); + bool PushToCursorBuffer(ItemInstance::pointer &inst); bool PopFromCursorBuffer(); - InventorySlot FindFreeSlot(bool for_bag, bool try_cursor, int min_size = 0, bool is_arrow = false); + InventorySlot FindFreeSlot(ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end); + int FindFreeStackSlots(ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end); + void UpdateSlot(const InventorySlot &slot, ItemInstance::pointer &inst); //utility static int CalcMaterialFromSlot(const InventorySlot &slot); static InventorySlot CalcSlotFromMaterial(int material); - bool CanEquip(std::shared_ptr inst, const EQEmu::InventorySlot &slot); + bool CanEquip(EQEmu::ItemInstance::pointer &inst, const EQEmu::InventorySlot &slot); bool CheckLoreConflict(const ItemData *item); bool Serialize(MemoryBuffer &buf); diff --git a/common/inventory_data_model.h b/common/inventory_data_model.h index 5bf6a2ec9..8679e1112 100644 --- a/common/inventory_data_model.h +++ b/common/inventory_data_model.h @@ -32,7 +32,7 @@ namespace EQEmu virtual void Begin() = 0; virtual bool Commit() = 0; virtual void Rollback() = 0; - virtual void Insert(const InventorySlot &slot, std::shared_ptr inst) = 0; + virtual void Insert(const InventorySlot &slot, ItemInstance::pointer &inst) = 0; virtual void Delete(const InventorySlot &slot) = 0; }; } // EQEmu diff --git a/common/inventory_db_data_model.cpp b/common/inventory_db_data_model.cpp index 63035f67c..2465ef9f3 100644 --- a/common/inventory_db_data_model.cpp +++ b/common/inventory_db_data_model.cpp @@ -14,7 +14,7 @@ struct DataEvent { DataEventTypes evt; EQEmu::InventorySlot slot; - std::shared_ptr inst; + EQEmu::ItemInstance::pointer inst; }; struct EQEmu::InventoryDatabaseDataModel::impl { @@ -135,7 +135,7 @@ void EQEmu::InventoryDatabaseDataModel::Rollback() { impl_->events_.clear(); } -void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, std::shared_ptr inst) { +void EQEmu::InventoryDatabaseDataModel::Insert(const InventorySlot &slot, ItemInstance::pointer &inst) { DataEvent evt; evt.evt = DB_Insert; evt.inst = inst; diff --git a/common/inventory_db_data_model.h b/common/inventory_db_data_model.h index b43ec6412..b26129095 100644 --- a/common/inventory_db_data_model.h +++ b/common/inventory_db_data_model.h @@ -34,7 +34,7 @@ namespace EQEmu virtual void Begin(); virtual bool Commit(); virtual void Rollback(); - virtual void Insert(const InventorySlot &slot, std::shared_ptr inst); + virtual void Insert(const InventorySlot &slot, ItemInstance::pointer &inst); virtual void Delete(const InventorySlot &slot); private: struct impl; diff --git a/common/inventory_null_data_model.h b/common/inventory_null_data_model.h index ed1872393..de7005e26 100644 --- a/common/inventory_null_data_model.h +++ b/common/inventory_null_data_model.h @@ -32,7 +32,7 @@ namespace EQEmu virtual void Begin() { } virtual bool Commit() { return true; } virtual void Rollback() { } - virtual void Insert(const InventorySlot &slot, std::shared_ptr inst) { } + virtual void Insert(const InventorySlot &slot, ItemInstance::pointer &inst) { } virtual void Delete(const InventorySlot &slot) { } }; } // EQEmu diff --git a/common/item_container.cpp b/common/item_container.cpp index 5a38b009a..ecb7797bc 100644 --- a/common/item_container.cpp +++ b/common/item_container.cpp @@ -4,7 +4,7 @@ struct EQEmu::ItemContainer::impl { - std::map> items_; + std::map items_; ItemContainerSerializationStrategy *serialize_strat_; }; @@ -41,16 +41,16 @@ EQEmu::ItemContainer& EQEmu::ItemContainer::operator=(ItemContainer &&other) { return *this; } -std::shared_ptr EQEmu::ItemContainer::Get(const int slot_id) { +EQEmu::ItemInstance::pointer EQEmu::ItemContainer::Get(const int slot_id) { auto iter = impl_->items_.find(slot_id); if(iter != impl_->items_.end()) { return iter->second; } - return std::shared_ptr(nullptr); + return EQEmu::ItemInstance::pointer(nullptr); } -bool EQEmu::ItemContainer::Put(const int slot_id, std::shared_ptr inst) { +bool EQEmu::ItemContainer::Put(const int slot_id, ItemInstance::pointer &inst) { if(!inst) { impl_->items_.erase(slot_id); return true; diff --git a/common/item_container.h b/common/item_container.h index 2ea0829ec..14690bcfd 100644 --- a/common/item_container.h +++ b/common/item_container.h @@ -31,7 +31,7 @@ namespace EQEmu class ItemContainer { public: - typedef std::map>::const_iterator ItemContainerIter; + typedef std::map::const_iterator ItemContainerIter; ItemContainer(); ItemContainer(ItemContainerSerializationStrategy *strategy); @@ -39,8 +39,8 @@ namespace EQEmu ItemContainer(ItemContainer &&other); ItemContainer& operator=(ItemContainer &&other); - std::shared_ptr Get(const int slot_id); - bool Put(const int slot_id, std::shared_ptr inst); + ItemInstance::pointer Get(const int slot_id); + bool Put(const int slot_id, ItemInstance::pointer &inst); bool Delete(const int slot_id); //Utility diff --git a/common/item_container_default_serialization.cpp b/common/item_container_default_serialization.cpp index 0e51896a6..017221bd6 100644 --- a/common/item_container_default_serialization.cpp +++ b/common/item_container_default_serialization.cpp @@ -1,6 +1,6 @@ #include "item_container_default_serialization.h" -bool EQEmu::ItemContainerDefaultSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items) { +bool EQEmu::ItemContainerDefaultSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map& items) { if(items.size() == 0) { return false; } diff --git a/common/item_container_default_serialization.h b/common/item_container_default_serialization.h index 3626eded6..b30f55879 100644 --- a/common/item_container_default_serialization.h +++ b/common/item_container_default_serialization.h @@ -28,7 +28,7 @@ namespace EQEmu public: ItemContainerDefaultSerialization() { } virtual ~ItemContainerDefaultSerialization() { } - virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items); + virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map& items); }; } // EQEmu diff --git a/common/item_container_personal_serialization.cpp b/common/item_container_personal_serialization.cpp index 2a242a645..61e877836 100644 --- a/common/item_container_personal_serialization.cpp +++ b/common/item_container_personal_serialization.cpp @@ -1,6 +1,6 @@ #include "item_container_personal_serialization.h" -bool EQEmu::ItemContainerPersonalSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items) { +bool EQEmu::ItemContainerPersonalSerialization::Serialize(MemoryBuffer &buf, const int container_number, const std::map& items) { if(items.size() == 0) { return false; } diff --git a/common/item_container_personal_serialization.h b/common/item_container_personal_serialization.h index 0b41d5dc6..46ebe97ed 100644 --- a/common/item_container_personal_serialization.h +++ b/common/item_container_personal_serialization.h @@ -28,7 +28,7 @@ namespace EQEmu public: ItemContainerPersonalSerialization() { } virtual ~ItemContainerPersonalSerialization() { } - virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items); + virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map& items); }; } // EQEmu diff --git a/common/item_container_serialization_strategy.h b/common/item_container_serialization_strategy.h index e8fb61bee..b9415915c 100644 --- a/common/item_container_serialization_strategy.h +++ b/common/item_container_serialization_strategy.h @@ -30,7 +30,7 @@ namespace EQEmu public: ItemContainerSerializationStrategy() { } virtual ~ItemContainerSerializationStrategy() { } - virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map>& items) = 0; + virtual bool Serialize(MemoryBuffer &buf, const int container_number, const std::map& items) = 0; }; } // EQEmu diff --git a/common/item_instance.cpp b/common/item_instance.cpp index f727f0d79..3e59d5f6b 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -86,21 +86,21 @@ EQEmu::ItemInstance::~ItemInstance() { } -std::shared_ptr EQEmu::ItemInstance::Split(int charges) { +EQEmu::ItemInstance::pointer EQEmu::ItemInstance::Split(int charges) { if(!IsStackable()) { //Can't split non stackable items! - return std::shared_ptr(nullptr); + return pointer(nullptr); } if(charges >= GetCharges()) { - return std::shared_ptr(nullptr); + return pointer(nullptr); } if(impl_->contents_.Size() > 0) { - return std::shared_ptr(nullptr); + return pointer(nullptr); } - std::shared_ptr split = std::shared_ptr(new EQEmu::ItemInstance(impl_->base_item_, charges)); + pointer split = pointer(new EQEmu::ItemInstance(impl_->base_item_, charges)); split->SetSerialNumber(EQEmu::GetNextItemInstanceSerial()); //Set Tracking here split->impl_->attuned_ = impl_->attuned_; @@ -130,20 +130,20 @@ const ItemData *EQEmu::ItemInstance::GetBaseItem() const { return impl_->base_item_; } -std::shared_ptr EQEmu::ItemInstance::Get(const int index) { +EQEmu::ItemInstance::pointer EQEmu::ItemInstance::Get(const int index) { if(EQEmu::ValueWithin(index, 0, 255)) { return impl_->contents_.Get(index); } - return std::shared_ptr(nullptr); + return pointer(nullptr); } -bool EQEmu::ItemInstance::Put(const int index, std::shared_ptr inst) { +bool EQEmu::ItemInstance::Put(const int index, pointer &inst) { if(!impl_->base_item_) { return false; } - auto *item = impl_->base_item_; + auto item = impl_->base_item_; if(item->ItemClass == ItemClassContainer) { // Bag if(!EQEmu::ValueWithin(index, 0, item->BagSlots)) { return false; diff --git a/common/item_instance.h b/common/item_instance.h index 93cbecf6f..08b6d14af 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -30,6 +30,7 @@ namespace EQEmu class ItemInstance { public: + typedef std::shared_ptr pointer; ItemInstance(const ItemData* idata); ItemInstance(const ItemData* idata, const int16 charges); ~ItemInstance(); @@ -38,11 +39,11 @@ namespace EQEmu const ItemData *GetBaseItem(); const ItemData *GetBaseItem() const; - std::shared_ptr Split(int charges); + pointer Split(int charges); //Container - std::shared_ptr Get(const int index); - bool Put(const int index, std::shared_ptr inst); + pointer Get(const int index); + bool Put(const int index, pointer &inst); //Persistent State int16 GetCharges(); @@ -108,6 +109,8 @@ namespace EQEmu bool IsNoDrop(); bool IsNoDrop() const; + void CheckStackRemaining(pointer &insert, int &charges); + //Internal state //Used for low level operations such as encode/decode ItemContainer *GetContainer(); diff --git a/common/ruletypes.h b/common/ruletypes.h index 1919c7168..37124281b 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -584,27 +584,6 @@ RULE_CATEGORY_END() RULE_CATEGORY(QueryServ) RULE_BOOL(QueryServ, PlayerLogChat, false) // Logs Player Chat -RULE_BOOL(QueryServ, PlayerLogTrades, false) // Logs Player Trades -RULE_BOOL(QueryServ, PlayerLogHandins, false) // Logs Player Handins -RULE_BOOL(QueryServ, PlayerLogNPCKills, false) // Logs Player NPC Kills -RULE_BOOL(QueryServ, PlayerLogDeletes, false) // Logs Player Deletes -RULE_BOOL(QueryServ, PlayerLogMoves, false) // Logs Player Moves -RULE_BOOL(QueryServ, PlayerLogMerchantTransactions, false) // Logs Merchant Transactions -RULE_BOOL(QueryServ, PlayerLogPCCoordinates, false) // Logs Player Coordinates with certain events -RULE_BOOL(QueryServ, PlayerLogDropItem, false) // Logs Player Drop Item -RULE_BOOL(QueryServ, PlayerLogZone, false) // Logs Player Zone Events -RULE_BOOL(QueryServ, PlayerLogDeaths, false) // Logs Player Deaths -RULE_BOOL(QueryServ, PlayerLogConnectDisconnect, false) // Logs Player Connect Disconnect State -RULE_BOOL(QueryServ, PlayerLogLevels, false) // Logs Player Leveling/Deleveling -RULE_BOOL(QueryServ, PlayerLogAARate, false) // Logs Player AA Experience Rates -RULE_BOOL(QueryServ, PlayerLogQGlobalUpdate, false) // Logs Player QGlobal Updates -RULE_BOOL(QueryServ, PlayerLogTaskUpdates, false) // Logs Player Task Updates -RULE_BOOL(QueryServ, PlayerLogKeyringAddition, false) // Log PLayer Keyring additions -RULE_BOOL(QueryServ, PlayerLogAAPurchases, false) // Log Player AA Purchases -RULE_BOOL(QueryServ, PlayerLogTradeSkillEvents, false) // Log Player Tradeskill Transactions -RULE_BOOL(QueryServ, PlayerLogIssuedCommandes, false) // Log Player Issued Commands -RULE_BOOL(QueryServ, PlayerLogMoneyTransactions, false) // Log Player Money Transaction/Splits -RULE_BOOL(QueryServ, PlayerLogAlternateCurrencyTransactions, false) // Log Ploayer Alternate Currency Transactions RULE_CATEGORY_END() RULE_CATEGORY(Inventory) diff --git a/common/servertalk.h b/common/servertalk.h index af39bfaa4..a3fa488d5 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -181,14 +181,7 @@ #define ServerOP_CZMessagePlayer 0x4008 #define ServerOP_ReloadWorld 0x4009 #define ServerOP_ReloadLogs 0x4010 -/* Query Server OP Codes */ -#define ServerOP_QSPlayerLogTrades 0x5010 -#define ServerOP_QSPlayerLogHandins 0x5011 -#define ServerOP_QSPlayerLogNPCKills 0x5012 -#define ServerOP_QSPlayerLogDeletes 0x5013 -#define ServerOP_QSPlayerLogMoves 0x5014 -#define ServerOP_QSPlayerLogMerchantTransactions 0x5015 -#define ServerOP_QSSendQuery 0x5016 +#define ServerOP_QSSendQuery 0x5000 #define ServerOP_CZSignalNPC 0x5017 #define ServerOP_CZSetEntityVariableByNPCTypeID 0x5018 @@ -1113,132 +1106,6 @@ struct CZClientSignalByName_Struct { uint32 data; }; -struct QSTradeItems_Struct { - uint32 from_id; - uint16 from_slot; - uint32 to_id; - uint16 to_slot; - uint32 item_id; - uint16 charges; - uint32 aug_1; - uint32 aug_2; - uint32 aug_3; - uint32 aug_4; - uint32 aug_5; -}; - -struct QSPlayerLogTrade_Struct { - uint32 char1_id; - MoneyUpdate_Struct char1_money; - uint16 char1_count; - uint32 char2_id; - MoneyUpdate_Struct char2_money; - uint16 char2_count; - uint16 _detail_count; - QSTradeItems_Struct items[0]; -}; - -struct QSHandinItems_Struct { - char action_type[7]; // handin, return or reward - uint16 char_slot; - uint32 item_id; - uint16 charges; - uint32 aug_1; - uint32 aug_2; - uint32 aug_3; - uint32 aug_4; - uint32 aug_5; -}; - -struct QSPlayerLogHandin_Struct { - uint32 quest_id; - uint32 char_id; - MoneyUpdate_Struct char_money; - uint16 char_count; - uint32 npc_id; - MoneyUpdate_Struct npc_money; - uint16 npc_count; - uint16 _detail_count; - QSHandinItems_Struct items[0]; -}; - -struct QSPlayerLogNPCKillSub_Struct{ - uint32 NPCID; - uint32 ZoneID; - uint32 Type; -}; - -struct QSPlayerLogNPCKillsPlayers_Struct{ - uint32 char_id; -}; - -struct QSPlayerLogNPCKill_Struct{ - QSPlayerLogNPCKillSub_Struct s1; - QSPlayerLogNPCKillsPlayers_Struct Chars[0]; -}; - -struct QSDeleteItems_Struct { - uint16 char_slot; - uint32 item_id; - uint16 charges; - uint32 aug_1; - uint32 aug_2; - uint32 aug_3; - uint32 aug_4; - uint32 aug_5; -}; - -struct QSPlayerLogDelete_Struct { - uint32 char_id; - uint16 stack_size; // '0' indicates full stack or non-stackable item move - uint16 char_count; - QSDeleteItems_Struct items[0]; -}; - -struct QSMoveItems_Struct { - uint16 from_slot; - uint16 to_slot; - uint32 item_id; - uint16 charges; - uint32 aug_1; - uint32 aug_2; - uint32 aug_3; - uint32 aug_4; - uint32 aug_5; -}; - -struct QSPlayerLogMove_Struct { - uint32 char_id; - uint16 from_slot; - uint16 to_slot; - uint16 stack_size; // '0' indicates full stack or non-stackable item move - uint16 char_count; - bool postaction; - QSMoveItems_Struct items[0]; -}; - -struct QSTransactionItems_Struct { - uint16 char_slot; - uint32 item_id; - uint16 charges; - uint32 aug_1; - uint32 aug_2; - uint32 aug_3; - uint32 aug_4; - uint32 aug_5; -}; - -struct QSMerchantLogTransaction_Struct { - uint32 zone_id; - uint32 merchant_id; - MoneyUpdate_Struct merchant_money; - uint16 merchant_count; - uint32 char_id; - MoneyUpdate_Struct char_money; - uint16 char_count; - QSTransactionItems_Struct items[0]; -}; - struct QSGeneralQuery_Struct { char QueryString[0]; }; diff --git a/common/shareddb.cpp b/common/shareddb.cpp index ea3f1a55a..fac3d48de 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1255,7 +1255,7 @@ ItemInst* SharedDatabase::CreateBaseItemOld(const ItemData* item, int16 charges) return inst; } -std::shared_ptr SharedDatabase::CreateItem(uint32 item_id, int16 charges, bool unique) { +EQEmu::ItemInstance::pointer SharedDatabase::CreateItem(uint32 item_id, int16 charges, bool unique) { const ItemData* item = GetItem(item_id); if(item) { if(charges == 0 && item->MaxCharges == -1) { @@ -1266,7 +1266,7 @@ std::shared_ptr SharedDatabase::CreateItem(uint32 item_id, charges = 1; } - std::shared_ptr inst = std::shared_ptr(new EQEmu::ItemInstance(item, charges)); + EQEmu::ItemInstance::pointer inst = EQEmu::ItemInstance::pointer(new EQEmu::ItemInstance(item, charges)); if(unique) { inst->SetSerialNumber(EQEmu::GetNextItemInstanceSerial()); //Set Tracking here @@ -1274,7 +1274,7 @@ std::shared_ptr SharedDatabase::CreateItem(uint32 item_id, return inst; } - return std::shared_ptr(nullptr); + return EQEmu::ItemInstance::pointer(nullptr); } int32 SharedDatabase::DeleteStalePlayerCorpses() { diff --git a/common/shareddb.h b/common/shareddb.h index f995bd0df..33ad207b1 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -85,7 +85,7 @@ class SharedDatabase : public Database ItemInst* CreateItemOld(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); ItemInst* CreateItemOld(const ItemData* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0); ItemInst* CreateBaseItemOld(const ItemData* item, int16 charges = 0); - std::shared_ptr CreateItem(uint32 item_id, int16 charges = 0, bool unique = true); + EQEmu::ItemInstance::pointer CreateItem(uint32 item_id, int16 charges = 0, bool unique = true); /* Shared Memory crap diff --git a/queryserv/database.cpp b/queryserv/database.cpp index ea5bdff65..a65255cfc 100644 --- a/queryserv/database.cpp +++ b/queryserv/database.cpp @@ -123,229 +123,6 @@ void Database::AddSpeech(const char* from, const char* to, const char* message, } -void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 detailCount) { - - std::string query = StringFormat("INSERT INTO `qs_player_trade_record` SET `time` = NOW(), " - "`char1_id` = '%i', `char1_pp` = '%i', `char1_gp` = '%i', " - "`char1_sp` = '%i', `char1_cp` = '%i', `char1_items` = '%i', " - "`char2_id` = '%i', `char2_pp` = '%i', `char2_gp` = '%i', " - "`char2_sp` = '%i', `char2_cp` = '%i', `char2_items` = '%i'", - QS->char1_id, QS->char1_money.platinum, QS->char1_money.gold, - QS->char1_money.silver, QS->char1_money.copper, QS->char1_count, - QS->char2_id, QS->char2_money.platinum, QS->char2_money.gold, - QS->char2_money.silver, QS->char2_money.copper, QS->char2_count); - auto results = QueryDatabase(query); - if(!results.Success()) { - Log.Out(Logs::Detail, Logs::QS_Server, "Failed Trade Log Record Insert: %s", results.ErrorMessage().c_str()); - Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); - } - - if(detailCount == 0) - return; - - int lastIndex = results.LastInsertedID(); - - for(int i = 0; i < detailCount; i++) { - query = StringFormat("INSERT INTO `qs_player_trade_record_entries` SET `event_id` = '%i', " - "`from_id` = '%i', `from_slot` = '%i', `to_id` = '%i', `to_slot` = '%i', " - "`item_id` = '%i', `charges` = '%i', `aug_1` = '%i', `aug_2` = '%i', " - "`aug_3` = '%i', `aug_4` = '%i', `aug_5` = '%i'", - lastIndex, QS->items[i].from_id, QS->items[i].from_slot, - QS->items[i].to_id, QS->items[i].to_slot, QS->items[i].item_id, - QS->items[i].charges, QS->items[i].aug_1, QS->items[i].aug_2, - QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5); - results = QueryDatabase(query); - if(!results.Success()) { - Log.Out(Logs::Detail, Logs::QS_Server, "Failed Trade Log Record Entry Insert: %s", results.ErrorMessage().c_str()); - Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); - } - - } - -} - -void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 detailCount) { - - std::string query = StringFormat("INSERT INTO `qs_player_handin_record` SET `time` = NOW(), " - "`quest_id` = '%i', `char_id` = '%i', `char_pp` = '%i', " - "`char_gp` = '%i', `char_sp` = '%i', `char_cp` = '%i', " - "`char_items` = '%i', `npc_id` = '%i', `npc_pp` = '%i', " - "`npc_gp` = '%i', `npc_sp` = '%i', `npc_cp` = '%i', " - "`npc_items`='%i'", - QS->quest_id, QS->char_id, QS->char_money.platinum, - QS->char_money.gold, QS->char_money.silver, QS->char_money.copper, - QS->char_count, QS->npc_id, QS->npc_money.platinum, - QS->npc_money.gold, QS->npc_money.silver, QS->npc_money.copper, - QS->npc_count); - auto results = QueryDatabase(query); - if(!results.Success()) { - Log.Out(Logs::Detail, Logs::QS_Server, "Failed Handin Log Record Insert: %s", results.ErrorMessage().c_str()); - Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); - } - - if(detailCount == 0) - return; - - int lastIndex = results.LastInsertedID(); - - for(int i = 0; i < detailCount; i++) { - query = StringFormat("INSERT INTO `qs_player_handin_record_entries` SET `event_id` = '%i', " - "`action_type` = '%s', `char_slot` = '%i', `item_id` = '%i', " - "`charges` = '%i', `aug_1` = '%i', `aug_2` = '%i', `aug_3` = '%i', " - "`aug_4` = '%i', `aug_5` = '%i'", - lastIndex, QS->items[i].action_type, QS->items[i].char_slot, - QS->items[i].item_id, QS->items[i].charges, QS->items[i].aug_1, - QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, - QS->items[i].aug_5); - if(!results.Success()) { - Log.Out(Logs::Detail, Logs::QS_Server, "Failed Handin Log Record Entry Insert: %s", results.ErrorMessage().c_str()); - Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); - } - } - -} - -void Database::LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 members){ - - std::string query = StringFormat("INSERT INTO `qs_player_npc_kill_record` " - "SET `npc_id` = '%i', `type` = '%i', " - "`zone_id` = '%i', `time` = NOW()", - QS->s1.NPCID, QS->s1.Type, QS->s1.ZoneID); - auto results = QueryDatabase(query); - if(!results.Success()) { - Log.Out(Logs::Detail, Logs::QS_Server, "Failed NPC Kill Log Record Insert: %s", results.ErrorMessage().c_str()); - Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); - } - - if(members == 0) - return; - - int lastIndex = results.LastInsertedID(); - - for (int i = 0; i < members; i++) { - query = StringFormat("INSERT INTO `qs_player_npc_kill_record_entries` " - "SET `event_id` = '%i', `char_id` = '%i'", - lastIndex, QS->Chars[i].char_id); - auto results = QueryDatabase(query); - if(!results.Success()) { - Log.Out(Logs::Detail, Logs::QS_Server, "Failed NPC Kill Log Entry Insert: %s", results.ErrorMessage().c_str()); - Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); - } - - } - -} - -void Database::LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 items) { - - std::string query = StringFormat("INSERT INTO `qs_player_delete_record` SET `time` = NOW(), " - "`char_id` = '%i', `stack_size` = '%i', `char_items` = '%i'", - QS->char_id, QS->stack_size, QS->char_count, QS->char_count); - auto results = QueryDatabase(query); - if(!results.Success()) { - Log.Out(Logs::Detail, Logs::QS_Server, "Failed Delete Log Record Insert: %s", results.ErrorMessage().c_str()); - Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); - } - - if(items == 0) - return; - - int lastIndex = results.LastInsertedID(); - - for(int i = 0; i < items; i++) { - query = StringFormat("INSERT INTO `qs_player_delete_record_entries` SET `event_id` = '%i', " - "`char_slot` = '%i', `item_id` = '%i', `charges` = '%i', `aug_1` = '%i', " - "`aug_2` = '%i', `aug_3` = '%i', `aug_4` = '%i', `aug_5` = '%i'", - lastIndex, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges, - QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, - QS->items[i].aug_5); - results = QueryDatabase(query); - if(!results.Success()) { - Log.Out(Logs::Detail, Logs::QS_Server, "Failed Delete Log Record Entry Insert: %s", results.ErrorMessage().c_str()); - Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); - } - - } - -} - -void Database::LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 items) { - /* These are item moves */ - - std::string query = StringFormat("INSERT INTO `qs_player_move_record` SET `time` = NOW(), " - "`char_id` = '%i', `from_slot` = '%i', `to_slot` = '%i', " - "`stack_size` = '%i', `char_items` = '%i', `postaction` = '%i'", - QS->char_id, QS->from_slot, QS->to_slot, QS->stack_size, - QS->char_count, QS->postaction); - auto results = QueryDatabase(query); - if(!results.Success()) { - Log.Out(Logs::Detail, Logs::QS_Server, "Failed Move Log Record Insert: %s", results.ErrorMessage().c_str()); - Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); - } - - if(items == 0) - return; - - int lastIndex = results.LastInsertedID(); - - for(int i = 0; i < items; i++) { - query = StringFormat("INSERT INTO `qs_player_move_record_entries` SET `event_id` = '%i', " - "`from_slot` = '%i', `to_slot` = '%i', `item_id` = '%i', `charges` = '%i', " - "`aug_1` = '%i', `aug_2` = '%i', `aug_3` = '%i', `aug_4` = '%i', `aug_5` = '%i'", - lastIndex, QS->items[i].from_slot, QS->items[i].to_slot, QS->items[i].item_id, - QS->items[i].charges, QS->items[i].aug_1, QS->items[i].aug_2, - QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5); - results = QueryDatabase(query); - if(!results.Success()) { - Log.Out(Logs::Detail, Logs::QS_Server, "Failed Move Log Record Entry Insert: %s", results.ErrorMessage().c_str()); - Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); - } - - } - -} - -void Database::LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 items) { - /* Merchant transactions are from the perspective of the merchant, not the player */ - std::string query = StringFormat("INSERT INTO `qs_merchant_transaction_record` SET `time` = NOW(), " - "`zone_id` = '%i', `merchant_id` = '%i', `merchant_pp` = '%i', " - "`merchant_gp` = '%i', `merchant_sp` = '%i', `merchant_cp` = '%i', " - "`merchant_items` = '%i', `char_id` = '%i', `char_pp` = '%i', " - "`char_gp` = '%i', `char_sp` = '%i', `char_cp` = '%i', " - "`char_items` = '%i'", - QS->zone_id, QS->merchant_id, QS->merchant_money.platinum, - QS->merchant_money.gold, QS->merchant_money.silver, - QS->merchant_money.copper, QS->merchant_count, QS->char_id, - QS->char_money.platinum, QS->char_money.gold, QS->char_money.silver, - QS->char_money.copper, QS->char_count); - auto results = QueryDatabase(query); - if(!results.Success()) { - Log.Out(Logs::Detail, Logs::QS_Server, "Failed Transaction Log Record Insert: %s", results.ErrorMessage().c_str()); - Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); - } - - if(items == 0) - return; - - int lastIndex = results.LastInsertedID(); - - for(int i = 0; i < items; i++) { - query = StringFormat("INSERT INTO `qs_merchant_transaction_record_entries` SET `event_id` = '%i', " - "`char_slot` = '%i', `item_id` = '%i', `charges` = '%i', `aug_1` = '%i', " - "`aug_2` = '%i', `aug_3` = '%i', `aug_4` = '%i', `aug_5` = '%i'", - lastIndex, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges, - QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, - QS->items[i].aug_5); - results = QueryDatabase(query); - if(!results.Success()) { - Log.Out(Logs::Detail, Logs::QS_Server, "Failed Transaction Log Record Entry Insert: %s", results.ErrorMessage().c_str()); - Log.Out(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); - } - - } - -} - void Database::GeneralQueryReceive(ServerPacket *pack) { /* These are general queries passed from anywhere in zone instead of packing structures and breaking them down again and again diff --git a/queryserv/database.h b/queryserv/database.h index b2d32341b..02448b6ef 100644 --- a/queryserv/database.h +++ b/queryserv/database.h @@ -44,12 +44,6 @@ public: ~Database(); void AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type); - void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 DetailCount); - void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 DetailCount); - void LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members); - void LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items); - void LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items); - void LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 Items); void GeneralQueryReceive(ServerPacket *pack); void LoadLogSettings(EQEmuLogSys::LogSettings* log_settings); diff --git a/queryserv/worldserver.cpp b/queryserv/worldserver.cpp index 2d2f288a4..914a63708 100644 --- a/queryserv/worldserver.cpp +++ b/queryserv/worldserver.cpp @@ -81,41 +81,6 @@ void WorldServer::Process() database.AddSpeech(tmp1.c_str(), tmp2.c_str(), SSS->message, SSS->minstatus, SSS->guilddbid, SSS->type); break; } - case ServerOP_QSPlayerLogTrades: { - QSPlayerLogTrade_Struct *QS = (QSPlayerLogTrade_Struct*)pack->pBuffer; - database.LogPlayerTrade(QS, QS->_detail_count); - break; - } - case ServerOP_QSPlayerLogHandins: { - QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct*)pack->pBuffer; - database.LogPlayerHandin(QS, QS->_detail_count); - break; - } - case ServerOP_QSPlayerLogNPCKills: { - QSPlayerLogNPCKill_Struct *QS = (QSPlayerLogNPCKill_Struct*)pack->pBuffer; - uint32 Members = pack->size - sizeof(QSPlayerLogNPCKill_Struct); - if (Members > 0) Members = Members / sizeof(QSPlayerLogNPCKillsPlayers_Struct); - database.LogPlayerNPCKill(QS, Members); - break; - } - case ServerOP_QSPlayerLogDeletes: { - QSPlayerLogDelete_Struct *QS = (QSPlayerLogDelete_Struct*)pack->pBuffer; - uint32 Items = QS->char_count; - database.LogPlayerDelete(QS, Items); - break; - } - case ServerOP_QSPlayerLogMoves: { - QSPlayerLogMove_Struct *QS = (QSPlayerLogMove_Struct*)pack->pBuffer; - uint32 Items = QS->char_count; - database.LogPlayerMove(QS, Items); - break; - } - case ServerOP_QSPlayerLogMerchantTransactions: { - QSMerchantLogTransaction_Struct *QS = (QSMerchantLogTransaction_Struct*)pack->pBuffer; - uint32 Items = QS->char_count + QS->merchant_count; - database.LogMerchantTransaction(QS, Items); - break; - } case ServerOP_QueryServGeneric: { /* The purpose of ServerOP_QueryServerGeneric is so that we don't have to add code to world just to relay packets diff --git a/tests/inventory_test.h b/tests/inventory_test.h index 11ff2acd0..da3f4892d 100644 --- a/tests/inventory_test.h +++ b/tests/inventory_test.h @@ -147,10 +147,10 @@ private: void InitInventory() { - std::shared_ptr m_bag(new EQEmu::ItemInstance(&container)); - std::shared_ptr m_armor(new EQEmu::ItemInstance(&armor)); - std::shared_ptr m_augment(new EQEmu::ItemInstance(&augment)); - std::shared_ptr m_stackable(new EQEmu::ItemInstance(&stackable, 100)); + EQEmu::ItemInstance::pointer m_bag(new EQEmu::ItemInstance(&container)); + EQEmu::ItemInstance::pointer m_armor(new EQEmu::ItemInstance(&armor)); + EQEmu::ItemInstance::pointer m_augment(new EQEmu::ItemInstance(&augment)); + EQEmu::ItemInstance::pointer m_stackable(new EQEmu::ItemInstance(&stackable, 100)); inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1), m_bag); inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 0), m_armor); inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, 1), m_augment); @@ -294,7 +294,7 @@ private: } void InventorySplitStackToCursor2() { - std::shared_ptr m_stackable_i(new EQEmu::ItemInstance(&stackable, 10)); + EQEmu::ItemInstance::pointer m_stackable_i(new EQEmu::ItemInstance(&stackable, 10)); inv.Put(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 8), m_stackable_i); auto swap_result = inv.Swap(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral2, 8), diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 17cac7f62..42574bb09 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -1268,15 +1268,8 @@ bool ZoneServer::Process() { UCSLink.SendPacket(pack); break; } - case ServerOP_QSSendQuery: case ServerOP_QueryServGeneric: case ServerOP_Speech: - case ServerOP_QSPlayerLogTrades: - case ServerOP_QSPlayerLogHandins: - case ServerOP_QSPlayerLogNPCKills: - case ServerOP_QSPlayerLogDeletes: - case ServerOP_QSPlayerLogMoves: - case ServerOP_QSPlayerLogMerchantTransactions: { QSLink.SendPacket(pack); break; diff --git a/zone/aa.cpp b/zone/aa.cpp index 51872cce2..ce0ad5477 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -1035,24 +1035,12 @@ void Client::BuyAA(AA_Action* action) */ /* Initial purchase of an AA ability */ - if (cur_level < 1){ + if (cur_level < 1) { Message(15, "You have gained the ability \"%s\" at a cost of %d ability %s.", aa2->name, real_cost, (real_cost>1) ? "points" : "point"); - - /* QS: Player_Log_AA_Purchases */ - if (RuleB(QueryServ, PlayerLogAAPurchases)){ - std::string event_desc = StringFormat("Initial AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc); - } } /* Ranked purchase of an AA ability */ else{ Message(15, "You have improved %s %d at a cost of %d ability %s.", aa2->name, cur_level + 1, real_cost, (real_cost > 1) ? "points" : "point"); - - /* QS: Player_Log_AA_Purchases */ - if (RuleB(QueryServ, PlayerLogAAPurchases)){ - std::string event_desc = StringFormat("Ranked AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc); - } } SendAAStats(); diff --git a/zone/attack.cpp b/zone/attack.cpp index 95cf1a376..32c3d74e0 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1706,14 +1706,6 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att GoToDeath(); } - /* QS: PlayerLogDeaths */ - if (RuleB(QueryServ, PlayerLogDeaths)){ - const char * killer_name = ""; - if (killerMob && killerMob->GetCleanName()){ killer_name = killerMob->GetCleanName(); } - std::string event_desc = StringFormat("Died in zoneid:%i instid:%i by '%s', spellid:%i, damage:%i", this->GetZoneID(), this->GetInstanceID(), killer_name, spell, damage); - QServ->PlayerLogEvent(Player_Log_Deaths, this->CharacterID(), event_desc); - } - parse->EventPlayer(EVENT_DEATH_COMPLETE, this, buffer, 0); return true; } @@ -2180,27 +2172,6 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack PlayerCount++; } } - - // QueryServ Logging - Raid Kills - if(RuleB(QueryServ, PlayerLogNPCKills)){ - ServerPacket* pack = new ServerPacket(ServerOP_QSPlayerLogNPCKills, sizeof(QSPlayerLogNPCKill_Struct) + (sizeof(QSPlayerLogNPCKillsPlayers_Struct) * PlayerCount)); - PlayerCount = 0; - QSPlayerLogNPCKill_Struct* QS = (QSPlayerLogNPCKill_Struct*) pack->pBuffer; - QS->s1.NPCID = this->GetNPCTypeID(); - QS->s1.ZoneID = this->GetZoneID(); - QS->s1.Type = 2; // Raid Fight - for (int i = 0; i < MAX_RAID_MEMBERS; i++) { - if (kr->members[i].member != nullptr && kr->members[i].member->IsClient()) { // If Group Member is Client - Client *c = kr->members[i].member; - QS->Chars[PlayerCount].char_id = c->CharacterID(); - PlayerCount++; - } - } - worldserver.SendPacket(pack); // Send Packet to World - safe_delete(pack); - } - // End QueryServ Logging - } else if (give_exp_client->IsGrouped() && kg != nullptr) { @@ -2227,26 +2198,6 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack PlayerCount++; } } - - // QueryServ Logging - Group Kills - if(RuleB(QueryServ, PlayerLogNPCKills)){ - ServerPacket* pack = new ServerPacket(ServerOP_QSPlayerLogNPCKills, sizeof(QSPlayerLogNPCKill_Struct) + (sizeof(QSPlayerLogNPCKillsPlayers_Struct) * PlayerCount)); - PlayerCount = 0; - QSPlayerLogNPCKill_Struct* QS = (QSPlayerLogNPCKill_Struct*) pack->pBuffer; - QS->s1.NPCID = this->GetNPCTypeID(); - QS->s1.ZoneID = this->GetZoneID(); - QS->s1.Type = 1; // Group Fight - for (int i = 0; i < MAX_GROUP_MEMBERS; i++) { - if (kg->members[i] != nullptr && kg->members[i]->IsClient()) { // If Group Member is Client - Client *c = kg->members[i]->CastToClient(); - QS->Chars[PlayerCount].char_id = c->CharacterID(); - PlayerCount++; - } - } - worldserver.SendPacket(pack); // Send Packet to World - safe_delete(pack); - } - // End QueryServ Logging } else { @@ -2273,21 +2224,6 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack if(RuleB(TaskSystem, EnableTaskSystem)) give_exp_client->UpdateTasksOnKill(GetNPCTypeID()); - - // QueryServ Logging - Solo - if(RuleB(QueryServ, PlayerLogNPCKills)){ - ServerPacket* pack = new ServerPacket(ServerOP_QSPlayerLogNPCKills, sizeof(QSPlayerLogNPCKill_Struct) + (sizeof(QSPlayerLogNPCKillsPlayers_Struct) * 1)); - QSPlayerLogNPCKill_Struct* QS = (QSPlayerLogNPCKill_Struct*) pack->pBuffer; - QS->s1.NPCID = this->GetNPCTypeID(); - QS->s1.ZoneID = this->GetZoneID(); - QS->s1.Type = 0; // Solo Fight - Client *c = give_exp_client; - QS->Chars[0].char_id = c->CharacterID(); - PlayerCount++; - worldserver.SendPacket(pack); // Send Packet to World - safe_delete(pack); - } - // End QueryServ Logging } } diff --git a/zone/client.cpp b/zone/client.cpp index 0274ba6d6..96b53647f 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2113,79 +2113,18 @@ bool Client::TakeMoneyFromPP(uint64 copper, bool updateclient) { } } -void Client::AddMoneyToPP(uint64 copper, bool updateclient){ - uint64 tmp; - uint64 tmp2; - tmp = copper; +void Client::AddMoneyToPP(uint64 copper, bool updateclient) { - /* Add Amount of Platinum */ - tmp2 = tmp/1000; - int32 new_val = m_pp.platinum + tmp2; - if(new_val < 0) { m_pp.platinum = 0; } - else { m_pp.platinum = m_pp.platinum + tmp2; } - tmp-=tmp2*1000; - - //if (updateclient) - // SendClientMoneyUpdate(3,tmp2); - - /* Add Amount of Gold */ - tmp2 = tmp/100; - new_val = m_pp.gold + tmp2; - if(new_val < 0) { m_pp.gold = 0; } - else { m_pp.gold = m_pp.gold + tmp2; } - - tmp-=tmp2*100; - //if (updateclient) - // SendClientMoneyUpdate(2,tmp2); - - /* Add Amount of Silver */ - tmp2 = tmp/10; - new_val = m_pp.silver + tmp2; - if(new_val < 0) { - m_pp.silver = 0; - } else { - m_pp.silver = m_pp.silver + tmp2; - } - tmp-=tmp2*10; - //if (updateclient) - // SendClientMoneyUpdate(1,tmp2); - - // Add Copper - //tmp = tmp - (tmp2* 10); - //if (updateclient) - // SendClientMoneyUpdate(0,tmp); - tmp2 = tmp; - new_val = m_pp.copper + tmp2; - if(new_val < 0) { - m_pp.copper = 0; - } else { - m_pp.copper = m_pp.copper + tmp2; - } - - - //send them all at once, since the above code stopped working. - if(updateclient) - SendMoneyUpdate(); - - RecalcWeight(); - - SaveCurrency(); - - Log.Out(Logs::General, Logs::None, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i", GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper); + uint64 plat = copper / 1000; + copper -= plat * 1000; + uint64 gold = copper / 100; + copper -= gold * 100; + uint64 silver = copper / 10; + copper -= silver * 10; + AddMoneyToPP(copper, silver, gold, plat, updateclient); } -void Client::ItemScriptStopReturn(){ - /* Set a timestamp in an entity variable for plugin check_handin.pl in return_items - This will stopgap players from items being returned if global_npc.pl has a catch all return_items - */ - struct timeval read_time; - char buffer[50]; - gettimeofday(&read_time, 0); - sprintf(buffer, "%li.%li \n", read_time.tv_sec, read_time.tv_usec); - SetEntityVariable("Stop_Return", buffer); -} - -void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool updateclient){ +void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool updateclient) { ItemScriptStopReturn(); int32 new_value = m_pp.platinum + platinum; @@ -2209,11 +2148,17 @@ void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 plat RecalcWeight(); SaveCurrency(); +} -#if (EQDEBUG>=5) - Log.Out(Logs::General, Logs::None, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i", - GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper); -#endif +void Client::ItemScriptStopReturn() { + /* Set a timestamp in an entity variable for plugin check_handin.pl in return_items + This will stopgap players from items being returned if global_npc.pl has a catch all return_items + */ + struct timeval read_time; + char buffer[50]; + gettimeofday(&read_time, 0); + sprintf(buffer, "%li.%li \n", read_time.tv_sec, read_time.tv_usec); + SetEntityVariable("Stop_Return", buffer); } void Client::SendMoneyUpdate() { @@ -2517,31 +2462,32 @@ void Client::SetFeigned(bool in_feigned) { void Client::LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const ItemData* item, bool buying) { - if(!player || !merchant || !item) - return; - - std::string LogText = "Qty: "; - - char Buffer[255]; - memset(Buffer, 0, sizeof(Buffer)); - - snprintf(Buffer, sizeof(Buffer)-1, "%3i", quantity); - LogText += Buffer; - snprintf(Buffer, sizeof(Buffer)-1, "%10i", price); - LogText += " TotalValue: "; - LogText += Buffer; - snprintf(Buffer, sizeof(Buffer)-1, " ItemID: %7i", item->ID); - LogText += Buffer; - LogText += " "; - snprintf(Buffer, sizeof(Buffer)-1, " %s", item->Name); - LogText += Buffer; - - if (buying==true) { - database.logevents(player->AccountName(),player->AccountID(),player->admin,player->GetName(),merchant->GetName(),"Buying from Merchant",LogText.c_str(),2); - } - else { - database.logevents(player->AccountName(),player->AccountID(),player->admin,player->GetName(),merchant->GetName(),"Selling to Merchant",LogText.c_str(),3); - } + //Inv2 redo or remove + //if(!player || !merchant || !item) + // return; + // + //std::string LogText = "Qty: "; + // + //char Buffer[255]; + //memset(Buffer, 0, sizeof(Buffer)); + // + //snprintf(Buffer, sizeof(Buffer)-1, "%3i", quantity); + //LogText += Buffer; + //snprintf(Buffer, sizeof(Buffer)-1, "%10i", price); + //LogText += " TotalValue: "; + //LogText += Buffer; + //snprintf(Buffer, sizeof(Buffer)-1, " ItemID: %7i", item->ID); + //LogText += Buffer; + //LogText += " "; + //snprintf(Buffer, sizeof(Buffer)-1, " %s", item->Name); + //LogText += Buffer; + // + //if (buying==true) { + // database.logevents(player->AccountName(),player->AccountID(),player->admin,player->GetName(),merchant->GetName(),"Buying from Merchant",LogText.c_str(),2); + //} + //else { + // database.logevents(player->AccountName(),player->AccountID(),player->admin,player->GetName(),merchant->GetName(),"Selling to Merchant",LogText.c_str(),3); + //} } bool Client::BindWound(Mob* bindmob, bool start, bool fail){ @@ -6922,11 +6868,7 @@ void Client::AddAlternateCurrencyValue(uint32 currency_id, int32 amount, int8 me /* Added via Quest, rest of the logging methods may be done inline due to information available in that area of the code */ if (method == 1){ - /* QS: PlayerLogAlternateCurrencyTransactions :: Cursor to Item Storage */ - if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){ - std::string event_desc = StringFormat("Added via Quest :: Cursor to Item :: alt_currency_id:%i amount:%i in zoneid:%i instid:%i", currency_id, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc); - } + } if(amount == 0) { diff --git a/zone/client.h b/zone/client.h index f9a43aa2d..55c8ee07c 100644 --- a/zone/client.h +++ b/zone/client.h @@ -245,8 +245,6 @@ public: virtual bool IsClient() const { return true; } void CompleteConnect(); bool TryStacking(ItemInst* item, uint8 type = ItemPacketTrade, bool try_worn = true, bool try_cursor = true); - bool TryStacking(std::shared_ptr item, uint8 type = ItemPacketTrade, bool try_worn = true, bool try_cursor = true); - bool TryStacking(std::shared_ptr item, const EQEmu::InventorySlot &slot, uint8 type = ItemPacketTrade); void SendTraderPacket(Client* trader, uint32 Unknown72 = 51); void SendBuyerPacket(Client* Buyer); GetItems_Struct* GetTraderItems(); @@ -818,7 +816,6 @@ public: void DeleteItemInInventory(int16 slot_id, int8 quantity = 0, bool client_update = false, bool update_db = true); bool SwapItem(MoveItemOld_Struct* move_in); void SwapItemResync(MoveItemOld_Struct* move_slots); - void QSSwapItemAuditor(MoveItemOld_Struct* move_in, bool postaction_call = false); 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 SummonItem(uint32 item_id, int16 charges = -1, @@ -844,7 +841,10 @@ public: uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0); - bool PutItemInInventory(const EQEmu::InventorySlot &slot, std::shared_ptr inst, bool client_update = false); + bool PutItemInInventory(const EQEmu::InventorySlot &slot, EQEmu::ItemInstance::pointer &inst, bool client_update = false); + bool CanPutItemInInventory(EQEmu::ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end); + void StackItem(EQEmu::ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end, bool client_update); + void PutItemInInventory(EQEmu::ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end, bool client_update); // // class Client::TextLink @@ -902,7 +902,7 @@ public: bool IsBankSlot(uint32 slot); //inv2 - void SendItemPacket(const EQEmu::InventorySlot &slot, std::shared_ptr inst, ItemPacketType packet_type); + void SendItemPacket(const EQEmu::InventorySlot &slot, EQEmu::ItemInstance::pointer &inst, ItemPacketType packet_type); inline bool IsTrader() const { return(Trader); } inline bool IsBuyer() const { return(Buyer); } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 829612a12..8666218d9 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -783,11 +783,6 @@ void Client::CompleteConnect() /* This sub event is for if a player logs in for the first time since entering world. */ if (firstlogon == 1){ parse->EventPlayer(EVENT_CONNECT, this, "", 0); - /* QS: PlayerLogConnectDisconnect */ - if (RuleB(QueryServ, PlayerLogConnectDisconnect)){ - std::string event_desc = StringFormat("Connect :: Logged into zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Connect_State, this->CharacterID(), event_desc); - } } if (zone) { @@ -2585,12 +2580,6 @@ void Client::Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app) return; } - /* QS: PlayerLogAlternateCurrencyTransactions :: Merchant Purchase */ - if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){ - std::string event_desc = StringFormat("Merchant Purchase :: Spent alt_currency_id:%i cost:%i for itemid:%i in zoneid:%i instid:%i", alt_cur_id, cost, item->ID, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc); - } - AddAlternateCurrencyValue(alt_cur_id, -((int32)cost)); int16 charges = 1; if (item->MaxCharges != 0) @@ -2628,12 +2617,6 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app) uint32 removed = NukeItem(item_id, invWhereWorn | invWherePersonal | invWhereCursor); if (removed > 0) { AddAlternateCurrencyValue(reclaim->currency_id, removed); - - /* QS: PlayerLogAlternateCurrencyTransactions :: Item to Currency */ - if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){ - std::string event_desc = StringFormat("Reclaim :: Item to Currency :: alt_currency_id:%i amount:%i to currency tab in zoneid:%i instid:%i", reclaim->currency_id, removed, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc); - } } } /* Cursor to Item storage */ @@ -2652,11 +2635,6 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app) SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, 0, false, MainCursor); AddAlternateCurrencyValue(reclaim->currency_id, -((int32)reclaim->count)); } - /* QS: PlayerLogAlternateCurrencyTransactions :: Cursor to Item Storage */ - if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){ - std::string event_desc = StringFormat("Reclaim :: Cursor to Item :: alt_currency_id:%i amount:-%i in zoneid:%i instid:%i", reclaim->currency_id, reclaim->count, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc); - } } } @@ -2746,12 +2724,6 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app) sell->cost = cost; - /* QS: PlayerLogAlternateCurrencyTransactions :: Sold to Merchant*/ - if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){ - std::string event_desc = StringFormat("Sold to Merchant :: itemid:%u npcid:%u alt_currency_id:%u cost:%u in zoneid:%u instid:%i", item->ID, npc_id, alt_cur_id, cost, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc); - } - FastQueuePacket(&outapp); AddAlternateCurrencyValue(alt_cur_id, cost); Save(1); @@ -12000,22 +11972,23 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) return; } Merchant_Sell_Struct* mp = (Merchant_Sell_Struct*)app->pBuffer; - + int merchantid; bool tmpmer_used = false; Mob* tmp = entity_list.GetMob(mp->npcid); - + if (!tmp || !tmp->IsNPC() || tmp->GetClass() != MERCHANT) return; - - if (mp->quantity < 1) return; - + + if (mp->quantity < 1) + return; + //you have to be somewhat close to them to be properly using them if (DistanceSquared(m_Position, tmp->GetPosition()) > USE_NPC_RANGE2) return; - + merchantid = tmp->CastToNPC()->MerchantType; - + uint32 item_id = 0; std::list merlist = zone->merchanttable[merchantid]; std::list::const_iterator itr; @@ -12024,18 +11997,18 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) if (GetLevel() < ml.level_required) { continue; } - + int32 fac = tmp->GetPrimaryFaction(); if (fac != 0 && GetModCharacterFactionLevel(fac) < ml.faction_required) { continue; } - + if (mp->itemslot == ml.slot){ item_id = ml.item; break; } } - const ItemData* item = nullptr; + uint32 prevcharges = 0; if (item_id == 0) { //check to see if its on the temporary table std::list tmp_merlist = zone->tmpmerchanttable[tmp->GetNPCTypeID()]; @@ -12051,7 +12024,8 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) } } } - item = database.GetItem(item_id); + + const ItemData* item = database.GetItem(item_id); if (!item){ //error finding item, client didnt get the update packet for whatever reason, roleplay a tad Message(15, "%s tells you 'Sorry, that item is for display purposes only.' as they take the item off the shelf.", tmp->GetCleanName()); @@ -12065,11 +12039,13 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) safe_delete(delitempacket); return; } + if (m_inventory.CheckLoreConflict(item)) { Message(15, "You can only have one of a lore item."); return; } + if (tmpmer_used && (mp->quantity > prevcharges || item->MaxCharges > 1)) { if (prevcharges > item->MaxCharges && item->MaxCharges > 1) @@ -12077,88 +12053,75 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) else mp->quantity = prevcharges; } - + // Item's stackable, but the quantity they want to buy exceeds the max stackable quantity. if (item->Stackable && mp->quantity > item->StackSize) mp->quantity = item->StackSize; - + EQApplicationPacket* outapp = new EQApplicationPacket(OP_ShopPlayerBuy, sizeof(Merchant_Sell_Struct)); Merchant_Sell_Struct* mpo = (Merchant_Sell_Struct*)outapp->pBuffer; mpo->quantity = mp->quantity; mpo->playerid = mp->playerid; mpo->npcid = mp->npcid; mpo->itemslot = mp->itemslot; - + EQEmu::InventorySlot free_slot; - int16 charges = 0; + int charges = 0; if (item->Stackable || item->MaxCharges > 1) charges = mp->quantity; else charges = item->MaxCharges; - - auto inst = database.CreateItem(item->ID, charges); - + int SinglePrice = 0; if (RuleB(Merchant, UsePriceMod)) SinglePrice = (item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(tmp, false)); else SinglePrice = (item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate); - + if (item->MaxCharges > 1) mpo->price = SinglePrice; else mpo->price = SinglePrice * mp->quantity; - + if (mpo->price < 0) { safe_delete(outapp); return; } + + if(m_inventory.Get(EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor))) { + safe_delete(outapp); + return; + } + + auto inst = database.CreateItem(item->ID, charges); + + if(!CanPutItemInInventory(inst, EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, EQEmu::PersonalSlotGeneral10)) { + Message(13, "You do not have room for any more items."); + + QueuePacket(outapp); + safe_delete(outapp); + return; + } // this area needs some work..two inventory insertion check failure points // below do not return player's money..is this the intended behavior? - if (!TakeMoneyFromPP(mpo->price)) { - char *hacker_str = nullptr; - MakeAnyLenString(&hacker_str, "Vendor Cheat: attempted to buy %i of %i: %s that cost %d cp but only has %d pp %d gp %d sp %d cp\n", + std::string hacker_str = StringFormat("Vendor Cheat: attempted to buy %i of %i: %s that cost %d cp but only has %d pp %d gp %d sp %d cp\n", mpo->quantity, item->ID, item->Name, mpo->price, m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper); - database.SetMQDetectionFlag(AccountName(), GetName(), hacker_str, zone->GetShortName()); - safe_delete_array(hacker_str); + database.SetMQDetectionFlag(AccountName(), GetName(), hacker_str.c_str(), zone->GetShortName()); safe_delete(outapp); return; } - bool stacked = TryStacking(inst); - if(!stacked) { - free_slot = m_inventory.FindFreeSlot(false, true, item->Size); - } - - if(free_slot.IsCursor()) { - Message(13, "You do not have room for any more items."); - safe_delete(outapp); - return; - } - - if(!stacked && !free_slot.IsValid()) - { - Message(13, "You do not have room for any more items."); - safe_delete(outapp); - return; - } - - std::string packet; - if(!stacked && inst) { - PutItemInInventory(free_slot, inst); - SendItemPacket(free_slot, inst, ItemPacketTrade); - } - else if (!stacked){ - Log.Out(Logs::General, Logs::Error, "OP_ShopPlayerBuy: item->ItemClass Unknown! Type: %i", item->ItemClass); - } - QueuePacket(outapp); - if (inst && tmpmer_used){ + safe_delete(outapp); + + PutItemInInventory(inst, EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, EQEmu::PersonalSlotGeneral10, true); + + if (inst && tmpmer_used) { int32 new_charges = prevcharges - mp->quantity; zone->SaveTempItem(merchantid, tmp->GetNPCTypeID(), item_id, new_charges); if (new_charges <= 0){ @@ -12181,12 +12144,8 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) SendItemPacket(EQEmu::InventorySlot(EQEmu::InvTypeMerchant, mp->itemslot), inst, ItemPacketMerchant); } } - safe_delete(outapp); - - - if (RuleB(EventLog, RecordBuyFromMerchant)) - LogMerchant(this, tmp, mpo->quantity, mpo->price, item, true); + zone->LogEvent(EventLogItemBuy, this, StringFormat("Merc(%i) -> player %s(%i) %i charges for %ic", merchantid, item->Name, item->ID, mpo->quantity, mpo->price)); if ((RuleB(Character, EnableDiscoveredItems))) { if (!GetGM() && !IsDiscovered(item_id)) @@ -12288,38 +12247,38 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) } // start QS code - if (RuleB(QueryServ, PlayerLogMerchantTransactions)) { - ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogMerchantTransactions, sizeof(QSMerchantLogTransaction_Struct)+sizeof(QSTransactionItems_Struct)); - QSMerchantLogTransaction_Struct* qsaudit = (QSMerchantLogTransaction_Struct*)qspack->pBuffer; - - qsaudit->zone_id = zone->GetZoneID(); - qsaudit->merchant_id = vendor->CastToNPC()->MerchantType; - qsaudit->merchant_money.platinum = (price / 1000); - qsaudit->merchant_money.gold = (price / 100) % 10; - qsaudit->merchant_money.silver = (price / 10) % 10; - qsaudit->merchant_money.copper = price % 10; - qsaudit->merchant_count = 0; - qsaudit->char_id = character_id; - qsaudit->char_money.platinum = 0; - qsaudit->char_money.gold = 0; - qsaudit->char_money.silver = 0; - qsaudit->char_money.copper = 0; - qsaudit->char_count = 1; - - qsaudit->items[0].char_slot = mp->itemslot; - qsaudit->items[0].item_id = itemid; - qsaudit->items[0].charges = charges; - qsaudit->items[0].aug_1 = m_inv[mp->itemslot]->GetAugmentItemID(1); - qsaudit->items[0].aug_2 = m_inv[mp->itemslot]->GetAugmentItemID(2); - qsaudit->items[0].aug_3 = m_inv[mp->itemslot]->GetAugmentItemID(3); - qsaudit->items[0].aug_4 = m_inv[mp->itemslot]->GetAugmentItemID(4); - qsaudit->items[0].aug_5 = m_inv[mp->itemslot]->GetAugmentItemID(5); - - qspack->Deflate(); - if (worldserver.Connected()) { worldserver.SendPacket(qspack); } - safe_delete(qspack); - } - // end QS code + //if (RuleB(QueryServ, PlayerLogMerchantTransactions)) { + // ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogMerchantTransactions, sizeof(QSMerchantLogTransaction_Struct)+sizeof(QSTransactionItems_Struct)); + // QSMerchantLogTransaction_Struct* qsaudit = (QSMerchantLogTransaction_Struct*)qspack->pBuffer; + // + // qsaudit->zone_id = zone->GetZoneID(); + // qsaudit->merchant_id = vendor->CastToNPC()->MerchantType; + // qsaudit->merchant_money.platinum = (price / 1000); + // qsaudit->merchant_money.gold = (price / 100) % 10; + // qsaudit->merchant_money.silver = (price / 10) % 10; + // qsaudit->merchant_money.copper = price % 10; + // qsaudit->merchant_count = 0; + // qsaudit->char_id = character_id; + // qsaudit->char_money.platinum = 0; + // qsaudit->char_money.gold = 0; + // qsaudit->char_money.silver = 0; + // qsaudit->char_money.copper = 0; + // qsaudit->char_count = 1; + // + // qsaudit->items[0].char_slot = mp->itemslot; + // qsaudit->items[0].item_id = itemid; + // qsaudit->items[0].charges = charges; + // qsaudit->items[0].aug_1 = m_inv[mp->itemslot]->GetAugmentItemID(1); + // qsaudit->items[0].aug_2 = m_inv[mp->itemslot]->GetAugmentItemID(2); + // qsaudit->items[0].aug_3 = m_inv[mp->itemslot]->GetAugmentItemID(3); + // qsaudit->items[0].aug_4 = m_inv[mp->itemslot]->GetAugmentItemID(4); + // qsaudit->items[0].aug_5 = m_inv[mp->itemslot]->GetAugmentItemID(5); + // + // qspack->Deflate(); + // if (worldserver.Connected()) { worldserver.SendPacket(qspack); } + // safe_delete(qspack); + //} + //// end QS code // Now remove the item from the player, this happens regardless of outcome if (!inst->IsStackable()) @@ -13107,46 +13066,8 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) other->trade->LogTrade(); trade->LogTrade(); - // start QS code - if (RuleB(QueryServ, PlayerLogTrades)) { - QSPlayerLogTrade_Struct event_entry; - std::list event_details; - - memset(&event_entry, 0, sizeof(QSPlayerLogTrade_Struct)); - - // Perform actual trade - this->FinishTrade(other, true, &event_entry, &event_details); - other->FinishTrade(this, false, &event_entry, &event_details); - - event_entry._detail_count = event_details.size(); - - ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogTrades, sizeof(QSPlayerLogTrade_Struct)+(sizeof(QSTradeItems_Struct)* event_entry._detail_count)); - QSPlayerLogTrade_Struct* qs_buf = (QSPlayerLogTrade_Struct*)qs_pack->pBuffer; - - memcpy(qs_buf, &event_entry, sizeof(QSPlayerLogTrade_Struct)); - - int offset = 0; - - for (std::list::iterator iter = event_details.begin(); iter != event_details.end(); ++iter, ++offset) { - QSTradeItems_Struct* detail = reinterpret_cast(*iter); - qs_buf->items[offset] = *detail; - safe_delete(detail); - } - - event_details.clear(); - - qs_pack->Deflate(); - - if (worldserver.Connected()) - worldserver.SendPacket(qs_pack); - - safe_delete(qs_pack); - // end QS code - } - else { - this->FinishTrade(other); - other->FinishTrade(this); - } + this->FinishTrade(other); + other->FinishTrade(this); other->trade->Reset(); trade->Reset(); @@ -13163,42 +13084,7 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) QueuePacket(outapp); safe_delete(outapp); if (with->IsNPC()) { - // Audit trade to database for player trade stream - if (RuleB(QueryServ, PlayerLogHandins)) { - QSPlayerLogHandin_Struct event_entry; - std::list event_details; - - memset(&event_entry, 0, sizeof(QSPlayerLogHandin_Struct)); - - FinishTrade(with->CastToNPC(), false, &event_entry, &event_details); - - event_entry._detail_count = event_details.size(); - - ServerPacket* qs_pack = new ServerPacket(ServerOP_QSPlayerLogHandins, sizeof(QSPlayerLogHandin_Struct)+(sizeof(QSHandinItems_Struct)* event_entry._detail_count)); - QSPlayerLogHandin_Struct* qs_buf = (QSPlayerLogHandin_Struct*)qs_pack->pBuffer; - - memcpy(qs_buf, &event_entry, sizeof(QSPlayerLogHandin_Struct)); - - int offset = 0; - - for (std::list::iterator iter = event_details.begin(); iter != event_details.end(); ++iter, ++offset) { - QSHandinItems_Struct* detail = reinterpret_cast(*iter); - qs_buf->items[offset] = *detail; - safe_delete(detail); - } - - event_details.clear(); - - qs_pack->Deflate(); - - if (worldserver.Connected()) - worldserver.SendPacket(qs_pack); - - safe_delete(qs_pack); - } - else { - FinishTrade(with->CastToNPC()); - } + FinishTrade(with->CastToNPC()); } #ifdef BOTS // TODO: Log Bot trades diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 21bcdbceb..a0056852b 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -782,12 +782,6 @@ void Client::OnDisconnect(bool hard_disconnect) { MyRaid->MemberZoned(this); parse->EventPlayer(EVENT_DISCONNECT, this, "", 0); - - /* QS: PlayerLogConnectDisconnect */ - if (RuleB(QueryServ, PlayerLogConnectDisconnect)){ - std::string event_desc = StringFormat("Disconnect :: in zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Connect_State, this->CharacterID(), event_desc); - } } Mob *Other = trade->With(); diff --git a/zone/command.cpp b/zone/command.cpp index 7a351234a..5ed6e23a7 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -547,8 +547,6 @@ int command_realdispatch(Client *c, const char *message) { Seperator sep(message, ' ', 10, 100, true); // "three word argument" should be considered 1 arg - command_logcommand(c, message); - std::string cstr(sep.arg[0]+1); if(commandlist.count(cstr) != 1) { @@ -561,12 +559,6 @@ int command_realdispatch(Client *c, const char *message) return(-1); } - /* QS: Player_Log_Issued_Commands */ - if (RuleB(QueryServ, PlayerLogIssuedCommandes)){ - std::string event_desc = StringFormat("Issued command :: '%s' in zoneid:%i instid:%i", message, c->GetZoneID(), c->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Issued_Commands, c->CharacterID(), event_desc); - } - if(cur->access >= COMMANDS_LOGGING_MIN_STATUS) { Log.Out(Logs::General, Logs::Commands, "%s (%s) used command: %s (target=%s)", c->GetName(), c->AccountName(), message, c->GetTarget()?c->GetTarget()->GetName():"NONE"); } @@ -582,71 +574,6 @@ int command_realdispatch(Client *c, const char *message) } -void command_logcommand(Client *c, const char *message) -{ - int admin=c->Admin(); - - bool continueevents=false; - switch (zone->loglevelvar){ //catch failsafe - case 9: { // log only LeadGM - if ((admin>= 150) && (admin <200)) - continueevents=true; - break; - } - case 8: { // log only GM - if ((admin>= 100) && (admin <150)) - continueevents=true; - break; - } - case 1: { - if ((admin>= 200)) - continueevents=true; - break; - } - case 2: { - if ((admin>= 150)) - continueevents=true; - break; - } - case 3: { - if ((admin>= 100)) - continueevents=true; - break; - } - case 4: { - if ((admin>= 80)) - continueevents=true; - break; - } - case 5: { - if ((admin>= 20)) - continueevents=true; - break; - } - case 6: { - if ((admin>= 10)) - continueevents=true; - break; - } - case 7: { - continueevents=true; - break; - } - } - - if (continueevents) - database.logevents( - c->AccountName(), - c->AccountID(), - admin,c->GetName(), - c->GetTarget()?c->GetTarget()->GetName():"None", - "Command", - message, - 1 - ); -} - - /* * commands go below here */ diff --git a/zone/command.h b/zone/command.h index 0560b8eff..04e51866a 100644 --- a/zone/command.h +++ b/zone/command.h @@ -60,7 +60,6 @@ void command_deinit(void); int command_add(const char *command_string, const char *desc, int access, CmdFuncPtr function); int command_notavail(Client *c, const char *message); int command_realdispatch(Client *c, char const *message); -void command_logcommand(Client *c, const char *message); //commands void command_resetaa(Client* c,const Seperator *sep); diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 6db7777ac..de49b6040 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -3520,10 +3520,11 @@ XS(XS__qs_player_event) if (items != 2){ Perl_croak(aTHX_ "Usage: qs_player_event(char_id, event_desc)"); } - else{ + else { int char_id = (int)SvIV(ST(0)); std::string event_desc = (std::string)SvPV_nolen(ST(1)); - QServ->PlayerLogEvent(Player_Log_Quest, char_id, event_desc); + Client *c = entity_list.GetClientByCharID(char_id); + zone->LogEvent(EventLogQuest, c, event_desc); } XSRETURN_EMPTY; } diff --git a/zone/exp.cpp b/zone/exp.cpp index 2ddf1318b..0982aeac3 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -430,13 +430,6 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) { //Message(15, "You have gained %d skill points!!", m_pp.aapoints - last_unspentAA); char val1[20]={0}; Message_StringID(MT_Experience, GAIN_ABILITY_POINT,ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2. - - /* QS: PlayerLogAARate */ - if (RuleB(QueryServ, PlayerLogAARate)){ - int add_points = (m_pp.aapoints - last_unspentAA); - std::string query = StringFormat("INSERT INTO `qs_player_aa_rate_hourly` (char_id, aa_count, hour_time) VALUES (%i, %i, UNIX_TIMESTAMP() - MOD(UNIX_TIMESTAMP(), 3600)) ON DUPLICATE KEY UPDATE `aa_count` = `aa_count` + %i", this->CharacterID(), add_points, add_points); - QServ->SendQuery(query.c_str()); - } //Message(15, "You now have %d skill points available to spend.", m_pp.aapoints); } @@ -571,18 +564,6 @@ void Client::SetLevel(uint8 set_level, bool command) } if(set_level > m_pp.level) { parse->EventPlayer(EVENT_LEVEL_UP, this, "", 0); - /* QS: PlayerLogLevels */ - if (RuleB(QueryServ, PlayerLogLevels)){ - std::string event_desc = StringFormat("Leveled UP :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Levels, this->CharacterID(), event_desc); - } - } - else if (set_level < m_pp.level){ - /* QS: PlayerLogLevels */ - if (RuleB(QueryServ, PlayerLogLevels)){ - std::string event_desc = StringFormat("Leveled DOWN :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Levels, this->CharacterID(), event_desc); - } } m_pp.level = set_level; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index e1eec88cc..769c9285c 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -20,6 +20,7 @@ #include "../common/eqemu_logsys.h" #include "../common/string_util.h" #include "../common/data_verification.h" +#include "../common/item_data.h" #include "quest_parser_collection.h" #include "worldserver.h" #include "zonedb.h" @@ -981,47 +982,6 @@ bool Client::TryStacking(ItemInst* item, uint8 type, bool try_worn, bool try_cur return false; } -bool Client::TryStacking(std::shared_ptr item, uint8 type, bool try_worn, bool try_cursor) { - if(!item || !item->IsStackable() || item->GetCharges() >= item->GetItem()->StackSize) - return false; - - if(try_worn) { - for(int i = EQEmu::PersonalSlotCharm; i <= EQEmu::PersonalSlotAmmo; ++i) { - if(TryStacking(item, EQEmu::InventorySlot(EQEmu::InvTypePersonal, i), type)) { - return true; - } - } - } - - for(int i = EQEmu::PersonalSlotGeneral1; i <= EQEmu::PersonalSlotGeneral10; ++i) { - if(TryStacking(item, EQEmu::InventorySlot(EQEmu::InvTypePersonal, i), type)) { - return true; - } - } - - if(try_cursor) { - if(TryStacking(item, EQEmu::InventorySlot(EQEmu::InvTypePersonal, EQEmu::PersonalSlotCursor), type)) { - return true; - } - } - - return false; -} - -bool Client::TryStacking(std::shared_ptr item, const EQEmu::InventorySlot &slot, uint8 type) { - //make this a function - uint32 item_id = item->GetItem()->ID; - auto tmp_inst = m_inventory.Get(slot); - if(tmp_inst && tmp_inst->GetItem()->ID == item_id && tmp_inst->GetCharges() < tmp_inst->GetItem()->StackSize) { - bool v = m_inventory.TryStacking(item, slot); - if(v) { - SendItemPacket(slot, item, ItemPacketTrade); - } - } - - return item->GetCharges() == 0; -} - // Locate an available space in inventory to place an item // and then put the item there // The change will be saved to the database @@ -1416,7 +1376,7 @@ bool Client::SwapItem(MoveItemOld_Struct* move_in) { } if (move_in->from_slot == move_in->to_slot) { // Item summon, no further processing needed - if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit + if (GetClientVersion() >= ClientVersion::RoF) { return true; } // Can't do RoF+ if (move_in->to_slot == MainCursor) { @@ -1448,7 +1408,7 @@ bool Client::SwapItem(MoveItemOld_Struct* move_in) { if (move_in->to_slot == (uint32)INVALID_INDEX) { if (move_in->from_slot == (uint32)MainCursor) { Log.Out(Logs::Detail, Logs::Inventory, "Client destroyed item from cursor slot %d", move_in->from_slot); - if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit + ItemInst *inst = m_inv.GetItem(MainCursor); if(inst) { @@ -1462,7 +1422,7 @@ bool Client::SwapItem(MoveItemOld_Struct* move_in) { } else { Log.Out(Logs::Detail, Logs::Inventory, "Deleted item from slot %d as a result of an inventory container tradeskill combine.", move_in->from_slot); - if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit + DeleteItemInInventory(move_in->from_slot); return true; // Item deletion } @@ -1623,7 +1583,7 @@ bool Client::SwapItem(MoveItemOld_Struct* move_in) { safe_delete(inst); } - if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in, true); } // QS Audit + return true; } @@ -1693,7 +1653,7 @@ bool Client::SwapItem(MoveItemOld_Struct* move_in) { database.SaveInventory(character_id, m_inv[src_slot_id], src_slot_id); } - if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in, true); } // QS Audit + return true; } @@ -1715,7 +1675,7 @@ bool Client::SwapItem(MoveItemOld_Struct* move_in) { // Add cursor item to trade bucket // Also sends trade information to other client of trade session - if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit + trade->AddEntity(dst_slot_id, move_in->number_in_stack); if (dstitemid == 0) @@ -1725,7 +1685,7 @@ bool Client::SwapItem(MoveItemOld_Struct* move_in) { return true; } else { - if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit + SummonItem(src_inst->GetID(), src_inst->GetCharges(), 0); DeleteItemInInventory(MainCursor); @@ -1859,7 +1819,7 @@ bool Client::SwapItem(MoveItemOld_Struct* move_in) { database.SaveInventory(character_id, m_inv.GetItem(dst_slot_id), dst_slot_id); } - if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in, true); } // QS Audit + // Step 8: Re-calc stats CalcBonuses(); @@ -1960,104 +1920,6 @@ void Client::SwapItemResync(MoveItemOld_Struct* move_slots) { } } -void Client::QSSwapItemAuditor(MoveItemOld_Struct* move_in, bool postaction_call) { - int16 from_slot_id = static_cast(move_in->from_slot); - int16 to_slot_id = static_cast(move_in->to_slot); - int16 move_amount = static_cast(move_in->number_in_stack); - - if(!m_inv[from_slot_id] && !m_inv[to_slot_id]) { return; } - - uint16 move_count = 0; - - if(m_inv[from_slot_id]) { move_count += m_inv[from_slot_id]->GetTotalItemCount(); } - if(to_slot_id != from_slot_id) { if(m_inv[to_slot_id]) { move_count += m_inv[to_slot_id]->GetTotalItemCount(); } } - - ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogMoves, sizeof(QSPlayerLogMove_Struct) + (sizeof(QSMoveItems_Struct) * move_count)); - QSPlayerLogMove_Struct* qsaudit = (QSPlayerLogMove_Struct*)qspack->pBuffer; - - qsaudit->char_id = character_id; - qsaudit->stack_size = move_amount; - qsaudit->char_count = move_count; - qsaudit->postaction = postaction_call; - qsaudit->from_slot = from_slot_id; - qsaudit->to_slot = to_slot_id; - - move_count = 0; - - const ItemInst* from_inst = m_inv[postaction_call?to_slot_id:from_slot_id]; - - if(from_inst) { - qsaudit->items[move_count].from_slot = from_slot_id; - qsaudit->items[move_count].to_slot = to_slot_id; - qsaudit->items[move_count].item_id = from_inst->GetID(); - qsaudit->items[move_count].charges = from_inst->GetCharges(); - qsaudit->items[move_count].aug_1 = from_inst->GetAugmentItemID(1); - qsaudit->items[move_count].aug_2 = from_inst->GetAugmentItemID(2); - qsaudit->items[move_count].aug_3 = from_inst->GetAugmentItemID(3); - qsaudit->items[move_count].aug_4 = from_inst->GetAugmentItemID(4); - qsaudit->items[move_count++].aug_5 = from_inst->GetAugmentItemID(5); - - if(from_inst->IsType(ItemClassContainer)) { - for(uint8 bag_idx = SUB_BEGIN; bag_idx < from_inst->GetItem()->BagSlots; bag_idx++) { - const ItemInst* from_baginst = from_inst->GetItem(bag_idx); - - if(from_baginst) { - qsaudit->items[move_count].from_slot = InventoryOld::CalcSlotId(from_slot_id, bag_idx); - qsaudit->items[move_count].to_slot = InventoryOld::CalcSlotId(to_slot_id, bag_idx); - qsaudit->items[move_count].item_id = from_baginst->GetID(); - qsaudit->items[move_count].charges = from_baginst->GetCharges(); - qsaudit->items[move_count].aug_1 = from_baginst->GetAugmentItemID(1); - qsaudit->items[move_count].aug_2 = from_baginst->GetAugmentItemID(2); - qsaudit->items[move_count].aug_3 = from_baginst->GetAugmentItemID(3); - qsaudit->items[move_count].aug_4 = from_baginst->GetAugmentItemID(4); - qsaudit->items[move_count++].aug_5 = from_baginst->GetAugmentItemID(5); - } - } - } - } - - if(to_slot_id != from_slot_id) { - const ItemInst* to_inst = m_inv[postaction_call?from_slot_id:to_slot_id]; - - if(to_inst) { - qsaudit->items[move_count].from_slot = to_slot_id; - qsaudit->items[move_count].to_slot = from_slot_id; - qsaudit->items[move_count].item_id = to_inst->GetID(); - qsaudit->items[move_count].charges = to_inst->GetCharges(); - qsaudit->items[move_count].aug_1 = to_inst->GetAugmentItemID(1); - qsaudit->items[move_count].aug_2 = to_inst->GetAugmentItemID(2); - qsaudit->items[move_count].aug_3 = to_inst->GetAugmentItemID(3); - qsaudit->items[move_count].aug_4 = to_inst->GetAugmentItemID(4); - qsaudit->items[move_count++].aug_5 = to_inst->GetAugmentItemID(5); - - if(to_inst->IsType(ItemClassContainer)) { - for(uint8 bag_idx = SUB_BEGIN; bag_idx < to_inst->GetItem()->BagSlots; bag_idx++) { - const ItemInst* to_baginst = to_inst->GetItem(bag_idx); - - if(to_baginst) { - qsaudit->items[move_count].from_slot = InventoryOld::CalcSlotId(to_slot_id, bag_idx); - qsaudit->items[move_count].to_slot = InventoryOld::CalcSlotId(from_slot_id, bag_idx); - qsaudit->items[move_count].item_id = to_baginst->GetID(); - qsaudit->items[move_count].charges = to_baginst->GetCharges(); - qsaudit->items[move_count].aug_1 = to_baginst->GetAugmentItemID(1); - qsaudit->items[move_count].aug_2 = to_baginst->GetAugmentItemID(2); - qsaudit->items[move_count].aug_3 = to_baginst->GetAugmentItemID(3); - qsaudit->items[move_count].aug_4 = to_baginst->GetAugmentItemID(4); - qsaudit->items[move_count++].aug_5 = to_baginst->GetAugmentItemID(5); - } - } - } - } - } - - if(move_count && worldserver.Connected()) { - qspack->Deflate(); - worldserver.SendPacket(qspack); - } - - safe_delete(qspack); -} - void Client::DyeArmor(DyeStruct* dye){ int16 slot=0; for (int i = EmuConstants::MATERIAL_BEGIN; i <= EmuConstants::MATERIAL_TINT_END; i++) { @@ -2710,7 +2572,7 @@ void Client::SendItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType // FastQueuePacket(&outapp); } -void Client::SendItemPacket(const EQEmu::InventorySlot &slot, std::shared_ptr inst, ItemPacketType packet_type) { +void Client::SendItemPacket(const EQEmu::InventorySlot &slot, EQEmu::ItemInstance::pointer &inst, ItemPacketType packet_type) { if(!inst) { return; } @@ -3462,13 +3324,13 @@ bool Client::SummonItem(uint32 item_id, uint32 ornament_idfile, uint32 ornament_hero_model) { - std::shared_ptr inst = database.CreateItem(item_id, charges); + EQEmu::ItemInstance::pointer &inst = database.CreateItem(item_id, charges); if(!inst) return false; if(inst->GetBaseItem()->ItemClass == ItemClassCommon) { if(aug1) { - std::shared_ptr aug = database.CreateItem(aug1); + EQEmu::ItemInstance::pointer aug = database.CreateItem(aug1); if(!aug) return false; @@ -3478,7 +3340,7 @@ bool Client::SummonItem(uint32 item_id, } if(aug2) { - std::shared_ptr aug = database.CreateItem(aug2); + EQEmu::ItemInstance::pointer aug = database.CreateItem(aug2); if(!aug) return false; @@ -3488,7 +3350,7 @@ bool Client::SummonItem(uint32 item_id, } if(aug3) { - std::shared_ptr aug = database.CreateItem(aug3); + EQEmu::ItemInstance::pointer aug = database.CreateItem(aug3); if(!aug) return false; @@ -3498,7 +3360,7 @@ bool Client::SummonItem(uint32 item_id, } if(aug4) { - std::shared_ptr aug = database.CreateItem(aug4); + EQEmu::ItemInstance::pointer aug = database.CreateItem(aug4); if(!aug) return false; @@ -3508,7 +3370,7 @@ bool Client::SummonItem(uint32 item_id, } if(aug5) { - std::shared_ptr aug = database.CreateItem(aug5); + EQEmu::ItemInstance::pointer aug = database.CreateItem(aug5); if(!aug) return false; @@ -3518,7 +3380,7 @@ bool Client::SummonItem(uint32 item_id, } if(aug6) { - std::shared_ptr aug = database.CreateItem(aug6); + EQEmu::ItemInstance::pointer aug = database.CreateItem(aug6); if(!aug) return false; @@ -3536,7 +3398,7 @@ bool Client::SummonItem(uint32 item_id, return res; } -bool Client::PutItemInInventory(const EQEmu::InventorySlot &slot, std::shared_ptr inst, bool client_update) { +bool Client::PutItemInInventory(const EQEmu::InventorySlot &slot, EQEmu::ItemInstance::pointer &inst, bool client_update) { if(!inst) return false; @@ -3555,4 +3417,134 @@ bool Client::PutItemInInventory(const EQEmu::InventorySlot &slot, std::shared_pt } CalcBonuses(); + return true; +} + +bool Client::CanPutItemInInventory(EQEmu::ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end) { + if(inst->IsStackable()) { + int charges = m_inventory.FindFreeStackSlots(inst, EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, EQEmu::PersonalSlotGeneral10); + + if(charges < inst->GetCharges()) { + EQEmu::InventorySlot slot = m_inventory.FindFreeSlot(inst, container_id, slot_id_start, slot_id_end); + + if(!slot.IsValid()) { + return false; + } + } + } + else { + EQEmu::InventorySlot slot = m_inventory.FindFreeSlot(inst, container_id, slot_id_start, slot_id_end); + if(!slot.IsValid()) { + return false; + } + } + + return true; +} + +void Client::StackItem(EQEmu::ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end, bool client_update) { + auto item_id = inst->GetBaseItem()->ID; + + //not the most efficient of functions but in reality it's fast enough + + //go through the top level slots first + for(int i = slot_id_start; i < slot_id_end; ++i) { + EQEmu::InventorySlot slot(container_id, i); + auto item = m_inventory.Get(slot); + + if(!item) { + continue; + } + + if(item->GetBaseItem()->ID == item_id) { + auto free_charges = item->GetItem()->StackSize - item->GetCharges(); + + if(inst->GetCharges() > free_charges) { + item->SetCharges(item->GetCharges() + free_charges); + inst->SetCharges(inst->GetCharges() - free_charges); + + m_inventory.UpdateSlot(slot, item); + + if(client_update) { + SendItemPacket(slot, item, slot.IsCursor() ? ItemPacketSummonItem : ItemPacketTrade); + } + } else { + item->SetCharges(item->GetCharges() + inst->GetCharges()); + inst->SetCharges(0); + + m_inventory.UpdateSlot(slot, item); + if(client_update) { + SendItemPacket(slot, item, slot.IsCursor() ? ItemPacketSummonItem : ItemPacketTrade); + } + + return; + } + } + } + + //go through the top level slots bag slots + for(int i = slot_id_start; i < slot_id_end; ++i) { + EQEmu::InventorySlot slot(container_id, i); + auto item = m_inventory.Get(slot); + + if(!item) { + continue; + } + + if(item->GetBaseItem()->ItemClass != ItemClassContainer) { + continue; + } + + int sz = item->GetBaseItem()->BagSlots; + bool update_bag = false; + for(int j = 0; j < sz; ++j) { + auto sub_item = item->Get(j); + + if(!sub_item) { + continue; + } + + if(sub_item->GetBaseItem()->ID == item_id) { + EQEmu::InventorySlot bag_slot(container_id, i, j); + auto free_charges = sub_item->GetItem()->StackSize - sub_item->GetCharges(); + + if(inst->GetCharges() > free_charges) { + sub_item->SetCharges(sub_item->GetCharges() + free_charges); + inst->SetCharges(inst->GetCharges() - free_charges); + + m_inventory.UpdateSlot(bag_slot, sub_item); + update_bag = true; + } + else { + sub_item->SetCharges(sub_item->GetCharges() + inst->GetCharges()); + inst->SetCharges(0); + + m_inventory.UpdateSlot(bag_slot, sub_item); + if(client_update) { + SendItemPacket(slot, item, slot.IsCursor() ? ItemPacketSummonItem : ItemPacketTrade); + } + + return; + } + } + } + + if(update_bag && client_update) { + SendItemPacket(slot, item, slot.IsCursor() ? ItemPacketSummonItem : ItemPacketTrade); + } + } +} + +void Client::PutItemInInventory(EQEmu::ItemInstance::pointer &inst, int container_id, int slot_id_start, int slot_id_end, bool client_update) { + if(inst->IsStackable()) { + StackItem(inst, EQEmu::InvTypePersonal, EQEmu::PersonalSlotGeneral1, EQEmu::PersonalSlotGeneral10, client_update); + + if(inst->GetCharges() > 0) { + EQEmu::InventorySlot slot = m_inventory.FindFreeSlot(inst, container_id, slot_id_start, slot_id_end); + PutItemInInventory(slot, inst, client_update); + } + } else { + EQEmu::InventorySlot slot = m_inventory.FindFreeSlot(inst, container_id, slot_id_start, slot_id_end); + PutItemInInventory(slot, inst, client_update); + } } diff --git a/zone/queryserv.cpp b/zone/queryserv.cpp index d67ca46c7..b8960f89d 100644 --- a/zone/queryserv.cpp +++ b/zone/queryserv.cpp @@ -42,10 +42,3 @@ void QueryServ::SendQuery(std::string Query) safe_delete(pack); } -void QueryServ::PlayerLogEvent(int Event_Type, int Character_ID, std::string Event_Desc) -{ - std::string query = StringFormat( - "INSERT INTO `qs_player_events` (event, char_id, event_desc, time) VALUES (%i, %i, '%s', UNIX_TIMESTAMP(now()))", - Event_Type, Character_ID, EscapeString(Event_Desc).c_str()); - SendQuery(query); -} diff --git a/zone/queryserv.h b/zone/queryserv.h index 8aafcafda..b3732d2ba 100644 --- a/zone/queryserv.h +++ b/zone/queryserv.h @@ -29,7 +29,6 @@ class QueryServ{ QueryServ(); ~QueryServ(); void SendQuery(std::string Query); - void PlayerLogEvent(int Event_Type, int Character_ID, std::string Event_Desc); }; #endif /* QUERYSERV_ZONE_H */ \ No newline at end of file diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 5dba6f00a..6750195b7 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -1370,12 +1370,6 @@ void QuestManager::setglobal(const char *varname, const char *newvalue, int opti } InsertQuestGlobal(qgCharid, qgNpcid, qgZoneid, varname, newvalue, QGVarDuration(duration)); - - /* QS: PlayerLogQGlobalUpdate */ - if (RuleB(QueryServ, PlayerLogQGlobalUpdate) && qgCharid && qgCharid > 0 && initiator && initiator->IsClient()){ - std::string event_desc = StringFormat("Update :: qglobal:%s to qvalue:%s zoneid:%i instid:%i", varname, newvalue, initiator->GetZoneID(), initiator->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_QGlobal_Update, qgCharid, event_desc); - } } /* Inserts global variable into quest_globals table */ @@ -1462,12 +1456,6 @@ void QuestManager::delglobal(const char *varname) { else qgCharid=-qgNpcid; // make char id negative npc id as a fudge - /* QS: PlayerLogQGlobalUpdate */ - if (RuleB(QueryServ, PlayerLogQGlobalUpdate) && qgCharid && qgCharid > 0 && initiator && initiator->IsClient()){ - std::string event_desc = StringFormat("Deleted :: qglobal:%s zoneid:%i instid:%i", varname, initiator->GetZoneID(), initiator->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_QGlobal_Update, qgCharid, event_desc); - } - std::string query = StringFormat("DELETE FROM quest_globals " "WHERE name = '%s' " "&& (npcid=0 || npcid=%i) " diff --git a/zone/tasks.cpp b/zone/tasks.cpp index 96acb1487..f1c8c627a 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -1821,11 +1821,6 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T buf[23] = '\0'; parse->EventPlayer(EVENT_TASK_STAGE_COMPLETE, c, buf, 0); } - /* QS: PlayerLogTaskUpdates :: Update */ - if (RuleB(QueryServ, PlayerLogTaskUpdates)){ - std::string event_desc = StringFormat("Task Stage Complete :: taskid:%i activityid:%i donecount:%i in zoneid:%i instid:%i", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, c->GetZoneID(), c->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Task_Updates, c->CharacterID(), event_desc); - } } // If this task is now complete, the Completed tasks will have been @@ -1837,12 +1832,6 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T buf[23] = '\0'; parse->EventPlayer(EVENT_TASK_COMPLETE, c, buf, 0); - /* QS: PlayerLogTaskUpdates :: Complete */ - if (RuleB(QueryServ, PlayerLogTaskUpdates)){ - std::string event_desc = StringFormat("Task Complete :: taskid:%i activityid:%i donecount:%i in zoneid:%i instid:%i", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, c->GetZoneID(), c->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Task_Updates, c->CharacterID(), event_desc); - } - taskmanager->SendCompletedTasksToClient(c, this); c->SendTaskActivityComplete(ActiveTasks[TaskIndex].TaskID, 0, TaskIndex, false); taskmanager->SaveClientState(c, this); diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 37e4189bd..b9e946758 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -1091,12 +1091,6 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { entity_list.MessageGroup(this, true, MT_Skills, "%s has successfully fashioned %s!", GetName(), item->Name); } - /* QS: Player_Log_Trade_Skill_Events */ - if (RuleB(QueryServ, PlayerLogTradeSkillEvents)){ - std::string event_desc = StringFormat("Success :: fashioned recipe_id:%i tskillid:%i trivial:%i chance:%4.2f in zoneid:%i instid:%i", spec->recipe_id, spec->tradeskill, spec->trivial, chance, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Trade_Skill_Events, this->CharacterID(), event_desc); - } - if(RuleB(TaskSystem, EnableTaskSystem)) UpdateTasksForItem(ActivityTradeSkill, itr->first, itr->second); ++itr; @@ -1119,12 +1113,6 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { } - /* QS: Player_Log_Trade_Skill_Events */ - if (RuleB(QueryServ, PlayerLogTradeSkillEvents)){ - std::string event_desc = StringFormat("Failed :: recipe_id:%i tskillid:%i trivial:%i chance:%4.2f in zoneid:%i instid:%i", spec->recipe_id, spec->tradeskill, spec->trivial, chance, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Trade_Skill_Events, this->CharacterID(), event_desc); - } - itr = spec->onfail.begin(); while(itr != spec->onfail.end()) { //should we check these arguments? diff --git a/zone/trading.cpp b/zone/trading.cpp index 1948a3887..b1d5f8633 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -189,107 +189,107 @@ void Trade::SendItemData(const ItemInst* inst, int16 dest_slot_id) // Audit trade: The part logged is what travels owner -> with void Trade::LogTrade() { - Mob* with = With(); - if (!owner->IsClient() || !with) - return; // Should never happen - - Client* trader = owner->CastToClient(); - bool logtrade = false; - int admin_level = 0; - uint8 item_count = 0; - - if (zone->tradevar != 0) { - for (uint16 i = EmuConstants::TRADE_BEGIN; i <= EmuConstants::TRADE_END; i++) { - if (trader->GetInv().GetItem(i)) - item_count++; - } - - if (((this->cp + this->sp + this->gp + this->pp)>0) || (item_count>0)) - admin_level = trader->Admin(); - else - admin_level = 999; - - if (zone->tradevar == 7) { - logtrade = true; - } - else if ((admin_level>=10) && (admin_level<20)) { - if ((zone->tradevar<8) && (zone->tradevar>5)) - logtrade = true; - } - else if (admin_level<=20) { - if ((zone->tradevar<8) && (zone->tradevar>4)) - logtrade = true; - } - else if (admin_level<=80) { - if ((zone->tradevar<8) && (zone->tradevar>3)) - logtrade = true; - } - else if (admin_level<=100){ - if ((zone->tradevar<9) && (zone->tradevar>2)) - logtrade = true; - } - else if (admin_level<=150){ - if (((zone->tradevar<8) && (zone->tradevar>1)) || (zone->tradevar==9)) - logtrade = true; - } - else if (admin_level<=255){ - if ((zone->tradevar<8) && (zone->tradevar>0)) - logtrade = true; - } - } - - if (logtrade == true) { - char logtext[1000] = {0}; - uint32 cash = 0; - bool comma = false; - - // Log items offered by owner - cash = this->cp + this->sp + this->gp + this->pp; - if ((cash>0) || (item_count>0)) { - sprintf(logtext, "%s gave %s ", trader->GetName(), with->GetName()); - - if (item_count > 0) { - strcat(logtext, "items {"); - - for (uint16 i = EmuConstants::TRADE_BEGIN; i <= EmuConstants::TRADE_END; i++) { - const ItemInst* inst = trader->GetInv().GetItem(i); - - if (!comma) - comma = true; - else { - if (inst) - strcat(logtext, ","); - } - - if (inst) { - char item_num[15] = {0}; - sprintf(item_num, "%i", inst->GetItem()->ID); - strcat(logtext, item_num); - - if (inst->IsType(ItemClassContainer)) { - for (uint8 j = SUB_BEGIN; j < EmuConstants::ITEM_CONTAINER_SIZE; j++) { - inst = trader->GetInv().GetItem(i, j); - if (inst) { - strcat(logtext, ","); - sprintf(item_num, "%i", inst->GetItem()->ID); - strcat(logtext, item_num); - } - } - } - } - } - } - - if (cash > 0) { - char money[100] = {0}; - sprintf(money, " %ipp, %igp, %isp, %icp", trader->trade->pp, trader->trade->gp, trader->trade->sp, trader->trade->cp); - strcat(logtext, money); - } - - database.logevents(trader->AccountName(), trader->AccountID(), - trader->Admin(), trader->GetName(), with->GetName(), "Trade", logtext, 6); - } - } + //Mob* with = With(); + //if (!owner->IsClient() || !with) + // return; // Should never happen + // + //Client* trader = owner->CastToClient(); + //bool logtrade = false; + //int admin_level = 0; + //uint8 item_count = 0; + // + //if (zone->tradevar != 0) { + // for (uint16 i = EmuConstants::TRADE_BEGIN; i <= EmuConstants::TRADE_END; i++) { + // if (trader->GetInv().GetItem(i)) + // item_count++; + // } + // + // if (((this->cp + this->sp + this->gp + this->pp)>0) || (item_count>0)) + // admin_level = trader->Admin(); + // else + // admin_level = 999; + // + // if (zone->tradevar == 7) { + // logtrade = true; + // } + // else if ((admin_level>=10) && (admin_level<20)) { + // if ((zone->tradevar<8) && (zone->tradevar>5)) + // logtrade = true; + // } + // else if (admin_level<=20) { + // if ((zone->tradevar<8) && (zone->tradevar>4)) + // logtrade = true; + // } + // else if (admin_level<=80) { + // if ((zone->tradevar<8) && (zone->tradevar>3)) + // logtrade = true; + // } + // else if (admin_level<=100){ + // if ((zone->tradevar<9) && (zone->tradevar>2)) + // logtrade = true; + // } + // else if (admin_level<=150){ + // if (((zone->tradevar<8) && (zone->tradevar>1)) || (zone->tradevar==9)) + // logtrade = true; + // } + // else if (admin_level<=255){ + // if ((zone->tradevar<8) && (zone->tradevar>0)) + // logtrade = true; + // } + //} + // + //if (logtrade == true) { + // char logtext[1000] = {0}; + // uint32 cash = 0; + // bool comma = false; + // + // // Log items offered by owner + // cash = this->cp + this->sp + this->gp + this->pp; + // if ((cash>0) || (item_count>0)) { + // sprintf(logtext, "%s gave %s ", trader->GetName(), with->GetName()); + // + // if (item_count > 0) { + // strcat(logtext, "items {"); + // + // for (uint16 i = EmuConstants::TRADE_BEGIN; i <= EmuConstants::TRADE_END; i++) { + // const ItemInst* inst = trader->GetInv().GetItem(i); + // + // if (!comma) + // comma = true; + // else { + // if (inst) + // strcat(logtext, ","); + // } + // + // if (inst) { + // char item_num[15] = {0}; + // sprintf(item_num, "%i", inst->GetItem()->ID); + // strcat(logtext, item_num); + // + // if (inst->IsType(ItemClassContainer)) { + // for (uint8 j = SUB_BEGIN; j < EmuConstants::ITEM_CONTAINER_SIZE; j++) { + // inst = trader->GetInv().GetItem(i, j); + // if (inst) { + // strcat(logtext, ","); + // sprintf(item_num, "%i", inst->GetItem()->ID); + // strcat(logtext, item_num); + // } + // } + // } + // } + // } + // } + // + // if (cash > 0) { + // char money[100] = {0}; + // sprintf(money, " %ipp, %igp, %isp, %icp", trader->trade->pp, trader->trade->gp, trader->trade->sp, trader->trade->cp); + // strcat(logtext, money); + // } + // + // database.logevents(trader->AccountName(), trader->AccountID(), + // trader->Admin(), trader->GetName(), with->GetName(), "Trade", logtext, 6); + // } + //} } @@ -454,38 +454,12 @@ void Client::ResetTrade() { void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, std::list* event_details) { if(tradingWith && tradingWith->IsClient()) { Client* other = tradingWith->CastToClient(); - QSPlayerLogTrade_Struct* qs_audit = nullptr; - bool qs_log = false; if(other) { Log.Out(Logs::Detail, Logs::Trading, "Finishing trade with client %s", other->GetName()); this->AddMoneyToPP(other->trade->cp, other->trade->sp, other->trade->gp, other->trade->pp, true); - // step 0: pre-processing - // QS code - if (RuleB(QueryServ, PlayerLogTrades) && event_entry && event_details) { - qs_audit = (QSPlayerLogTrade_Struct*)event_entry; - qs_log = true; - - if (finalizer) { - qs_audit->char2_id = this->character_id; - - qs_audit->char2_money.platinum = this->trade->pp; - qs_audit->char2_money.gold = this->trade->gp; - qs_audit->char2_money.silver = this->trade->sp; - qs_audit->char2_money.copper = this->trade->cp; - } - else { - qs_audit->char1_id = this->character_id; - - qs_audit->char1_money.platinum = this->trade->pp; - qs_audit->char1_money.gold = this->trade->gp; - qs_audit->char1_money.silver = this->trade->sp; - qs_audit->char1_money.copper = this->trade->cp; - } - } - // step 1: process bags for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) { const ItemInst* inst = m_inv[trade_slot]; @@ -500,56 +474,6 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st if (free_slot != INVALID_INDEX) { if (other->PutItemInInventory(free_slot, *inst, true)) { Log.Out(Logs::Detail, Logs::Trading, "Container %s (%d) successfully transferred, deleting from trade slot.", inst->GetItem()->Name, inst->GetItem()->ID); - if (qs_log) { - QSTradeItems_Struct* detail = new QSTradeItems_Struct; - - detail->from_id = this->character_id; - detail->from_slot = trade_slot; - detail->to_id = other->CharacterID(); - detail->to_slot = free_slot; - detail->item_id = inst->GetID(); - detail->charges = 1; - detail->aug_1 = inst->GetAugmentItemID(1); - detail->aug_2 = inst->GetAugmentItemID(2); - detail->aug_3 = inst->GetAugmentItemID(3); - detail->aug_4 = inst->GetAugmentItemID(4); - detail->aug_5 = inst->GetAugmentItemID(5); - - event_details->push_back(detail); - - if (finalizer) - qs_audit->char2_count += detail->charges; - else - qs_audit->char1_count += detail->charges; - - //for (uint8 sub_slot = SUB_BEGIN; ((sub_slot < inst->GetItem()->BagSlots) && (sub_slot < EmuConstants::ITEM_CONTAINER_SIZE)); ++sub_slot) { - for (uint8 sub_slot = SUB_BEGIN; (sub_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++sub_slot) { // this is to catch ALL items - const ItemInst* bag_inst = inst->GetItem(sub_slot); - - if (bag_inst) { - detail = new QSTradeItems_Struct; - - detail->from_id = this->character_id; - detail->from_slot = InventoryOld::CalcSlotId(trade_slot, sub_slot); - detail->to_id = other->CharacterID(); - detail->to_slot = InventoryOld::CalcSlotId(free_slot, sub_slot); - detail->item_id = bag_inst->GetID(); - detail->charges = (!bag_inst->IsStackable() ? 1 : bag_inst->GetCharges()); - detail->aug_1 = bag_inst->GetAugmentItemID(1); - detail->aug_2 = bag_inst->GetAugmentItemID(2); - detail->aug_3 = bag_inst->GetAugmentItemID(3); - detail->aug_4 = bag_inst->GetAugmentItemID(4); - detail->aug_5 = bag_inst->GetAugmentItemID(5); - - event_details->push_back(detail); - - if (finalizer) - qs_audit->char2_count += detail->charges; - else - qs_audit->char1_count += detail->charges; - } - } - } } else { Log.Out(Logs::Detail, Logs::Trading, "Transfer of container %s (%d) to %s failed, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID, other->GetName()); @@ -611,28 +535,6 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st if (other->PutItemInInventory(partial_slot, *partial_inst, true)) { Log.Out(Logs::Detail, Logs::Trading, "Partial stack %s (%d) successfully transferred, deleting %i charges from trade slot.", inst->GetItem()->Name, inst->GetItem()->ID, (old_charges - inst->GetCharges())); - if (qs_log) { - QSTradeItems_Struct* detail = new QSTradeItems_Struct; - - detail->from_id = this->character_id; - detail->from_slot = trade_slot; - detail->to_id = other->CharacterID(); - detail->to_slot = partial_slot; - detail->item_id = inst->GetID(); - detail->charges = (old_charges - inst->GetCharges()); - detail->aug_1 = 0; - detail->aug_2 = 0; - detail->aug_3 = 0; - detail->aug_4 = 0; - detail->aug_5 = 0; - - event_details->push_back(detail); - - if (finalizer) - qs_audit->char2_count += detail->charges; - else - qs_audit->char1_count += detail->charges; - } } else { Log.Out(Logs::Detail, Logs::Trading, "Transfer of partial stack %s (%d) to %s failed, returning %i charges to trade slot.", @@ -679,24 +581,6 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st inst->SetCharges(0); } - if (qs_log) { - QSTradeItems_Struct* detail = new QSTradeItems_Struct; - - detail->from_id = this->character_id; - detail->from_slot = trade_slot; - detail->to_id = this->character_id; - detail->to_slot = bias_slot; - detail->item_id = inst->GetID(); - detail->charges = (old_charges - inst->GetCharges()); - detail->aug_1 = 0; - detail->aug_2 = 0; - detail->aug_3 = 0; - detail->aug_4 = 0; - detail->aug_5 = 0; - - event_details->push_back(detail); - } - if (inst->GetCharges() == 0) { DeleteItemInInventory(trade_slot); break; @@ -719,57 +603,6 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st if (free_slot != INVALID_INDEX) { if (other->PutItemInInventory(free_slot, *inst, true)) { Log.Out(Logs::Detail, Logs::Trading, "Item %s (%d) successfully transferred, deleting from trade slot.", inst->GetItem()->Name, inst->GetItem()->ID); - if (qs_log) { - QSTradeItems_Struct* detail = new QSTradeItems_Struct; - - detail->from_id = this->character_id; - detail->from_slot = trade_slot; - detail->to_id = other->CharacterID(); - detail->to_slot = free_slot; - detail->item_id = inst->GetID(); - detail->charges = (!inst->IsStackable() ? 1 : inst->GetCharges()); - detail->aug_1 = inst->GetAugmentItemID(1); - detail->aug_2 = inst->GetAugmentItemID(2); - detail->aug_3 = inst->GetAugmentItemID(3); - detail->aug_4 = inst->GetAugmentItemID(4); - detail->aug_5 = inst->GetAugmentItemID(5); - - event_details->push_back(detail); - - if (finalizer) - qs_audit->char2_count += detail->charges; - else - qs_audit->char1_count += detail->charges; - - // 'step 3' should never really see containers..but, just in case... - //for (uint8 sub_slot = SUB_BEGIN; ((sub_slot < inst->GetItem()->BagSlots) && (sub_slot < EmuConstants::ITEM_CONTAINER_SIZE)); ++sub_slot) { - for (uint8 sub_slot = SUB_BEGIN; (sub_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++sub_slot) { // this is to catch ALL items - const ItemInst* bag_inst = inst->GetItem(sub_slot); - - if (bag_inst) { - detail = new QSTradeItems_Struct; - - detail->from_id = this->character_id; - detail->from_slot = trade_slot; - detail->to_id = other->CharacterID(); - detail->to_slot = free_slot; - detail->item_id = bag_inst->GetID(); - detail->charges = (!bag_inst->IsStackable() ? 1 : bag_inst->GetCharges()); - detail->aug_1 = bag_inst->GetAugmentItemID(1); - detail->aug_2 = bag_inst->GetAugmentItemID(2); - detail->aug_3 = bag_inst->GetAugmentItemID(3); - detail->aug_4 = bag_inst->GetAugmentItemID(4); - detail->aug_5 = bag_inst->GetAugmentItemID(5); - - event_details->push_back(detail); - - if (finalizer) - qs_audit->char2_count += detail->charges; - else - qs_audit->char1_count += detail->charges; - } - } - } } else { Log.Out(Logs::Detail, Logs::Trading, "Transfer of Item %s (%d) to %s failed, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID, other->GetName()); @@ -794,79 +627,6 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st } } else if(tradingWith && tradingWith->IsNPC()) { - QSPlayerLogHandin_Struct* qs_audit = nullptr; - bool qs_log = false; - - // QS code - if(RuleB(QueryServ, PlayerLogTrades) && event_entry && event_details) { - // Currently provides only basic functionality. Calling method will also - // need to be modified before item returns and rewards can be logged. - qs_audit = (QSPlayerLogHandin_Struct*)event_entry; - qs_log = true; - - qs_audit->quest_id = 0; - qs_audit->char_id = character_id; - qs_audit->char_money.platinum = trade->pp; - qs_audit->char_money.gold = trade->gp; - qs_audit->char_money.silver = trade->sp; - qs_audit->char_money.copper = trade->cp; - qs_audit->char_count = 0; - qs_audit->npc_id = tradingWith->GetNPCTypeID(); - qs_audit->npc_money.platinum = 0; - qs_audit->npc_money.gold = 0; - qs_audit->npc_money.silver = 0; - qs_audit->npc_money.copper = 0; - qs_audit->npc_count = 0; - } - - if(qs_log) { // This can be incorporated below when revisions are made - for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_NPC_END; ++trade_slot) { - const ItemInst* trade_inst = m_inv[trade_slot]; - - if(trade_inst) { - QSHandinItems_Struct* detail = new QSHandinItems_Struct; - - strcpy(detail->action_type, "HANDIN"); - - detail->char_slot = trade_slot; - detail->item_id = trade_inst->GetID(); - detail->charges = (!trade_inst->IsStackable() ? 1 : trade_inst->GetCharges()); - detail->aug_1 = trade_inst->GetAugmentItemID(1); - detail->aug_2 = trade_inst->GetAugmentItemID(2); - detail->aug_3 = trade_inst->GetAugmentItemID(3); - detail->aug_4 = trade_inst->GetAugmentItemID(4); - detail->aug_5 = trade_inst->GetAugmentItemID(5); - - event_details->push_back(detail); - qs_audit->char_count += detail->charges; - - if(trade_inst->IsType(ItemClassContainer)) { - for (uint8 sub_slot = SUB_BEGIN; sub_slot < trade_inst->GetItem()->BagSlots; ++sub_slot) { - const ItemInst* trade_baginst = trade_inst->GetItem(sub_slot); - - if(trade_baginst) { - detail = new QSHandinItems_Struct; - - strcpy(detail->action_type, "HANDIN"); - - detail->char_slot = InventoryOld::CalcSlotId(trade_slot, sub_slot); - detail->item_id = trade_baginst->GetID(); - detail->charges = (!trade_inst->IsStackable() ? 1 : trade_inst->GetCharges()); - detail->aug_1 = trade_baginst->GetAugmentItemID(1); - detail->aug_2 = trade_baginst->GetAugmentItemID(2); - detail->aug_3 = trade_baginst->GetAugmentItemID(3); - detail->aug_4 = trade_baginst->GetAugmentItemID(4); - detail->aug_5 = trade_baginst->GetAugmentItemID(5); - - event_details->push_back(detail); - qs_audit->char_count += detail->charges; - } - } - } - } - } - } - bool quest_npc = false; if(parse->HasQuestSub(tradingWith->GetNPCTypeID(), EVENT_TRADE)) { // This is a quest NPC diff --git a/zone/zone.cpp b/zone/zone.cpp index 469351ea5..4fc745c6b 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -51,6 +51,7 @@ #include "worldserver.h" #include "zone.h" #include "zone_config.h" +#include "queryserv.h" #include #include @@ -62,8 +63,6 @@ #define strcasecmp _stricmp #endif - - extern bool staticzone; extern NetConnection net; extern PetitionList petition_list; @@ -72,6 +71,7 @@ extern uint16 adverrornum; extern uint32 numclients; extern WorldServer worldserver; extern Zone* zone; +extern QueryServ* QServ; Mutex MZoneShutdown; @@ -104,34 +104,6 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) { zone->zonemap = Map::LoadMapFile(zone->map_name); zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name); zone->pathing = PathManager::LoadPathFile(zone->map_name); - - char tmp[10]; - if (database.GetVariable("loglevel",tmp, 9)) { - int log_levels[4]; - if (atoi(tmp)>9){ //Server is using the new code - for(int i=0;i<4;i++){ - if (((int)tmp[i]>=48) && ((int)tmp[i]<=57)) - log_levels[i]=(int)tmp[i]-48; //get the value to convert it to an int from the ascii value - else - log_levels[i]=0; //set to zero on a bogue char - } - zone->loglevelvar = log_levels[0]; - Log.Out(Logs::General, Logs::Status, "General logging level: %i", zone->loglevelvar); - zone->merchantvar = log_levels[1]; - Log.Out(Logs::General, Logs::Status, "Merchant logging level: %i", zone->merchantvar); - zone->tradevar = log_levels[2]; - Log.Out(Logs::General, Logs::Status, "Trade logging level: %i", zone->tradevar); - zone->lootvar = log_levels[3]; - Log.Out(Logs::General, Logs::Status, "Loot logging level: %i", zone->lootvar); - } - else { - zone->loglevelvar = uint8(atoi(tmp)); //continue supporting only command logging (for now) - zone->merchantvar = 0; - zone->tradevar = 0; - zone->lootvar = 0; - } - } - ZoneLoaded = true; worldserver.SetZone(iZoneID, iInstanceID); @@ -762,11 +734,6 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name) is_zone_time_localized = false; - loglevelvar = 0; - merchantvar = 0; - tradevar = 0; - lootvar = 0; - if(RuleB(TaskSystem, EnableTaskSystem)) { taskmanager->LoadProximities(zoneid); } @@ -2299,3 +2266,70 @@ void Zone::UpdateHotzone() is_hotzone = atoi(row[0]) == 0 ? false: true; } +void Zone::LogEvent(EventLogTypes type, Client *c, const std::string &desc) { + if(!c) + return; + + int zone_id = GetZoneID(); + int zone_instance = GetInstanceID(); + int zone_version = GetInstanceVersion(); + + int account_id = c->AccountID(); + std::string name = c->GetName(); + int id = c->CharacterID(); + + int target_account_id; + std::string target_name; + int target_id; + + Mob *target = c->GetTarget(); + if(target && target->IsClient()) { + Client *target_c = target->CastToClient(); + + target_account_id = target_c->AccountID(); + target_name = target_c->GetName(); + target_id = target_c->CharacterID(); + } + else if(target && target->IsNPC()) { + NPC *target_n = target->CastToNPC(); + + target_account_id = 0; + target_name = target_n->GetName(); + target_id = target_n->GetNPCTypeID(); + } + else if(target) { + target_account_id = 0; + target_name = target->GetName(); + target_id = 0; + } + else { + target_account_id = 0; + target_name = ""; + target_id = 0; + } + + + std::string query = StringFormat("INSERT INTO event_log " + "(type, zone_id, zone_instance, zone_version, player_account_id, " + "player_id, player_name, target_account_id, target_id, target_name, `desc`)" + " VALUES " + "(%i, %i, %i, %i, %i, %i, '%s', %i, %i, '%s', '%s')", + (int)type, + zone_id, + zone_instance, + zone_version, + account_id, + id, + EscapeString(name).c_str(), + target_account_id, + target_id, + EscapeString(target_name).c_str(), + EscapeString(desc).c_str() + ); + + auto results = database.QueryDatabase(query); + if(!results.Success()) { + Log.Out(Logs::General, Logs::Error, "Log Error: %s", results.ErrorMessage().c_str()); + } + //QServ->SendQuery(query); +} \ No newline at end of file diff --git a/zone/zone.h b/zone/zone.h index 7b1b855a7..8c4008df0 100644 --- a/zone/zone.h +++ b/zone/zone.h @@ -69,6 +69,14 @@ struct item_tick_struct { std::string qglobal; }; +enum EventLogTypes +{ + EventLogItemSummon = 0, + EventLogItemBuy = 1, + EventLogQuest = 500, + EventLogMax +}; + class Client; class Map; class Mob; @@ -227,11 +235,6 @@ public: uint8 weather_intensity; uint8 zone_weather; - uint8 loglevelvar; - uint8 merchantvar; - uint8 tradevar; - uint8 lootvar; - bool HasGraveyard(); void SetGraveyard(uint32 zoneid, const glm::vec4& graveyardPosition); @@ -282,6 +285,8 @@ public: } } + void LogEvent(EventLogTypes type, Client *c, const std::string &desc); + //MODDING HOOKS void mod_init(); void mod_repop(); diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 49c09ecd9..a6285294b 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -311,33 +311,6 @@ void ZoneDatabase::UpdateSpawn2Status(uint32 id, uint8 new_status) QueryDatabase(query); } -bool ZoneDatabase::logevents(const char* accountname,uint32 accountid,uint8 status,const char* charname, const char* target,const char* descriptiontype, const char* description,int event_nid){ - - uint32 len = strlen(description); - uint32 len2 = strlen(target); - char* descriptiontext = new char[2*len+1]; - char* targetarr = new char[2*len2+1]; - memset(descriptiontext, 0, 2*len+1); - memset(targetarr, 0, 2*len2+1); - DoEscapeString(descriptiontext, description, len); - DoEscapeString(targetarr, target, len2); - - std::string query = StringFormat("INSERT INTO eventlog (accountname, accountid, status, " - "charname, target, descriptiontype, description, event_nid) " - "VALUES('%s', %i, %i, '%s', '%s', '%s', '%s', '%i')", - accountname, accountid, status, charname, targetarr, - descriptiontype, descriptiontext, event_nid); - safe_delete_array(descriptiontext); - safe_delete_array(targetarr); - auto results = QueryDatabase(query); - if (!results.Success()) { - return false; - } - - return true; -} - - void ZoneDatabase::UpdateBug(BugStruct* bug) { uint32 len = strlen(bug->bug); diff --git a/zone/zonedb.h b/zone/zonedb.h index 1fb4d3b29..a3b8c9ae9 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -488,7 +488,6 @@ public: * PLEASE DO NOT ADD TO THIS COLLECTION OF CRAP UNLESS YOUR METHOD * REALLY HAS NO BETTER SECTION */ - bool logevents(const char* accountname,uint32 accountid,uint8 status,const char* charname,const char* target, const char* descriptiontype, const char* description,int event_nid); void GetEventLogs(const char* name,char* target,uint32 account_id=0,uint8 eventid=0,char* detail=0,char* timestamp=0, CharacterEventLog_Struct* cel=0); uint32 GetKarma(uint32 acct_id); void UpdateKarma(uint32 acct_id, uint32 amount); diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 5b60448ec..f8ec4d2c2 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -335,12 +335,6 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc SendLogoutPackets(); - /* QS: PlayerLogZone */ - if (RuleB(QueryServ, PlayerLogZone)){ - std::string event_desc = StringFormat("Zoning :: zoneid:%u instid:%u x:%4.2f y:%4.2f z:%4.2f h:%4.2f zonemode:%d from zoneid:%u instid:%i", zone_id, instance_id, dest_x, dest_y, dest_z, dest_h, zone_mode, this->GetZoneID(), this->GetInstanceID()); - QServ->PlayerLogEvent(Player_Log_Zoning, this->CharacterID(), event_desc); - } - /* Dont clear aggro until the zone is successful */ entity_list.RemoveFromHateLists(this);