From c68ff9bc5a65acd82ea6a887ce416f9c96f46dde Mon Sep 17 00:00:00 2001 From: Quintinon Date: Sat, 30 Jul 2022 11:16:47 -0700 Subject: [PATCH] [Rules] Update logic checks everywhere for FVNoDropFlag. (#2179) * Update logic checks everywhere for FVNoDropFlag. FVNoDropFlag == 0 is disabled FVNoDropFlag == 1 is enabled for everyone FVNoDropFlag == 2 is enabled for Admin() >= Character:MinStatusForNoDropExemptions * Adding extra parenthesis to reduce ambiquity of order of operations for FVNoDropFlag checks * Move FVNoDropFlag checks into a helper function in emu_constants.cpp and make an enum for the possible values. Added console warning if setting is outside of allowed values. * Move to client scoped helper method Co-authored-by: Akkadius --- common/emu_constants.cpp | 15 +++++++++------ common/emu_constants.h | 12 ++++-------- common/eq_constants.h | 7 +++++++ world/client.cpp | 22 +++++++++++++++++++++- world/client.h | 1 + zone/client.h | 1 + zone/client_packet.cpp | 20 ++++++++++++++++++++ zone/inventory.cpp | 5 ++--- zone/trading.cpp | 5 +++-- 9 files changed, 68 insertions(+), 20 deletions(-) diff --git a/common/emu_constants.cpp b/common/emu_constants.cpp index ad720123c..9b8fb9076 100644 --- a/common/emu_constants.cpp +++ b/common/emu_constants.cpp @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify @@ -18,9 +18,12 @@ */ #include "emu_constants.h" -#include "languages.h" -#include "data_verification.h" #include "bodytypes.h" +#include "data_verification.h" +#include "eqemu_logsys.h" +#include "eqemu_logsys_log_aliases.h" +#include "languages.h" +#include "rulesys.h" int16 EQ::invtype::GetInvTypeSize(int16 inv_type) { static const int16 local_array[] = { @@ -117,7 +120,7 @@ EQ::bug::CategoryID EQ::bug::CategoryNameToCategoryID(const char* category_name) return catLoNTCG; if (!strcmp(category_name, "Mercenaries")) return catMercenaries; - + return catOther; } @@ -221,7 +224,7 @@ std::string EQ::constants::GetLDoNThemeName(uint32 theme_id) return EQ::constants::GetLDoNThemeMap().find(theme_id)->second; } - return std::string(); + return std::string(); } const std::map& EQ::constants::GetFlyModeMap() @@ -321,7 +324,7 @@ const std::map& EQ::constants::GetAccountStatusMap() { AccountStatus::GMAreas, "GM Areas" }, { AccountStatus::GMCoder, "GM Coder" }, { AccountStatus::GMMgmt, "GM Mgmt" }, - { AccountStatus::GMImpossible, "GM Impossible" }, + { AccountStatus::GMImpossible, "GM Impossible" }, { AccountStatus::Max, "GM Max" } }; diff --git a/common/emu_constants.h b/common/emu_constants.h index 941393316..ba4aaedc5 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify @@ -32,10 +32,6 @@ namespace EQ { using RoF2::IINVALID; using RoF2::INULL; - - namespace inventory { - - } /*inventory*/ namespace invtype { using namespace RoF2::invtype::enum_; @@ -201,7 +197,7 @@ namespace EQ using RoF2::constants::EXPANSIONS_MASK; using RoF2::constants::CHARACTER_CREATION_LIMIT; - + const size_t SAY_LINK_OPENER_SIZE = 1; using RoF2::constants::SAY_LINK_BODY_SIZE; const size_t SAY_LINK_TEXT_SIZE = 256; // this may be varied until it breaks something (tested:374) - the others are constant @@ -260,7 +256,7 @@ namespace EQ extern const std::map& GetLDoNThemeMap(); std::string GetLDoNThemeName(uint32 theme_id); - + extern const std::map& GetFlyModeMap(); std::string GetFlyModeName(int8 flymode_id); @@ -291,7 +287,7 @@ namespace EQ namespace profile { using RoF2::profile::BANDOLIERS_SIZE; using RoF2::profile::BANDOLIER_ITEM_COUNT; - + using RoF2::profile::POTION_BELT_SIZE; using RoF2::profile::SKILL_ARRAY_SIZE; diff --git a/common/eq_constants.h b/common/eq_constants.h index 8949ea109..4f3c89f7a 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -1009,4 +1009,11 @@ enum StartZoneIndex { SharVahl }; +enum FVNoDropFlagRule +{ + Disabled = 0, + Enabled = 1, + AdminOnly = 2 +}; + #endif /*COMMON_EQ_CONSTANTS_H*/ diff --git a/world/client.cpp b/world/client.cpp index c08cb419a..fc9aa73af 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -156,13 +156,33 @@ void Client::SendLogServer() if(RuleB(World, IsGMPetitionWindowEnabled)) l->enable_petition_wnd = 1; - if((RuleI(World, FVNoDropFlag) == 1 || RuleI(World, FVNoDropFlag) == 2) && GetAdmin() > RuleI(Character, MinStatusForNoDropExemptions)) + if (CanTradeFVNoDropItem()) { l->enable_FV = 1; + } QueuePacket(outapp); safe_delete(outapp); } +bool Client::CanTradeFVNoDropItem() +{ + const int16 admin_status = GetAdmin(); + const int no_drop_flag = RuleI(World, FVNoDropFlag); + const int no_drop_min_admin_status = RuleI(Character, MinStatusForNoDropExemptions); + switch (no_drop_flag) { + case FVNoDropFlagRule::Disabled: + return false; + case FVNoDropFlagRule::Enabled: + return true; + case FVNoDropFlagRule::AdminOnly: + return admin_status >= no_drop_min_admin_status; + default: + LogWarning("Invalid value {0} set for FVNoDropFlag", no_drop_flag); + return false; + } + return false; +} + void Client::SendEnterWorld(std::string name) { char char_name[64] = { 0 }; diff --git a/world/client.h b/world/client.h index 76f14e6c1..93aacb31d 100644 --- a/world/client.h +++ b/world/client.h @@ -120,6 +120,7 @@ private: bool ChecksumVerificationCRCBaseData(uint64 checksum); EQStreamInterface* eqs; + bool CanTradeFVNoDropItem(); }; bool CheckCharCreateInfoSoF(CharCreate_Struct *cc); diff --git a/zone/client.h b/zone/client.h index 0d693dee3..99e02e002 100644 --- a/zone/client.h +++ b/zone/client.h @@ -2049,6 +2049,7 @@ private: bool m_bot_precombat; #endif + bool CanTradeFVNoDropItem(); }; #endif diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index d27a153ec..ff72a57d5 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -15559,3 +15559,23 @@ void Client::SetSharedTaskId(int64 shared_task_id) { Client::m_shared_task_id = shared_task_id; } + +bool Client::CanTradeFVNoDropItem() +{ + const int16 admin_status = Admin(); + const int no_drop_flag = RuleI(World, FVNoDropFlag); + const int no_drop_min_admin_status = RuleI(Character, MinStatusForNoDropExemptions); + switch (no_drop_flag) { + case FVNoDropFlagRule::Disabled: + return false; + case FVNoDropFlagRule::Enabled: + return true; + case FVNoDropFlagRule::AdminOnly: + return admin_status >= no_drop_min_admin_status; + default: + LogWarning("Invalid value {0} set for FVNoDropFlag", no_drop_flag); + return false; + } + + return false; +} diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 7fe8a7789..055b3931c 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -814,8 +814,7 @@ void Client::DropItem(int16 slot_id, bool recurse) LogInventory("[{}] (char_id: [{}]) Attempting to drop item from slot [{}] on the ground", GetCleanName(), CharacterID(), slot_id); - if(GetInv().CheckNoDrop(slot_id, recurse) && RuleI(World, FVNoDropFlag) == 0 || - RuleI(Character, MinStatusForNoDropExemptions) < Admin() && RuleI(World, FVNoDropFlag) == 2) + if(GetInv().CheckNoDrop(slot_id, recurse) && !CanTradeFVNoDropItem()) { auto invalid_drop = m_inv.GetItem(slot_id); if (!invalid_drop) { @@ -1963,7 +1962,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { if (((with && with->IsClient() && dst_slot_id >= EQ::invslot::TRADE_BEGIN && dst_slot_id <= EQ::invslot::TRADE_END) || (dst_slot_id >= EQ::invslot::SHARED_BANK_BEGIN && dst_slot_id <= EQ::invbag::SHARED_BANK_BAGS_END)) && GetInv().CheckNoDrop(src_slot_id) - && RuleI(World, FVNoDropFlag) == 0 || RuleI(Character, MinStatusForNoDropExemptions) < Admin() && RuleI(World, FVNoDropFlag) == 2) { + && !CanTradeFVNoDropItem()) { auto ndh_inst = m_inv[src_slot_id]; std::string ndh_item_data; if (ndh_inst == nullptr) { diff --git a/zone/trading.cpp b/zone/trading.cpp index 9ae72ceb5..22c1006b5 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -499,7 +499,8 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st LogTrading("Giving container [{}] ([{}]) in slot [{}] to [{}]", inst->GetItem()->Name, inst->GetItem()->ID, trade_slot, other->GetName()); // TODO: need to check bag items/augments for no drop..everything for attuned... - if (inst->GetItem()->NoDrop != 0 || Admin() >= RuleI(Character, MinStatusForNoDropExemptions) || RuleI(World, FVNoDropFlag) == 1 || other == this) { + if (inst->GetItem()->NoDrop != 0 || + CanTradeFVNoDropItem() && CanTradeFVNoDropItem() || other == this) { int16 free_slot = other->GetInv().FindFreeSlotForTradeItem(inst); if (free_slot != INVALID_INDEX) { @@ -717,7 +718,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st LogTrading("Giving item [{}] ([{}]) in slot [{}] to [{}]", inst->GetItem()->Name, inst->GetItem()->ID, trade_slot, other->GetName()); // TODO: need to check bag items/augments for no drop..everything for attuned... - if (inst->GetItem()->NoDrop != 0 || Admin() >= RuleI(Character, MinStatusForNoDropExemptions) || RuleI(World, FVNoDropFlag) == 1 || other == this) { + if (inst->GetItem()->NoDrop != 0 || CanTradeFVNoDropItem() || other == this) { int16 free_slot = other->GetInv().FindFreeSlotForTradeItem(inst); if (free_slot != INVALID_INDEX) {