aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMachiavelli <none@none>2010-06-22 00:42:31 +0200
committerMachiavelli <none@none>2010-06-22 00:42:31 +0200
commiteefe75a31f58c24ec471aa8cd9502fc2b2dfb95b (patch)
tree084b8faffd1b727074003a029ad53ed1fabb2614 /src
parent4e361d0d9b339dde22a1edd7cc9ce5a33cb2f9f0 (diff)
Fix possible bug occuring during shuffling of raid subgroups, and prevent client side exploit. Author: Vladimir.
--HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Groups/Group.cpp19
-rw-r--r--src/server/game/Groups/Group.h7
-rw-r--r--src/server/game/Server/Protocol/Handlers/GroupHandler.cpp24
3 files changed, 31 insertions, 19 deletions
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 95912f21f10..53fa9a3ecdb 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -1192,7 +1192,7 @@ bool Group::_addMember(const uint64 &guid, const char* name)
if (m_subGroupsCounts)
{
bool groupFound = false;
- for (; groupid < MAXRAIDSIZE/MAXGROUPSIZE; ++groupid)
+ for (; groupid < MAX_RAID_SUBGROUPS; ++groupid)
{
if (m_subGroupsCounts[groupid] < MAXGROUPSIZE)
{
@@ -1445,17 +1445,20 @@ void Group::ChangeMembersGroup(const uint64 &guid, const uint8 &group)
{
if (!isRaidGroup())
return;
+
Player *player = objmgr.GetPlayer(guid);
if (!player)
{
- uint8 prevSubGroup;
- prevSubGroup = GetMemberGroup(guid);
-
- SubGroupCounterDecrease(prevSubGroup);
+ uint8 prevSubGroup = GetMemberGroup(guid);
+ if (prevSubGroup == group)
+ return;
if (_setMembersGroup(guid, group))
+ {
+ SubGroupCounterDecrease(prevSubGroup);
SendUpdate();
+ }
}
else
// This methods handles itself groupcounter decrease
@@ -1467,9 +1470,13 @@ void Group::ChangeMembersGroup(Player *player, const uint8 &group)
{
if (!player || !isRaidGroup())
return;
+
+ uint8 prevSubGroup = player->GetSubGroup();
+ if (prevSubGroup == group)
+ return;
+
if (_setMembersGroup(player->GetGUID(), group))
{
- uint8 prevSubGroup = player->GetSubGroup();
if (player->GetGroup() == this)
player->GetGroupRef().setSubGroup(group);
//if player is in BG raid, it is possible that he is also in normal raid - and that normal raid is stored in m_originalGroup reference
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index 808de417b79..8ec44c53b02 100644
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -33,6 +33,7 @@
#define MAXGROUPSIZE 5
#define MAXRAIDSIZE 40
+#define MAX_RAID_SUBGROUPS MAXRAIDSIZE/MAXGROUPSIZE
#define TARGETICONCOUNT 8
enum RollVote
@@ -260,7 +261,7 @@ class Group
{
member_citerator mslot = _getMemberCSlot(guid);
if (mslot == m_memberSlots.end())
- return (MAXRAIDSIZE/MAXGROUPSIZE+1);
+ return (MAX_RAID_SUBGROUPS+1);
return mslot->group;
}
@@ -381,9 +382,9 @@ class Group
{
// Sub group counters initialization
if (!m_subGroupsCounts)
- m_subGroupsCounts = new uint8[MAXRAIDSIZE / MAXGROUPSIZE];
+ m_subGroupsCounts = new uint8[MAX_RAID_SUBGROUPS];
- memset((void*)m_subGroupsCounts, 0, (MAXRAIDSIZE / MAXGROUPSIZE)*sizeof(uint8));
+ memset((void*)m_subGroupsCounts, 0, (MAX_RAID_SUBGROUPS)*sizeof(uint8));
for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
++m_subGroupsCounts[itr->group];
diff --git a/src/server/game/Server/Protocol/Handlers/GroupHandler.cpp b/src/server/game/Server/Protocol/Handlers/GroupHandler.cpp
index 29178465ec3..bcefc763ae2 100644
--- a/src/server/game/Server/Protocol/Handlers/GroupHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/GroupHandler.cpp
@@ -534,8 +534,10 @@ void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket & recv_data)
std::string name;
uint8 groupNr;
recv_data >> name;
-
recv_data >> groupNr;
+
+ if (groupNr >= MAX_RAID_SUBGROUPS)
+ return;
/** error handling **/
uint64 senderGuid = GetPlayer()->GetGUID();
@@ -546,16 +548,18 @@ void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket & recv_data)
return;
/********************/
- Player *movedPlayer=objmgr.GetPlayer(name.c_str());
- if (!movedPlayer)
- return;
-
- //Do not allow leader to change group of player in combat
- if (movedPlayer->isInCombat())
- return;
+ Player *movedPlayer = objmgr.GetPlayer(name.c_str());
+ if (movedPlayer)
+ {
+ //Do not allow leader to change group of player in combat
+ if (movedPlayer->isInCombat())
+ return;
- // everything's fine, do it
- group->ChangeMembersGroup(movedPlayer, groupNr);
+ // everything's fine, do it
+ group->ChangeMembersGroup(movedPlayer, groupNr);
+ }
+ else
+ group->ChangeMembersGroup(objmgr.GetPlayerGUIDByName(name.c_str()), groupNr);
}
void WorldSession::HandleGroupAssistantLeaderOpcode(WorldPacket & recv_data)