root/trunk/src/arcemu-world/GroupHandler.cpp @ 3160

Revision 3160, 12.8 kB (checked in by jackpoz, 7 months ago)

FIXED: Raid leaders received a "You left the group" message when inviting someone in the raid, even if they were still in the raid.
FIXED: Crash added in r3158.

  • Property svn:eol-style set to native
  • Property ff set to
    *.cpp = svn:eol-style=native
    Makefile = svn:eol-style=native
    README = svn:eol-style=native
    CHANGELOG = svn:eol-style=native
    LICENSE = svn:eol-style=native
  • Property svn:keywords set to Date Author Rev
Line 
1/*
2 * ArcEmu MMORPG Server
3 * Copyright (C) 2005-2007 Ascent Team <http://www.ascentemu.com/>
4 * Copyright (C) 2008-2010 <http://www.ArcEmu.org/>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include "StdAfx.h"
22
23//////////////////////////////////////////////////////////////
24/// This function handles CMSG_GROUP_INVITE
25//////////////////////////////////////////////////////////////
26void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )
27{
28        if(!_player->IsInWorld()) return;
29        CHECK_PACKET_SIZE(recv_data, 1);
30        WorldPacket data(100);
31        std::string membername;
32        Group *group = NULL;
33
34        recv_data >> membername;
35        if( _player->HasBeenInvited() )
36                return;
37
38        Player * player = objmgr.GetPlayer( membername.c_str(), false );
39
40        if( player == NULL)
41        {
42                SendPartyCommandResult(_player, 0, membername, ERR_PARTY_CANNOT_FIND);
43                return;
44        }
45
46        if( player == _player )
47        {
48                return;
49        }
50
51        if ( _player->InGroup() && !_player->IsGroupLeader() )
52        {
53                SendPartyCommandResult(_player, 0, "", ERR_PARTY_YOU_ARE_NOT_LEADER);
54                return;
55        }
56
57        group = _player->GetGroup();
58        if ( group != NULL )
59        {
60                if (group->IsFull())
61                {
62                        SendPartyCommandResult(_player, 0, "", ERR_PARTY_IS_FULL);
63                        return;
64                }
65        }
66       
67        if ( player->InGroup() )
68        {
69                SendPartyCommandResult(_player, player->GetGroup()->GetGroupType(), membername, ERR_PARTY_ALREADY_IN_GROUP);
70                data.SetOpcode(SMSG_GROUP_INVITE);
71                data << uint8(0);
72                data << GetPlayer()->GetName();
73                player->GetSession()->SendPacket(&data);
74                return;
75        }
76       
77        if(player->GetTeam()!=_player->GetTeam() && _player->GetSession()->GetPermissionCount() == 0 && !sWorld.interfaction_group)
78        {
79                SendPartyCommandResult(_player, 0, membername, ERR_PARTY_WRONG_FACTION);
80                return;
81        }
82
83        if ( player->HasBeenInvited() )
84        {
85                SendPartyCommandResult(_player, 0, membername, ERR_PARTY_ALREADY_IN_GROUP);
86                return;
87        }
88
89        if( player->Social_IsIgnoring( _player->GetLowGUID() ) )
90        {
91                SendPartyCommandResult(_player, 0, membername, ERR_PARTY_IS_IGNORING_YOU);
92                return;
93        }
94       
95        if( player->bGMTagOn && !_player->GetSession()->HasPermissions())
96        {
97                SendPartyCommandResult(_player, 0, membername, ERR_PARTY_CANNOT_FIND);
98                return;
99        }
100       
101        data.SetOpcode(SMSG_GROUP_INVITE);
102        data << uint8(1);
103        data << GetPlayer()->GetName();
104
105        player->GetSession()->SendPacket(&data);
106
107        SendPartyCommandResult(_player, 0, membername, ERR_PARTY_NO_ERROR);
108
109        // 16/08/06 - change to guid to prevent very unlikely event of a crash in deny, etc
110        player->SetInviter(_player->GetLowGUID());
111}
112
113///////////////////////////////////////////////////////////////
114///This function handles CMSG_GROUP_CANCEL:
115///////////////////////////////////////////////////////////////
116void WorldSession::HandleGroupCancelOpcode( WorldPacket & recv_data )
117{
118        if(!_player->IsInWorld()) return;
119        sLog.outDebug( "WORLD: got CMSG_GROUP_CANCEL." );
120}
121
122////////////////////////////////////////////////////////////////
123///This function handles CMSG_GROUP_ACCEPT:
124////////////////////////////////////////////////////////////////
125void WorldSession::HandleGroupAcceptOpcode( WorldPacket & recv_data )
126{
127        if(!_player->IsInWorld()) return;
128
129        Player *player = objmgr.GetPlayer(_player->GetInviter());
130        if ( !player )
131                return;
132       
133        player->SetInviter(0);
134        _player->SetInviter(0);
135       
136        Group *grp = player->GetGroup();
137
138        if(grp)
139        {
140                grp->AddMember(_player->m_playerInfo);
141                _player->iInstanceType = grp->m_difficulty;
142                _player->SendDungeonDifficulty();
143
144        //sInstanceSavingManager.ResetSavedInstancesForPlayer(_player);
145                return;
146        }
147       
148        // If we're this far, it means we have no existing group, and have to make one.
149        grp = new Group(true);
150        grp->m_difficulty = static_cast<uint8>( player->iInstanceType );
151        grp->AddMember(player->m_playerInfo);           // add the inviter first, therefore he is the leader
152        grp->AddMember(_player->m_playerInfo);     // add us.
153        _player->iInstanceType = grp->m_difficulty;
154        _player->SendDungeonDifficulty();
155
156        Instance *instance = sInstanceMgr.GetInstanceByIds(player->GetMapId(), player->GetInstanceID());
157        if(instance != NULL && instance->m_creatorGuid == player->GetLowGUID())
158        {
159                grp->m_instanceIds[instance->m_mapId][instance->m_difficulty] = instance->m_instanceId;
160                instance->m_creatorGroup = grp->GetID();
161                instance->m_creatorGuid = 0;
162                instance->SaveToDB();
163        }
164
165    //sInstanceSavingManager.ResetSavedInstancesForPlayer(_player);
166
167        // Currentgroup and all that shit are set by addmember.
168}
169
170///////////////////////////////////////////////////////////////////////////////////////
171///This function handles CMSG_GROUP_DECLINE:
172//////////////////////////////////////////////////////////////////////////////////////
173void WorldSession::HandleGroupDeclineOpcode( WorldPacket & recv_data )
174{
175        if(!_player->IsInWorld()) return;
176        WorldPacket data(SMSG_GROUP_DECLINE, 100);
177
178        Player *player = objmgr.GetPlayer(_player->GetInviter());
179        if(!player) return;
180
181        data << GetPlayer()->GetName();
182
183        player->GetSession()->SendPacket( &data );
184        player->SetInviter(0);
185        _player->SetInviter(0);
186}
187
188//////////////////////////////////////////////////////////////////////////////////////////
189///This function handles CMSG_GROUP_UNINVITE(unused since 3.1.3):
190//////////////////////////////////////////////////////////////////////////////////////////
191void WorldSession::HandleGroupUninviteOpcode( WorldPacket & recv_data )
192{
193        if(!_player->IsInWorld()) return;
194        CHECK_PACKET_SIZE(recv_data, 1);
195        std::string membername;
196        Group *group;
197        Player * player;
198        PlayerInfo * info;
199
200        recv_data >> membername;
201
202        player = objmgr.GetPlayer(membername.c_str(), false);
203        info = objmgr.GetPlayerInfoByName(membername.c_str());
204        if ( player == NULL && info == NULL )
205        {
206                SendPartyCommandResult(_player, 0, membername, ERR_PARTY_CANNOT_FIND);
207                return;
208        }
209
210        if ( !_player->InGroup() || info->m_Group != _player->GetGroup() )
211        {
212                SendPartyCommandResult(_player, 0, membername, ERR_PARTY_IS_NOT_IN_YOUR_PARTY);
213                return;
214        }
215
216        if ( !_player->IsGroupLeader() )
217        {
218                if (player == NULL)
219                {
220                        SendPartyCommandResult(_player, 0, membername, ERR_PARTY_CANNOT_FIND);
221                        return;
222                }
223                else if(_player != player)
224                {
225                        SendPartyCommandResult(_player, 0, "", ERR_PARTY_YOU_ARE_NOT_LEADER);
226                        return;
227                }
228        }
229
230        group = _player->GetGroup();
231
232        if(group)
233        {
234                group->RemovePlayer(info);
235        }
236}
237
238//////////////////////////////////////////////////////////////////////////////////////////
239///This function handles CMSG_GROUP_UNINVITE_GUID(used since 3.1.3):
240//////////////////////////////////////////////////////////////////////////////////////////
241void WorldSession::HandleGroupUninviteGuidOpcode( WorldPacket & recv_data )
242{
243        if(!_player->IsInWorld()) return;
244        CHECK_PACKET_SIZE(recv_data, 1);
245        uint64 PlayerGUID;
246        std::string membername = "unknown";
247        Group *group;
248        Player * player;
249        PlayerInfo * info;
250
251        recv_data >> PlayerGUID;
252
253        player = objmgr.GetPlayer( Arcemu::Util::GUID_LOPART(PlayerGUID));
254        info = objmgr.GetPlayerInfo( Arcemu::Util::GUID_LOPART(PlayerGUID));
255        // If both conditions match the player gets thrown out of the group by the server since this means the character is deleted
256        if ( player == NULL && info == NULL )
257        {
258                SendPartyCommandResult(_player, 0, membername, ERR_PARTY_CANNOT_FIND);
259                return;
260        }
261
262        membername = player ? player->GetName() : info->name;
263
264        if ( !_player->InGroup() || info->m_Group != _player->GetGroup() )
265        {
266                SendPartyCommandResult(_player, 0, membername, ERR_PARTY_IS_NOT_IN_YOUR_PARTY);
267                return;
268        }
269
270        if ( !_player->IsGroupLeader() )
271        {
272                if (player == NULL)
273                {
274                        SendPartyCommandResult(_player, 0, membername, ERR_PARTY_CANNOT_FIND);
275                        return;
276                }
277                else if(_player != player)
278                {
279                        SendPartyCommandResult(_player, 0, "", ERR_PARTY_YOU_ARE_NOT_LEADER);
280                        return;
281                }
282        }
283
284        group = _player->GetGroup();
285        if(group)
286        {
287                group->RemovePlayer(info);
288        }
289}
290
291//////////////////////////////////////////////////////////////////////////////////////////
292///This function handles CMSG_GROUP_SET_LEADER:
293//////////////////////////////////////////////////////////////////////////////////////////
294void WorldSession::HandleGroupSetLeaderOpcode( WorldPacket & recv_data )
295{
296        if(!_player->IsInWorld()) return;
297        // important note _player->GetName() can be wrong.
298        CHECK_PACKET_SIZE(recv_data, 1);
299        WorldPacket data;
300        uint64 MemberGuid;
301        Player * player;
302
303        recv_data >> MemberGuid;
304       
305        player = objmgr.GetPlayer((uint32)MemberGuid);
306
307        if ( player == NULL )
308        {
309                //SendPartyCommandResult(_player, 0, membername, ERR_PARTY_CANNOT_FIND);
310                SendPartyCommandResult(_player, 0, _player->GetName(), ERR_PARTY_CANNOT_FIND);
311                return;
312        }
313
314        if(!_player->IsGroupLeader())
315        {
316                SendPartyCommandResult(_player, 0, "", ERR_PARTY_YOU_ARE_NOT_LEADER);
317                return;
318        }
319       
320        if(player->GetGroup() != _player->GetGroup())
321        {
322                //SendPartyCommandResult(_player, 0, membername, ERR_PARTY_IS_NOT_IN_YOUR_PARTY);
323                SendPartyCommandResult(_player, 0, _player->GetName(), ERR_PARTY_IS_NOT_IN_YOUR_PARTY);
324                return;
325        }
326
327        Group *pGroup = _player->GetGroup();
328        if(pGroup)
329                pGroup->SetLeader(player,false);
330}
331
332//////////////////////////////////////////////////////////////////////////////////////////
333///This function handles CMSG_GROUP_DISBAND:
334//////////////////////////////////////////////////////////////////////////////////////////
335void WorldSession::HandleGroupDisbandOpcode( WorldPacket & recv_data )
336{
337        if(!_player->IsInWorld()) return;
338        Group* pGroup = _player->GetGroup();
339        if(!pGroup) return;
340
341        //pGroup->Disband();
342        pGroup->RemovePlayer(_player->m_playerInfo);
343}
344
345//////////////////////////////////////////////////////////////////////////////////////////
346///This function handles CMSG_LOOT_METHOD:
347//////////////////////////////////////////////////////////////////////////////////////////
348void WorldSession::HandleLootMethodOpcode( WorldPacket & recv_data )
349{
350        if(!_player->IsInWorld()) return;
351        CHECK_PACKET_SIZE(recv_data, 16);
352        uint32 lootMethod;
353        uint64 lootMaster;
354        uint32 threshold;
355
356        recv_data >> lootMethod >> lootMaster >>threshold;
357 
358        if(!_player->IsGroupLeader())
359        {
360                SendPartyCommandResult(_player, 0, "", ERR_PARTY_YOU_ARE_NOT_LEADER);
361                return;
362        }
363       
364        Group* pGroup = _player->GetGroup(); 
365
366        if( pGroup == NULL)
367                return;
368
369        /*Player * pLootMaster = objmgr.GetPlayer((uint32)lootMaster);
370
371        if ( pLootMaster )
372                pGroup->SetLooter(pLootMaster , lootMethod, threshold );
373        else
374                pGroup->SetLooter(_player , lootMethod, threshold );*/
375
376  // cebernic: Extended this code,it supports diff leader & lootmaster.
377  Player *plr = objmgr.GetPlayer((uint32)lootMaster);
378  if ( _player->m_playerInfo->guid == lootMaster || !plr) {
379    Group* pGroup = _player->GetGroup();
380    if ( !pGroup ) return;
381    pGroup->SetLooter(_player, static_cast<uint8>( lootMethod ), static_cast<uint16>( threshold ));
382  }
383  else {
384    Group* pGroup = plr->GetGroup();
385    if ( !pGroup ) 
386                return;
387    pGroup->SetLooter(plr, static_cast<uint8>( lootMethod ), static_cast<uint16>( threshold ));
388  }
389
390}
391
392void WorldSession::HandleMinimapPingOpcode( WorldPacket & recv_data )
393{
394        if( !_player->IsInWorld() ) 
395                return;
396        CHECK_PACKET_SIZE(recv_data, 8);
397        if( !_player->InGroup() )
398        return;
399        Group * party= _player->GetGroup();
400        if(!party)return;
401
402        float x,y;
403        recv_data >> x >>y;
404        WorldPacket data;
405        data.SetOpcode(MSG_MINIMAP_PING);
406        data << _player->GetGUID();
407        data << x << y;
408        party->SendPacketToAllButOne(&data, _player);
409}
410
411void WorldSession::HandleSetPlayerIconOpcode(WorldPacket& recv_data)
412{
413        uint64 guid;
414        uint8 icon;
415        Group * pGroup = _player->GetGroup();
416        if(!_player->IsInWorld() || !pGroup) return;
417
418        recv_data >> icon;
419        if(icon == 0xFF)
420        {
421                // client request
422                WorldPacket data(MSG_RAID_TARGET_UPDATE, 73);
423                data << uint8(1);
424                for(uint8 i = 0; i < 8; ++i)
425                        data << i << pGroup->m_targetIcons[i];
426
427                SendPacket(&data);
428        }
429        else if(_player->IsGroupLeader())
430        {
431                recv_data >> guid;
432                if(icon > 7)
433                        return;                 // whoops, buffer overflow :p
434
435                // setting icon
436                WorldPacket data(MSG_RAID_TARGET_UPDATE, 10);
437                data << uint8(0);
438                data << icon;
439                data << uint64(GetPlayer()->GetGUID());
440                data << guid;
441                pGroup->SendPacketToAll(&data);
442
443                pGroup->m_targetIcons[icon] = guid;
444        }
445}
446
447void WorldSession::SendPartyCommandResult(Player *pPlayer, uint32 p1, std::string name, uint32 err)
448{
449        if(!_player->IsInWorld()) return;
450        // if error message do not work, please sniff it and leave me a message
451        if(pPlayer)
452        {
453                WorldPacket data;
454                data.Initialize(SMSG_PARTY_COMMAND_RESULT);
455                data << p1;
456                if(!name.length())
457                        data << uint8(0);
458                else
459                        data << name.c_str();
460
461                data << err;
462                pPlayer->GetSession()->SendPacket(&data);
463        }
464}
Note: See TracBrowser for help on using the browser.