OregonCore  revision 3611e8a-git
Your Favourite TBC server
ArenaTeamHandler.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "Player.h"
19 #include "World.h"
20 #include "WorldPacket.h"
21 #include "WorldSession.h"
22 #include "Database/DatabaseEnv.h"
23 
24 #include "ArenaTeam.h"
25 #include "Log.h"
26 #include "ObjectMgr.h"
27 #include "SocialMgr.h"
28 
30 {
31  sLog.outDebug("MSG_INSPECT_ARENA_TEAMS");
32 
33  uint64 guid;
34  recv_data >> guid;
35  sLog.outDebug("Inspect Arena stats (GUID: %u TypeId: %u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid)));
36 
37  Player* player = ObjectAccessor::FindPlayer(guid);
38 
39  if (!player)
40  return;
41 
42  if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
43  return;
44 
45  if (_player->IsHostileTo(player))
46  return;
47 
48  for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
49  {
50  if (uint32 a_id = player->GetArenaTeamId(i))
51  if (ArenaTeam* arenaTeam = sObjectMgr.GetArenaTeamById(a_id))
52  arenaTeam->InspectStats(this, player->GetGUID());
53  }
54 }
55 
57 {
58  sLog.outDebug("WORLD: Received CMSG_ARENA_TEAM_QUERY");
59 
60  uint32 arenaTeamId;
61  recv_data >> arenaTeamId;
62 
63  if (ArenaTeam* arenaTeam = sObjectMgr.GetArenaTeamById(arenaTeamId))
64  {
65  arenaTeam->Query(this);
66  arenaTeam->Stats(this);
67  }
68 }
69 
71 {
72  sLog.outDebug("WORLD: Received CMSG_ARENA_TEAM_ROSTER");
73 
74  uint32 arenaTeamId; // arena team id
75  recv_data >> arenaTeamId;
76 
77  if (ArenaTeam* arenaTeam = sObjectMgr.GetArenaTeamById(arenaTeamId))
78  arenaTeam->Roster(this);
79 }
80 
82 {
83  sLog.outDebug("CMSG_ARENA_TEAM_ADD_MEMBER");
84 
85  uint32 arenaTeamId; // arena team id
86  std::string invitedName;
87 
88  Player* player = NULL;
89 
90  recv_data >> arenaTeamId >> invitedName;
91 
92  if (!invitedName.empty())
93  {
94  if (!normalizePlayerName(invitedName))
95  return;
96 
97  player = ObjectAccessor::Instance().FindPlayerByName(invitedName.c_str());
98  }
99 
100  if (!player)
101  {
103  return;
104  }
105 
106  if (player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
107  {
109  return;
110  }
111 
112  ArenaTeam* arenaTeam = sObjectMgr.GetArenaTeamById(arenaTeamId);
113  if (!arenaTeam)
114  {
116  return;
117  }
118 
119  if (GetPlayer()->GetArenaTeamId(arenaTeam->GetSlot()) != arenaTeamId)
120  {
122  return;
123  }
124 
125  // OK result but not send invite
126  if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
127  return;
128 
129  if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
130  {
132  return;
133  }
134 
135  if (player->GetArenaTeamId(arenaTeam->GetSlot()))
136  {
138  return;
139  }
140 
141  if (player->GetArenaTeamIdInvited())
142  {
144  return;
145  }
146 
147  if (arenaTeam->GetMembersSize() >= arenaTeam->GetType() * 2)
148  {
150  return;
151  }
152 
153  sLog.outDebug("Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), invitedName.c_str());
154 
155  player->SetArenaTeamIdInvited(arenaTeam->GetId());
156 
157  WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8 + 10));
158  data << GetPlayer()->GetName();
159  data << arenaTeam->GetName();
160  player->GetSession()->SendPacket(&data);
161 
162  DEBUG_LOG("WORLD: Sent SMSG_ARENA_TEAM_INVITE");
163 }
164 
166 {
167  sLog.outDebug("CMSG_ARENA_TEAM_INVITE_ACCEPT"); // empty opcode
168 
169  ArenaTeam* at = sObjectMgr.GetArenaTeamById(_player->GetArenaTeamIdInvited());
170  if (!at)
171  return;
172 
173  if (_player->GetArenaTeamId(at->GetSlot()))
174  {
175  // already in arena team that size
177  return;
178  }
179 
180  if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != sObjectMgr.GetPlayerTeamByGUID(at->GetCaptain()))
181  {
182  // not let enemies sign petition
184  return;
185  }
186 
187  if (!at->AddMember(_player->GetGUID()))
188  {
189  // arena team not found
191  return;
192  }
193 
194  // event
196 }
197 
199 {
200  sLog.outDebug("CMSG_ARENA_TEAM_INVITE_DECLINE"); // empty opcode
201 
202  _player->SetArenaTeamIdInvited(0); // no more invited
203 }
204 
206 {
207  sLog.outDebug("CMSG_ARENA_TEAM_LEAVE");
208 
209  uint32 arenaTeamId; // arena team id
210  recv_data >> arenaTeamId;
211 
212  ArenaTeam* at = sObjectMgr.GetArenaTeamById(arenaTeamId);
213  if (!at)
214  return;
215 
216  // Prevent leaving team while in arena queue
218  {
220  return;
221  }
222 
223  // Disallow leave team while in arena
224  if (_player->InArena())
225  {
227  return;
228  }
229 
230  if (_player->GetGUID() == at->GetCaptain() && at->GetMembersSize() > 1)
231  {
232  // check for correctness
234  return;
235  }
236 
237  // arena team has only one member (=captain)
238  if (_player->GetGUID() == at->GetCaptain())
239  {
240  at->Disband(this);
241  delete at;
242  return;
243  }
244 
245  at->DelMember(_player->GetGUID());
246 
247  // event
249 
250  // send you are no longer member of team
252 }
253 
255 {
256  sLog.outDebug("CMSG_ARENA_TEAM_DISBAND");
257 
258  uint32 arenaTeamId; // arena team id
259  recv_data >> arenaTeamId;
260 
261  if (GetPlayer()->InArena() || GetPlayer()->InBattlegroundQueue())
262  return;
263 
264  if (ArenaTeam* at = sObjectMgr.GetArenaTeamById(arenaTeamId))
265  {
266  if (at->GetCaptain() != _player->GetGUID())
267  return;
268 
269  if (at->IsFighting())
270  return;
271 
272  at->Disband(this);
273  delete at;
274  }
275 }
276 
278 {
279  sLog.outDebug("CMSG_ARENA_TEAM_REMOVE_FROM_TEAM");
280 
281  uint32 arenaTeamId;
282  std::string name;
283 
284  recv_data >> arenaTeamId;
285  recv_data >> name;
286 
287  ArenaTeam* at = sObjectMgr.GetArenaTeamById(arenaTeamId);
288  if (!at) // arena team not found
289  return;
290 
291  if (at->GetCaptain() != _player->GetGUID())
292  {
294  return;
295  }
296 
297  if (!normalizePlayerName(name))
298  return;
299 
300  ArenaTeamMember* member = at->GetMember(name);
301  if (!member) // member not found
302  {
304  return;
305  }
306 
307  if (at->GetCaptain() == member->guid)
308  {
310  return;
311  }
312 
313  Player* player = ObjectAccessor::FindPlayer(member->guid);
314  if (player && player->InArena())
315  return;
316 
317  at->DelMember(member->guid);
318 
319  // event
320  at->BroadcastEvent(ERR_ARENA_TEAM_REMOVE_SSS, name.c_str(), at->GetName().c_str(), _player->GetName());
321 }
322 
324 {
325  sLog.outDebug("CMSG_ARENA_TEAM_PROMOTE_TO_CAPTAIN");
326 
327  uint32 arenaTeamId;
328  std::string name;
329 
330  recv_data >> arenaTeamId;
331  recv_data >> name;
332 
333  ArenaTeam* at = sObjectMgr.GetArenaTeamById(arenaTeamId);
334  if (!at) // arena team not found
335  return;
336 
337  if (at->GetCaptain() != _player->GetGUID())
338  {
340  return;
341  }
342 
343  if (!normalizePlayerName(name))
344  return;
345 
346  ArenaTeamMember* member = at->GetMember(name);
347  if (!member) // member not found
348  {
350  return;
351  }
352 
353  if (at->GetCaptain() == member->guid) // target player already captain
354  return;
355 
356  at->SetCaptain(member->guid);
357 
358  // event
359  at->BroadcastEvent(ERR_ARENA_TEAM_LEADER_CHANGED_SSS, _player->GetName(), name.c_str(), at->GetName().c_str());
360 }
361 
362 void WorldSession::SendArenaTeamCommandResult(uint32 team_action, const std::string& team, const std::string& player, uint32 error_id)
363 {
364  WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4 + team.length() + 1 + player.length() + 1 + 4);
365  data << uint32(team_action);
366  data << team;
367  data << player;
368  data << uint32(error_id);
369  SendPacket(&data);
370 }
371 
373 {
374  WorldPacket data(SMSG_ARENA_ERROR, 4 + 1); // 886 - You are not in a %uv%u arena team
375  uint32 unk = 0;
376  data << uint32(unk); // unk(0)
377  if (!unk)
378  data << uint8(type); // team type (2=2v2,3=3v3,5=5v5), can be used for custom types...
379  SendPacket(&data);
380 }
381 
382 /*
383 +ERR_ARENA_NO_TEAM_II "You are not in a %dv%d arena team"
384 
385 +ERR_ARENA_TEAM_CREATE_S "%s created. To disband, use /teamdisband [2v2, 3v3, 5v5]."
386 +ERR_ARENA_TEAM_INVITE_SS "You have invited %s to join %s"
387 +ERR_ARENA_TEAM_QUIT_S "You are no longer a member of %s"
388 ERR_ARENA_TEAM_FOUNDER_S "Congratulations, you are a founding member of %s! To leave, use /teamquit [2v2, 3v3, 5v5]."
389 
390 +ERR_ARENA_TEAM_INTERNAL "Internal arena team error"
391 +ERR_ALREADY_IN_ARENA_TEAM "You are already in an arena team of that size"
392 +ERR_ALREADY_IN_ARENA_TEAM_S "%s is already in an arena team of that size"
393 +ERR_INVITED_TO_ARENA_TEAM "You have already been invited into an arena team"
394 +ERR_ALREADY_INVITED_TO_ARENA_TEAM_S "%s has already been invited to an arena team"
395 +ERR_ARENA_TEAM_NAME_INVALID "That name contains invalid characters, please enter a new name"
396 +ERR_ARENA_TEAM_NAME_EXISTS_S "There is already an arena team named \"%s\""
397 +ERR_ARENA_TEAM_LEADER_LEAVE_S "You must promote a new team captain using /teamcaptain before leaving the team"
398 +ERR_ARENA_TEAM_PERMISSIONS "You don't have permission to do that"
399 +ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM "You are not in an arena team of that size"
400 +ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS "%s is not in %s"
401 +ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S "\"%s\" not found"
402 +ERR_ARENA_TEAM_NOT_ALLIED "You cannot invite players from the opposing alliance"
403 
404 +ERR_ARENA_TEAM_JOIN_SS "%s has joined %s"
405 +ERR_ARENA_TEAM_YOU_JOIN_S "You have joined %s. To leave, use /teamquit [2v2, 3v3, 5v5]."
406 
407 +ERR_ARENA_TEAM_LEAVE_SS "%s has left %s"
408 
409 +ERR_ARENA_TEAM_LEADER_IS_SS "%s is the captain of %s"
410 +ERR_ARENA_TEAM_LEADER_CHANGED_SSS "%s has made %s the new captain of %s"
411 
412 +ERR_ARENA_TEAM_REMOVE_SSS "%s has been kicked out of %s by %s"
413 
414 +ERR_ARENA_TEAM_DISBANDED_S "%s has disbanded %s"
415 
416 ERR_ARENA_TEAM_TARGET_TOO_LOW_S "%s is not high enough level to join your team"
417 
418 ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S "%s is full"
419 
420 ERR_ARENA_TEAM_LEVEL_TOO_LOW_I "You must be level %d to form an arena team"
421 */
422 
size_t GetMembersSize() const
Definition: ArenaTeam.h:182
void DelMember(uint64 guid)
Definition: ArenaTeam.cpp:269
void HandleArenaTeamInviteDeclineOpcode(WorldPacket &recv_data)
void Disband(WorldSession *session)
Definition: ArenaTeam.cpp:307
#define GUID_LOPART(x)
Definition: ObjectGuid.h:110
bool AddMember(const uint64 &playerGuid)
Definition: ArenaTeam.cpp:90
uint32 GetType() const
Definition: ArenaTeam.h:128
void HandleInspectArenaStatsOpcode(WorldPacket &recv_data)
void SetCaptain(const uint64 &guid)
Definition: ArenaTeam.cpp:248
void BroadcastEvent(ArenaTeamEvents event, uint64 guid, char const *str1=NULL, char const *str2=NULL, char const *str3=NULL)
Definition: ArenaTeam.cpp:472
bool HasIgnore(uint32 ignore_guid)
Definition: SocialMgr.cpp:162
bool InArena() const
Definition: Player.cpp:19394
#define sLog
Log class singleton.
Definition: Log.h:187
ArenaTeamMember * GetMember(const uint64 &guid)
Definition: ArenaTeam.h:200
#define GUID_HIPART(x)
Definition: ObjectGuid.h:82
Player * GetPlayer() const
Definition: WorldSession.h:104
void HandleArenaTeamRemoveFromTeamOpcode(WorldPacket &recv_data)
void HandleArenaTeamPromoteToCaptainOpcode(WorldPacket &recv_data)
#define sObjectMgr
Definition: ObjectMgr.h:1285
void SendPacket(WorldPacket const *packet)
void HandleArenaTeamAddMemberOpcode(WorldPacket &recv_data)
#define INSPECT_DISTANCE
Definition: Object.h:37
bool normalizePlayerName(std::string &name)
Definition: ObjectMgr.cpp:225
ACE_UINT8 uint8
Definition: Define.h:73
PlayerSocial * GetSocial()
Definition: Player.h:985
uint32 GuidHigh2TypeId(uint32 guid_hi)
Definition: Object.cpp:43
uint32 GetId() const
Definition: ArenaTeam.h:124
void SetArenaTeamIdInvited(uint32 ArenaTeamId)
Definition: Player.h:1871
static Player * FindPlayer(uint64, bool force=false)
void HandleArenaTeamDisbandOpcode(WorldPacket &recv_data)
#define DEBUG_LOG(...)
Definition: Log.h:194
void HandleArenaTeamInviteAcceptOpcode(WorldPacket &recv_data)
const char * GetName() const
Definition: Object.h:692
void SendArenaTeamCommandResult(uint32 team_action, const std::string &team, const std::string &player, uint32 error_id)
bool InBattlegroundQueue() const
Definition: Player.h:2222
ACE_UINT64 uint64
Definition: Define.h:70
std::string GetName() const
Definition: ArenaTeam.h:141
uint32 GetArenaTeamId(uint8 slot)
Definition: Player.h:1862
Player * _player
Definition: WorldSession.h:729
const uint64 & GetCaptain() const
Definition: ArenaTeam.h:137
uint32 GetArenaTeamIdInvited()
Definition: Player.h:1875
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:7279
uint32 GetTeam() const
Definition: Player.h:2075
uint8 GetSlot() const
Definition: ArenaTeam.h:132
void HandleArenaTeamQueryOpcode(WorldPacket &recv_data)
void HandleArenaTeamRosterOpcode(WorldPacket &recv_data)
WorldSession * GetSession() const
Definition: Player.h:1959
#define sWorld
Definition: World.h:860
Player * FindPlayerByName(const char *name, bool force=false)
ACE_UINT32 uint32
Definition: Define.h:71
uint32 getLevel() const
Definition: Unit.h:1029
Definition: Player.h:922
void SendNotInArenaTeamPacket(uint8 type)
void HandleArenaTeamLeaveOpcode(WorldPacket &recv_data)
#define MAX_ARENA_SLOT
Definition: ArenaTeam.h:111
const uint64 & GetGUID() const
Definition: Object.h:156