diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 1e37138bd..30d4e85b1 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -451,6 +451,9 @@ void Group::Disband(bool hideDestroy) void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r) { + ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(r.itemid); + uint8 voteMask = pProto->Flags2 & ITEM_FLAGS2_NEED_ROLL_DISABLED ? ROLL_VOTE_MASK_NO_NEED : ROLL_VOTE_MASK_ALL; + WorldPacket data(SMSG_LOOT_START_ROLL, (8+4+4+4+4+4+4+1)); data << r.lootedTargetGUID; // creature guid what we're looting data << uint32(mapid); // 3.3.3 mapid @@ -460,7 +463,7 @@ void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r) data << uint32(r.itemRandomPropId); // item random property ID data << uint32(r.itemCount); // items in stack data << uint32(CountDown); // the countdown time to choose "need" or "greed" - data << uint8(ALL_ROLL_VOTE_MASK); // roll type mask, allowed choises + data << uint8(voteMask); // roll type mask, allowed choices for (Roll::PlayerVote::const_iterator itr = r.playerVote.begin(); itr != r.playerVote.end(); ++itr) { @@ -619,7 +622,7 @@ void Group::MasterLoot(Creature *creature, Loot* loot) } } -void Group::CountRollVote(ObjectGuid const& playerGUID, ObjectGuid const& lootedTarget, uint32 itemSlot, RollVote choise) +bool Group::CountRollVote(ObjectGuid const& playerGUID, ObjectGuid const& lootedTarget, uint32 itemSlot, RollVote vote) { Rolls::iterator rollI = RollId.begin(); for (; rollI != RollId.end(); ++rollI) @@ -627,12 +630,18 @@ void Group::CountRollVote(ObjectGuid const& playerGUID, ObjectGuid const& looted break; if (rollI == RollId.end()) - return; + return false; - CountRollVote(playerGUID, rollI, choise); + // possible cheating + ItemPrototype const* pProto = ObjectMgr::GetItemPrototype((*rollI)->itemid); + if ((pProto->Flags2 & ITEM_FLAGS2_NEED_ROLL_DISABLED) && vote == ROLL_NEED) + return false; + + CountRollVote(playerGUID, rollI, vote); // result not related this function result meaning, ignore + return true; } -bool Group::CountRollVote(ObjectGuid const& playerGUID, Rolls::iterator& rollI, RollVote choise) +bool Group::CountRollVote(ObjectGuid const& playerGUID, Rolls::iterator& rollI, RollVote vote) { Roll* roll = *rollI; @@ -645,7 +654,7 @@ bool Group::CountRollVote(ObjectGuid const& playerGUID, Rolls::iterator& rollI, if (roll->getLoot()->items.empty()) return false; - switch (choise) + switch (vote) { case ROLL_PASS: // Player choose pass { diff --git a/src/game/Group.h b/src/game/Group.h index ea8d73708..927d326f0 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -42,8 +42,6 @@ enum LootMethod NEED_BEFORE_GREED = 4 }; -#define ALL_ROLL_VOTE_MASK 0x0F // set what votes allowed - enum RollVote { ROLL_PASS = 0, @@ -58,6 +56,20 @@ enum RollVote ROLL_NOT_VALID = 5 // not send to client }; +// set what votes allowed +enum RollVoteMask +{ + ROLL_VOTE_MASK_PASS = 0x01, + ROLL_VOTE_MASK_NEED = 0x02, + ROLL_VOTE_MASK_GREED = 0x04, + ROLL_VOTE_MASK_DISENCHANT = 0x08, + + ROLL_VOTE_MASK_ALL = 0x0F, + + ROLL_VOTE_MASK_NO_NEED = ROLL_VOTE_MASK_ALL & ~ROLL_VOTE_MASK_NEED, +}; + + enum GroupMemberOnlineStatus { MEMBER_STATUS_OFFLINE = 0x0000, @@ -345,7 +357,7 @@ class MANGOS_DLL_SPEC Group void GroupLoot(Creature *creature, Loot *loot); void NeedBeforeGreed(Creature *creature, Loot *loot); void MasterLoot(Creature *creature, Loot *loot); - void CountRollVote(ObjectGuid const& playerGUID, ObjectGuid const& lootedTarget, uint32 itemSlot, RollVote choise); + bool CountRollVote(ObjectGuid const& playerGUID, ObjectGuid const& lootedTarget, uint32 itemSlot, RollVote vote); void StartLootRool(Creature* lootTarget, Loot* loot, uint8 itemSlot, bool skipIfCanNotUse); void EndRoll(); @@ -418,7 +430,7 @@ class MANGOS_DLL_SPEC Group } void CountTheRoll(Rolls::iterator& roll); // iterator update to next, in CountRollVote if true - bool CountRollVote(ObjectGuid const& playerGUID, Rolls::iterator& roll, RollVote choise); + bool CountRollVote(ObjectGuid const& playerGUID, Rolls::iterator& roll, RollVote vote); GroupFlagMask GetFlags(MemberSlot const& slot) const { diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index d73b2330d..ef0b40502 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -392,8 +392,9 @@ void WorldSession::HandleLootRoll( WorldPacket &recv_data ) if (rollType >= MAX_ROLL_FROM_CLIENT) return; - // everything is fine, do it - group->CountRollVote(GetPlayer()->GetObjectGuid(), lootedTarget, itemSlot, RollVote(rollType)); + // everything is fine, do it, if false then some cheating problem found + if(!group->CountRollVote(GetPlayer()->GetObjectGuid(), lootedTarget, itemSlot, RollVote(rollType))) + return; switch (rollType) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index eba602429..e9dc983ab 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10212" + #define REVISION_NR "10213" #endif // __REVISION_NR_H__