void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) { uint64 guid; uint32 bgTypeId_; uint32 instanceId; // sent to queue for particular bg from battlemaster's list, currently not used uint8 joinAsGroup; recvData >> guid; // battlemaster guid recvData >> bgTypeId_; // battleground type id (DBC id) recvData >> instanceId; // instance id, 0 if First Available selected recvData >> joinAsGroup; // join as group // entry not found if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) return; // chosen battleground type is disabled if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, NULL)) { ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED); return; } // get queue typeid and random typeid to check if already queued for them BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_); BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0); BattlegroundQueueTypeId bgQueueTypeIdRandom = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, 0); // safety check - bgQueueTypeId == BATTLEGROUND_QUEUE_NONE if tried to queue for arena using this function if (bgQueueTypeId == BATTLEGROUND_QUEUE_NONE) return; // get bg template Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId); if (!bgt) return; // expected bracket entry PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgt->GetMapId(), _player->getLevel()); if (!bracketEntry) return; // pussywizard: if trying to queue for already queued // just remove from queue and it will requeue! uint32 qSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId); if (qSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) { BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); if (bgQueue.IsPlayerInvitedToRatedArena(_player->GetGUID())) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_JOIN_FAILED); SendPacket(&data); return; } bgQueue.RemovePlayer(_player->GetGUID(), false, qSlot); _player->RemoveBattlegroundQueueId(bgQueueTypeId); } // must have free queue slot if (!_player->HasFreeBattlegroundQueueId()) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES); SendPacket(&data); return; } // queue result (default ok) GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult(bgt->GetBgTypeID()); // check if player can queue: if (!joinAsGroup) { if (GetPlayer()->InBattleground()) // currently in battleground err = ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND; else if (GetPlayer()->isUsingLfg()) // using lfg system err = ERR_LFG_CANT_USE_BATTLEGROUND; else if (!_player->CanJoinToBattleground()) // has deserter debuff err = ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS; else if (_player->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom)) // queued for random bg, so can't queue for anything else err = ERR_IN_RANDOM_BG; else if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) // already in queue, so can't queue for random err = ERR_IN_NON_RANDOM_BG; else if (_player->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_2v2) || _player->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_3v3) || _player->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_5v5)) // can't be already queued for arenas err = ERR_BATTLEGROUND_QUEUED_FOR_RATED; if (err <= 0) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); SendPacket(&data); return; } BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bracketEntry, false, false, 0, 0, 0); uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo); uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); // send status packet WorldPacket data; sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, 0, TEAM_NEUTRAL); SendPacket(&data); sScriptMgr->OnPlayerJoinBG(_player); } // check if group can queue: else { Group* grp = _player->GetGroup(); // no group or not a leader if (!grp || grp->GetLeaderGUID() != _player->GetGUID()) return; // pussywizard: for party members - remove queues for which leader is not queued to! std::set<uint32> leaderQueueTypeIds; for (uint32 i=0; i<PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) leaderQueueTypeIds.insert((uint32)_player->GetBattlegroundQueueTypeId(i)); for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) if (Player* member = itr->GetSource()) for (uint32 i=0; i<PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) if (BattlegroundQueueTypeId mqtid = member->GetBattlegroundQueueTypeId(i)) if (leaderQueueTypeIds.count((uint32)mqtid) == 0) { BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(mqtid); if (bgQueue.IsPlayerInvitedToRatedArena(member->GetGUID())) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_JOIN_FAILED); SendPacket(&data); return; } bgQueue.RemovePlayer(member->GetGUID(), false, i); member->RemoveBattlegroundQueueId(mqtid); } if (_player->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom)) // queued for random bg, so can't queue for anything else err = ERR_IN_RANDOM_BG; else if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) // already in queue, so can't queue for random err = ERR_IN_NON_RANDOM_BG; else if (_player->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_2v2) || _player->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_3v3) || _player->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_5v5)) // can't be already queued for arenas err = ERR_BATTLEGROUND_QUEUED_FOR_RATED; if (err > 0) err = grp->CanJoinBattlegroundQueue(bgt, bgQueueTypeId, 0, bgt->GetMaxPlayersPerTeam(), false, 0); bool isPremade = (grp->GetMembersCount() >= bgt->GetMinPlayersPerTeam() && bgTypeId != BATTLEGROUND_RB); uint32 avgWaitTime = 0; if (err > 0) { BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bracketEntry, false, isPremade, 0, 0, 0); avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo); } WorldPacket data; for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; if (err <= 0) { sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); member->GetSession()->SendPacket(&data); continue; } uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); // send status packet sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, 0, TEAM_NEUTRAL); member->GetSession()->SendPacket(&data); sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); member->GetSession()->SendPacket(&data); sScriptMgr->OnPlayerJoinBG(member); } } }
void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA"); uint64 guid; // arena Battlemaster guid uint8 arenaslot; // 2v2, 3v3 or 5v5 uint8 asGroup; // asGroup uint8 isRated; // isRated Group* grp = NULL; recvData >> guid >> arenaslot >> asGroup >> isRated; // ignore if we already in BG or BG queue if (_player->InBattleground()) return; Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) return; if (!unit->isBattleMaster()) // it's not battle master return; uint8 arenatype = 0; uint32 arenaRating = 0; uint32 matchmakerRating = 0; switch (arenaslot) { case 0: arenatype = ARENA_TYPE_2v2; break; case 1: arenatype = ARENA_TYPE_3v3; break; case 2: arenatype = ARENA_TYPE_5v5; break; default: sLog->outError(LOG_FILTER_NETWORKIO, "Unknown arena slot %u at HandleBattlemasterJoinArena()", arenaslot); return; } //check existance Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA); if (!bg) { sLog->outError(LOG_FILTER_NETWORKIO, "Battleground: template bg (all arenas) not found"); return; } if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, NULL)) { ChatHandler(this).PSendSysMessage(LANG_ARENA_DISABLED); return; } BattlegroundTypeId bgTypeId = bg->GetTypeID(); BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype); PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel()); if (!bracketEntry) return; GroupJoinBattlegroundResult err = ERR_GROUP_JOIN_BATTLEGROUND_FAIL; if (!asGroup) { // check if already in queue if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES) //player is already in this queue return; // check if has free queue slots if (!_player->HasFreeBattlegroundQueueId()) return; } else { grp = _player->GetGroup(); // no group found, error if (!grp) return; if (grp->GetLeaderGUID() != _player->GetGUID()) return; err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot); } uint32 ateamId = 0; if (isRated) { ateamId = _player->GetArenaTeamId(arenaslot); // check real arenateam existence only here (if it was moved to group->CanJoin .. () then we would ahve to get it twice) ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ateamId); if (!at) { _player->GetSession()->SendNotInArenaTeamPacket(arenatype); return; } // get the team rating for queueing arenaRating = at->GetRating(); matchmakerRating = at->GetAverageMMR(grp); // the arenateam id must match for everyone in the group if (arenaRating <= 0) arenaRating = 1; } BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); if (asGroup) { uint32 avgTime = 0; if (err > 0) { sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: arena join as group start"); if (isRated) { sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: arena team id %u, leader %s queued with matchmaker rating %u for type %u", _player->GetArenaTeamId(arenaslot), _player->GetName().c_str(), matchmakerRating, arenatype); bg->SetRated(true); } else bg->SetRated(false); GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, matchmakerRating, ateamId); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); } for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->getSource(); if (!member) continue; WorldPacket data; if (err <= 0) { sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); member->GetSession()->SendPacket(&data); continue; } // add to queue uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, 0); member->GetSession()->SendPacket(&data); sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); member->GetSession()->SendPacket(&data); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str()); } } else { GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, matchmakerRating, ateamId); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); WorldPacket data; // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, 0); SendPacket(&data); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName().c_str()); } sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); }
void WorldSession::HandleBattlemasterJoinArena(WorldPackets::Battleground::BattlemasterJoinArena& packet) { // ignore if we already in BG or BG queue if (_player->InBattleground()) return; uint8 arenatype = ArenaTeam::GetTypeBySlot(packet.TeamSizeIndex); //check existence Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA); if (!bg) { TC_LOG_ERROR("network", "Battleground: template bg (all arenas) not found"); return; } if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, nullptr)) { ChatHandler(this).PSendSysMessage(LANG_ARENA_DISABLED); return; } BattlegroundTypeId bgTypeId = bg->GetTypeID(); BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype); PvpDifficultyEntry const* bracketEntry = DB2Manager::GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel()); if (!bracketEntry) return; Group* grp = _player->GetGroup(); // no group found, error if (!grp) return; if (grp->GetLeaderGUID() != _player->GetGUID()) return; uint32 ateamId = _player->GetArenaTeamId(packet.TeamSizeIndex); // check real arenateam existence only here (if it was moved to group->CanJoin .. () then we would ahve to get it twice) ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ateamId); if (!at) { _player->GetSession()->SendNotInArenaTeamPacket(arenatype); return; } // get the team rating for queuing uint32 arenaRating = at->GetRating(); uint32 matchmakerRating = at->GetAverageMMR(grp); // the arenateam id must match for everyone in the group if (arenaRating <= 0) arenaRating = 1; BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); uint32 avgTime = 0; GroupQueueInfo* ginfo = nullptr; ObjectGuid errorGuid; GroupJoinBattlegroundResult err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, arenatype, arenatype, true, packet.TeamSizeIndex, errorGuid); if (!err) { TC_LOG_DEBUG("bg.battleground", "Battleground: arena team id %u, leader %s queued with matchmaker rating %u for type %u", _player->GetArenaTeamId(packet.TeamSizeIndex), _player->GetName().c_str(), matchmakerRating, arenatype); ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, true, false, arenaRating, matchmakerRating, ateamId); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); } for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; if (err) { WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus; sBattlegroundMgr->BuildBattlegroundStatusFailed(&battlefieldStatus, bg, _player, 0, arenatype, err, &errorGuid); member->SendDirectMessage(battlefieldStatus.Write()); continue; } // add to queue uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); WorldPackets::Battleground::BattlefieldStatusQueued battlefieldStatus; sBattlegroundMgr->BuildBattlegroundStatusQueued(&battlefieldStatus, bg, member, queueSlot, ginfo->JoinTime, avgTime, arenatype, true); member->SendDirectMessage(battlefieldStatus.Write()); TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type %u bg type %u, %s, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUID().ToString().c_str(), member->GetName().c_str()); } sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); }
void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_LOOT_MONEY"); Player* player = GetPlayer(); uint64 guid = player->GetLootGUID(); if (!guid) return; Loot* loot = NULL; bool shareMoney = true; switch (GUID_HIPART(guid)) { case HIGHGUID_GAMEOBJECT: { GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid); // do not check distance for GO if player is the owner of it (ex. fishing bobber) if (go && ((go->GetOwnerGUID() == player->GetGUID() || go->IsWithinDistInMap(player, INTERACTION_DISTANCE)))) loot = &go->loot; break; } case HIGHGUID_CORPSE: // remove insignia ONLY in BG { Corpse* bones = ObjectAccessor::GetCorpse(*player, guid); if (bones && bones->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &bones->loot; shareMoney = false; } break; } case HIGHGUID_ITEM: { if (Item* item = player->GetItemByGuid(guid)) { loot = &item->loot; shareMoney = false; } break; } case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: { Creature* creature = player->GetMap()->GetCreature(guid); bool lootAllowed = creature && creature->isAlive() == (player->getClass() == CLASS_ROGUE && creature->lootForPickPocketed); if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &creature->loot; if (creature->isAlive()) shareMoney = false; } break; } default: return; // unlootable type } if (loot) { loot->NotifyMoneyRemoved(); if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player { Group* group = player->GetGroup(); std::vector<Player*> playersNear; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->getSource(); if (!member) continue; if (player->IsWithinDistInMap(member, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false)) playersNear.push_back(member); } uint32 goldPerPlayer = uint32((loot->gold) / (playersNear.size())); for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) { (*i)->ModifyMoney(goldPerPlayer); (*i)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(goldPerPlayer); data << uint8(playersNear.size() > 1 ? 0 : 1); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..." (*i)->GetSession()->SendPacket(&data); } } else { player->ModifyMoney(loot->gold); player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(loot->gold); data << uint8(1); // "You loot..." SendPacket(&data); } loot->gold = 0; } }
void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data ) { uint64 guid; uint32 quest; uint32 unk1; recv_data >> guid >> quest >> unk1; if(!GetPlayer()->isAlive()) return; DEBUG_LOG( "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), quest, unk1 ); Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM); // no or incorrect quest giver if(!pObject || (pObject->GetTypeId()!=TYPEID_PLAYER && !pObject->hasQuest(quest)) || (pObject->GetTypeId()==TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest)) ) { _player->PlayerTalkClass->CloseGossip(); _player->SetDivider( 0 ); return; } Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest); if ( qInfo ) { // prevent cheating if(!GetPlayer()->CanTakeQuest(qInfo,true) ) { _player->PlayerTalkClass->CloseGossip(); _player->SetDivider( 0 ); return; } if( _player->GetDivider() != 0 ) { Player *pPlayer = ObjectAccessor::FindPlayer( _player->GetDivider() ); if( pPlayer ) { pPlayer->SendPushToPartyResponse( _player, QUEST_PARTY_MSG_ACCEPT_QUEST ); _player->SetDivider( 0 ); } } if( _player->CanAddQuest( qInfo, true ) ) { _player->AddQuest( qInfo, pObject ); if (qInfo->HasFlag(QUEST_FLAGS_PARTY_ACCEPT)) { if (Group* pGroup = _player->GetGroup()) { for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pPlayer = itr->getSource(); if (!pPlayer || pPlayer == _player) // not self continue; if (pPlayer->CanTakeQuest(qInfo, true)) { pPlayer->SetDivider(_player->GetGUID()); //need confirmation that any gossip window will close pPlayer->PlayerTalkClass->CloseGossip(); _player->SendQuestConfirmAccept(qInfo, pPlayer); } } } } if ( _player->CanCompleteQuest( quest ) ) _player->CompleteQuest( quest ); _player->GetAchievementMgr().StartTimedAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest); switch(pObject->GetTypeId()) { case TYPEID_UNIT: Script->QuestAccept(_player, ((Creature*)pObject), qInfo ); break; case TYPEID_ITEM: case TYPEID_CONTAINER: { Script->ItemQuestAccept(_player, ((Item*)pObject), qInfo ); // destroy not required for quest finish quest starting item bool destroyItem = true; for(int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) { if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount > 0)) { destroyItem = false; break; } } if(destroyItem) _player->DestroyItem(((Item*)pObject)->GetBagSlot(), ((Item*)pObject)->GetSlot(), true); break; } case TYPEID_GAMEOBJECT: Script->GOQuestAccept(_player, ((GameObject*)pObject), qInfo ); break; } _player->PlayerTalkClass->CloseGossip(); if( qInfo->GetSrcSpell() > 0 ) _player->CastSpell( _player, qInfo->GetSrcSpell(), true); return; } } _player->PlayerTalkClass->CloseGossip(); }
void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket & recv_data) { uint64 guid; uint32 quest; uint32 unk1; recv_data >> guid >> quest >> unk1; if (!GetPlayer()->isAlive()) return; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), quest, unk1); Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER); // From 4.0.1 Player can be QuestGiver for self if (!IS_PLAYER_GUID(guid)) { if (!pObject || (pObject->GetTypeId() != TYPEID_PLAYER && !pObject->hasQuest(quest)) || (pObject->GetTypeId() == TYPEID_PLAYER && !pObject->ToPlayer()->CanShareQuest(quest))) { _player->PlayerTalkClass->CloseGossip(); _player->SetDivider(0); return; } } Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest); if (qInfo) { // prevent cheating if (!GetPlayer()->CanTakeQuest(qInfo, true)) { _player->PlayerTalkClass->CloseGossip(); _player->SetDivider(0); return; } if (_player->GetDivider() != 0) { Player *pPlayer = ObjectAccessor::FindPlayer(_player->GetDivider()); if (pPlayer) { pPlayer->SendPushToPartyResponse(_player, QUEST_PARTY_MSG_ACCEPT_QUEST); _player->SetDivider(0); } } if (_player->CanAddQuest(qInfo, true)) { _player->AddQuest(qInfo, pObject); if (qInfo->HasFlag(QUEST_FLAGS_PARTY_ACCEPT)) { if (Group* pGroup = _player->GetGroup()) { for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pPlayer = itr->getSource(); if (!pPlayer || pPlayer == _player) // not self continue; if (pPlayer->CanTakeQuest(qInfo, true)) { pPlayer->SetDivider(_player->GetGUID()); //need confirmation that any gossip window will close pPlayer->PlayerTalkClass->CloseGossip(); _player->SendQuestConfirmAccept(qInfo, pPlayer); } } } } if (_player->CanCompleteQuest(quest)) _player->CompleteQuest(quest); switch(pObject->GetTypeId()) { case TYPEID_UNIT: sScriptMgr->OnQuestAccept(_player, (pObject->ToCreature()), qInfo); (pObject->ToCreature())->AI()->sQuestAccept(_player, qInfo); break; case TYPEID_ITEM: case TYPEID_CONTAINER: { sScriptMgr->OnQuestAccept(_player, ((Item*)pObject), qInfo); // destroy not required for quest finish quest starting item bool destroyItem = true; for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) { if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount > 0)) { destroyItem = false; break; } } if (destroyItem) _player->DestroyItem(((Item*)pObject)->GetBagSlot(), ((Item*)pObject)->GetSlot(), true); break; } case TYPEID_GAMEOBJECT: sScriptMgr->OnQuestAccept(_player, ((GameObject*)pObject), qInfo); (pObject->ToGameObject())->AI()->QuestAccept(_player, qInfo); break; default: break; } _player->PlayerTalkClass->CloseGossip(); if (qInfo->GetSrcSpell() > 0) _player->CastSpell(_player, qInfo->GetSrcSpell(), true); return; } } _player->PlayerTalkClass->CloseGossip(); }
void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recv_data) { DEBUG_LOG("WORLD: CMSG_BATTLEMASTER_JOIN_ARENA"); // recv_data.hexlike(); uint8 arenaslot; // 2v2, 3v3 or 5v5 recv_data >> arenaslot; // ignore if we already in BG or BG queue if (_player->InBattleGround()) return; ArenaType arenatype = ArenaTeam::GetTypeBySlot(arenaslot); uint32 arenaRating = 0; if (!IsArenaTypeValid(arenatype)) { sLog.outError("Unknown arena slot %u at HandleBattlemasterJoinArena()", arenaslot); return; } // check existence BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA); if (!bg) { sLog.outError("Battleground: template bg (all arenas) not found"); return; } BattleGroundTypeId bgTypeId = bg->GetTypeID(); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype); PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel()); if (!bracketEntry) return; Group* grp = _player->GetGroup(); // no group found, error if (!grp) return; if (grp->GetLeaderGuid() != _player->GetObjectGuid()) return; uint32 ateamId = _player->GetArenaTeamId(arenaslot); // check real arena team existence only here (if it was moved to group->CanJoin .. () then we would have to get it twice) ArenaTeam* at = sObjectMgr.GetArenaTeamById(ateamId); if (!at) { _player->GetSession()->SendNotInArenaTeamPacket(arenatype); return; } // get the team rating for queue arenaRating = at->GetRating(); // the arena team id must match for everyone in the group // get the personal ratings for queue uint32 avg_pers_rating = 0; for (Group::member_citerator citr = grp->GetMemberSlots().begin(); citr != grp->GetMemberSlots().end(); ++citr) { ArenaTeamMember const* at_member = at->GetMember(citr->guid); if (!at_member) // group member joining to arena must be in leader arena team return; avg_pers_rating += at_member->matchmaker_rating; } avg_pers_rating /= grp->GetMembersCount(); /* Save mmr before enter arena (matchmaker rating fix) */ at->SetBattleRating(avg_pers_rating); arenaRating = avg_pers_rating; BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId]; uint32 avgTime = 0; // may be Group::CanJoinBattleGroundQueue should be moved to player class... GroupJoinBattlegroundResult err = grp->CanJoinBattleGroundQueue(bg, bgQueueTypeId, arenatype, arenatype, true, arenaslot); if (!err) { DEBUG_LOG("Battleground: arena join as group start"); DEBUG_LOG("Battleground: arena team id %u, leader %s queued with rating %u for type %u", _player->GetArenaTeamId(arenaslot), _player->GetName(), arenaRating, arenatype); GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, true, false, arenaRating, ateamId); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); } for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->getSource(); if (!member) continue; WorldPacket data; if (err) { sBattleGroundMgr.BuildBattleGroundStatusFailedPacket(&data, bg, member, 0, err); member->GetSession()->SendPacket(&data); continue; } // add to queue uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId); // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype); member->GetSession()->SendPacket(&data); DEBUG_LOG("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName()); } DEBUG_LOG("Battleground: arena join as group end"); sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); }
void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data) { uint32 type; uint32 lang; recv_data >> type; recv_data >> lang; if (type >= MAX_CHAT_MSG_TYPE) { sLog.outError("CHAT: Wrong message type received: %u", type); return; } DEBUG_LOG("CHAT: packet received. type %u, lang %u", type, lang); // prevent talking at unknown language (cheating) LanguageDesc const* langDesc = GetLanguageDescByID(lang); if (!langDesc) { SendNotification(LANG_UNKNOWN_LANGUAGE); return; } if (langDesc->skill_id != 0 && !_player->HasSkill(langDesc->skill_id)) { // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) Unit::AuraList const& langAuras = _player->GetAurasByType(SPELL_AURA_COMPREHEND_LANGUAGE); bool foundAura = false; for (Unit::AuraList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i) { if ((*i)->GetModifier()->m_miscvalue == int32(lang)) { foundAura = true; break; } } if (!foundAura) { SendNotification(LANG_NOT_LEARNED_LANGUAGE); return; } } if (lang == LANG_ADDON) { // Disabled addon channel? if (!sWorld.getConfig(CONFIG_BOOL_ADDON_CHANNEL)) return; } // LANG_ADDON should not be changed nor be affected by flood control else { // send in universal language if player in .gmon mode (ignore spell effects) if (_player->isGameMaster()) lang = LANG_UNIVERSAL; else { // send in universal language in two side iteration allowed mode if (sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHAT)) lang = LANG_UNIVERSAL; else { switch (type) { case CHAT_MSG_PARTY: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: // allow two side chat at group channel if two side group allowed if (sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GROUP)) lang = LANG_UNIVERSAL; break; case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: // allow two side chat at guild channel if two side guild allowed if (sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD)) lang = LANG_UNIVERSAL; break; } } // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used) Unit::AuraList const& ModLangAuras = _player->GetAurasByType(SPELL_AURA_MOD_LANGUAGE); if (!ModLangAuras.empty()) lang = ModLangAuras.front()->GetModifier()->m_miscvalue; } if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND) { if (!_player->CanSpeak()) { std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); SendNotification(GetMangosString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); return; } GetPlayer()->UpdateSpeakTime(); } } switch (type) { case CHAT_MSG_SAY: case CHAT_MSG_EMOTE: case CHAT_MSG_YELL: { std::string msg; recv_data >> msg; if (msg.empty()) break; if (ChatHandler(this).ParseCommands(msg.c_str())) break; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; if (type == CHAT_MSG_SAY) GetPlayer()->Say(msg, lang); else if (type == CHAT_MSG_EMOTE) GetPlayer()->TextEmote(msg); else if (type == CHAT_MSG_YELL) GetPlayer()->Yell(msg, lang); } break; case CHAT_MSG_WHISPER: { std::string to, msg; recv_data >> to; recv_data >> msg; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; if (!normalizePlayerName(to)) { SendPlayerNotFoundNotice(to); break; } Player* player = sObjectMgr.GetPlayer(to.c_str()); uint32 tSecurity = GetSecurity(); uint32 pSecurity = player ? player->GetSession()->GetSecurity() : SEC_PLAYER; if (!player || (tSecurity == SEC_PLAYER && pSecurity > SEC_PLAYER && !player->isAcceptWhispers())) { SendPlayerNotFoundNotice(to); return; } if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHAT) && tSecurity == SEC_PLAYER && pSecurity == SEC_PLAYER) { if (GetPlayer()->GetTeam() != player->GetTeam()) { SendWrongFactionNotice(); return; } } // Playerbot mod: handle whispered command to bot if (player->GetPlayerbotAI()) { player->GetPlayerbotAI()->HandleCommand(msg, *GetPlayer()); GetPlayer()->m_speakTime = 0; GetPlayer()->m_speakCount = 0; } else GetPlayer()->Whisper(msg, lang, player->GetObjectGuid()); } break; case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: { std::string msg; recv_data >> msg; if (msg.empty()) break; if (ChatHandler(this).ParseCommands(msg.c_str())) break; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; // if player is in battleground, he cannot say to battleground members by /p Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = _player->GetGroup(); if (!group || group->isBGGroup()) return; } if ((type == CHAT_MSG_PARTY_LEADER) && !group->IsLeader(_player->GetObjectGuid())) return; // Playerbot mod: broadcast message to bot members for(GroupReference* itr = group->GetFirstMember(); itr != NULL; itr=itr->next()) { Player* player = itr->getSource(); if (player && player->GetPlayerbotAI() && ((msg.find("help",0) != std::string::npos) || (msg.find("gm",0) != std::string::npos) || (msg.find("complete",0) != std::string::npos))) { player->GetPlayerbotAI()->HandleCommand(msg, *GetPlayer()); GetPlayer()->m_speakTime = 0; GetPlayer()->m_speakCount = 0; break; } if (player && player->GetPlayerbotAI()) { player->GetPlayerbotAI()->HandleCommand(msg, *GetPlayer()); GetPlayer()->m_speakTime = 0; GetPlayer()->m_speakCount = 0; } } // END Playerbot mod WorldPacket data; ChatHandler::FillMessageData(&data, this, type, lang, msg.c_str()); group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetObjectGuid())); break; } case CHAT_MSG_GUILD: { std::string msg; recv_data >> msg; if (msg.empty()) break; if (ChatHandler(this).ParseCommands(msg.c_str())) break; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; if (GetPlayer()->GetGuildId()) if (Guild* guild = sGuildMgr.GetGuildById(GetPlayer()->GetGuildId())) guild->BroadcastToGuild(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); break; } case CHAT_MSG_OFFICER: { std::string msg; recv_data >> msg; if (msg.empty()) break; if (ChatHandler(this).ParseCommands(msg.c_str())) break; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; if (GetPlayer()->GetGuildId()) if (Guild* guild = sGuildMgr.GetGuildById(GetPlayer()->GetGuildId())) guild->BroadcastToOfficers(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); break; } case CHAT_MSG_RAID: { std::string msg; recv_data >> msg; if (msg.empty()) break; if (ChatHandler(this).ParseCommands(msg.c_str())) break; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; // if player is in battleground, he cannot say to battleground members by /ra Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = GetPlayer()->GetGroup(); if (!group || group->isBGGroup() || !group->isRaidGroup()) return; } WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, msg.c_str()); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_LEADER: { std::string msg; recv_data >> msg; if (msg.empty()) break; if (ChatHandler(this).ParseCommands(msg.c_str())) break; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; // if player is in battleground, he cannot say to battleground members by /ra Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = GetPlayer()->GetGroup(); if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(_player->GetObjectGuid())) return; } WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, msg.c_str()); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_WARNING: { std::string msg; recv_data >> msg; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; Group* group = GetPlayer()->GetGroup(); if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetObjectGuid()) || group->IsAssistant(GetPlayer()->GetObjectGuid()))) return; WorldPacket data; // in battleground, raid warning is sent only to players in battleground - code is ok ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_WARNING, lang, msg.c_str()); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND: { std::string msg; recv_data >> msg; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group* group = GetPlayer()->GetGroup(); if (!group || !group->isBGGroup()) return; WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, msg.c_str()); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND_LEADER: { std::string msg; recv_data >> msg; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group* group = GetPlayer()->GetGroup(); if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetObjectGuid())) return; WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, msg.c_str()); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_CHANNEL: { std::string channel, msg; recv_data >> channel; recv_data >> msg; if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; if (msg.empty()) break; if (ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if (Channel* chn = cMgr->GetChannel(channel, _player)) chn->Say(_player->GetObjectGuid(), msg.c_str(), lang); } break; case CHAT_MSG_AFK: { std::string msg; recv_data >> msg; if (!_player->isInCombat()) { if (_player->isAFK()) // Already AFK { if (msg.empty()) _player->ToggleAFK(); // Remove AFK else _player->autoReplyMsg = msg; // Update message } else // New AFK mode { _player->autoReplyMsg = msg.empty() ? GetMangosString(LANG_PLAYER_AFK_DEFAULT) : msg; if (_player->isDND()) _player->ToggleDND(); _player->ToggleAFK(); } } break; } case CHAT_MSG_DND: { std::string msg; recv_data >> msg; if (_player->isDND()) // Already DND { if (msg.empty()) _player->ToggleDND(); // Remove DND else _player->autoReplyMsg = msg; // Update message } else // New DND mode { _player->autoReplyMsg = msg.empty() ? GetMangosString(LANG_PLAYER_DND_DEFAULT) : msg; if (_player->isAFK()) _player->ToggleAFK(); _player->ToggleDND(); } break; } default: sLog.outError("CHAT: unknown message type %u, lang: %u", type, lang); break; } }
void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) { uint32 questId; recvPacket >> questId; DEBUG_LOG("WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", questId); if (Quest const *pQuest = sObjectMgr.GetQuestTemplate(questId)) { if (Group* pGroup = _player->GetGroup()) { for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player *pPlayer = itr->getSource(); if (!pPlayer || pPlayer == _player) // skip self continue; _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST); if (!pPlayer->SatisfyQuestStatus(pQuest, false)) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_HAVE_QUEST); continue; } if (pPlayer->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_FINISH_QUEST); continue; } if (!pPlayer->CanTakeQuest(pQuest, false)) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_CANT_TAKE_QUEST); continue; } if (!pPlayer->SatisfyQuestLog(false)) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_LOG_FULL); continue; } if (pPlayer->GetDividerGuid()) { _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_BUSY); continue; } pPlayer->SetDividerGuid(_player->GetObjectGuid()); if (pPlayer->GetPlayerbotAI()) pPlayer->GetPlayerbotAI()->AcceptQuest( pQuest, _player ); else { pPlayer->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, _player->GetObjectGuid(), true); pPlayer->SetDividerGuid(_player->GetObjectGuid()); } } } } }
void WorldSession::HandleBattlegroundArenaJoin(WorldPacket& recv_data) { sLog.outDebug("WORLD: CMSG_BATTLEMASTER_JOIN_ARENA"); //recv_data.hexlike(); uint64 guid; // arena Battlemaster guid uint8 arenaslot; // 2v2, 3v3 or 5v5 uint8 asGroup; // asGroup uint8 isRated; // isRated Group* grp = NULL; recv_data >> guid >> arenaslot >> asGroup >> isRated; // ignore if we already in BG or BG queue if (_player->InBattleground()) return; Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) return; if (!unit->IsBattleMaster()) // it's not battle master return; uint8 arenatype = 0; uint32 arenaRating = 0; switch (arenaslot) { case 0: arenatype = ARENA_TYPE_2v2; break; case 1: arenatype = ARENA_TYPE_3v3; break; case 2: arenatype = ARENA_TYPE_5v5; break; default: sLog.outError("Unknown arena slot %u at HandleBattlegroundArenaJoin()", arenaslot); return; } //check existance Battleground* bg = NULL; if (!(bg = sBattlegroundMgr.GetBattlegroundTemplate(BATTLEGROUND_AA))) { sLog.outError("Battleground: template bg (all arenas) not found"); return; } if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, NULL)) { ChatHandler(this).PSendSysMessage(LANG_ARENA_DISABLED); return; } uint8 bgTypeId = bg->GetTypeID(); uint32 bgQueueTypeId = sBattlegroundMgr.BGQueueTypeId(bgTypeId, arenatype); // check queueing conditions if (!asGroup) { // check if already in queue if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES) //player is already in this queue return; // check if has free queue slots if (!_player->HasFreeBattlegroundQueueId()) return; } else { grp = _player->GetGroup(); // no group found, error if (!grp) return; uint32 err = grp->CanJoinBattlegroundQueue(bgTypeId, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot); if (err != BG_JOIN_ERR_OK) { SendBattlegroundOrArenaJoinError(err); return; } } uint32 ateamId = 0; if (isRated) { ateamId = _player->GetArenaTeamId(arenaslot); // check real arenateam existence only here (if it was moved to group->CanJoin .. () then we would ahve to get it twice) ArenaTeam* at = sObjectMgr.GetArenaTeamById(ateamId); if (!at) { _player->GetSession()->SendNotInArenaTeamPacket(arenatype); return; } // get the team rating for queueing arenaRating = at->GetRating(); // the arenateam id must match for everyone in the group // get the personal ratings for queueing uint32 avg_pers_rating = 0; for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); // calc avg personal rating avg_pers_rating += member->GetArenaPersonalRating(arenaslot); } if (arenatype) avg_pers_rating /= arenatype; // if avg personal rating is more than 150 points below the teams rating, the team will be queued against an opponent matching or similar to the average personal rating if (avg_pers_rating + 150 < arenaRating) arenaRating = avg_pers_rating; } if (asGroup) { GroupQueueInfo* ginfo = sBattlegroundMgr.m_BattlegroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, arenaRating, ateamId); sLog.outDebug("Battleground: arena join as group start"); if (isRated) sLog.outDebug("Battleground: arena team id %u, leader %s queued with rating %u for type %u", _player->GetArenaTeamId(arenaslot), _player->GetName(), arenaRating, arenatype); for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);// add to queue // store entry point coords (same as leader entry point) if (!sWorld.getConfig(CONFIG_BATTLEGROUND_WRATH_LEAVE_MODE)) member->SetBattlegroundEntryPoint(_player->GetMapId(), _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetOrientation()); WorldPacket data; // send status packet (in queue) sBattlegroundMgr.BuildBattlegroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0, arenatype, isRated); member->GetSession()->SendPacket(&data); sBattlegroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId); member->GetSession()->SendPacket(&data); sBattlegroundMgr.m_BattlegroundQueues[bgQueueTypeId].AddPlayer(member, ginfo); sLog.outDebug("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName()); } sLog.outDebug("Battleground: arena join as group end"); sBattlegroundMgr.m_BattlegroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattlegroundQueueIdFromLevel(), arenatype, isRated, arenaRating); } else { uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); // store entry point coords if (!sWorld.getConfig(CONFIG_BATTLEGROUND_WRATH_LEAVE_MODE)) _player->SetBattlegroundEntryPoint(_player->GetMapId(), _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetOrientation()); WorldPacket data; // send status packet (in queue) sBattlegroundMgr.BuildBattlegroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0, arenatype, isRated); SendPacket(&data); GroupQueueInfo* ginfo = sBattlegroundMgr.m_BattlegroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, arenaRating); sBattlegroundMgr.m_BattlegroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo); sBattlegroundMgr.m_BattlegroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattlegroundQueueIdFromLevel(), arenatype, isRated, arenaRating); sLog.outDebug("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName()); } }
void WorldSession::HandleBattlegroundJoinOpcode(WorldPacket& recv_data) { uint64 guid; uint32 bgTypeId; uint32 instanceId; uint8 joinAsGroup; Group* grp; recv_data >> guid; // battlemaster guid recv_data >> bgTypeId; // battleground type id (DBC id) recv_data >> instanceId; // instance id, 0 if First Available selected recv_data >> joinAsGroup; // join as group if (bgTypeId >= MAX_BATTLEGROUND_TYPES) { sLog.outError("Battleground: invalid bgtype received. possible cheater? player guid %u", _player->GetGUIDLow()); return; } if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId, NULL)) { ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED); return; } sLog.outDebug("WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid))); // can do this, since it's battleground, not arena uint32 bgQueueTypeId = sBattlegroundMgr.BGQueueTypeId(bgTypeId, 0); // ignore if player is already in BG if (_player->InBattleground()) return; Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) return; if (!unit->IsBattleMaster()) // it's not battlemaster return; // get bg instance or bg template if instance not found Battleground* bg = NULL; if (instanceId) bg = sBattlegroundMgr.GetBattleground(instanceId); if (!bg && !(bg = sBattlegroundMgr.GetBattlegroundTemplate(bgTypeId))) { sLog.outError("Battleground: no available bg / template found"); return; } // check queueing conditions if (!joinAsGroup) { // check Deserter debuff if (!_player->CanJoinToBattleground()) { WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4); data << (uint32) 0xFFFFFFFE; _player->GetSession()->SendPacket(&data); return; } // check if already in queue if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES) //player is already in this queue return; // check if has free queue slots if (!_player->HasFreeBattlegroundQueueId()) return; } else { grp = _player->GetGroup(); // no group found, error if (!grp) return; uint32 err = grp->CanJoinBattlegroundQueue(bgTypeId, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0); if (err != BG_JOIN_ERR_OK) { SendBattlegroundOrArenaJoinError(err); return; } } // if we're here, then the conditions to join a bg are met. We can proceed in joining. // _player->GetGroup() was already checked, grp is already initialized if (joinAsGroup /* && _player->GetGroup()*/) { sLog.outDebug("Battleground: the following players are joining as group:"); GroupQueueInfo* ginfo = sBattlegroundMgr.m_BattlegroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, 0); for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; // this should never happen uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); // add to queue // store entry point coords (same as leader entry point) if (!sWorld.getConfig(CONFIG_BATTLEGROUND_WRATH_LEAVE_MODE)) member->SetBattlegroundEntryPoint(_player->GetMapId(), _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetOrientation()); WorldPacket data; // send status packet (in queue) sBattlegroundMgr.BuildBattlegroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0); member->GetSession()->SendPacket(&data); sBattlegroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId); member->GetSession()->SendPacket(&data); sBattlegroundMgr.m_BattlegroundQueues[bgQueueTypeId].AddPlayer(member, ginfo); sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName()); } sLog.outDebug("Battleground: group end"); sBattlegroundMgr.m_BattlegroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattlegroundQueueIdFromLevel()); } else { // already checked if queueSlot is valid, now just get it uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); // store entry point coords if (!sWorld.getConfig(CONFIG_BATTLEGROUND_WRATH_LEAVE_MODE)) _player->SetBattlegroundEntryPoint(_player->GetMapId(), _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetOrientation()); WorldPacket data; // send status packet (in queue) sBattlegroundMgr.BuildBattlegroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0); SendPacket(&data); GroupQueueInfo* ginfo = sBattlegroundMgr.m_BattlegroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, 0); sBattlegroundMgr.m_BattlegroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo); sBattlegroundMgr.m_BattlegroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattlegroundQueueIdFromLevel()); sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName()); } }
void WorldSession::SendLfgUpdateProposal(uint32 proposalId, const LfgProposal* pProp) { if (!pProp) return; uint64 guid = GetPlayer()->GetGUID(); LfgProposalPlayerMap::const_iterator itPlayer = pProp->players.find(guid); if (itPlayer == pProp->players.end()) // Player MUST be in the proposal return; LfgProposalPlayer* ppPlayer = itPlayer->second; uint32 pLowGroupGuid = ppPlayer->groupLowGuid; uint32 dLowGuid = pProp->groupLowGuid; uint32 dungeonId = pProp->dungeonId; bool isSameDungeon = false; bool isContinue = false; Group* group = dLowGuid ? sGroupMgr->GetGroupByGUID(dLowGuid) : NULL; uint32 completedEncounters = 0; if (group) { uint64 gguid = group->GetGUID(); isContinue = group->isLFGGroup() && sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON; isSameDungeon = GetPlayer()->GetGroup() == group && isContinue; } sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PROPOSAL_UPDATE [" UI64FMTD "] state: %u", GetPlayer()->GetGUID(), pProp->state); WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + pProp->players.size() * (4 + 1 + 1 + 1 + 1 +1)); if (!isContinue) // Only show proposal dungeon if it's continue { LfgDungeonSet playerDungeons = sLFGMgr->GetSelectedDungeons(guid); if (playerDungeons.size() == 1) dungeonId = (*playerDungeons.begin()); } if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) { dungeonId = dungeon->Entry(); // Select a player inside to be get completed encounters from if (group) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* groupMember = itr->getSource(); if (groupMember && groupMember->GetMapId() == uint32(dungeon->map)) { if (InstanceScript* instance = groupMember->GetInstanceScript()) completedEncounters = instance->GetCompletedEncounterMask(); break; } } } } data << uint32(dungeonId); // Dungeon data << uint8(pProp->state); // Result state data << uint32(proposalId); // Internal Proposal ID data << uint32(completedEncounters); // Bosses killed data << uint8(isSameDungeon); // Silent (show client window) data << uint8(pProp->players.size()); // Group size for (itPlayer = pProp->players.begin(); itPlayer != pProp->players.end(); ++itPlayer) { ppPlayer = itPlayer->second; data << uint32(ppPlayer->role); // Role data << uint8(itPlayer->first == guid); // Self player if (!ppPlayer->groupLowGuid) // Player not it a group { data << uint8(0); // Not in dungeon data << uint8(0); // Not same group } else { data << uint8(ppPlayer->groupLowGuid == dLowGuid); // In dungeon (silent) data << uint8(ppPlayer->groupLowGuid == pLowGroupGuid); // Same Group than player } data << uint8(ppPlayer->accept != LFG_ANSWER_PENDING); // Answered data << uint8(ppPlayer->accept == LFG_ANSWER_AGREE); // Accepted } SendPacket(&data); }
void WorldSession::SendLfgRoleCheckUpdate() { if (!sWorld.getConfig(CONFIG_BOOL_LFG_ENABLE)) { DEBUG_LOG("SendLfgRoleCheckUpdate %u failed - Dungeon finder disabled", GetPlayer()->GetObjectGuid().GetCounter()); return; } Group* pGroup = GetPlayer()->GetGroup(); if (!pGroup) return; LFGDungeonSet const* dungeons = pGroup->GetLFGGroupState()->GetDungeons(); if (!dungeons) return; DEBUG_LOG("SMSG_LFG_ROLE_CHECK_UPDATE %u, dugeons size " SIZEFMTD, GetPlayer()->GetObjectGuid().GetCounter(), dungeons->size()); WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons->size() * 4 + 1 + pGroup->GetMembersCount() * (8 + 1 + 4 + 1)); data << uint32(pGroup->GetLFGGroupState()->GetRoleCheckState()); // Check result data << uint8(pGroup->GetLFGGroupState()->GetRoleCheckState() == LFG_ROLECHECK_INITIALITING); data << uint8(dungeons->size()); // Number of dungeons if (dungeons->size()) { for (LFGDungeonSet::const_iterator itr = dungeons->begin(); itr != dungeons->end(); ++itr) { data << uint32(*itr ? (*itr)->Entry() : 0); // Dungeon Entry } } data << uint8(pGroup->GetMembersCount()); // Players in group if (pGroup->GetMembersCount()) { // Leader info MUST be sent 1st :S ObjectGuid leaderguid = pGroup->GetLeaderGuid(); Player* pLeader = sObjectMgr.GetPlayer(leaderguid); LFGRoleMask roles = LFG_ROLE_MASK_NONE; uint8 leaderLevel = 1; if (pLeader) { roles = pLeader->GetLFGPlayerState()->GetRoles(); leaderLevel = pLeader->getLevel(); } data << leaderguid; // Guid data << uint8(roles != LFG_ROLE_MASK_NONE); // Ready data << uint32(roles); // Roles data << uint8(leaderLevel); // Level for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { if (Player* pGroupMember = itr->getSource()) { ObjectGuid guid = pGroupMember->GetObjectGuid(); // Leader data handle first if (guid == leaderguid) continue; roles = pGroupMember->GetLFGPlayerState()->GetRoles(); data << guid; // Guid data << uint8(roles != LFG_ROLE_MASK_NONE); // Ready data << uint32(roles); // Roles data << uint8(pGroupMember->getLevel()); // Level } } } SendPacket(&data); }
void WorldSession::SendLfgUpdateProposal(LFGProposal* pProposal) { if (!sWorld.getConfig(CONFIG_BOOL_LFG_ENABLE)) { DEBUG_LOG("SendLfgUpdateProposal %u failed - Dungeon finder disabled", GetPlayer()->GetObjectGuid().GetCounter()); return; } if (!pProposal) return; LFGDungeonEntry const* dungeon = pProposal->GetDungeon(); if (!dungeon) { DEBUG_LOG("SMSG_LFG_PROPOSAL_UPDATE: no dungeon in proposal %u, returning.", pProposal->m_uiID); return; } ObjectGuid guid = GetPlayer()->GetObjectGuid(); bool isSameDungeon = false; bool isSameGroup = false; uint32 completedEncounters = 0; LFGRolesMap rolesMap; if (Group* group = pProposal->GetGroup()) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pGroupMember = itr->getSource(); if (pGroupMember && pGroupMember->IsInWorld()) { rolesMap.insert(std::make_pair(pGroupMember->GetObjectGuid(), pGroupMember->GetLFGPlayerState()->GetRoles())); if (InstancePlayerBind* bind = pGroupMember->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty))) { if (DungeonPersistentState* state = bind->state) completedEncounters |= state->GetCompletedEncountersMask(); } } } // isContinue = group->isLFGGroup() && sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON; isSameDungeon = dungeon->map == GetPlayer()->GetMapId(); isSameGroup = GetPlayer()->GetGroup() == group; } GuidSet const proposalGuids = pProposal->GetMembers(); if (!proposalGuids.empty()) { for (GuidSet::const_iterator itr = proposalGuids.begin(); itr != proposalGuids.end(); ++itr) { Player* player = sObjectMgr.GetPlayer(*itr); if (player && player->IsInWorld()) rolesMap.insert(std::make_pair(player->GetObjectGuid(), player->GetLFGPlayerState()->GetRoles())); } } uint32 size = rolesMap.size(); DEBUG_LOG("SMSG_LFG_PROPOSAL_UPDATE proposal %u, player %u, state: %u", pProposal->m_uiID, GetPlayer()->GetObjectGuid().GetCounter(), pProposal->GetState()); WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + size * (4 + 1 + 1 + 1 + 1 +1)); data << uint32(dungeon->Entry()); // Dungeon data << uint8(pProposal->GetState()); // Result state data << uint32(pProposal->m_uiID); // Internal Proposal ID data << uint32(completedEncounters); // Bosses killed data << uint8(isSameDungeon); // Silent (show client window) data << uint8(size); // Group size for (LFGRolesMap::const_iterator itr = rolesMap.begin(); itr != rolesMap.end(); ++itr) { Player* pPlayer = sObjectMgr.GetPlayer(itr->first); if (!pPlayer) continue; isSameDungeon = dungeon->map == pPlayer->GetMapId(); isSameGroup = pPlayer->GetGroup() == pProposal->GetGroup(); data << uint32(itr->second); // Role data << uint8(pPlayer->GetObjectGuid() == guid); // Self player data << uint8(isSameDungeon); // Not in dungeon data << uint8(isSameGroup); // Not same group data << uint8(pPlayer->GetLFGPlayerState()->GetAnswer() != LFG_ANSWER_PENDING); // Answered data << uint8(pPlayer->GetLFGPlayerState()->GetAnswer() == LFG_ANSWER_AGREE); // Accepted } SendPacket(&data); }
//Summon group of player bool ChatHandler::HandleGroupSummonCommand(const char* args) { Player* target; if (!extractPlayerTarget((char*)args,&target)) return false; // check online security if (HasLowerSecurity(target, 0)) return false; Group *grp = target->GetGroup(); std::string nameLink = GetNameLink(target); if (!grp) { PSendSysMessage(LANG_NOT_IN_GROUP,nameLink.c_str()); SetSentErrorMessage(true); return false; } Map* gmMap = m_session->GetPlayer()->GetMap(); bool to_instance = gmMap->Instanceable(); // we are in instance, and can summon only player in our group with us as lead if (to_instance && ( !m_session->GetPlayer()->GetGroup() || (grp->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) || (m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()))) // the last check is a bit excessive, but let it be, just in case { SendSysMessage(LANG_CANNOT_SUMMON_TO_INST); SetSentErrorMessage(true); return false; } for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player *pl = itr->getSource(); if (!pl || pl == m_session->GetPlayer() || !pl->GetSession()) continue; // check online security if (HasLowerSecurity(pl, 0)) return false; std::string plNameLink = GetNameLink(pl); if (pl->IsBeingTeleported() == true) { PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str()); SetSentErrorMessage(true); return false; } if (to_instance) { Map* plMap = pl->GetMap(); if (plMap->Instanceable() && plMap->GetInstanceId() != gmMap->GetInstanceId()) { // cannot summon from instance to instance PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,plNameLink.c_str()); SetSentErrorMessage(true); return false; } } PSendSysMessage(LANG_SUMMONING, plNameLink.c_str(),""); if (needReportToTarget(pl)) ChatHandler(pl).PSendSysMessage(LANG_SUMMONED_BY, GetNameLink().c_str()); // stop flight if need if (pl->isInFlight()) { pl->GetMotionMaster()->MovementExpired(); pl->CleanupAfterTaxiFlight(); } // save only in non-flight case else pl->SaveRecallPosition(); // before GM float x,y,z; m_session->GetPlayer()->GetClosePoint(x, y, z, pl->GetObjectSize(), 0.0f, 0.0f, m_session->GetPlayer()); pl->TeleportTo(m_session->GetPlayer()->GetMapId(),x,y,z,pl->GetOrientation()); } return true; }
void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData) { ObjectGuid guid; uint32 questId; recvData >> questId; guid[6] = recvData.ReadBit(); guid[0] = recvData.ReadBit(); recvData.ReadBit(); guid[2] = recvData.ReadBit(); guid[7] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); guid[4] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[1] = recvData.ReadBit(); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[4]); recvData.ReadByteSeq(guid[0]); recvData.ReadByteSeq(guid[1]); recvData.ReadByteSeq(guid[6]); recvData.ReadByteSeq(guid[2]); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[7]); TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u", uint32(GUID_LOPART(guid)), questId); Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER); #define CLOSE_GOSSIP_CLEAR_DIVIDER() \ do { \ _player->PlayerTalkClass->SendCloseGossip(); \ _player->SetDivider(0); \ } while (0) // no or incorrect quest giver if (!object) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } if (Player* playerQuestObject = object->ToPlayer()) { if ((_player->GetDivider() && _player->GetDivider() != guid) || ((object != _player && !playerQuestObject->CanShareQuest(questId)))) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } } else { if (!object->hasQuest(questId)) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } } // some kind of WPE protection if (!_player->CanInteractWithQuestGiver(object)) return; if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { // prevent cheating if (!GetPlayer()->CanTakeQuest(quest, true)) { CLOSE_GOSSIP_CLEAR_DIVIDER(); return; } if (_player->GetDivider() != 0) { Player* player = ObjectAccessor::FindPlayer(_player->GetDivider()); if (player) { player->SendPushToPartyResponse(_player, QUEST_PARTY_MSG_ACCEPT_QUEST); _player->SetDivider(0); } } if (_player->CanAddQuest(quest, true)) { _player->AddQuest(quest, object); if (quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT)) { if (Group* group = _player->GetGroup()) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* player = itr->GetSource(); if (!player || player == _player) // not self continue; if (player->CanTakeQuest(quest, true)) { player->SetDivider(_player->GetGUID()); //need confirmation that any gossip window will close player->PlayerTalkClass->SendCloseGossip(); _player->SendQuestConfirmAccept(quest, player); } } } } if (_player->CanCompleteQuest(questId)) _player->CompleteQuest(questId); switch (object->GetTypeId()) { case TYPEID_UNIT: object->ToCreature()->AI()->sQuestAccept(_player, quest); break; case TYPEID_ITEM: case TYPEID_CONTAINER: { Item* item = (Item*)object; // destroy not required for quest finish quest starting item bool destroyItem = true; for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) { if (quest->RequiredItemId[i] == item->GetEntry() && item->GetTemplate()->MaxCount > 0) { destroyItem = false; break; } } if (destroyItem) _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); break; } case TYPEID_GAMEOBJECT: object->ToGameObject()->AI()->QuestAccept(_player, quest); break; default: break; } _player->PlayerTalkClass->SendCloseGossip(); if (quest->GetSrcSpell() > 0) _player->CastSpell(_player, quest->GetSrcSpell(), true); return; } } _player->PlayerTalkClass->SendCloseGossip(); #undef CLOSE_GOSSIP_CLEAR_DIVIDER }
// add group or player (grp == NULL) to bg queue with the given leader and bg specifications GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, BattlegroundTypeId BgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating, uint32 arenateamid) { BattlegroundBracketId bracketId = bracketEntry->GetBracketId(); // create new ginfo GroupQueueInfo* ginfo = new GroupQueueInfo; ginfo->BgTypeId = BgTypeId; ginfo->ArenaType = ArenaType; ginfo->ArenaTeamId = arenateamid; ginfo->IsRated = isRated; ginfo->IsInvitedToBGInstanceGUID = 0; ginfo->JoinTime = getMSTime(); ginfo->RemoveInviteTime = 0; ginfo->Team = leader->GetTeam(); ginfo->ArenaTeamRating = ArenaRating; ginfo->ArenaMatchmakerRating = MatchmakerRating; ginfo->OpponentsTeamRating = 0; ginfo->OpponentsMatchmakerRating = 0; ginfo->Players.clear(); //compute index (if group is premade or joined a rated match) to queues uint32 index = 0; if (!isRated && !isPremade) index += BG_TEAMS_COUNT; if (ginfo->Team == HORDE) index++; TC_LOG_DEBUG("bg.battleground", "Adding Group to BattlegroundQueue bgTypeId : %u, bracket_id : %u, index : %u", BgTypeId, bracketId, index); uint32 lastOnlineTime = getMSTime(); //announce world (this don't need mutex) if (isRated && sWorld->getBoolConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE)) { ArenaTeam* Team = sArenaTeamMgr->GetArenaTeamById(arenateamid); if (Team) sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, Team->GetName().c_str(), ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating); } //add players from group to ginfo if (grp) { for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; // this should never happen PlayerQueueInfo& pl_info = m_QueuedPlayers[member->GetGUID()]; pl_info.LastOnlineTime = lastOnlineTime; pl_info.GroupInfo = ginfo; // add the pinfo to ginfo's list ginfo->Players[member->GetGUID()] = &pl_info; } } else { PlayerQueueInfo& pl_info = m_QueuedPlayers[leader->GetGUID()]; pl_info.LastOnlineTime = lastOnlineTime; pl_info.GroupInfo = ginfo; ginfo->Players[leader->GetGUID()] = &pl_info; } //add GroupInfo to m_QueuedGroups { //ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_Lock); m_QueuedGroups[bracketId][index].push_back(ginfo); //announce to world, this code needs mutex if (!isRated && !isPremade && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE)) { if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(ginfo->BgTypeId)) { char const* bgName = bg->GetName(); uint32 MinPlayers = bg->GetMinPlayersPerTeam(); uint32 qHorde = 0; uint32 qAlliance = 0; uint32 q_min_level = bracketEntry->minLevel; uint32 q_max_level = bracketEntry->maxLevel; GroupsQueueType::const_iterator itr; for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_ALLIANCE].end(); ++itr) if (!(*itr)->IsInvitedToBGInstanceGUID) qAlliance += (*itr)->Players.size(); for (itr = m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[bracketId][BG_QUEUE_NORMAL_HORDE].end(); ++itr) if (!(*itr)->IsInvitedToBGInstanceGUID) qHorde += (*itr)->Players.size(); // Show queue status to player only (when joining queue) if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) { ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); } // System message else { sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bgName, q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); } } } //release mutex } return ginfo; }
void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) { uint32 questId; recvPacket >> questId; if (!_player->CanShareQuest(questId)) return; TC_LOG_DEBUG("network", "WORLD: Received CMSG_PUSHQUESTTOPARTY questId = %u", questId); Quest const* quest = sObjectMgr->GetQuestTemplate(questId); if (!quest) return; Player * const sender = GetPlayer(); Group* group = sender->GetGroup(); if (!group) return; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* receiver = itr->GetSource(); if (!receiver || receiver == sender) continue; if (!receiver->SatisfyQuestStatus(quest, false)) { sender->SendPushToPartyResponse(receiver, QUEST_PARTY_MSG_HAVE_QUEST); continue; } if (receiver->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE) { sender->SendPushToPartyResponse(receiver, QUEST_PARTY_MSG_FINISH_QUEST); continue; } if (!receiver->CanTakeQuest(quest, false)) { sender->SendPushToPartyResponse(receiver, QUEST_PARTY_MSG_CANT_TAKE_QUEST); continue; } if (!receiver->SatisfyQuestLog(false)) { sender->SendPushToPartyResponse(receiver, QUEST_PARTY_MSG_LOG_FULL); continue; } if (receiver->GetDivider() != 0) { sender->SendPushToPartyResponse(receiver, QUEST_PARTY_MSG_BUSY); continue; } sender->SendPushToPartyResponse(receiver, QUEST_PARTY_MSG_SHARING_QUEST); if (quest->IsAutoAccept() && receiver->CanAddQuest(quest, true) && receiver->CanTakeQuest(quest, true)) { receiver->AddQuest(quest, sender); if (receiver->CanCompleteQuest(questId)) receiver->CompleteQuest(questId); } if ((quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly()) || quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE)) receiver->PlayerTalkClass->SendQuestGiverRequestItems(quest, sender->GetGUID(), receiver->CanCompleteRepeatableQuest(quest), true); else { receiver->SetDivider(sender->GetGUID()); receiver->PlayerTalkClass->SendQuestGiverQuestDetails(quest, sender->GetGUID(), true); } } }
void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket & recv_data) { ObjectGuid guid; uint32 quest; uint32 unk1; recv_data >> guid >> quest >> unk1; if (!CanInteractWithQuestGiver(guid, "CMSG_QUESTGIVER_ACCEPT_QUEST")) return; DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST - for %s to %s, quest = %u, unk1 = %u", _player->GetGuidStr().c_str(), guid.GetString().c_str(), quest, unk1 ); Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM); // no or incorrect quest giver if(!pObject || (pObject->GetTypeId()!=TYPEID_PLAYER && !pObject->HasQuest(quest)) || (pObject->GetTypeId()==TYPEID_PLAYER && !((Player*)pObject)->CanShareQuest(quest)) ) { _player->PlayerTalkClass->CloseGossip(); _player->ClearDividerGuid(); return; } Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest); if ( qInfo ) { // prevent cheating if(!GetPlayer()->CanTakeQuest(qInfo,true) ) { _player->PlayerTalkClass->CloseGossip(); _player->ClearDividerGuid(); return; } if (Player *pPlayer = ObjectAccessor::FindPlayer(_player->GetDividerGuid())) { pPlayer->SendPushToPartyResponse(_player, QUEST_PARTY_MSG_ACCEPT_QUEST); _player->ClearDividerGuid(); } if( _player->CanAddQuest( qInfo, true ) ) { _player->AddQuest( qInfo, pObject ); // pObject (if it item) can be destroyed at call if (qInfo->HasQuestFlag(QUEST_FLAGS_PARTY_ACCEPT)) { if (Group* pGroup = _player->GetGroup()) { for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pPlayer = itr->getSource(); if (!pPlayer || pPlayer == _player) // not self continue; if (pPlayer->CanTakeQuest(qInfo, true)) { pPlayer->SetDividerGuid(_player->GetObjectGuid()); //need confirmation that any gossip window will close pPlayer->PlayerTalkClass->CloseGossip(); _player->SendQuestConfirmAccept(qInfo, pPlayer); } } } } if ( _player->CanCompleteQuest( quest ) ) _player->CompleteQuest( quest ); _player->GetAchievementMgr().StartTimedAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest); _player->PlayerTalkClass->CloseGossip(); if( qInfo->GetSrcSpell() > 0 ) _player->CastSpell( _player, qInfo->GetSrcSpell(), true); return; } } _player->PlayerTalkClass->CloseGossip(); }
void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) { DEBUG_LOG("WORLD: CMSG_BATTLEMASTER_JOIN_ARENA"); //recv_data.hexlike(); ObjectGuid guid; // arena Battlemaster guid uint8 arenaslot; // 2v2, 3v3 or 5v5 uint8 asGroup; // asGroup uint8 isRated; // isRated recv_data >> guid >> arenaslot >> asGroup >> isRated; // ignore if we already in BG or BG queue if (_player->InBattleGround()) return; Creature *unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) return; if(!unit->isBattleMaster()) // it's not battle master return; ArenaType arenatype; uint32 arenaRating = 0; switch(arenaslot) { case 0: arenatype = ARENA_TYPE_2v2; break; case 1: arenatype = ARENA_TYPE_3v3; break; case 2: arenatype = ARENA_TYPE_5v5; break; default: sLog.outError("Unknown arena slot %u at HandleBattlemasterJoinArena()", arenaslot); return; } // check existance BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA); if (!bg) { sLog.outError("Battleground: template bg (all arenas) not found"); return; } BattleGroundTypeId bgTypeId = bg->GetTypeID(); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype); BattleGroundBracketId bgBracketId = _player->GetBattleGroundBracketIdFromLevel(bgTypeId); Group * grp = NULL; // check queue conditions if (!asGroup) { // you can't join in this way by client if (isRated) return; // check if already in queue if (_player->GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES) //player is already in this queue return; // check if has free queue slots if (!_player->HasFreeBattleGroundQueueId()) return; } else { grp = _player->GetGroup(); // no group found, error if (!grp) return; uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot); if (err != BG_JOIN_ERR_OK) { SendBattleGroundOrArenaJoinError(err); return; } } uint32 ateamId = 0; if (isRated) { ateamId = _player->GetArenaTeamId(arenaslot); // check real arena team existence only here (if it was moved to group->CanJoin .. () then we would have to get it twice) ArenaTeam * at = sObjectMgr.GetArenaTeamById(ateamId); if (!at) { _player->GetSession()->SendNotInArenaTeamPacket(arenatype); return; } // get the team rating for queue arenaRating = at->GetRating(); // the arena team id must match for everyone in the group // get the personal ratings for queue uint32 avg_pers_rating = 0; for(Group::member_citerator citr = grp->GetMemberSlots().begin(); citr != grp->GetMemberSlots().end(); ++citr) { ArenaTeamMember const* at_member = at->GetMember(citr->guid); if (!at_member) // group member joining to arena must be in leader arena team return; // calc avg personal rating avg_pers_rating += at_member->personal_rating; } avg_pers_rating /= grp->GetMembersCount(); // if avg personal rating is more than 150 points below the teams rating, the team will be queued against an opponent matching or similar to the average personal rating if (avg_pers_rating + 150 < arenaRating) arenaRating = avg_pers_rating; } BattleGroundQueue &bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId]; if (asGroup) { DEBUG_LOG("Battleground: arena join as group start"); if (isRated) DEBUG_LOG("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(arenaslot),_player->GetName(),arenaRating,arenatype); GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bgBracketId, arenatype, isRated, false, arenaRating, ateamId); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player *member = itr->getSource(); if(!member) continue; uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId);// add to queue // store entry point coords (same as leader entry point) member->SetBattleGroundEntryPoint(_player); WorldPacket data; // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype); member->GetSession()->SendPacket(&data); sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId); member->GetSession()->SendPacket(&data); DEBUG_LOG("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName()); } DEBUG_LOG("Battleground: arena join as group end"); //announce to world ... removed } else { GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bgBracketId, arenatype, isRated, false, arenaRating, ateamId); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); // store entry point coords _player->SetBattleGroundEntryPoint(); WorldPacket data; // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype); SendPacket(&data); DEBUG_LOG("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName()); } sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); }
void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recv_data) { ObjectGuid guid; uint32 bgTypeId_; uint32 instanceId; uint8 joinAsGroup; bool isPremade = false; Group* grp; recv_data >> guid; // battlemaster guid recv_data >> bgTypeId_; // battleground type id (DBC id) recv_data >> instanceId; // instance id, 0 if First Available selected recv_data.ReadGuidMask<2, 0, 3, 1, 5>(guid); joinAsGroup = recv_data.ReadBit(); recv_data.ReadGuidMask<4, 6, 7>(guid); recv_data.ReadGuidBytes<2, 6, 4, 3, 7, 0, 5, 1>(guid); bgTypeId_ = guid.GetCounter(); DEBUG_LOG("WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from %s, typeid: %u, asGroup: %u, bg guid: %s", _player->GetGuidStr().c_str(), bgTypeId_, joinAsGroup, guid.GetString().c_str()); if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { sLog.outError("Battleground: invalid bgtype (%u) received. possible cheater? player guid %u", bgTypeId_, _player->GetGUIDLow()); return; } BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_); DEBUG_LOG("WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from %s", guid.GetString().c_str()); // can do this, since it's battleground, not arena BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, ARENA_TYPE_NONE); BattleGroundQueueTypeId bgQueueTypeIdRandom = BattleGroundMgr::BGQueueTypeId(BATTLEGROUND_RB, ARENA_TYPE_NONE); // ignore if player is already in BG if (_player->InBattleGround()) return; // get bg instance or bg template if instance not found BattleGround* bg = NULL; if (instanceId) bg = sBattleGroundMgr.GetBattleGroundThroughClientInstance(instanceId, bgTypeId); if (!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId))) { sLog.outError("Battleground: no available bg / template found"); return; } // expected bracket entry PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel()); if (!bracketEntry) return; GroupJoinBattlegroundResult err = ERR_BATTLEGROUND_NONE; // check queue conditions if (!joinAsGroup) { // check Deserter debuff if (!_player->CanJoinToBattleground()) { WorldPacket data; sBattleGroundMgr.BuildBattleGroundStatusFailedPacket(&data, bg, _player, 0, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); _player->GetSession()->SendPacket(&data); return; } // check if already in queue if (_player->GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is already in this queue return; // check if has free queue slots if (!_player->HasFreeBattleGroundQueueId()) return; } else { grp = _player->GetGroup(); // no group found, error if (!grp) return; if (grp->GetLeaderGuid() != _player->GetObjectGuid()) return; err = grp->CanJoinBattleGroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0); isPremade = sWorld.getConfig(CONFIG_UINT32_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH) && (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam()); } // if we're here, then the conditions to join a bg are met. We can proceed in joining. // _player->GetGroup() was already checked, grp is already initialized BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId]; if (err) { WorldPacket data; sBattleGroundMgr.BuildBattleGroundStatusFailedPacket(&data, bg, _player, 0, err); SendPacket(&data); } else if (joinAsGroup) { GroupQueueInfo* ginfo = NULL; uint32 avgTime = 0; DEBUG_LOG("Battleground: the following players are joining as group:"); ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, ARENA_TYPE_NONE, false, isPremade, 0); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->getSource(); if (!member) continue; // this should never happen // add to queue uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId); // send status packet (in queue) WorldPacket data; sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->arenaType); member->GetSession()->SendPacket(&data); DEBUG_LOG("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName()); } DEBUG_LOG("Battleground: group end"); } else { GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, ARENA_TYPE_NONE, false, isPremade, 0); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); // already checked if queueSlot is valid, now just get it uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); WorldPacket data; // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->arenaType); SendPacket(&data); DEBUG_LOG("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName()); } sBattleGroundMgr.ScheduleQueueUpdate(0, ARENA_TYPE_NONE, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); }
void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) { TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA"); uint8 arenaslot; // 2v2, 3v3 or 5v5 recvData >> arenaslot; // ignore if we already in BG or BG queue if (_player->InBattleground()) return; uint32 arenaRating = 0; uint32 matchmakerRating = 0; uint8 arenatype = ArenaTeam::GetTypeBySlot(arenaslot); //check existance Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA); if (!bg) { TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "Battleground: template bg (all arenas) not found"); return; } if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, NULL)) { ChatHandler(this).PSendSysMessage(LANG_ARENA_DISABLED); return; } BattlegroundTypeId bgTypeId = bg->GetTypeID(); BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype); PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel()); if (!bracketEntry) return; GroupJoinBattlegroundResult err = ERR_BATTLEGROUND_NONE; Group* grp = _player->GetGroup(); // no group found, error if (!grp) return; if (grp->GetLeaderGUID() != _player->GetGUID()) return; uint32 ateamId = _player->GetArenaTeamId(arenaslot); // check real arenateam existence only here (if it was moved to group->CanJoin .. () then we would ahve to get it twice) ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ateamId); if (!at) { _player->GetSession()->SendNotInArenaTeamPacket(arenatype); return; } // get the team rating for queueing arenaRating = at->GetRating(); matchmakerRating = at->GetAverageMMR(grp); // the arenateam id must match for everyone in the group if (arenaRating <= 0) arenaRating = 1; BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); uint32 avgTime = 0; GroupQueueInfo* ginfo = NULL; err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, arenatype, arenatype, true, arenaslot); if (!err) { TC_LOG_DEBUG(LOG_FILTER_BATTLEGROUND, "Battleground: arena team id %u, leader %s queued with matchmaker rating %u for type %u", _player->GetArenaTeamId(arenaslot), _player->GetName().c_str(), matchmakerRating, arenatype); ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, true, false, arenaRating, matchmakerRating, ateamId); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); } for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; if (err) { WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, err); member->GetSession()->SendPacket(&data); continue; } // add to queue uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); // add joined time data member->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime); WorldPacket data; // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, arenatype); member->GetSession()->SendPacket(&data); TC_LOG_DEBUG(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str()); } sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); }
//Teleport group to given game_tele.entry static bool HandleTeleGroupCommand(ChatHandler* handler, const char* args) { if (!*args) return false; Player* target = handler->getSelectedPlayer(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); handler->SetSentErrorMessage(true); return false; } // check online security if (handler->HasLowerSecurity(target, 0)) return false; // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r GameTele const* tele = handler->extractGameTeleFromLink((char*)args); if (!tele) { handler->SendSysMessage(LANG_COMMAND_TELE_NOTFOUND); handler->SetSentErrorMessage(true); return false; } MapEntry const* map = sMapStore.LookupEntry(tele->mapId); if (!map || map->IsBattlegroundOrArena()) { handler->SendSysMessage(LANG_CANNOT_TELE_TO_BG); handler->SetSentErrorMessage(true); return false; } std::string nameLink = handler->GetNameLink(target); Group* grp = target->GetGroup(); if (!grp) { handler->PSendSysMessage(LANG_NOT_IN_GROUP, nameLink.c_str()); handler->SetSentErrorMessage(true); return false; } for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* player = itr->GetSource(); if (!player || !player->GetSession()) continue; // check online security if (handler->HasLowerSecurity(player, 0)) return false; std::string plNameLink = handler->GetNameLink(player); if (player->IsBeingTeleported()) { handler->PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str()); continue; } handler->PSendSysMessage(LANG_TELEPORTING_TO, plNameLink.c_str(), "", tele->name.c_str()); if (handler->needReportToTarget(player)) ChatHandler(player->GetSession()).PSendSysMessage(LANG_TELEPORTED_TO_BY, nameLink.c_str()); // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); player->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation); } return true; }
void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) { uint32 bgTypeId_; uint32 instanceId; uint8 asGroup; bool isPremade = false; Group* grp = NULL; ObjectGuid guid; recvData >> instanceId; // Instance Id guid[2] = recvData.ReadBit(); guid[0] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[1] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); asGroup = recvData.ReadBit(); // As Group guid[4] = recvData.ReadBit(); guid[6] = recvData.ReadBit(); guid[7] = recvData.ReadBit(); recvData.ReadByteSeq(guid[2]); recvData.ReadByteSeq(guid[6]); recvData.ReadByteSeq(guid[4]); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[7]); recvData.ReadByteSeq(guid[0]); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[1]); //extract from guid bgTypeId_ = GUID_LOPART(guid); if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "Battleground: invalid bgtype (%u) received. possible cheater? player guid %u", bgTypeId_, _player->GetGUIDLow()); return; } if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, NULL)) { ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED); return; } BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_); //TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID:"UI64FMTD" TypeId:%u)", guid, bgTypeId_); // can do this, since it's battleground, not arena BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0); BattlegroundQueueTypeId bgQueueTypeIdRandom = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, 0); // ignore if player is already in BG if (_player->InBattleground()) return; // get bg instance or bg template if instance not found Battleground* bg = NULL; if (instanceId) bg = sBattlegroundMgr->GetBattlegroundThroughClientInstance(instanceId, bgTypeId); if (!bg) bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId); if (!bg) return; // expected bracket entry PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel()); if (!bracketEntry) return; GroupJoinBattlegroundResult err = ERR_BATTLEGROUND_NONE; // check queue conditions if (!asGroup) { if (GetPlayer()->isUsingLfg()) { WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_LFG_CANT_USE_BATTLEGROUND); GetPlayer()->GetSession()->SendPacket(&data); return; } // check Deserter debuff if (!_player->CanJoinToBattleground(bg)) { WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); _player->GetSession()->SendPacket(&data); return; } if (_player->GetBattlegroundQueueIndex(bgQueueTypeIdRandom) < PLAYER_MAX_BATTLEGROUND_QUEUES) { // player is already in random queue WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_IN_RANDOM_BG); _player->GetSession()->SendPacket(&data); return; } if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) { // player is already in queue, can't start random queue WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_IN_NON_RANDOM_BG); _player->GetSession()->SendPacket(&data); return; } // check if already in queue if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is already in this queue return; // check if has free queue slots if (!_player->HasFreeBattlegroundQueueId()) { WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_BATTLEGROUND_TOO_MANY_QUEUES); _player->GetSession()->SendPacket(&data); return; } BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); // add joined time data _player->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime); WorldPacket data; // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, ginfo->ArenaType); SendPacket(&data); TC_LOG_DEBUG(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName().c_str()); } else { grp = _player->GetGroup(); if (!grp) return; if (grp->GetLeaderGUID() != _player->GetGUID()) return; err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0); isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam()); BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo* ginfo = NULL; uint32 avgTime = 0; if (!err) { TC_LOG_DEBUG(LOG_FILTER_BATTLEGROUND, "Battleground: the following players are joining as group:"); ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); } for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; // this should never happen if (err) { WorldPacket data; sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, err); member->GetSession()->SendPacket(&data); continue; } // add to queue uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); // add joined time data member->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime); WorldPacket data; // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, ginfo->ArenaType); member->GetSession()->SendPacket(&data); TC_LOG_DEBUG(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str()); } TC_LOG_DEBUG(LOG_FILTER_BATTLEGROUND, "Battleground: group end"); } sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); }
void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) { ObjectGuid guid; uint32 instanceId; uint32 mapId; uint8 joinAsGroup; bool isPremade = false; Group * grp; recv_data >> guid; // battlemaster guid recv_data >> mapId; recv_data >> instanceId; // instance id, 0 if First Available selected recv_data >> joinAsGroup; // join as group BattleGroundTypeId bgTypeId = GetBattleGroundTypeIdByMapId(mapId); if(bgTypeId == BATTLEGROUND_TYPE_NONE) { sLog.outError("Battleground: invalid bgtype (%u) received. possible cheater? player guid %u",bgTypeId,_player->GetGUIDLow()); return; } DEBUG_LOG( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from %s", guid.GetString().c_str()); // can do this, since it's battleground, not arena BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId); // ignore if player is already in BG if (_player->InBattleGround()) return; Creature *unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) return; if (!unit->isBattleMaster()) // it's not battlemaster return; // get bg instance or bg template if instance not found BattleGround *bg = NULL; if (instanceId) bg = sBattleGroundMgr.GetBattleGroundThroughClientInstance(instanceId, bgTypeId); if (!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId))) { sLog.outError("Battleground: no available bg / template found"); return; } BattleGroundBracketId bgBracketId = _player->GetBattleGroundBracketIdFromLevel(bgTypeId); // check queue conditions if (!joinAsGroup) { // check Deserter debuff if (!_player->CanJoinToBattleground()) { WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4); data << uint32(0xFFFFFFFE); _player->GetSession()->SendPacket(&data); return; } // check if already in queue if (_player->GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES) //player is already in this queue return; // check if has free queue slots if (!_player->HasFreeBattleGroundQueueId()) return; } else { grp = _player->GetGroup(); // no group found, error if (!grp) return; uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam()); isPremade = sWorld.getConfig(CONFIG_UINT32_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH) && (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam()); if (err != BG_JOIN_ERR_OK) { SendBattleGroundJoinError(err); return; } } // if we're here, then the conditions to join a bg are met. We can proceed in joining. // _player->GetGroup() was already checked, grp is already initialized BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId]; if (joinAsGroup) { DEBUG_LOG("Battleground: the following players are joining as group:"); GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bgBracketId, isPremade); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player *member = itr->getSource(); if(!member) continue; // this should never happen uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId); // add to queue // store entry point coords (same as leader entry point) member->SetBattleGroundEntryPoint(_player); WorldPacket data; // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0); member->GetSession()->SendPacket(&data); sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId); member->GetSession()->SendPacket(&data); DEBUG_LOG("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName()); } DEBUG_LOG("Battleground: group end"); } else { GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bgBracketId, isPremade); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); // already checked if queueSlot is valid, now just get it uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); // store entry point coords _player->SetBattleGroundEntryPoint(); WorldPacket data; // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0); SendPacket(&data); DEBUG_LOG("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName()); } sBattleGroundMgr.ScheduleQueueUpdate(bgQueueTypeId, bgTypeId, _player->GetBattleGroundBracketIdFromLevel(bgTypeId)); }
void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ ) { sLog.outDebug("WORLD: CMSG_LOOT_MONEY"); Player *player = GetPlayer(); uint64 guid = player->GetLootGUID(); if(!guid) return; Loot *pLoot = NULL; switch(GUID_HIPART(guid)) { case HIGHGUID_GAMEOBJECT: { GameObject *pGameObject = GetPlayer()->GetMap()->GetGameObject(guid); // not check distance for GO in case owned GO (fishing bobber case, for example) if( pGameObject && (pGameObject->GetOwnerGUID()==_player->GetGUID() || pGameObject->IsWithinDistInMap(_player,INTERACTION_DISTANCE)) ) pLoot = &pGameObject->loot; break; } case HIGHGUID_CORPSE: // remove insignia ONLY in BG { Corpse *bones = _player->GetMap()->GetCorpse(guid); if (bones && bones->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) pLoot = &bones->loot; break; } case HIGHGUID_ITEM: { if(Item *item = GetPlayer()->GetItemByGuid(guid)) pLoot = &item->loot; break; } case HIGHGUID_UNIT: { Creature* pCreature = GetPlayer()->GetMap()->GetCreature(guid); bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass()==CLASS_ROGUE && pCreature->lootForPickPocketed); if ( ok_loot && pCreature->IsWithinDistInMap(_player,INTERACTION_DISTANCE) ) pLoot = &pCreature->loot ; break; } default: return; // unlootable type } if( pLoot ) { if (!IS_ITEM_GUID(guid) && player->GetGroup()) //item can be looted only single player { Group *group = player->GetGroup(); std::vector<Player*> playersNear; for(GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* playerGroup = itr->getSource(); if(!playerGroup) continue; if (player->IsWithinDistInMap(playerGroup,sWorld.getConfig(CONFIG_FLOAT_GROUP_XP_DISTANCE),false)) playersNear.push_back(playerGroup); } uint32 money_per_player = uint32((pLoot->gold)/(playersNear.size())); for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) { (*i)->ModifyMoney( money_per_player ); (*i)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, money_per_player); //Offset surely incorrect, but works WorldPacket data( SMSG_LOOT_MONEY_NOTIFY, 4 ); data << uint32(money_per_player); (*i)->GetSession()->SendPacket( &data ); } } else { player->ModifyMoney( pLoot->gold ); player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, pLoot->gold); } pLoot->gold = 0; pLoot->NotifyMoneyRemoved(); } }
void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) { uint64 guid; uint32 bgTypeId_; uint32 instanceId; uint8 joinAsGroup; bool isPremade = false; Group* grp = NULL; recvData >> guid; // battlemaster guid recvData >> bgTypeId_; // battleground type id (DBC id) recvData >> instanceId; // instance id, 0 if First Available selected recvData >> joinAsGroup; // join as group if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { sLog->outError(LOG_FILTER_NETWORKIO, "Battleground: invalid bgtype (%u) received. possible cheater? player guid %u", bgTypeId_, _player->GetGUIDLow()); return; } if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, NULL)) { ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED); return; } BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid))); // can do this, since it's battleground, not arena BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0); BattlegroundQueueTypeId bgQueueTypeIdRandom = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, 0); // ignore if player is already in BG if (_player->InBattleground()) return; // get bg instance or bg template if instance not found Battleground* bg = NULL; if (instanceId) bg = sBattlegroundMgr->GetBattlegroundThroughClientInstance(instanceId, bgTypeId); if (!bg) bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId); if (!bg) return; // expected bracket entry PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel()); if (!bracketEntry) return; GroupJoinBattlegroundResult err; // check queue conditions if (!joinAsGroup) { if (GetPlayer()->isUsingLfg()) { // player is using dungeon finder or raid finder WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_LFG_CANT_USE_BATTLEGROUND); GetPlayer()->GetSession()->SendPacket(&data); return; } // check Deserter debuff if (!_player->CanJoinToBattleground()) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); _player->GetSession()->SendPacket(&data); return; } if (_player->GetBattlegroundQueueIndex(bgQueueTypeIdRandom) < PLAYER_MAX_BATTLEGROUND_QUEUES) { // player is already in random queue WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_RANDOM_BG); _player->GetSession()->SendPacket(&data); return; } if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) { // player is already in queue, can't start random queue WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_NON_RANDOM_BG); _player->GetSession()->SendPacket(&data); return; } // check if already in queue if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is already in this queue return; // check if has free queue slots if (!_player->HasFreeBattlegroundQueueId()) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES); _player->GetSession()->SendPacket(&data); return; } BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); // already checked if queueSlot is valid, now just get it uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); WorldPacket data; // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType, 0); SendPacket(&data); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName().c_str()); } else { grp = _player->GetGroup(); // no group found, error if (!grp) return; if (grp->GetLeaderGUID() != _player->GetGUID()) return; err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0); isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam()); BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo* ginfo = NULL; uint32 avgTime = 0; if (err > 0) { sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: the following players are joining as group:"); ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); } for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->getSource(); if (!member) continue; // this should never happen WorldPacket data; if (err <= 0) { sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); member->GetSession()->SendPacket(&data); continue; } // add to queue uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType, 0); member->GetSession()->SendPacket(&data); sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); member->GetSession()->SendPacket(&data); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str()); } sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: group end"); } sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); }
void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recv_data*/) { DEBUG_LOG("WORLD: CMSG_LOOT_MONEY"); Player* player = GetPlayer(); ObjectGuid guid = player->GetLootGuid(); if (!guid) return; Loot* pLoot = NULL; Item* pItem = NULL; switch (guid.GetHigh()) { case HIGHGUID_GAMEOBJECT: { GameObject* pGameObject = GetPlayer()->GetMap()->GetGameObject(guid); // not check distance for GO in case owned GO (fishing bobber case, for example) if (pGameObject && (pGameObject->GetOwnerGuid() == _player->GetObjectGuid() || pGameObject->IsWithinDistInMap(_player, INTERACTION_DISTANCE))) pLoot = &pGameObject->loot; break; } case HIGHGUID_CORPSE: // remove insignia ONLY in BG { Corpse* bones = _player->GetMap()->GetCorpse(guid); if (bones && bones->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) pLoot = &bones->loot; break; } case HIGHGUID_ITEM: { pItem = GetPlayer()->GetItemByGuid(guid); if (!pItem || !pItem->HasGeneratedLoot()) return; pLoot = &pItem->loot; break; } case HIGHGUID_UNIT: { Creature* pCreature = GetPlayer()->GetMap()->GetCreature(guid); bool ok_loot = pCreature && pCreature->isAlive() == (player->getClass() == CLASS_ROGUE && pCreature->lootForPickPocketed); if (ok_loot && pCreature->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) pLoot = &pCreature->loot ; break; } default: return; // unlootable type } if (pLoot) { pLoot->NotifyMoneyRemoved(); if (!guid.IsItem() && player->GetGroup()) // item can be looted only single player { Group* group = player->GetGroup(); std::vector<Player*> playersNear; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* playerGroup = itr->getSource(); if (!playerGroup) continue; if (player->IsWithinDistInMap(playerGroup, sWorld.getConfig(CONFIG_FLOAT_GROUP_XP_DISTANCE), false)) playersNear.push_back(playerGroup); } uint32 money_per_player = uint32((pLoot->gold) / (playersNear.size())); for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) { (*i)->ModifyMoney(money_per_player); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4); data << uint32(money_per_player); (*i)->GetSession()->SendPacket(&data); } } else player->ModifyMoney(pLoot->gold); pLoot->gold = 0; if (pItem) pItem->SetLootState(ITEM_LOOT_CHANGED); } }
void WorldSession::HandleBattlemasterJoinOpcode(WorldPackets::Battleground::BattlemasterJoin& battlemasterJoin) { bool isPremade = false; Group* grp = NULL; uint32 bgTypeId_ = battlemasterJoin.QueueID & 0xFFFF; if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { TC_LOG_ERROR("network", "Battleground: invalid bgtype (%u) received. possible cheater? %s", bgTypeId_, _player->GetGUID().ToString().c_str()); return; } if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, NULL)) { ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED); return; } BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_); // can do this, since it's battleground, not arena BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0); BattlegroundQueueTypeId bgQueueTypeIdRandom = BattlegroundMgr::BGQueueTypeId(BATTLEGROUND_RB, 0); // ignore if player is already in BG if (_player->InBattleground()) return; // get bg instance or bg template if instance not found Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId); if (!bg) return; // expected bracket entry PvpDifficultyEntry const* bracketEntry = DB2Manager::GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel()); if (!bracketEntry) return; GroupJoinBattlegroundResult err = ERR_BATTLEGROUND_NONE; // check queue conditions if (!battlemasterJoin.JoinAsGroup) { if (GetPlayer()->isUsingLfg()) { WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus; sBattlegroundMgr->BuildBattlegroundStatusFailed(&battlefieldStatus, bg, _player, 0, 0, ERR_LFG_CANT_USE_BATTLEGROUND); SendPacket(battlefieldStatus.Write()); return; } // check Deserter debuff if (!_player->CanJoinToBattleground(bg)) { WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus; sBattlegroundMgr->BuildBattlegroundStatusFailed(&battlefieldStatus, bg, _player, 0, 0, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); SendPacket(battlefieldStatus.Write()); return; } if (_player->GetBattlegroundQueueIndex(bgQueueTypeIdRandom) < PLAYER_MAX_BATTLEGROUND_QUEUES) { // player is already in random queue WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus; sBattlegroundMgr->BuildBattlegroundStatusFailed(&battlefieldStatus, bg, _player, 0, 0, ERR_IN_RANDOM_BG); SendPacket(battlefieldStatus.Write()); return; } if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) { // player is already in queue, can't start random queue WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus; sBattlegroundMgr->BuildBattlegroundStatusFailed(&battlefieldStatus, bg, _player, 0, 0, ERR_IN_NON_RANDOM_BG); SendPacket(battlefieldStatus.Write()); return; } // check if already in queue if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is already in this queue return; // check if has free queue slots if (!_player->HasFreeBattlegroundQueueId()) { WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus; sBattlegroundMgr->BuildBattlegroundStatusFailed(&battlefieldStatus, bg, _player, 0, 0, ERR_BATTLEGROUND_TOO_MANY_QUEUES); SendPacket(battlefieldStatus.Write()); return; } // check Freeze debuff if (_player->HasAura(9454)) return; BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); WorldPackets::Battleground::BattlefieldStatusQueued battlefieldStatus; sBattlegroundMgr->BuildBattlegroundStatusQueued(&battlefieldStatus, bg, _player, queueSlot, ginfo->JoinTime, avgTime, ginfo->ArenaType, false); SendPacket(battlefieldStatus.Write()); TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type %u bg type %u, %s, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUID().ToString().c_str(), _player->GetName().c_str()); } else { grp = _player->GetGroup(); if (!grp) return; if (grp->GetLeaderGUID() != _player->GetGUID()) return; ObjectGuid errorGuid; err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0, errorGuid); isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam()); BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo* ginfo = NULL; uint32 avgTime = 0; if (!err) { TC_LOG_DEBUG("bg.battleground", "Battleground: the following players are joining as group:"); ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); } for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; // this should never happen if (err) { WorldPackets::Battleground::BattlefieldStatusFailed battlefieldStatus; sBattlegroundMgr->BuildBattlegroundStatusFailed(&battlefieldStatus, bg, _player, 0, 0, err, &errorGuid); member->SendDirectMessage(battlefieldStatus.Write()); continue; } // add to queue uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); WorldPackets::Battleground::BattlefieldStatusQueued battlefieldStatus; sBattlegroundMgr->BuildBattlegroundStatusQueued(&battlefieldStatus, bg, member, queueSlot, ginfo->JoinTime, avgTime, ginfo->ArenaType, true); member->SendDirectMessage(battlefieldStatus.Write()); TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type %u bg type %u, %s, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUID().ToString().c_str(), member->GetName().c_str()); } TC_LOG_DEBUG("bg.battleground", "Battleground: group end"); } sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); }
void WorldSession::HandleBattlemasterJoinArena(WorldPacket & recvData) { uint64 guid; // arena Battlemaster guid uint8 arenaslot; // 2v2, 3v3 or 5v5 uint8 asGroup; // asGroup uint8 isRated; // isRated recvData >> guid >> arenaslot >> asGroup >> isRated; // can't queue for rated without a group if (isRated && !asGroup) return; // find creature by guid Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit || !unit->IsBattleMaster()) return; // get arena type uint8 arenatype = 0; switch (arenaslot) { case 0: arenatype = ARENA_TYPE_2v2; break; case 1: arenatype = ARENA_TYPE_3v3; break; case 2: arenatype = ARENA_TYPE_5v5; break; default: return; } // get template for all arenas Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA); if (!bgt) return; // arenas disabled if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, NULL)) { ChatHandler(this).PSendSysMessage(LANG_ARENA_DISABLED); return; } BattlegroundTypeId bgTypeId = bgt->GetBgTypeID(); BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype); // expected bracket entry PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgt->GetMapId(), _player->getLevel()); if (!bracketEntry) return; // pussywizard: if trying to queue for already queued // just remove from queue and it will requeue! uint32 qSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId); if (qSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) { BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); if (bgQueue.IsPlayerInvitedToRatedArena(_player->GetGUID())) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_JOIN_FAILED); SendPacket(&data); return; } bgQueue.RemovePlayer(_player->GetGUID(), false, qSlot); _player->RemoveBattlegroundQueueId(bgQueueTypeId); } // must have free queue slot // pussywizard: allow being queued only in one arena queue, and it even cannot be together with bg queues if (_player->InBattlegroundQueue()) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED); SendPacket(&data); return; } // queue result (default ok) GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult(bgt->GetBgTypeID()); // check if player can queue: if (!asGroup) { if (GetPlayer()->InBattleground()) // currently in battleground err = ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND; else if (GetPlayer()->isUsingLfg()) // using lfg system err = ERR_LFG_CANT_USE_BATTLEGROUND; if (err <= 0) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); SendPacket(&data); return; } BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bracketEntry, false, false, 0, 0, 0); uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo); uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); WorldPacket data; sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, arenatype, TEAM_NEUTRAL); SendPacket(&data); sScriptMgr->OnPlayerJoinArena(_player); } // check if group can queue: else { Group* grp = _player->GetGroup(); // no group or not a leader if (!grp || grp->GetLeaderGUID() != _player->GetGUID()) return; // pussywizard: for party members - remove queues for which leader is not queued to! std::set<uint32> leaderQueueTypeIds; for (uint32 i=0; i<PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) leaderQueueTypeIds.insert((uint32)_player->GetBattlegroundQueueTypeId(i)); for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) if (Player* member = itr->GetSource()) for (uint32 i=0; i<PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) if (BattlegroundQueueTypeId mqtid = member->GetBattlegroundQueueTypeId(i)) if (leaderQueueTypeIds.count((uint32)mqtid) == 0) { BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(mqtid); if (bgQueue.IsPlayerInvitedToRatedArena(member->GetGUID())) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_JOIN_FAILED); SendPacket(&data); return; } bgQueue.RemovePlayer(member->GetGUID(), false, i); member->RemoveBattlegroundQueueId(mqtid); } uint32 ateamId = 0; uint32 arenaRating = 0; uint32 matchmakerRating = 0; // additional checks for rated arenas if (isRated) { // pussywizard: for rated matches check if season is in progress! if (!sWorld->getBoolConfig(CONFIG_ARENA_SEASON_IN_PROGRESS)) return; ateamId = _player->GetArenaTeamId(arenaslot); // check team existence ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ateamId); if (!at) { SendNotInArenaTeamPacket(arenatype); return; } // get team rating for queueing arenaRating = at->GetRating(); matchmakerRating = at->GetAverageMMR(grp); if (arenaRating <= 0) arenaRating = 1; } err = grp->CanJoinBattlegroundQueue(bgt, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot); uint32 avgWaitTime = 0; if (err > 0) { BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bracketEntry, isRated, false, arenaRating, matchmakerRating, ateamId); avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo); } WorldPacket data; for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; if (err <= 0) { sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); member->GetSession()->SendPacket(&data); continue; } uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); // send status packet sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, arenatype, TEAM_NEUTRAL, isRated); member->GetSession()->SendPacket(&data); sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); member->GetSession()->SendPacket(&data); sScriptMgr->OnPlayerJoinArena(member); } // pussywizard: schedule update for rated arena if (ateamId) sBattlegroundMgr->ScheduleArenaQueueUpdate(ateamId, bgQueueTypeId, bracketEntry->GetBracketId()); } }