Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
BattleGroundHandler.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "ArenaTeamMgr.h"
7#include "Common.h"
8#include "ObjectAccessor.h"
9#include "ObjectMgr.h"
10#include "WorldPacket.h"
11#include "WorldSession.h"
12
13#include "ArenaTeam.h"
14#include "Battleground.h"
15#include "BattlegroundMgr.h"
16#include "Chat.h"
17#include "DisableMgr.h"
18#include "Group.h"
19#include "Language.h"
20#include "Log.h"
21#include "Object.h"
22#include "Opcodes.h"
23#include "Player.h"
24
26{
27 uint64 guid;
28 recvData >> guid;
29 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), uint8(GuidHigh2TypeId(GUID_HIPART(guid))));
30
31 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
32 if (!unit)
33 return;
34
35 if (!unit->IsBattleMaster()) // it's not battlemaster
36 return;
37
38 // Stop the npc if moving
39 unit->StopMoving();
40
41 BattlegroundTypeId bgTypeId = sBattlegroundMgr->GetBattleMasterBG(unit->GetEntry());
42
43 if (!_player->GetBGAccessByLevel(bgTypeId))
44 {
45 // temp, must be gossip message...
47 return;
48 }
49
50 SendBattleGroundList(guid, bgTypeId);
51}
52
54{
55 WorldPacket data;
56 sBattlegroundMgr->BuildBattlegroundListPacket(&data, guid, _player, bgTypeId);
57 SendPacket(&data);
58}
59
61{
62 uint32 bgTypeId_;
63 uint8 asGroup;
64 bool isPremade = false;
65 Group* grp = NULL;
66 ObjectGuid guid;
67 bool hasRoleMask;
68 uint8 roleMask = 0;
69
70 for (int i = 0; i < 2; i++) // blacklistedMapIds
71 recvData.read_skip<uint32>();
72
73 recvData.ReadGuidMask(guid, 1, 7, 0, 3);
74 asGroup = recvData.ReadBit(); // As Group
75 recvData.ReadGuidMask(guid, 4);
76 hasRoleMask = !recvData.ReadBit();
77 recvData.ReadGuidMask(guid, 6, 2, 5);
78
79 recvData.ReadGuidBytes(guid, 7, 2, 4, 5, 0, 6, 3, 1);
80
81 if (hasRoleMask)
82 recvData >> roleMask; // Need to set this as group role later
83
84 //extract from guid
85 bgTypeId_ = GUID_LOPART(guid);
86
87 if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
88 {
89 SF_LOG_ERROR("network", "Battleground: invalid bgtype (%u) received. possible cheater? player guid %u", bgTypeId_, _player->GetGUIDLow());
90 return;
91 }
92
94 {
96 return;
97 }
98 BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
99
100 //SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID:"UI64FMTD" TypeId:%u)", guid, bgTypeId_);
101
102 // can do this, since it's battleground, not arena
103 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0);
105
106 // ignore if player is already in BG
107 if (_player->InBattleground())
108 return;
109
110 // get bg instance or bg template if instance not found
111 Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
112 if (!bg)
113 return;
114
115 // expected bracket entry
116 PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel());
117 if (!bracketEntry)
118 return;
119
121
122 // check queue conditions
123 if (!asGroup)
124 {
125 if (GetPlayer()->isUsingLfg())
126 {
127 WorldPacket data;
129 GetPlayer()->GetSession()->SendPacket(&data);
130 return;
131 }
132
133 // check Deserter debuff
134 if (!_player->CanJoinToBattleground(bg))
135 {
136 WorldPacket data;
138 _player->GetSession()->SendPacket(&data);
139 return;
140 }
141
142 if (_player->GetBattlegroundQueueIndex(bgQueueTypeIdRandom) < PLAYER_MAX_BATTLEGROUND_QUEUES)
143 {
144 // player is already in random queue
145 WorldPacket data;
146 sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, GroupJoinBattlegroundResult::ERR_IN_RANDOM_BG);
147 _player->GetSession()->SendPacket(&data);
148 return;
149 }
150
151 if (_player->InBattlegroundQueue() && bgTypeId == BattlegroundTypeId::BATTLEGROUND_RB)
152 {
153 // player is already in queue, can't start random queue
154 WorldPacket data;
155 sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, GroupJoinBattlegroundResult::ERR_IN_NON_RANDOM_BG);
156 _player->GetSession()->SendPacket(&data);
157 return;
158 }
159
160 // check if already in queue
161 if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
162 // player is already in this queue
163 return;
164
165 // check if has free queue slots
166 if (!_player->HasFreeBattlegroundQueueId())
167 {
168 WorldPacket data;
170 _player->GetSession()->SendPacket(&data);
171 return;
172 }
173
174 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
175 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
176
177 uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
178 uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
179
180 // add joined time data
181 _player->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime);
182
183 WorldPacket data; // send status packet (in queue)
184 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, ginfo->ArenaType);
185 SendPacket(&data);
186
187 SF_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",
188 bgQueueTypeId, uint32(bgTypeId), _player->GetGUIDLow(), _player->GetName().c_str());
189 }
190 else
191 {
192 grp = _player->GetGroup();
193
194 if (!grp)
195 return;
196
197 if (grp->GetLeaderGUID() != _player->GetGUID())
198 return;
199
200 err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
201 isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam());
202
203 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
204 GroupQueueInfo* ginfo = NULL;
205 uint32 avgTime = 0;
206
208 {
209 SF_LOG_DEBUG("bg.battleground", "Battleground: the following players are joining as group:");
210 ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
211 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
212 }
213
214 for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
215 {
216 Player* member = itr->GetSource();
217 if (!member)
218 continue; // this should never happen
219
221 {
222 WorldPacket data;
223 sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, err);
224 member->GetSession()->SendPacket(&data);
225 continue;
226 }
227
228 // add to queue
229 uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
230
231 // add joined time data
232 member->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime);
233
234 WorldPacket data; // send status packet (in queue)
235 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, ginfo->ArenaType);
236 member->GetSession()->SendPacket(&data);
237 SF_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",
238 bgQueueTypeId, uint32(bgTypeId), member->GetGUIDLow(), member->GetName().c_str());
239 }
240 SF_LOG_DEBUG("bg.battleground", "Battleground: group end");
241 }
242
243 sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
244}
245
247{
248 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEGROUND_PLAYER_POSITIONS Message");
249
250 Battleground* bg = _player->GetBattleground();
251 if (!bg) // can't be received if player not in battleground
252 return;
253
254 uint32 acount = 0;
255 uint32 hcount = 0;
256 Player* aplr = NULL;
257 Player* hplr = NULL;
258
259 if (uint64 guid = bg->GetFlagPickerGUID(TEAM_ALLIANCE))
260 {
261 aplr = ObjectAccessor::FindPlayer(guid);
262 if (aplr)
263 ++acount;
264 }
265
266 if (uint64 guid = bg->GetFlagPickerGUID(TEAM_HORDE))
267 {
268 hplr = ObjectAccessor::FindPlayer(guid);
269 if (hplr)
270 ++hcount;
271 }
272
273 ObjectGuid aguid = aplr ? aplr->GetGUID() : 0;
274 ObjectGuid hguid = hplr ? hplr->GetGUID() : 0;
275
277
278 data.WriteBits(acount, 22);
279 for (uint8 i = 0; i < acount; i++)
280 {
281 data.WriteBit(aguid[3]);
282 data.WriteBit(aguid[5]);
283 data.WriteBit(aguid[1]);
284 data.WriteBit(aguid[6]);
285 data.WriteBit(aguid[7]);
286 data.WriteBit(aguid[0]);
287 data.WriteBit(aguid[2]);
288 data.WriteBit(aguid[4]);
289 }
290
291 data.WriteBits(hcount, 22);
292 for (uint8 i = 0; i < hcount; i++)
293 {
294 data.WriteBit(hguid[6]);
295 data.WriteBit(hguid[5]);
296 data.WriteBit(hguid[4]);
297 data.WriteBit(hguid[7]);
298 data.WriteBit(hguid[2]);
299 data.WriteBit(hguid[1]);
300 data.WriteBit(hguid[0]);
301 data.WriteBit(hguid[3]);
302 }
303
304 data.FlushBits();
305
306 for (uint8 i = 0; i < hcount; i++)
307 {
308 data.WriteByteSeq(hguid[2]);
309 data.WriteByteSeq(hguid[1]);
310 data << float(hplr->GetPositionY());
311 data.WriteByteSeq(hguid[5]);
312 data.WriteByteSeq(hguid[4]);
313 data.WriteByteSeq(hguid[7]);
314 data.WriteByteSeq(hguid[0]);
315 data.WriteByteSeq(hguid[6]);
316 data.WriteByteSeq(hguid[3]);
317 data << float(hplr->GetPositionX());
318 }
319
320 for (uint8 i = 0; i < acount; i++)
321 {
322 data.WriteByteSeq(aguid[6]);
323 data << float(aplr->GetPositionX());
324 data.WriteByteSeq(aguid[5]);
325 data.WriteByteSeq(aguid[3]);
326 data << float(aplr->GetPositionY());
327 data.WriteByteSeq(aguid[1]);
328 data.WriteByteSeq(aguid[7]);
329 data.WriteByteSeq(aguid[0]);
330 data.WriteByteSeq(aguid[2]);
331 data.WriteByteSeq(aguid[4]);
332 }
333
334 SendPacket(&data);
335}
336
338{
339 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_PVP_LOG_DATA Message");
340
341 Battleground* bg = _player->GetBattleground();
342 if (!bg)
343 return;
344
345 // Prevent players from sending BuildPvpLogDataPacket in an arena except for when sent in BattleGround::EndBattleGround.
346 if (bg->isArena())
347 return;
348
349 WorldPacket data;
350 sBattlegroundMgr->BuildPvpLogDataPacket(&data, bg);
351 SendPacket(&data);
352
353 SF_LOG_DEBUG("network", "WORLD: Sent SMSG_PVP_LOG_DATA Message");
354}
355
357{
358 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_LIST Message");
359
360 uint32 bgTypeId;
361 recvData >> bgTypeId; // id from DBC
362
363 if (Battleground* currentBg = _player->GetBattleground())
364 if (currentBg->GetTypeID(true) == BattlegroundTypeId::BATTLEGROUND_SA && currentBg->GetStatus() == STATUS_IN_PROGRESS)
365 return;
366
367 BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
368 if (!bl)
369 {
370 SF_LOG_DEBUG("bg.battleground", "BattlegroundHandler: invalid bgtype (%u) with player (Name: %s, GUID: %u) received.", bgTypeId, _player->GetName().c_str(), _player->GetGUIDLow());
371 return;
372 }
373
374 WorldPacket data;
375 sBattlegroundMgr->BuildBattlegroundListPacket(&data, 0, _player, BattlegroundTypeId(bgTypeId));
376 SendPacket(&data);
377}
378
380{
381 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_PORT Message");
382
383 uint32 time;
384 uint32 queueSlot;
385 uint32 id;
386 uint8 action; // enter battle 0x1, leave queue 0x0
387 ObjectGuid guid;
388
389 action = recvData.ReadBit();
390
391 recvData >> queueSlot;
392 recvData >> id;
393 recvData >> time;
394
395 recvData.ReadGuidMask(guid, 6, 4, 2, 5, 0, 1, 7, 3);
396 recvData.ReadGuidBytes(guid, 2, 5, 3, 0, 7, 4, 6, 1);
397
398 if (!_player->InBattlegroundQueue())
399 {
400 SF_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Player not in queue!",
401 GetPlayerInfo().c_str(), queueSlot, id, time, action);
402 return;
403 }
404
405 BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(queueSlot);
406 if (bgQueueTypeId == BATTLEGROUND_QUEUE_NONE)
407 {
408 SF_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Invalid queueSlot!",
409 GetPlayerInfo().c_str(), queueSlot, id, time, action);
410 return;
411 }
412
413 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
414
415 //we must use temporary variable, because GroupQueueInfo pointer can be deleted in BattlegroundQueue::RemovePlayer() function
416 GroupQueueInfo ginfo;
417 if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
418 {
419 SF_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Player not in queue (No player Group Info)!",
420 GetPlayerInfo().c_str(), queueSlot, id, time, action);
421 return;
422 }
423 // if action == 1, then instanceId is required
424 if (!ginfo.IsInvitedToBGInstanceGUID && action == 1)
425 {
426 SF_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Player is not invited to any bg!",
427 GetPlayerInfo().c_str(), queueSlot, id, time, action);
428 return;
429 }
430
431 BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId);
432 // BGTemplateId returns BATTLEGROUND_AA when it is arena queue.
433 // Do instance id search as there is no AA bg instances.
435 if (!bg)
436 {
437 if (action)
438 {
439 SF_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Cant find BG with id %u!",
440 GetPlayerInfo().c_str(), queueSlot, id, time, action, ginfo.IsInvitedToBGInstanceGUID);
441 return;
442 }
443
444 bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
445 if (!bg)
446 {
447 SF_LOG_ERROR("network", "BattlegroundHandler: bg_template not found for type id %u.", uint32(bgTypeId));
448 return;
449 }
450 }
451
452 SF_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u.",
453 GetPlayerInfo().c_str(), queueSlot, id, time, action);
454
455 // get real bg type
456 bgTypeId = bg->GetTypeID();
457
458 // expected bracket entry
459 PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel());
460 if (!bracketEntry)
461 return;
462
463 //some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it
464 if (action == 1 && ginfo.ArenaType == 0)
465 {
466 //if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue
467 if (!_player->CanJoinToBattleground(bg))
468 {
469 //send bg command result to show nice message
470 WorldPacket data2;
472 _player->GetSession()->SendPacket(&data2);
473 action = 0;
474 SF_LOG_DEBUG("bg.battleground", "Player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName().c_str(), _player->GetGUIDLow());
475 }
476 //if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue
477 if (_player->getLevel() > bg->GetMaxLevel())
478 {
479 SF_LOG_DEBUG("network", "Player %s (%u) has level (%u) higher than maxlevel (%u) of battleground (%u)! Do not port him to battleground!",
480 _player->GetName().c_str(), _player->GetGUIDLow(), _player->getLevel(), bg->GetMaxLevel(), uint32(bg->GetTypeID()));
481 action = 0;
482 }
483 }
484
485 WorldPacket data;
486 if (action)
487 {
488 if (!_player->IsInvitedForBattlegroundQueueType(bgQueueTypeId))
489 return; // cheating?
490
491 if (!_player->InBattleground())
492 _player->SetBattlegroundEntryPoint();
493
494 // resurrect the player
495 if (!_player->IsAlive())
496 {
497 _player->ResurrectPlayer(1.0f);
498 _player->SpawnCorpseBones();
499 }
500 // stop taxi flight at port
501 if (_player->IsInFlight())
502 {
503 _player->GetMotionMaster()->MovementExpired();
504 _player->CleanupAfterTaxiFlight();
505 }
506
507 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_IN_PROGRESS, _player->GetBattlegroundQueueJoinTime(bgTypeId), bg->GetElapsedTime(), bg->GetArenaType());
508 _player->GetSession()->SendPacket(&data);
509
510 // remove battleground queue status from BGmgr
511 bgQueue.RemovePlayer(_player->GetGUID(), false);
512 // this is still needed here if battleground "jumping" shouldn't add deserter debuff
513 // also this is required to prevent stuck at old battleground after SetBattlegroundId set to new
514 if (Battleground* currentBg = _player->GetBattleground())
515 currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true);
516
517 // set the destination instance id
518 _player->SetBattlegroundId(bg->GetInstanceID(), bgTypeId);
519 // set the destination team
520 _player->SetBGTeam(ginfo.Team);
521
522 // bg->HandleBeforeTeleportToBattleground(_player);
523 sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
524 // add only in HandleMoveWorldPortAck()
525 // bg->AddPlayer(_player, team);
526 SF_LOG_DEBUG("bg.battleground", "Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName().c_str(), _player->GetGUIDLow(), bg->GetInstanceID(), uint32(bg->GetTypeID()), bgQueueTypeId);
527 }
528 else // leave queue
529 {
530 // if player leaves rated arena match before match start, it is counted as he played but he lost
531 if (ginfo.IsRated && ginfo.IsInvitedToBGInstanceGUID)
532 {
533 /*
534 ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ginfo.Team);
535 if (at)
536 {
537 SF_LOG_DEBUG("bg.battleground", "UPDATING memberLost's personal arena rating for %u by opponents rating: %u, because he has left queue!", GUID_LOPART(_player->GetGUID()), ginfo.OpponentsTeamRating);
538 at->MemberLost(_player, ginfo.OpponentsMatchmakerRating);
539 at->SaveToDB();
540 }*/
541 }
542 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_NONE, _player->GetBattlegroundQueueJoinTime(bgTypeId), 0, 0);
543 SendPacket(&data);
544
545 _player->RemoveBattlegroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs
546 bgQueue.RemovePlayer(_player->GetGUID(), true);
547 // player left queue, we should update it - do not update Arena Queue
548 if (!ginfo.ArenaType)
549 sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
550
551 SF_LOG_DEBUG("bg.battleground", "Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName().c_str(), _player->GetGUIDLow(), uint32(bg->GetTypeID()), bgQueueTypeId);
552 }
553}
554
556{
557 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_LEAVE Message");
558
559 // not allow leave battleground in combat
560 if (_player->IsInCombat())
561 if (Battleground* bg = _player->GetBattleground())
562 if (bg->GetStatus() != STATUS_WAIT_LEAVE)
563 return;
564
565 _player->LeaveBattleground();
566}
567
569{
570 // empty opcode
571 SF_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_STATUS Message");
572
573 WorldPacket data;
574 // we must update all queues here
575 Battleground* bg = NULL;
576 for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
577 {
578 BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(i);
579 if (!bgQueueTypeId)
580 continue;
581 BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId);
582 uint8 arenaType = BattlegroundMgr::BGArenaType(bgQueueTypeId);
583 if (bgTypeId == _player->GetBattlegroundTypeId())
584 {
585 bg = _player->GetBattleground();
586 //i cannot check any variable from player class because player class doesn't know if player is in 2v2 / 3v3 or 5v5 arena
587 //so i must use bg pointer to get that information
588 if (bg && bg->GetArenaType() == arenaType)
589 {
590 // this line is checked, i only don't know if GetElapsedTime() is changing itself after bg end!
591 // send status in Battleground
592 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_IN_PROGRESS, _player->GetBattlegroundQueueJoinTime(bgTypeId), bg->GetElapsedTime(), arenaType);
593 SendPacket(&data);
594 continue;
595 }
596 }
597
598 //we are sending update to player about queue - he can be invited there!
599 //get GroupQueueInfo for queue status
600 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
601 GroupQueueInfo ginfo;
602 if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
603 continue;
605 {
606 bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
607 if (!bg)
608 continue;
609
610 // send status invited to Battleground
611 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_WAIT_JOIN, getMSTimeDiff(getMSTime(), ginfo.RemoveInviteTime), _player->GetBattlegroundQueueJoinTime(bgTypeId), arenaType);
612 SendPacket(&data);
613 }
614 else
615 {
616 bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
617 if (!bg)
618 continue;
619
620 // expected bracket entry
621 PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel());
622 if (!bracketEntry)
623 continue;
624
625 uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, bracketEntry->GetBracketId());
626 // send status in Battleground Queue
627 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_WAIT_QUEUE, avgTime, _player->GetBattlegroundQueueJoinTime(bgTypeId), arenaType);
628 SendPacket(&data);
629 }
630 }
631}
632
634{
635 SF_LOG_DEBUG("network", "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA");
636
637 uint8 arenaslot; // 2v2, 3v3 or 5v5
638
639 recvData >> arenaslot;
640
641 // ignore if we already in BG or BG queue
642 if (_player->InBattleground())
643 return;
644
645 uint32 arenaRating = 0;
646 uint32 matchmakerRating = 0;
647
648 uint8 arenatype = ArenaTeam::GetTypeBySlot(arenaslot);
649
650 //check existance
652 if (!bg)
653 {
654 SF_LOG_ERROR("network", "Battleground: template bg (all arenas) not found");
655 return;
656 }
657
659 {
661 return;
662 }
663
664 BattlegroundTypeId bgTypeId = bg->GetTypeID();
665 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype);
666 PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel());
667 if (!bracketEntry)
668 return;
669
671
672 Group* grp = _player->GetGroup();
673 // no group found, error
674 if (!grp)
675 return;
676 if (grp->GetLeaderGUID() != _player->GetGUID())
677 return;
678
679 /*
680 uint32 ateamId = _player->GetArenaTeamId(arenaslot);
681 // check real arenateam existence only here (if it was moved to group->CanJoin .. () then we would ahve to get it twice)
682 ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ateamId);
683 if (!at)
684 {
685 _player->GetSession()->SendNotInArenaTeamPacket(arenatype);
686 return;
687 }
688 */
689
690 arenaRating = 1;
691 matchmakerRating = 1;
692
693 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
694
695 uint32 avgTime = 0;
696 GroupQueueInfo* ginfo = NULL;
697
698 err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, arenatype, arenatype, true, arenaslot);
700 {
701 SF_LOG_DEBUG("bg.battleground", "Battleground: leader %s queued with matchmaker rating %u for type %u", _player->GetName().c_str(), matchmakerRating, arenatype);
702
703 ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, true, false, arenaRating, matchmakerRating);
704 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
705 }
706
707 for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
708 {
709 Player* member = itr->GetSource();
710 if (!member)
711 continue;
712
714 {
715 WorldPacket data;
716 sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, err);
717 member->GetSession()->SendPacket(&data);
718 continue;
719 }
720
721 // add to queue
722 uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
723
724 // add joined time data
725 member->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime);
726
727 WorldPacket data; // send status packet (in queue)
728 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, arenatype);
729 member->GetSession()->SendPacket(&data);
730
731 SF_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, uint32(bgTypeId), member->GetGUIDLow(), member->GetName().c_str());
732 }
733
734 sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
735}
736
738{
739 ObjectGuid playerGuid;
740
741 recvData.ReadGuidMask(playerGuid, 3, 6, 1, 4, 5, 0, 7, 2);
742 recvData.ReadGuidBytes(playerGuid, 3, 0, 4, 1, 7, 6, 2, 5);
743
744 Player* reportedPlayer = ObjectAccessor::FindPlayer(playerGuid);
745
746 if (!reportedPlayer)
747 {
748 SF_LOG_DEBUG("bg.battleground", "WorldSession::HandleReportPvPAFK: player not found");
749 return;
750 }
751
752 SF_LOG_DEBUG("bg.battleground", "WorldSession::HandleReportPvPAFK: %s reported %s", _player->GetName().c_str(), reportedPlayer->GetName().c_str());
753
754 reportedPlayer->ReportedAfkBy(_player);
755}
756
758{
759 SF_LOG_DEBUG("network", "WORLD: CMSG_REQUEST_PVP_OPTIONS_ENABLED");
760
761 // triggers PVP_TYPES_ENABLED lua event
763 data.WriteBit(1);
764 data.WriteBit(1);
765 data.WriteBit(1);
766 data.WriteBit(1);
767 data.WriteBit(1);
768
769 data.FlushBits();
770
771 SendPacket(&data);
772}
773
775{
776 SF_LOG_DEBUG("network", "WORLD: CMSG_REQUEST_PVP_REWARDS");
777
778 _player->SendPvpRewards();
779}
780
782{
783 SF_LOG_DEBUG("network", "WORLD: CMSG_REQUEST_CONQUEST_FORMULA_CONSTANTS");
784
786
787 data << uint32(2000); // PvpMinCPPerWeek
788 data << float(1639.28); // PvpCPExpCoefficient
789 data << float(0.00412); // PvpCPNumerator
790 data << uint32(3500); // PvpMaxCPPerWeek
791 data << float(1511.26); // PvpCPBaseCoefficient
792
793 SendPacket(&data);
794}
@ STATUS_WAIT_QUEUE
@ STATUS_NONE
@ STATUS_WAIT_LEAVE
@ STATUS_WAIT_JOIN
@ STATUS_IN_PROGRESS
#define sBattlegroundMgr
DBCStorage< BattlemasterListEntry > sBattlemasterListStore(BattlemasterListEntryfmt)
PvPDifficultyEntry const * GetBattlegroundBracketByLevel(uint32 mapid, uint32 level)
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
@ DISABLE_TYPE_BATTLEGROUND
Definition DisableMgr.h:18
@ LANG_ARENA_DISABLED
Definition Language.h:730
@ LANG_YOUR_BG_LEVEL_REQ_ERROR
Definition Language.h:695
@ LANG_BG_DISABLED
Definition Language.h:729
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
TypeID GuidHigh2TypeId(uint32 guid_hi)
Definition Object.cpp:44
uint32 GUID_LOPART(uint64 x)
uint32 GUID_HIPART(uint64 guid)
GroupJoinBattlegroundResult
BattlegroundQueueTypeId
@ BATTLEGROUND_QUEUE_NONE
@ TEAM_ALLIANCE
@ TEAM_HORDE
BattlegroundTypeId
#define PLAYER_MAX_BATTLEGROUND_QUEUES
uint32 getMSTime()
Definition Timer.h:12
uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
Definition Timer.h:17
static uint8 GetTypeBySlot(uint8 slot)
uint32 GetMapId() const
BattlegroundTypeId GetTypeID(bool GetRandom=false) const
virtual uint64 GetFlagPickerGUID(int32=-1) const
uint32 GetMinPlayersPerTeam() const
uint8 GetArenaType() const
uint32 GetMaxPlayersPerTeam() const
uint32 GetInstanceID() const
bool isArena() const
uint32 GetMaxLevel() const
uint32 GetElapsedTime() const
static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType)
static BattlegroundTypeId BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId)
static uint8 BGArenaType(BattlegroundQueueTypeId bgQueueTypeId)
GroupQueueInfo * AddGroup(Player *leader, Group *group, BattlegroundTypeId bgTypeId, PvPDifficultyEntry const *bracketEntry, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating)
uint32 GetAverageQueueWaitTime(GroupQueueInfo *ginfo, BattlegroundBracketId bracket_id) const
bool GetPlayerGroupInfoData(uint64 guid, GroupQueueInfo *ginfo)
void RemovePlayer(uint64 guid, bool decreaseInvitedCount)
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void read_skip()
Definition ByteBuffer.h:502
void ReadGuidBytes(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:256
void ReadGuidMask(ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:240
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
bool ReadBit()
Definition ByteBuffer.h:180
void PSendSysMessage(const char *format,...) ATTR_PRINTF(2
Definition Chat.cpp:221
Definition Group.h:147
GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const *bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
Definition Group.cpp:2158
uint32 GetMembersCount() const
Definition Group.h:227
GroupReference * GetFirstMember()
Definition Group.h:225
uint64 GetLeaderGUID() const
Definition Group.cpp:2568
GroupReference * next()
Creature * GetCreature(uint64 guid)
Definition Map.cpp:3179
static Player * FindPlayer(uint64)
uint64 GetGUID() const
Definition Object.h:119
uint32 GetGUIDLow() const
Definition Object.h:120
uint32 GetEntry() const
Definition Object.h:125
void AddBattlegroundQueueJoinTime(BattlegroundTypeId bgTypeId, uint32 joinTime)
Definition Player.h:2711
WorldSession * GetSession() const
Definition Player.h:2417
uint32 AddBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition Player.cpp:19260
void ReportedAfkBy(Player *reporter)
This player has been blamed to be inactive in a battleground.
Definition Player.cpp:18036
bool IsBattleMaster() const
Definition Unit.h:1849
void StopMoving()
-------—End of Pet responses methods-------—
Definition Unit.cpp:5877
Map * GetMap() const
Definition Object.h:740
std::string const & GetName() const
Definition Object.h:664
void HandleBattlegroundPlayerPositionsOpcode(WorldPacket &recvData)
void HandleBattlemasterJoinOpcode(WorldPacket &recvData)
void SendNotification(const char *format,...) ATTR_PRINTF(2
void HandleBattlefieldLeaveOpcode(WorldPacket &recvData)
void HandleBattlefieldStatusOpcode(WorldPacket &recvData)
std::string GetPlayerInfo() const
Player * GetPlayer() const
void HandlePVPLogDataOpcode(WorldPacket &recvData)
void HandleRequestPvpReward(WorldPacket &recvData)
void HandleBattlemasterHelloOpcode(WorldPacket &recvData)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
Player * _player
void HandleReportPvPAFK(WorldPacket &recvData)
void HandleRequestConquestFormulaConstants(WorldPacket &recvData)
void HandleRequestPvpOptions(WorldPacket &recvData)
void HandleBattlefieldListOpcode(WorldPacket &recvData)
void HandleBattleFieldPortOpcode(WorldPacket &recvData)
void SendBattleGroundList(uint64 guid, BattlegroundTypeId bgTypeId=BattlegroundTypeId::BATTLEGROUND_RB)
void HandleBattlemasterJoinArena(WorldPacket &recvData)
@ SMSG_PVP_OPTIONS_ENABLED
Definition Opcodes.h:893
@ SMSG_BATTLEFIELD_PLAYER_POSITIONS
Definition Opcodes.h:542
@ SMSG_CONQUEST_FORMULA_CONSTANTS
Definition Opcodes.h:620
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
uint32 IsInvitedToBGInstanceGUID
float GetPositionX() const
Definition Object.h:328
float GetPositionY() const
Definition Object.h:329
BattlegroundBracketId GetBracketId() const