From f26d303ee1824e5a2099cff4abaa3a21c52d21ac Mon Sep 17 00:00:00 2001 From: Trevius Date: Thu, 5 Feb 2015 22:34:55 -0600 Subject: [PATCH 1/9] Fixed Environmental Damage for RoF2. --- changelog.txt | 3 +++ common/patches/rof2_structs.h | 5 +++-- zone/client_packet.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/changelog.txt b/changelog.txt index 9494adfce..6e37c6513 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 02/05/2015 == +Trevius: Fixed Environmental Damage for RoF2. + == 02/03/2015 == Trevius: Crashfix for TempName() when numbers are passed at the end of the name. Uleat: Tweaking of item type exclusions to alleviate strobing conditions with light sources diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index dd9bfb587..9ef524f55 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -2865,7 +2865,7 @@ struct SetRunMode_Struct { }; // EnvDamage is EnvDamage2 without a few bytes at the end. -// Size: 37 bytes +// Size: 39 bytes struct EnvDamage2_Struct { /*0000*/ uint32 id; /*0004*/ uint16 unknown4; @@ -2877,7 +2877,8 @@ struct EnvDamage2_Struct { /*0031*/ uint16 unknown31; // New to Underfoot - Seen 66 /*0033*/ uint16 constant; // Always FFFF /*0035*/ uint16 unknown35; -/*0037*/ +/*0037*/ uint16 unknown37; +/*0039*/ }; //Bazaar Stuff diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 331c50435..95475f1ca 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -5516,7 +5516,7 @@ void Client::Handle_OP_EnvDamage(const EQApplicationPacket *app) if (damage < 0) damage = 31337; - if (admin >= minStatusToAvoidFalling && GetGM()){ + if (admin >= minStatusToAvoidFalling && GetGM()) { Message(13, "Your GM status protects you from %i points of type %i environmental damage.", ed->damage, ed->dmgtype); SetHP(GetHP() - 1);//needed or else the client wont acknowledge return; @@ -5526,11 +5526,11 @@ void Client::Handle_OP_EnvDamage(const EQApplicationPacket *app) SetHP(GetHP() - 1);//needed or else the client wont acknowledge return; } - - else if (zone->GetZoneID() == 183 || zone->GetZoneID() == 184){ + else if (zone->GetZoneID() == 183 || zone->GetZoneID() == 184) { + // Hard coded tutorial and load zones for no fall damage return; } - else{ + else { SetHP(GetHP() - (damage * RuleR(Character, EnvironmentDamageMulipliter))); /* EVENT_ENVIRONMENTAL_DAMAGE */ From 2bf2485b4c66ae9e6a8e7e35bf93fcdac09b3cea Mon Sep 17 00:00:00 2001 From: Uleat Date: Fri, 6 Feb 2015 07:57:15 -0500 Subject: [PATCH 2/9] Enforced const_interator returns on const_iterator return types in Inventory and ItemInst --- changelog.txt | 3 +++ common/item.cpp | 22 +++++++++++----------- common/item.h | 12 ++++++------ zone/client_packet.cpp | 4 ++-- zone/command.cpp | 2 +- zone/corpse.cpp | 4 ++-- zone/inventory.cpp | 26 +++++++++++++------------- 7 files changed, 38 insertions(+), 35 deletions(-) diff --git a/changelog.txt b/changelog.txt index 9494adfce..8d28ad3de 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 02/06/2015 == +Uleat: Updated returns for Inventory and ItemInst const iterators. (const == const) + == 02/03/2015 == Trevius: Crashfix for TempName() when numbers are passed at the end of the name. Uleat: Tweaking of item type exclusions to alleviate strobing conditions with light sources diff --git a/common/item.cpp b/common/item.cpp index 82da305f1..4119c7058 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -1060,7 +1060,7 @@ int Inventory::GetSlotByItemInstCollection(const std::map &col } if (t_inst && !t_inst->IsType(ItemClassContainer)) { - for (auto b_iter = t_inst->_begin(); b_iter != t_inst->_end(); ++b_iter) { + 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); } @@ -1095,7 +1095,7 @@ void Inventory::dumpBagContents(ItemInst *inst, iter_inst *it) { return; // Go through bag, if bag - for (itb = inst->_begin(); itb != inst->_end(); ++itb) { + for (itb = inst->_cbegin(); itb != inst->_cend(); ++itb) { ItemInst* baginst = itb->second; if (!baginst || !baginst->GetItem()) continue; @@ -1204,7 +1204,7 @@ int16 Inventory::_HasItem(std::map& bucket, uint32 item_id, ui if (!inst->IsType(ItemClassContainer)) { continue; } - for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) { + for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) { auto bag_inst = bag_iter->second; if (bag_inst == nullptr) { continue; } @@ -1235,7 +1235,7 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity) uint8 quantity_found = 0; - for (auto iter = iqueue.begin(); iter != iqueue.end(); ++iter) { + for (auto iter = iqueue.cbegin(); iter != iqueue.cend(); ++iter) { auto inst = *iter; if (inst == nullptr) { continue; } @@ -1252,7 +1252,7 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity) if (!inst->IsType(ItemClassContainer)) { continue; } - for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) { + for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) { auto bag_inst = bag_iter->second; if (bag_inst == nullptr) { continue; } @@ -1289,7 +1289,7 @@ int16 Inventory::_HasItemByUse(std::map& bucket, uint8 use, ui if (!inst->IsType(ItemClassContainer)) { continue; } - for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) { + for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) { auto bag_inst = bag_iter->second; if (bag_inst == nullptr) { continue; } @@ -1309,7 +1309,7 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity) { uint8 quantity_found = 0; - for (auto iter = iqueue.begin(); iter != iqueue.end(); ++iter) { + for (auto iter = iqueue.cbegin(); iter != iqueue.cend(); ++iter) { auto inst = *iter; if (inst == nullptr) { continue; } @@ -1321,7 +1321,7 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity) if (!inst->IsType(ItemClassContainer)) { continue; } - for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) { + for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) { auto bag_inst = bag_iter->second; if (bag_inst == nullptr) { continue; } @@ -1355,7 +1355,7 @@ int16 Inventory::_HasItemByLoreGroup(std::map& bucket, uint32 if (!inst->IsType(ItemClassContainer)) { continue; } - for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) { + for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) { auto bag_inst = bag_iter->second; if (bag_inst == nullptr) { continue; } @@ -1378,7 +1378,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) { - for (auto iter = iqueue.begin(); iter != iqueue.end(); ++iter) { + for (auto iter = iqueue.cbegin(); iter != iqueue.cend(); ++iter) { auto inst = *iter; if (inst == nullptr) { continue; } @@ -1395,7 +1395,7 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup) if (!inst->IsType(ItemClassContainer)) { continue; } - for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) { + for (auto bag_iter = inst->_cbegin(); bag_iter != inst->_cend(); ++bag_iter) { auto bag_inst = bag_iter->second; if (bag_inst == nullptr) { continue; } diff --git a/common/item.h b/common/item.h index fd30b5ea0..8554d1c55 100644 --- a/common/item.h +++ b/common/item.h @@ -86,8 +86,8 @@ public: // Public Methods ///////////////////////// - inline std::list::const_iterator begin() { return m_list.begin(); } - inline std::list::const_iterator end() { return m_list.end(); } + inline std::list::const_iterator cbegin() { return m_list.cbegin(); } + inline std::list::const_iterator cend() { return m_list.cend(); } inline int size() { return static_cast(m_list.size()); } // TODO: change to size_t inline bool empty() { return m_list.empty(); } @@ -140,8 +140,8 @@ public: ItemInst* GetItem(int16 slot_id) const; ItemInst* GetItem(int16 slot_id, uint8 bagidx) const; - inline std::list::const_iterator cursor_begin() { return m_cursor.begin(); } - inline std::list::const_iterator cursor_end() { return m_cursor.end(); } + inline std::list::const_iterator cursor_cbegin() { return m_cursor.cbegin(); } + inline std::list::const_iterator cursor_cend() { return m_cursor.cend(); } inline int CursorSize() { return m_cursor.size(); } inline bool CursorEmpty() { return m_cursor.empty(); } @@ -425,8 +425,8 @@ protected: ////////////////////////// // Protected Members ////////////////////////// - iter_contents _begin() { return m_contents.begin(); } - iter_contents _end() { return m_contents.end(); } + iter_contents _cbegin() { return m_contents.cbegin(); } + iter_contents _cend() { return m_contents.cend(); } friend class Inventory; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 331c50435..40dc0e35a 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1838,9 +1838,9 @@ 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_begin(); iter != m_inv.cursor_end(); ++iter) { + 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_begin()) + if (iter == m_inv.cursor_cbegin()) continue; const ItemInst *inst = *iter; SendItemPacket(MainCursor, inst, ItemPacketSummonItem); diff --git a/zone/command.cpp b/zone/command.cpp index c34bc1b9d..622f1d973 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -2618,7 +2618,7 @@ void command_peekinv(Client *c, const Seperator *sep) } else { int cursorDepth = 0; - for (auto it = targetClient->GetInv().cursor_begin(); (it != targetClient->GetInv().cursor_end()); ++it, ++cursorDepth) { + for (auto it = targetClient->GetInv().cursor_cbegin(); (it != targetClient->GetInv().cursor_cend()); ++it, ++cursorDepth) { inst_main = *it; item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); linker.SetItemInst(inst_main); diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 0dd4ed1f3..9f91b584b 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -361,8 +361,8 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( database.QueryDatabase(ss.str().c_str()); } - auto start = client->GetInv().cursor_begin(); - auto finish = client->GetInv().cursor_end(); + auto start = client->GetInv().cursor_cbegin(); + auto finish = client->GetInv().cursor_cend(); database.SaveCursor(client->CharacterID(), start, finish); client->CalcBonuses(); diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 1da2fb13d..94138fbe5 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -619,7 +619,7 @@ void Client::DropItem(int16 slot_id) // Save client inventory change to database if (slot_id == MainCursor) { SendCursorBuffer(); - auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); database.SaveCursor(CharacterID(), s, e); } else { database.SaveInventory(CharacterID(), nullptr, slot_id); @@ -772,7 +772,7 @@ void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_upd const ItemInst* inst = nullptr; if (slot_id == MainCursor) { - auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); if(update_db) database.SaveCursor(character_id, s, e); } @@ -826,7 +826,7 @@ bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update) SendItemPacket(MainCursor, &inst, ItemPacketSummonItem); } - auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); return database.SaveCursor(CharacterID(), s, e); } @@ -851,7 +851,7 @@ bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client } if (slot_id == MainCursor) { - auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); return database.SaveCursor(this->CharacterID(), s, e); } else { @@ -870,7 +870,7 @@ void Client::PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootI SendLootItemInPacket(&inst, slot_id); if (slot_id == MainCursor) { - auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); database.SaveCursor(this->CharacterID(), s, e); } else { @@ -1009,7 +1009,7 @@ void Client::MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type) from.SetCharges(from.GetCharges() - charges_to_move); SendLootItemInPacket(tmp_inst, to_slot); if (to_slot == MainCursor) { - auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); database.SaveCursor(this->CharacterID(), s, e); } else { @@ -1567,7 +1567,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { { SendCursorBuffer(); } - auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); database.SaveCursor(character_id, s, e); } else @@ -1726,7 +1726,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { { SendCursorBuffer(); } - auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); database.SaveCursor(character_id, s, e); } else { @@ -1734,7 +1734,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } if (dst_slot_id == MainCursor) { - auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); database.SaveCursor(character_id, s, e); } else { @@ -2170,7 +2170,7 @@ void Client::RemoveNoRent(bool client_update) } local.clear(); - auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); database.SaveCursor(this->CharacterID(), s, e); } } @@ -2298,7 +2298,7 @@ void Client::RemoveDuplicateLore(bool client_update) } local_2.clear(); - auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend(); database.SaveCursor(this->CharacterID(), s, e); } } @@ -2826,9 +2826,9 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool } int limbo = 0; - for (auto cursor_itr = m_inv.cursor_begin(); cursor_itr != m_inv.cursor_end(); ++cursor_itr, ++limbo) { + for (auto cursor_itr = m_inv.cursor_cbegin(); cursor_itr != m_inv.cursor_cend(); ++cursor_itr, ++limbo) { // m_inv.cursor_begin() is referenced as MainCursor in MapPossessions above - if (cursor_itr == m_inv.cursor_begin()) + if (cursor_itr == m_inv.cursor_cbegin()) continue; instmap[8000 + limbo] = *cursor_itr; From 5d64012d74df20e26ce25f481f9b3ce1055c54e6 Mon Sep 17 00:00:00 2001 From: Uleat Date: Fri, 6 Feb 2015 08:52:41 -0500 Subject: [PATCH 3/9] Removed iter_inst and iter_contents typedefs --- changelog.txt | 1 + common/item.cpp | 27 +++++++++++---------------- common/item.h | 9 +++------ 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/changelog.txt b/changelog.txt index 8d28ad3de..47aa7016f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- == 02/06/2015 == Uleat: Updated returns for Inventory and ItemInst const iterators. (const == const) +Uleat: Replaced 'iter_inst' and 'iter_contents' typedefs with their stl definitions == 02/03/2015 == Trevius: Crashfix for TempName() when numbers are passed at the end of the name. diff --git a/common/item.cpp b/common/item.cpp index 4119c7058..40fc98474 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -1071,13 +1071,10 @@ int Inventory::GetSlotByItemInstCollection(const std::map &col return -1; } -void Inventory::dumpItemCollection(const std::map &collection) { - iter_inst it; - iter_contents itb; - ItemInst* inst = nullptr; - - for (it = collection.begin(); it != collection.end(); ++it) { - inst = it->second; +void Inventory::dumpItemCollection(const std::map &collection) +{ + for (auto it = collection.cbegin(); it != collection.cend(); ++it) { + auto inst = it->second; if (!inst || !inst->GetItem()) continue; @@ -1088,14 +1085,13 @@ void Inventory::dumpItemCollection(const std::map &collection) } } -void Inventory::dumpBagContents(ItemInst *inst, iter_inst *it) { - iter_contents itb; - +void Inventory::dumpBagContents(ItemInst *inst, std::map::const_iterator *it) +{ if (!inst || !inst->IsType(ItemClassContainer)) return; // Go through bag, if bag - for (itb = inst->_cbegin(); itb != inst->_cend(); ++itb) { + for (auto itb = inst->_cbegin(); itb != inst->_cend(); ++itb) { ItemInst* baginst = itb->second; if (!baginst || !baginst->GetItem()) continue; @@ -1110,7 +1106,7 @@ void Inventory::dumpBagContents(ItemInst *inst, iter_inst *it) { // Internal Method: Retrieves item within an inventory bucket ItemInst* Inventory::_GetItem(const std::map& bucket, int16 slot_id) const { - iter_inst it = bucket.find(slot_id); + auto it = bucket.find(slot_id); if (it != bucket.end()) { return it->second; } @@ -1505,8 +1501,7 @@ ItemInst::ItemInst(const ItemInst& copy) m_attuned=copy.m_attuned; m_merchantcount=copy.m_merchantcount; // Copy container contents - iter_contents it; - for (it=copy.m_contents.begin(); it!=copy.m_contents.end(); ++it) { + for (auto it = copy.m_contents.begin(); it != copy.m_contents.end(); ++it) { ItemInst* inst_old = it->second; ItemInst* inst_new = nullptr; @@ -1676,7 +1671,7 @@ bool ItemInst::IsAugmentSlotAvailable(int32 augtype, uint8 slot) const // Retrieve item inside container ItemInst* ItemInst::GetItem(uint8 index) const { - iter_contents it = m_contents.find(index); + auto it = m_contents.find(index); if (it != m_contents.end()) { return it->second; } @@ -1739,7 +1734,7 @@ void ItemInst::ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent) // TODO: This needs work... // Destroy container contents - iter_contents cur, end, del; + std::map::const_iterator cur, end, del; cur = m_contents.begin(); end = m_contents.end(); for (; cur != end;) { diff --git a/common/item.h b/common/item.h index 8554d1c55..906e00313 100644 --- a/common/item.h +++ b/common/item.h @@ -33,9 +33,6 @@ class EvolveInfo; // Stores information about an evolving item family #include #include -// Helper typedefs -typedef std::map::const_iterator iter_inst; -typedef std::map::const_iterator iter_contents; namespace ItemField { @@ -227,7 +224,7 @@ protected: int GetSlotByItemInstCollection(const std::map &collection, ItemInst *inst); void dumpItemCollection(const std::map &collection); - void dumpBagContents(ItemInst *inst, iter_inst *it); + void dumpBagContents(ItemInst *inst, std::map::const_iterator *it); // Retrieves item within an inventory bucket ItemInst* _GetItem(const std::map& bucket, int16 slot_id) const; @@ -425,8 +422,8 @@ protected: ////////////////////////// // Protected Members ////////////////////////// - iter_contents _cbegin() { return m_contents.cbegin(); } - iter_contents _cend() { return m_contents.cend(); } + std::map::const_iterator _cbegin() { return m_contents.cbegin(); } + std::map::const_iterator _cend() { return m_contents.cend(); } friend class Inventory; From 5a619bddaf2b6e8033df2592c8be1e60b8ab7538 Mon Sep 17 00:00:00 2001 From: Uleat Date: Fri, 6 Feb 2015 09:58:57 -0500 Subject: [PATCH 4/9] Excluded limbo (cursor buffer) from HasItem checks --- changelog.txt | 1 + common/item.cpp | 14 ++++++++ zone/inventory.cpp | 80 ++++++++++++++++++++++++++++++++++------------ 3 files changed, 75 insertions(+), 20 deletions(-) diff --git a/changelog.txt b/changelog.txt index 47aa7016f..8dd4b77ec 100644 --- a/changelog.txt +++ b/changelog.txt @@ -3,6 +3,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) == 02/06/2015 == Uleat: Updated returns for Inventory and ItemInst const iterators. (const == const) Uleat: Replaced 'iter_inst' and 'iter_contents' typedefs with their stl definitions +Uleat: Removed 'limbo' from the 'HasItem' series of checks - including lore checks. The client excludes this range and it causes issues when performing item searches - dupe lore checks were added to account for this. == 02/03/2015 == Trevius: Crashfix for TempName() when numbers are passed at the end of the name. diff --git a/common/item.cpp b/common/item.cpp index 40fc98474..0e2f0f574 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -506,6 +506,7 @@ int16 Inventory::HasItem(uint32 item_id, uint8 quantity, uint8 where) return slot_id; } + // Behavioral change - Limbo is no longer checked due to improper handling of return value if (where & invWhereCursor) { // Check cursor queue slot_id = _HasItem(m_cursor, item_id, quantity); @@ -552,6 +553,7 @@ int16 Inventory::HasItemByUse(uint8 use, uint8 quantity, uint8 where) return slot_id; } + // Behavioral change - Limbo is no longer checked due to improper handling of return value if (where & invWhereCursor) { // Check cursor queue slot_id = _HasItemByUse(m_cursor, use, quantity); @@ -597,6 +599,7 @@ int16 Inventory::HasItemByLoreGroup(uint32 loregroup, uint8 where) return slot_id; } + // Behavioral change - Limbo is no longer checked due to improper handling of return value if (where & invWhereCursor) { // Check cursor queue slot_id = _HasItemByLoreGroup(m_cursor, loregroup); @@ -1119,6 +1122,8 @@ ItemInst* Inventory::_GetItem(const std::map& bucket, int16 sl // Assumes item has already been allocated int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst) { + // What happens here when we _PutItem(MainCursor)? Bad things..really bad things... + // // If putting a nullptr into slot, we need to remove slot without memory delete if (inst == nullptr) { //Why do we not delete the poped item here???? @@ -1263,6 +1268,9 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity) return legacy::SLOT_AUGMENT; } } + + // We only check the visible cursor due to lack of queue processing ability (client allows duplicate in limbo) + break; } return INVALID_INDEX; @@ -1327,6 +1335,9 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity) return Inventory::CalcSlotId(MainCursor, bag_iter->first); } } + + // We only check the visible cursor due to lack of queue processing ability (client allows duplicate in limbo) + break; } return INVALID_INDEX; @@ -1406,6 +1417,9 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup) return legacy::SLOT_AUGMENT; } } + + // We only check the visible cursor due to lack of queue processing ability (client allows duplicate in limbo) + break; } return INVALID_INDEX; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 94138fbe5..69f1de882 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -177,16 +177,16 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) { } -bool Client::CheckLoreConflict(const Item_Struct* item) { - if (!item) - return false; - if (!(item->LoreFlag)) - return false; +bool Client::CheckLoreConflict(const Item_Struct* item) +{ + if (!item) { return false; } + if (!item->LoreFlag) { return false; } + if (item->LoreGroup == 0) { return false; } - if (item->LoreGroup == -1) // Standard lore items; look everywhere except the shared bank, return the result + if (item->LoreGroup == 0xFFFFFFFF) // Standard lore items; look everywhere except the shared bank, return the result return (m_inv.HasItem(item->ID, 0, ~invWhereSharedBank) != INVALID_INDEX); - //If the item has a lore group, we check for other items with the same group and return the result + // If the item has a lore group, we check for other items with the same group and return the result return (m_inv.HasItemByLoreGroup(item->LoreGroup, ~invWhereSharedBank) != INVALID_INDEX); } @@ -680,20 +680,37 @@ int32 Client::GetAugmentIDAt(int16 slot_id, uint8 augslot) { return INVALID_ID; } -void Client::SendCursorBuffer() { +void Client::SendCursorBuffer() +{ // Temporary work-around for the RoF+ Client Buffer // Instead of dealing with client moving items in cursor buffer, // we can just send the next item in the cursor buffer to the cursor. - if (GetClientVersion() >= ClientVersion::RoF) - { - if (!GetInv().CursorEmpty()) - { - const ItemInst* inst = GetInv().GetCursorItem(); - if (inst) - { - SendItemPacket(MainCursor, inst, ItemPacketSummonItem); - } - } + if (GetClientVersion() < ClientVersion::RoF) { return; } + if (GetInv().CursorEmpty()) { return; } + + auto test_inst = GetInv().GetCursorItem(); + if (test_inst == nullptr) { return; } + auto test_item = test_inst->GetItem(); + if (test_item == nullptr) { return; } + + bool lore_pass = true; + if (test_item->LoreGroup == 0xFFFFFFFF) { + lore_pass = (m_inv.HasItem(test_item->ID, 0, ~(invWhereSharedBank | invWhereCursor)) == INVALID_INDEX); + } + else if (test_item->LoreGroup != 0) { + lore_pass = (m_inv.HasItemByLoreGroup(test_item->LoreGroup, ~(invWhereSharedBank | invWhereCursor)) == INVALID_INDEX); + } + + if (!lore_pass) { + Log.Out(Logs::General, Logs::Inventory, "(%s) Duplicate lore items are not allowed - destroying item %s(id:%u) on cursor", + GetName(), test_item->Name, test_item->ID); + Message_StringID(MT_LootMessages, 290); + parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0); + DeleteItemInInventory(MainCursor); + SendCursorBuffer(); + } + else { + SendItemPacket(MainCursor, test_inst, ItemPacketSummonItem); } } @@ -1320,10 +1337,33 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { return false; } - // This could be expounded upon at some point to let the server know that - // the client has moved a buffered cursor item onto the active cursor -U 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) { + auto test_inst = m_inv.GetItem(MainCursor); + if (test_inst == nullptr) { return true; } + auto test_item = test_inst->GetItem(); + if (test_item == nullptr) { return true; } + if (!test_item->LoreFlag) { return true; } + + bool lore_pass = true; + if (test_item->LoreGroup == 0xFFFFFFFF) { + lore_pass = (m_inv.HasItem(test_item->ID, 0, ~(invWhereSharedBank | invWhereCursor)) == INVALID_INDEX); + } + else if (test_item->LoreGroup != 0) { + lore_pass = (m_inv.HasItemByLoreGroup(test_item->LoreGroup, ~(invWhereSharedBank | invWhereCursor)) == INVALID_INDEX); + } + + if (!lore_pass) { + Log.Out(Logs::General, Logs::Inventory, "(%s) Duplicate lore items are not allowed - destroying item %s(id:%u) on cursor", + GetName(), test_item->Name, test_item->ID); + Message_StringID(MT_LootMessages, 290); + parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0); + DeleteItemInInventory(MainCursor, 0, true); + } + } return true; } From c9cd733d9a1a23ed71ce8c14a6ef3b6a8c25b521 Mon Sep 17 00:00:00 2001 From: Uleat Date: Fri, 6 Feb 2015 12:09:26 -0500 Subject: [PATCH 5/9] Updated command #iteminfo --- changelog.txt | 1 + zone/command.cpp | 66 ++++++++++++++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/changelog.txt b/changelog.txt index 8dd4b77ec..f0d5fc722 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,6 +4,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) Uleat: Updated returns for Inventory and ItemInst const iterators. (const == const) Uleat: Replaced 'iter_inst' and 'iter_contents' typedefs with their stl definitions Uleat: Removed 'limbo' from the 'HasItem' series of checks - including lore checks. The client excludes this range and it causes issues when performing item searches - dupe lore checks were added to account for this. +Uleat: Updated command #iteminfo to show light source information and a few other things == 02/03/2015 == Trevius: Crashfix for TempName() when numbers are passed at the end of the name. diff --git a/zone/command.cpp b/zone/command.cpp index 622f1d973..96a43d17a 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -4284,31 +4284,49 @@ void command_goto(Client *c, const Seperator *sep) void command_iteminfo(Client *c, const Seperator *sep) { - const ItemInst* inst = c->GetInv()[MainCursor]; - - if (!inst) - c->Message(13, "Error: You need an item on your cursor for this command"); - else { - const Item_Struct* item = inst->GetItem(); - c->Message(0, "ID: %i Name: %s", item->ID, item->Name); - c->Message(0, " Lore: %s ND: %i NS: %i Type: %i", (item->LoreFlag) ? "true":"false", item->NoDrop, item->NoRent, item->ItemClass); - c->Message(0, " IDF: %s Size: %i Weight: %i icon_id: %i Price: %i", item->IDFile, item->Size, item->Weight, item->Icon, item->Price); - if (c->Admin() >= 200) - c->Message(0, "MinStatus: %i", item->MinStatus); - if (item->ItemClass==ItemClassBook) - c->Message(0, " This item is a Book: %s", item->Filename); - else if (item->ItemClass==ItemClassContainer) - c->Message(0, " This item is a container with %i slots", item->BagSlots); - else { - c->Message(0, " equipableSlots: %u equipable Classes: %u", item->Slots, item->Classes); - c->Message(0, " Magic: %i SpellID: %i Proc Level: %i DBCharges: %i CurCharges: %i", item->Magic, item->Click.Effect, item->Click.Level, item->MaxCharges, inst->GetCharges()); - c->Message(0, " EffectType: 0x%02x CastTime: %.2f", (uint8) item->Click.Type, (double) item->CastTime/1000); - c->Message(0, " Material: 0x%02x Color: 0x%08x Skill: %i", item->Material, item->Color, item->ItemType); - c->Message(0, " Required level: %i Required skill: %i Recommended level:%i", item->ReqLevel, item->RecSkill, item->RecLevel); - c->Message(0, " Skill mod: %i percent: %i", item->SkillModType, item->SkillModValue); - c->Message(0, " BaneRace: %i BaneBody: %i BaneDMG: %i", item->BaneDmgRace, item->BaneDmgBody, item->BaneDmgAmt); - } + auto inst = c->GetInv()[MainCursor]; + if (!inst) { c->Message(13, "Error: You need an item on your cursor for this command"); } + auto item = inst->GetItem(); + if (!item) { + Log.Out(Logs::General, Logs::Inventory, "(%s) Command #iteminfo processed an item with no data pointer"); + c->Message(13, "Error: This item has no data reference"); } + + Client::TextLink linker; + linker.SetLinkType(linker.linkItemInst); + linker.SetItemInst(inst); + + auto item_link = linker.GenerateLink(); + + c->Message(0, "*** Item Info for [%s] ***", item_link.c_str()); + c->Message(0, ">> ID: %u, ItemUseType: %u, ItemClassType: %u", item->ID, item->ItemType, item->ItemClass); + c->Message(0, ">> IDFile: '%s', IconID: %u", item->IDFile, item->Icon); + c->Message(0, ">> Size: %u, Weight: %u, Price: %u, LDoNPrice: %u", item->Size, item->Weight, item->Price, item->LDoNPrice); + c->Message(0, ">> Material: 0x%02X, Color: 0x%08X, Tint: 0x%08X, Light: 0x%02X", item->Material, item->Color, inst->GetColor(), item->Light); + c->Message(0, ">> IsLore: %s, LoreGroup: %u, Lore: '%s'", (item->LoreFlag ? "TRUE" : "FALSE"), item->LoreGroup, item->Lore); + c->Message(0, ">> NoDrop: %u, NoRent: %u, NoPet: %u, NoTransfer: %u, FVNoDrop: %u", + item->NoDrop, item->NoRent, (uint8)item->NoPet, (uint8)item->NoTransfer, item->FVNoDrop); + + if (item->ItemClass == ItemClassBook) { + c->Message(0, "*** This item is a Book (filename:'%s') ***", item->Filename); + } + else if (item->ItemClass == ItemClassContainer) { + c->Message(0, "*** This item is a Container (%u slots) ***", item->BagSlots); + } + else { + c->Message(0, "*** This item is Common ***"); + c->Message(0, ">> Classes: %u, Races: %u, Slots: %u", item->Classes, item->Races, item->Slots); + c->Message(0, ">> ReqSkill: %u, ReqLevel: %u, RecLevel: %u", item->RecSkill, item->ReqLevel, item->RecLevel); + c->Message(0, ">> SkillModType: %u, SkillModValue: %i", item->SkillModType, item->SkillModValue); + c->Message(0, ">> BaneRaceType: %u, BaneRaceDamage: %u, BaneBodyType: %u, BaneBodyDamage: %i", + item->BaneDmgRace, item->BaneDmgRaceAmt, item->BaneDmgBody, item->BaneDmgAmt); + c->Message(0, ">> Magic: %s, SpellID: %i, ProcLevel: %u, Charges: %u, MaxCharges: %u", + (item->Magic ? "TRUE" : "FALSE"), item->Click.Effect, item->Click.Level, inst->GetCharges(), item->MaxCharges); + c->Message(0, ">> EffectType: 0x%02X, CastTime: %.2f", (uint8)item->Click.Type, ((double)item->CastTime / 1000)); + } + + if (c->Admin() >= 200) + c->Message(0, ">> MinStatus: %u", item->MinStatus); } void command_uptime(Client *c, const Seperator *sep) From d5047da637e1825cd31079d1e259e30906550ff0 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 6 Feb 2015 19:55:00 -0600 Subject: [PATCH 6/9] Fix an issue that is slowing repops down and unecessarily causing more work for respawn timer code --- zone/zonedb.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 07fe67679..cfde2ff19 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -195,11 +195,9 @@ void ZoneDatabase::UpdateSpawn2Timeleft(uint32 id, uint16 instance_id, uint32 ti //if we pass timeleft as 0 that means we clear from respawn time //otherwise we update with a REPLACE INTO if(timeleft == 0) { - std::string query = StringFormat("DELETE FROM respawn_times WHERE id=%lu " - "AND instance_id = %lu",(unsigned long)id, (unsigned long)instance_id); + std::string query = StringFormat("DELETE FROM respawn_times WHERE id=%lu AND instance_id = %lu",(unsigned long)id, (unsigned long)instance_id); auto results = QueryDatabase(query); - if (!results.Success()) - + return; } From 67ee327f5b2ffbff7accebff0473ed0c2fdb4392 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 7 Feb 2015 12:39:46 -0500 Subject: [PATCH 7/9] Better sanity checking in Client::BuyTraderItem to prevent potential exploits --- zone/trading.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/zone/trading.cpp b/zone/trading.cpp index 4d30691f5..4874716ae 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -1479,8 +1479,6 @@ static void BazaarAuditTrail(const char *seller, const char *buyer, const char * database.QueryDatabase(query); } - - void Client::BuyTraderItem(TraderBuy_Struct* tbs,Client* Trader,const EQApplicationPacket* app){ if(!Trader) return; @@ -1509,15 +1507,15 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs,Client* Trader,const EQApplicat BuyItem->GetItem()->Name, BuyItem->IsStackable(), tbs->Quantity, BuyItem->GetCharges()); // If the item is not stackable, then we can only be buying one of them. if(!BuyItem->IsStackable()) - outtbs->Quantity = tbs->Quantity; + outtbs->Quantity = 1; // normally you can't send more than 1 here else { // Stackable items, arrows, diamonds, etc - int ItemCharges = BuyItem->GetCharges(); + int32 ItemCharges = BuyItem->GetCharges(); // ItemCharges for stackables should not be <= 0 if(ItemCharges <= 0) outtbs->Quantity = 1; // If the purchaser requested more than is in the stack, just sell them how many are actually in the stack. - else if(ItemCharges < (int16)tbs->Quantity) + else if(static_cast(ItemCharges) < tbs->Quantity) outtbs->Quantity = ItemCharges; else outtbs->Quantity = tbs->Quantity; @@ -1609,7 +1607,6 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs,Client* Trader,const EQApplicat safe_delete(outapp); safe_delete(outapp2); - } void Client::SendBazaarWelcome() From edbd0552773343fd2dc47292874e946d5133d3c8 Mon Sep 17 00:00:00 2001 From: JJ Date: Sat, 7 Feb 2015 17:27:48 -0500 Subject: [PATCH 8/9] Revert b96e5a7f4d0087d98e186c45ee05b5aa5bf4dba0 to search for better fix. --- zone/groups.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/groups.h b/zone/groups.h index 71935bf81..7dcbd848b 100644 --- a/zone/groups.h +++ b/zone/groups.h @@ -73,7 +73,7 @@ public: void SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter = nullptr); inline void SetLeader(Mob* newleader){ leader=newleader; }; inline Mob* GetLeader() { return leader; }; - const char* GetLeaderName() { return leader->GetName(); }; + const char* GetLeaderName() { return membername[0]; }; void SendHPPacketsTo(Mob* newmember); void SendHPPacketsFrom(Mob* newmember); bool UpdatePlayer(Mob* update); From 452b1a1eae3aa627080a4f421f4f8469ae37f398 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 7 Feb 2015 15:54:42 -0800 Subject: [PATCH 9/9] Added throttling to some appearance packets, also removed responding to client light packets. With the new light code we'll tell the client when the light has changed not the other way around. --- zone/client.cpp | 5 +++++ zone/client.h | 5 +++++ zone/client_packet.cpp | 36 +++++++++++++++++++++--------------- zone/client_process.cpp | 7 +++++++ 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/zone/client.cpp b/zone/client.cpp index 5cc5ae309..6adffd471 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -141,6 +141,11 @@ Client::Client(EQStreamInterface* ieqs) merc_timer(RuleI(Mercs, UpkeepIntervalMS)), ItemTickTimer(10000), ItemQuestTimer(500), + anim_change_timer(100), + anon_toggle_timer(250), + afk_toggle_timer(250), + helm_toggle_timer(250), + light_update_timer(250), m_Proximity(FLT_MAX, FLT_MAX, FLT_MAX), //arbitrary large number m_ZoneSummonLocation(-2.0f,-2.0f,-2.0f), m_AutoAttackPosition(0.0f, 0.0f, 0.0f, 0.0f), diff --git a/zone/client.h b/zone/client.h index a2cb823f1..3d5bc8e4b 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1465,6 +1465,11 @@ private: Timer TrackingTimer; Timer RespawnFromHoverTimer; Timer merc_timer; + Timer anim_change_timer; + Timer anon_toggle_timer; + Timer afk_toggle_timer; + Timer helm_toggle_timer; + Timer light_update_timer; glm::vec3 m_Proximity; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 8ade0bc55..24a811016 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -12640,6 +12640,10 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app) else if (sa->type == AT_Anim) { if (IsAIControlled()) return; + + if(!anim_change_timer.Check()) + return; + if (sa->parameter == ANIM_STAND) { SetAppearance(eaStanding); playeraction = 0; @@ -12673,15 +12677,6 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app) SetFeigned(false); } - // This is from old code - // I have no clue what it's for - /* - else if (sa->parameter == 0x05) { - // Illusion - std::cout << "Illusion packet recv'd:" << std::endl; - DumpPacket(app); - } - */ else { std::cerr << "Client " << name << " unknown apperance " << (int)sa->parameter << std::endl; return; @@ -12690,6 +12685,10 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app) entity_list.QueueClients(this, app, true); } else if (sa->type == AT_Anon) { + if(!anon_toggle_timer.Check()) { + return; + } + // For Anon/Roleplay if (sa->parameter == 1) { // Anon m_pp.anon = 1; @@ -12711,13 +12710,18 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app) return; } else if (sa->type == AT_AFK) { - this->AFK = (sa->parameter == 1); - entity_list.QueueClients(this, app, true); + if(afk_toggle_timer.Check()) { + AFK = (sa->parameter == 1); + entity_list.QueueClients(this, app, true); + } } else if (sa->type == AT_Split) { m_pp.autosplit = (sa->parameter == 1); } else if (sa->type == AT_Sneak) { + if(sneaking == 0) + return; + if (sa->parameter != 0) { if (!HasSkill(SkillSneak)) @@ -12729,7 +12733,7 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app) } return; } - this->sneaking = 0; + sneaking = 0; entity_list.QueueClients(this, app, true); } else if (sa->type == AT_Size) @@ -12741,7 +12745,7 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app) } else if (sa->type == AT_Light) // client emitting light (lightstone, shiny shield) { - entity_list.QueueClients(this, app, false); + //don't do anything with this } else if (sa->type == AT_Levitate) { @@ -12750,8 +12754,10 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app) } else if (sa->type == AT_ShowHelm) { - m_pp.showhelm = (sa->parameter == 1); - entity_list.QueueClients(this, app, true); + if(helm_toggle_timer.Check()) { + m_pp.showhelm = (sa->parameter == 1); + entity_list.QueueClients(this, app, true); + } } else { std::cout << "Unknown SpawnAppearance type: 0x" << std::hex << std::setw(4) << std::setfill('0') << sa->type << std::dec diff --git a/zone/client_process.cpp b/zone/client_process.cpp index bddc874c2..e978552e8 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -260,6 +260,13 @@ bool Client::Process() { } } + if(light_update_timer.Check()) { + UpdateEquipLightValue(); + if(UpdateActiveLightValue()) { + SendAppearancePacket(AT_Light, GetActiveLightValue()); + } + } + bool may_use_attacks = false; /* Things which prevent us from attacking: