[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 <akkadius1@gmail.com>
This commit is contained in:
Quintinon 2022-07-30 11:16:47 -07:00 committed by GitHub
parent 3bda8251b9
commit c68ff9bc5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 68 additions and 20 deletions

View File

@ -18,9 +18,12 @@
*/ */
#include "emu_constants.h" #include "emu_constants.h"
#include "languages.h"
#include "data_verification.h"
#include "bodytypes.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) { int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
static const int16 local_array[] = { static const int16 local_array[] = {

View File

@ -33,10 +33,6 @@ namespace EQ
using RoF2::IINVALID; using RoF2::IINVALID;
using RoF2::INULL; using RoF2::INULL;
namespace inventory {
} /*inventory*/
namespace invtype { namespace invtype {
using namespace RoF2::invtype::enum_; using namespace RoF2::invtype::enum_;

View File

@ -1009,4 +1009,11 @@ enum StartZoneIndex {
SharVahl SharVahl
}; };
enum FVNoDropFlagRule
{
Disabled = 0,
Enabled = 1,
AdminOnly = 2
};
#endif /*COMMON_EQ_CONSTANTS_H*/ #endif /*COMMON_EQ_CONSTANTS_H*/

View File

@ -156,13 +156,33 @@ void Client::SendLogServer()
if(RuleB(World, IsGMPetitionWindowEnabled)) if(RuleB(World, IsGMPetitionWindowEnabled))
l->enable_petition_wnd = 1; l->enable_petition_wnd = 1;
if((RuleI(World, FVNoDropFlag) == 1 || RuleI(World, FVNoDropFlag) == 2) && GetAdmin() > RuleI(Character, MinStatusForNoDropExemptions)) if (CanTradeFVNoDropItem()) {
l->enable_FV = 1; l->enable_FV = 1;
}
QueuePacket(outapp); QueuePacket(outapp);
safe_delete(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) void Client::SendEnterWorld(std::string name)
{ {
char char_name[64] = { 0 }; char char_name[64] = { 0 };

View File

@ -120,6 +120,7 @@ private:
bool ChecksumVerificationCRCBaseData(uint64 checksum); bool ChecksumVerificationCRCBaseData(uint64 checksum);
EQStreamInterface* eqs; EQStreamInterface* eqs;
bool CanTradeFVNoDropItem();
}; };
bool CheckCharCreateInfoSoF(CharCreate_Struct *cc); bool CheckCharCreateInfoSoF(CharCreate_Struct *cc);

View File

@ -2049,6 +2049,7 @@ private:
bool m_bot_precombat; bool m_bot_precombat;
#endif #endif
bool CanTradeFVNoDropItem();
}; };
#endif #endif

View File

@ -15559,3 +15559,23 @@ void Client::SetSharedTaskId(int64 shared_task_id)
{ {
Client::m_shared_task_id = 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;
}

View File

@ -814,8 +814,7 @@ void Client::DropItem(int16 slot_id, bool recurse)
LogInventory("[{}] (char_id: [{}]) Attempting to drop item from slot [{}] on the ground", LogInventory("[{}] (char_id: [{}]) Attempting to drop item from slot [{}] on the ground",
GetCleanName(), CharacterID(), slot_id); GetCleanName(), CharacterID(), slot_id);
if(GetInv().CheckNoDrop(slot_id, recurse) && RuleI(World, FVNoDropFlag) == 0 || if(GetInv().CheckNoDrop(slot_id, recurse) && !CanTradeFVNoDropItem())
RuleI(Character, MinStatusForNoDropExemptions) < Admin() && RuleI(World, FVNoDropFlag) == 2)
{ {
auto invalid_drop = m_inv.GetItem(slot_id); auto invalid_drop = m_inv.GetItem(slot_id);
if (!invalid_drop) { 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) || 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)) (dst_slot_id >= EQ::invslot::SHARED_BANK_BEGIN && dst_slot_id <= EQ::invbag::SHARED_BANK_BAGS_END))
&& GetInv().CheckNoDrop(src_slot_id) && 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]; auto ndh_inst = m_inv[src_slot_id];
std::string ndh_item_data; std::string ndh_item_data;
if (ndh_inst == nullptr) { if (ndh_inst == nullptr) {

View File

@ -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()); 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... // 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); int16 free_slot = other->GetInv().FindFreeSlotForTradeItem(inst);
if (free_slot != INVALID_INDEX) { 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()); 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... // 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); int16 free_slot = other->GetInv().FindFreeSlotForTradeItem(inst);
if (free_slot != INVALID_INDEX) { if (free_slot != INVALID_INDEX) {