TrinityCore
Loading...
Searching...
No Matches
ArenaTeamHandler.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore 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 "WorldSession.h"
19#include "ArenaTeam.h"
20#include "ArenaTeamMgr.h"
21#include "BattlegroundMgr.h"
22#include "CharacterCache.h"
23#include "Log.h"
24#include "ObjectAccessor.h"
25#include "ObjectMgr.h"
26#include "Opcodes.h"
27#include "Player.h"
28#include "SocialMgr.h"
29#include "World.h"
30#include "WorldPacket.h"
31
33{
34 TC_LOG_DEBUG("network", "MSG_INSPECT_ARENA_TEAMS");
35
36 ObjectGuid guid;
37 recvData >> guid;
38 TC_LOG_DEBUG("network", "Inspect Arena stats {}", guid.ToString());
39
40 Player* player = ObjectAccessor::FindPlayer(guid);
41
42 if (!player)
43 return;
44
45 if (!GetPlayer()->IsWithinDistInMap(player, INSPECT_DISTANCE, false))
46 return;
47
48 if (GetPlayer()->IsValidAttackTarget(player))
49 return;
50
51 for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
52 {
53 if (uint32 a_id = player->GetArenaTeamId(i))
54 {
55 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(a_id))
56 arenaTeam->Inspect(this, player->GetGUID());
57 }
58 }
59}
60
62{
63 TC_LOG_DEBUG("network", "WORLD: Received CMSG_ARENA_TEAM_QUERY");
64
65 uint32 arenaTeamId;
66 recvData >> arenaTeamId;
67
68 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
69 {
70 arenaTeam->Query(this);
71 arenaTeam->SendStats(this);
72 }
73}
74
76{
77 TC_LOG_DEBUG("network", "WORLD: Received CMSG_ARENA_TEAM_ROSTER");
78
79 uint32 arenaTeamId; // arena team id
80 recvData >> arenaTeamId;
81
82 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
83 arenaTeam->Roster(this);
84}
85
87{
88 TC_LOG_DEBUG("network", "CMSG_ARENA_TEAM_INVITE");
89
90 uint32 arenaTeamId; // arena team id
91 std::string invitedName;
92
93 Player* player = nullptr;
94
95 recvData >> arenaTeamId >> invitedName;
96
97 if (!invitedName.empty())
98 {
99 if (!normalizePlayerName(invitedName))
100 return;
101
102 player = ObjectAccessor::FindPlayerByName(invitedName);
103 }
104
105 if (!player)
106 {
108 return;
109 }
110
111 if (!player->IsMaxLevel())
112 {
114 return;
115 }
116
117 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
118 if (!arenaTeam)
119 {
121 return;
122 }
123
124 if (GetPlayer()->GetArenaTeamId(arenaTeam->GetSlot()) != arenaTeamId)
125 {
127 return;
128 }
129
130 // OK result but don't send invite
131 if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID()))
132 return;
133
134 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
135 {
137 return;
138 }
139
140 if (player->GetArenaTeamId(arenaTeam->GetSlot()))
141 {
143 return;
144 }
145
146 if (player->GetArenaTeamIdInvited())
147 {
149 return;
150 }
151
152 if (arenaTeam->GetMembersSize() >= arenaTeam->GetType() * 2)
153 {
155 return;
156 }
157
158 TC_LOG_DEBUG("bg.battleground", "Player {} Invited {} to Join his ArenaTeam", GetPlayer()->GetName(), invitedName);
159
160 player->SetArenaTeamIdInvited(arenaTeam->GetId());
161
163 data << GetPlayer()->GetName();
164 data << arenaTeam->GetName();
165 player->SendDirectMessage(&data);
166
167 TC_LOG_DEBUG("network", "WORLD: Sent SMSG_ARENA_TEAM_INVITE");
168}
169
171{
172 TC_LOG_DEBUG("network", "CMSG_ARENA_TEAM_ACCEPT"); // empty opcode
173
174 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(_player->GetArenaTeamIdInvited());
175 if (!arenaTeam)
176 return;
177
178 // Check if player is already in another team of the same size
179 if (_player->GetArenaTeamId(arenaTeam->GetSlot()))
180 {
182 return;
183 }
184
185 // Only allow members of the other faction to join the team if cross faction interaction is enabled
186 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != sCharacterCache->GetCharacterTeamByGuid(arenaTeam->GetCaptain()))
187 {
189 return;
190 }
191
192 // Add player to team
193 if (!arenaTeam->AddMember(_player->GetGUID()))
194 {
196 return;
197 }
198
199 // Broadcast event
200 arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_JOIN_SS, _player->GetGUID(), 2, _player->GetName(), arenaTeam->GetName(), "");
201}
202
204{
205 TC_LOG_DEBUG("network", "CMSG_ARENA_TEAM_DECLINE"); // empty opcode
206
207 // Remove invite from player
209}
210
212{
213 TC_LOG_DEBUG("network", "CMSG_ARENA_TEAM_LEAVE");
214
215 uint32 arenaTeamId;
216 recvData >> arenaTeamId;
217
218 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
219 if (!arenaTeam)
220 return;
221
222 // Disallow leave team while in arena
223 if (_player->InArena())
224 {
226 return;
227 }
228
229 // Team captain can't leave the team if other members are still present
230 if (_player->GetGUID() == arenaTeam->GetCaptain() && arenaTeam->GetMembersSize() > 1)
231 {
233 return;
234 }
235
236 // Player cannot be removed during queues
237 for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
238 {
240 if (bgQueue.BattlemasterListId != BATTLEGROUND_AA || bgQueue.TeamSize != arenaTeam->GetType())
241 continue;
242
243 GroupQueueInfo ginfo;
244 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue);
245 if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
247 {
249 return;
250 }
251 }
252
253 // If team consists only of the captain, disband the team
254 if (_player->GetGUID() == arenaTeam->GetCaptain())
255 {
256 arenaTeam->Disband(this);
257 delete arenaTeam;
258 return;
259 }
260 else
261 arenaTeam->DelMember(_player->GetGUID(), true);
262
263 // Broadcast event
264 arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_LEAVE_SS, _player->GetGUID(), 2, _player->GetName(), arenaTeam->GetName(), "");
265
266 // Inform player who left
268}
269
271{
272 TC_LOG_DEBUG("network", "CMSG_ARENA_TEAM_DISBAND");
273
274 uint32 arenaTeamId;
275 recvData >> arenaTeamId;
276
277 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
278 {
279 // Only captain can disband the team
280 if (arenaTeam->GetCaptain() != _player->GetGUID())
281 return;
282
283 // Teams cannot be disbanded during queues
284 for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
285 {
287 if (bgQueue.BattlemasterListId != BATTLEGROUND_AA || bgQueue.TeamSize != arenaTeam->GetType())
288 continue;
289
290 GroupQueueInfo ginfo;
291 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue);
292 if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
294 return;
295 }
296
297 // Teams cannot be disbanded during fights
298 if (arenaTeam->IsFighting())
299 return;
300
301 arenaTeam->Disband(this);
302 delete arenaTeam;
303 }
304}
305
307{
308 TC_LOG_DEBUG("network", "CMSG_ARENA_TEAM_REMOVE");
309
310 uint32 arenaTeamId;
311 std::string name;
312
313 recvData >> arenaTeamId;
314 recvData >> name;
315
316 // Check for valid arena team
317 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
318 if (!arenaTeam)
319 return;
320
321 // Only captain can remove members
322 if (arenaTeam->GetCaptain() != _player->GetGUID())
323 {
325 return;
326 }
327
328 if (!normalizePlayerName(name))
329 return;
330
331 // Check if team member exists
332 ArenaTeamMember* member = arenaTeam->GetMember(name);
333 if (!member)
334 {
336 return;
337 }
338
339 // Captain cannot be removed
340 if (arenaTeam->GetCaptain() == member->Guid)
341 {
343 return;
344 }
345
346 // Team cannot be removed during queues
347 for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
348 {
350 if (bgQueue.BattlemasterListId != BATTLEGROUND_AA || bgQueue.TeamSize != arenaTeam->GetType())
351 continue;
352
353 GroupQueueInfo ginfo;
354 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue);
355 if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
357 {
359 return;
360 }
361 }
362
363 // Player cannot be removed during fights
364 if (arenaTeam->IsFighting())
365 return;
366
367 arenaTeam->DelMember(member->Guid, true);
368
369 // Broadcast event
371}
372
374{
375 TC_LOG_DEBUG("network", "CMSG_ARENA_TEAM_LEADER");
376
377 uint32 arenaTeamId;
378 std::string name;
379
380 recvData >> arenaTeamId;
381 recvData >> name;
382
383 // Check for valid arena team
384 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
385 if (!arenaTeam)
386 return;
387
388 // Only captain can pass leadership
389 if (arenaTeam->GetCaptain() != _player->GetGUID())
390 {
392 return;
393 }
394
395 if (!normalizePlayerName(name))
396 return;
397
398 // Check if team member exists
399 ArenaTeamMember* member = arenaTeam->GetMember(name);
400 if (!member)
401 {
403 return;
404 }
405
406 // Check if the target is already team captain
407 if (arenaTeam->GetCaptain() == member->Guid)
408 return;
409
410 arenaTeam->SetCaptain(member->Guid);
411
412 // Broadcast event
414}
415
416void WorldSession::SendArenaTeamCommandResult(uint32 teamAction, const std::string& team, const std::string& player, uint32 errorId)
417{
418 WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4 + team.length() + 1 + player.length() + 1 + 4);
419 data << uint32(teamAction);
420 data << team;
421 data << player;
422 data << uint32(errorId);
423 SendPacket(&data);
424}
425
427{
428 WorldPacket data(SMSG_ARENA_ERROR, 4+1);
429 uint32 error = 0;
430 data << uint32(error); // 0 = ERR_ARENA_NO_TEAM_II, 1 = ERR_ARENA_EXPIRED_CAIS, 2 = ERR_LFG_CANT_USE_BATTLEGROUND
431 if (!error)
432 data << uint8(type); // team type (2=2v2, 3=3v3, 5=5v5), can be used for custom types...
433 SendPacket(&data);
434}
435
436/*
437+ERR_ARENA_NO_TEAM_II "You are not in a %dv%d arena team"
438
439+ERR_ARENA_TEAM_CREATE_S "%s created. To disband, use /teamdisband [2v2, 3v3, 5v5]."
440+ERR_ARENA_TEAM_INVITE_SS "You have invited %s to join %s"
441+ERR_ARENA_TEAM_QUIT_S "You are no longer a member of %s"
442ERR_ARENA_TEAM_FOUNDER_S "Congratulations, you are a founding member of %s! To leave, use /teamquit [2v2, 3v3, 5v5]."
443
444+ERR_ARENA_TEAM_INTERNAL "Internal arena team error"
445+ERR_ALREADY_IN_ARENA_TEAM "You are already in an arena team of that size"
446+ERR_ALREADY_IN_ARENA_TEAM_S "%s is already in an arena team of that size"
447+ERR_INVITED_TO_ARENA_TEAM "You have already been invited into an arena team"
448+ERR_ALREADY_INVITED_TO_ARENA_TEAM_S "%s has already been invited to an arena team"
449+ERR_ARENA_TEAM_NAME_INVALID "That name contains invalid characters, please enter a new name"
450+ERR_ARENA_TEAM_NAME_EXISTS_S "There is already an arena team named \"%s\""
451+ERR_ARENA_TEAM_LEADER_LEAVE_S "You must promote a new team captain using /teamcaptain before leaving the team"
452+ERR_ARENA_TEAM_PERMISSIONS "You don't have permission to do that"
453+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM "You are not in an arena team of that size"
454+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS "%s is not in %s"
455+ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S "\"%s\" not found"
456+ERR_ARENA_TEAM_NOT_ALLIED "You cannot invite players from the opposing alliance"
457
458+ERR_ARENA_TEAM_JOIN_SS "%s has joined %s"
459+ERR_ARENA_TEAM_YOU_JOIN_S "You have joined %s. To leave, use /teamquit [2v2, 3v3, 5v5]."
460
461+ERR_ARENA_TEAM_LEAVE_SS "%s has left %s"
462
463+ERR_ARENA_TEAM_LEADER_IS_SS "%s is the captain of %s"
464+ERR_ARENA_TEAM_LEADER_CHANGED_SSS "%s has made %s the new captain of %s"
465
466+ERR_ARENA_TEAM_REMOVE_SSS "%s has been kicked out of %s by %s"
467
468+ERR_ARENA_TEAM_DISBANDED_S "%s has disbanded %s"
469
470ERR_ARENA_TEAM_TARGET_TOO_LOW_S "%s is not high enough level to join your team"
471
472ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S "%s is full"
473
474ERR_ARENA_TEAM_LEVEL_TOO_LOW_I "You must be level %d to form an arena team"
475*/
#define sArenaTeamMgr
@ ERR_ARENA_TEAM_INVITE_SS
Definition ArenaTeam.h:34
@ ERR_ARENA_TEAM_QUIT_S
Definition ArenaTeam.h:35
@ ERR_ARENA_TEAM_CREATE_S
Definition ArenaTeam.h:33
#define MAX_ARENA_SLOT
Definition ArenaTeam.h:114
@ ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S
Definition ArenaTeam.h:57
@ ERR_ALREADY_IN_ARENA_TEAM_S
Definition ArenaTeam.h:43
@ ERR_ARENA_TEAM_INTERNAL
Definition ArenaTeam.h:41
@ ERR_ALREADY_IN_ARENA_TEAM
Definition ArenaTeam.h:42
@ ERR_ARENA_TEAMS_LOCKED
Definition ArenaTeam.h:59
@ ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM
Definition ArenaTeam.h:50
@ ERR_ARENA_TEAM_LEADER_LEAVE_S
Definition ArenaTeam.h:48
@ ERR_ARENA_TEAM_PERMISSIONS
Definition ArenaTeam.h:49
@ ERR_ARENA_TEAM_NOT_ALLIED
Definition ArenaTeam.h:53
@ ERR_ARENA_TEAM_TARGET_TOO_LOW_S
Definition ArenaTeam.h:55
@ ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S
Definition ArenaTeam.h:52
@ ERR_ALREADY_INVITED_TO_ARENA_TEAM_S
Definition ArenaTeam.h:45
@ ERR_ARENA_TEAM_LEADER_CHANGED_SSS
Definition ArenaTeam.h:68
@ ERR_ARENA_TEAM_REMOVE_SSS
Definition ArenaTeam.h:66
@ ERR_ARENA_TEAM_LEAVE_SS
Definition ArenaTeam.h:65
@ ERR_ARENA_TEAM_JOIN_SS
Definition ArenaTeam.h:64
#define sBattlegroundMgr
#define sCharacterCache
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
#define INSPECT_DISTANCE
bool normalizePlayerName(std::string &name)
@ BATTLEGROUND_AA
#define PLAYER_MAX_BATTLEGROUND_QUEUES
void Disband(WorldSession *session)
ObjectGuid GetCaptain() const
Definition ArenaTeam.h:133
size_t GetMembersSize() const
Definition ArenaTeam.h:145
void DelMember(ObjectGuid guid, bool cleanDb)
uint8 GetSlot() const
Definition ArenaTeam.h:130
void SetCaptain(ObjectGuid guid)
bool AddMember(ObjectGuid PlayerGuid)
Definition ArenaTeam.cpp:94
ArenaTeamMember * GetMember(ObjectGuid guid)
uint32 GetType() const
Definition ArenaTeam.h:129
void BroadcastEvent(ArenaTeamEvents event, ObjectGuid guid, uint8 strCount, std::string const &str1, std::string const &str2, std::string const &str3)
bool IsFighting() const
std::string const & GetName() const
Definition ArenaTeam.h:134
uint32 GetId() const
Definition ArenaTeam.h:128
bool GetPlayerGroupInfoData(ObjectGuid guid, GroupQueueInfo *ginfo)
static ObjectGuid const Empty
Definition ObjectGuid.h:140
std::string ToString() const
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
bool HasIgnore(ObjectGuid const &ignoreGuid)
uint32 GetTeam() const
Definition Player.h:1832
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6161
uint32 GetArenaTeamIdInvited() const
Definition Player.h:1632
bool IsMaxLevel() const
Definition Player.cpp:2501
uint32 GetArenaTeamId(uint8 slot) const
Definition Player.h:1629
PlayerSocial * GetSocial()
Definition Player.h:982
bool InArena() const
Definition Player.cpp:23148
void SetArenaTeamIdInvited(uint32 ArenaTeamId)
Definition Player.h:1631
BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const
Definition Player.cpp:23066
std::string const & GetName() const
Definition Object.h:382
void HandleArenaTeamAcceptOpcode(WorldPacket &recvData)
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
void HandleInspectArenaTeamsOpcode(WorldPacket &recvData)
void SendNotInArenaTeamPacket(uint8 type)
void HandleArenaTeamQueryOpcode(WorldPacket &recvData)
Player * GetPlayer() const
void HandleArenaTeamRosterOpcode(WorldPacket &recvData)
void HandleArenaTeamDisbandOpcode(WorldPacket &recvData)
void HandleArenaTeamInviteOpcode(WorldPacket &recvData)
Player * _player
void HandleArenaTeamDeclineOpcode(WorldPacket &recvData)
void HandleArenaTeamLeaderOpcode(WorldPacket &recvData)
void SendArenaTeamCommandResult(uint32 team_action, std::string const &team, std::string const &player, uint32 error_id=0)
void HandleArenaTeamRemoveOpcode(WorldPacket &recvData)
void HandleArenaTeamLeaveOpcode(WorldPacket &recvData)
@ SMSG_ARENA_TEAM_COMMAND_RESULT
Definition Opcodes.h:870
@ SMSG_ARENA_ERROR
Definition Opcodes.h:915
@ SMSG_ARENA_TEAM_INVITE
Definition Opcodes.h:877
#define sWorld
Definition World.h:900
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD
Definition World.h:99
TC_GAME_API Player * FindPlayerByName(std::string_view name)
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
ObjectGuid Guid
Definition ArenaTeam.h:90
uint32 IsInvitedToBGInstanceGUID