void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data) { ArenaTeam * team; uint32 teamId; recv_data >> teamId; team = objmgr.GetArenaTeamById(teamId); if( !team || team->m_type >= NUM_ARENA_TEAM_TYPES ) { GetPlayer()->SoftDisconnect(); return; } team = _player->m_arenaTeams[team->m_type]; if( team == NULL ) { SystemMessage("You are not in an arena team of this type."); return; } //if there is anyone inside an arena match then do not destroy it if( _player->m_bg && IS_ARENA( _player->m_bg->GetType() ) ) { SystemMessage("You cannot leave team while inside arena."); return; } if (team->m_leader == _player->GetLowGUID() && team->m_memberCount == 1) { team->Destroy(); return; } if(team->m_leader == _player->GetLowGUID()) { SystemMessage("You cannot leave the team yet, promote someone else to captain first."); return; } if(team->RemoveMember(_player->m_playerInfo)) { char buffer[1024]; WorldPacket * data; snprintf(buffer,1024,"%s left the arena team, '%s'.", _player->GetName(), team->m_name.c_str()); data = sChatHandler.FillSystemMessageData(buffer); team->SendPacket(data); delete data; data = NULL; SystemMessage("You have left the arena team, '%s'.", team->m_name.c_str()); } }
bool CBattleground::HasFreeSlots(uint32 Team, uint32 type) { bool res; uint32 maxPlayers = BattlegroundManager.GetMaximumPlayers(type); m_mainLock.Acquire(); if(IS_ARENA(type)) { res = ((uint32)m_players[Team].size() + m_pendPlayers[Team].size() < maxPlayers); } else { uint32 size[2]; size[0] = uint32(m_players[0].size() + m_pendPlayers[0].size()); size[1] = uint32(m_players[1].size() + m_pendPlayers[1].size()); res = (size[Team] < maxPlayers) && (((int)size[Team] - (int)size[1 - Team]) <= 0); } m_mainLock.Release(); return res; }
void CBattleground::UpdatePvPData() { if(IS_ARENA(m_type)) { if(!m_ended) { return; } } if(UNIXTIME >= m_nextPvPUpdateTime) { m_mainLock.Acquire(); WorldPacket data(10 * (m_players[0].size() + m_players[1].size()) + 50); BuildPvPUpdateDataPacket(&data); DistributePacketToAll(&data); m_mainLock.Release(); m_nextPvPUpdateTime = UNIXTIME + 2; } }
void CBattlegroundManager::EventQueueUpdate() { deque<Player*> tempPlayerVec[2]; uint32 i,j,k; Player * plr; CBattleground * bg; list<uint32>::iterator it3, it4; //vector<Player*>::iterator it6; map<uint32, CBattleground*>::iterator iitr; Arena * arena; int32 team; m_queueLock.Acquire(); m_instanceLock.Acquire(); for(i = 0; i < BATTLEGROUND_NUM_TYPES; ++i) { for(j = 0; j < MAX_LEVEL_GROUP; ++j) { if(!m_queuedPlayers[i][j].size()) continue; tempPlayerVec[0].clear(); tempPlayerVec[1].clear(); for(it3 = m_queuedPlayers[i][j].begin(); it3 != m_queuedPlayers[i][j].end();) { it4 = it3++; plr = objmgr.GetPlayer(*it4); if(!plr || GetLevelGrouping(plr->getLevel()) != j) { m_queuedPlayers[i][j].erase(it4); continue; } // queued to a specific instance id? if(plr->m_bgQueueInstanceId != 0) { iitr = m_instances[i].find(plr->m_bgQueueInstanceId); if(iitr == m_instances[i].end()) { // queue no longer valid plr->GetSession()->SystemMessage("Your queue on battleground instance id %u is no longer valid. Reason: Instance Deleted.", plr->m_bgQueueInstanceId); plr->m_bgIsQueued = false; plr->m_bgQueueType = 0; plr->m_bgQueueInstanceId = 0; m_queuedPlayers[i][j].erase(it4); } // can we join? bg = iitr->second; if(bg->CanPlayerJoin(plr)) { bg->AddPlayer(plr, plr->GetTeam()); m_queuedPlayers[i][j].erase(it4); } } else { if(IS_ARENA(i)) tempPlayerVec[0].push_back(plr); else tempPlayerVec[plr->GetTeam()].push_back(plr); } } // try to join existing instances for(iitr = m_instances[i].begin(); iitr != m_instances[i].end(); ++iitr) { if( iitr->second->HasEnded() ) continue; if(IS_ARENA(i)) { arena = ((Arena*)iitr->second); if(arena->Rated()) continue; team = arena->GetFreeTeam(); while(team >= 0 && tempPlayerVec[0].size()) { plr = *tempPlayerVec[0].begin(); tempPlayerVec[0].pop_front(); plr->m_bgTeam=team; arena->AddPlayer(plr, team); ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]); team = arena->GetFreeTeam(); } } else { bg = iitr->second; for(k = 0; k < 2; ++k) { while(tempPlayerVec[k].size() && bg->HasFreeSlots(k)) { plr = *tempPlayerVec[k].begin(); tempPlayerVec[k].pop_front(); bg->AddPlayer(plr, plr->GetTeam()); ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]); } } } } if(IS_ARENA(i)) { // enough players to start a round? if(tempPlayerVec[0].size() < BGMinimumPlayers[i]) continue; if(CanCreateInstance(i,j)) { arena = ((Arena*)CreateInstance(i, j)); if ( arena == NULL ) { m_queueLock.Release(); m_instanceLock.Release(); return; } team = arena->GetFreeTeam(); while(!arena->IsFull() && tempPlayerVec[0].size() && team >= 0) { plr = *tempPlayerVec[0].begin(); tempPlayerVec[0].pop_front(); arena->AddPlayer(plr, team); team = arena->GetFreeTeam(); // remove from the main queue (painful!) ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]); } } } else { #ifdef ONLY_ONE_PERSON_REQUIRED_TO_JOIN_DEBUG if(tempPlayerVec[0].size() >= 1 || tempPlayerVec[1].size() >= 1) #else if(tempPlayerVec[0].size() >= BGMinimumPlayers[i] && tempPlayerVec[1].size() >= BGMinimumPlayers[i]) #endif { if(CanCreateInstance(i,j)) { bg = CreateInstance(i,j); //ASSERT(bg); if ( bg == NULL ) { m_queueLock.Release(); m_instanceLock.Release(); return; } // push as many as possible in for(k = 0; k < 2; ++k) { while(tempPlayerVec[k].size() && bg->HasFreeSlots(k)) { plr = *tempPlayerVec[k].begin(); tempPlayerVec[k].pop_front(); bg->AddPlayer(plr, k); ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]); } } } } } } } /* Handle paired arena team joining */ Group * group1, *group2; uint32 n; list<uint32>::iterator itz; for(i = BATTLEGROUND_ARENA_2V2; i < BATTLEGROUND_ARENA_5V5+1; ++i) { for(;;) { if(m_queuedGroups[i].size() < 2) /* got enough to have an arena battle ;P */ { break; } group1 = group2 = NULL; while(group1 == NULL) { n = RandomUInt((uint32)m_queuedGroups[i].size()) - 1; for(itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end() && n>0; ++itz) --n; if(itz == m_queuedGroups[i].end()) itz=m_queuedGroups[i].begin(); if(itz == m_queuedGroups[i].end()) { Log.Error("BattlegroundMgr", "Internal error at %s:%u", __FILE__, __LINE__); m_queueLock.Release(); m_instanceLock.Release(); return; } group1 = objmgr.GetGroupById(*itz); m_queuedGroups[i].erase(itz); } while(group2 == NULL) { n = RandomUInt((uint32)m_queuedGroups[i].size()) - 1; for(itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end() && n>0; ++itz) --n; if(itz == m_queuedGroups[i].end()) itz=m_queuedGroups[i].begin(); if(itz == m_queuedGroups[i].end()) { Log.Error("BattlegroundMgr", "Internal error at %s:%u", __FILE__, __LINE__); m_queueLock.Release(); m_instanceLock.Release(); return; } group2 = objmgr.GetGroupById(*itz); m_queuedGroups[i].erase(itz); } Arena * ar = ((Arena*)CreateInstance(i,LEVEL_GROUP_70)); GroupMembersSet::iterator itx; ar->rated_match=true; for(itx = group1->GetSubGroup(0)->GetGroupMembersBegin(); itx != group1->GetSubGroup(0)->GetGroupMembersEnd(); ++itx) { if((*itx)->m_loggedInPlayer) { if( ar->HasFreeSlots(0) ) ar->AddPlayer((*itx)->m_loggedInPlayer, 0); } } for(itx = group2->GetSubGroup(0)->GetGroupMembersBegin(); itx != group2->GetSubGroup(0)->GetGroupMembersEnd(); ++itx) { if((*itx)->m_loggedInPlayer) { if( ar->HasFreeSlots(1) ) ar->AddPlayer((*itx)->m_loggedInPlayer, 1); } } } } m_queueLock.Release(); m_instanceLock.Release(); }
void CBattlegroundManager::EventQueueUpdate() { deque<Player*> tempPlayerVec[2]; uint32 i,j,k; Player * plr; CBattleground * bg; list<uint32>::iterator it3, it4; //vector<Player*>::iterator it6; map<uint32, CBattleground*>::iterator iitr; Arena * arena; int32 team; m_queueLock.Acquire(); m_instanceLock.Acquire(); for(i = 0; i < BATTLEGROUND_NUM_TYPES; ++i) { for(j = 0; j < MAX_LEVEL_GROUP; ++j) { if(!m_queuedPlayers[i][j].size()) continue; tempPlayerVec[0].clear(); tempPlayerVec[1].clear(); for(it3 = m_queuedPlayers[i][j].begin(); it3 != m_queuedPlayers[i][j].end();) { it4 = it3++; plr = objmgr.GetPlayer(*it4); if(!plr || GetLevelGrouping(plr->getLevel()) != j) { m_queuedPlayers[i][j].erase(it4); continue; } // queued to a specific instance id? if(plr->m_bgQueueInstanceId != 0) { iitr = m_instances[i].find(plr->m_bgQueueInstanceId); if(iitr == m_instances[i].end()) { // queue no longer valid plr->GetSession()->SystemMessage("Your queue on battleground instance id %u is no longer valid. Reason: Instance Deleted.", plr->m_bgQueueInstanceId); plr->m_bgIsQueued = false; plr->m_bgQueueType = 0; plr->m_bgQueueInstanceId = 0; m_queuedPlayers[i][j].erase(it4); } // can we join? bg = iitr->second; if(bg->CanPlayerJoin(plr)) { bg->AddPlayer(plr, plr->GetTeam()); m_queuedPlayers[i][j].erase(it4); } } else { if(IS_ARENA(i)) tempPlayerVec[0].push_back(plr); else tempPlayerVec[plr->GetTeam()].push_back(plr); } } // try to join existing instances for(iitr = m_instances[i].begin(); iitr != m_instances[i].end(); ++iitr) { if( iitr->second->HasEnded() || iitr->second->GetLevelGroup() != j) continue; if(IS_ARENA(i)) { arena = ((Arena*)iitr->second); if(arena->Rated()) continue; team = arena->GetFreeTeam(); while(team >= 0 && tempPlayerVec[0].size()) { plr = *tempPlayerVec[0].begin(); tempPlayerVec[0].pop_front(); plr->m_bgTeam=team; arena->AddPlayer(plr, team); ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]); team = arena->GetFreeTeam(); } } else { bg = iitr->second; for(k = 0; k < 2; ++k) { while(tempPlayerVec[k].size() && bg->HasFreeSlots(k)) { plr = *tempPlayerVec[k].begin(); tempPlayerVec[k].pop_front(); bg->AddPlayer(plr, plr->GetTeam()); ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]); } } } } if(IS_ARENA(i)) { // enough players to start a round? if(tempPlayerVec[0].size() < BGMinimumPlayers[i]) continue; if(CanCreateInstance(i,j)) { arena = ((Arena*)CreateInstance(i, j)); team = arena->GetFreeTeam(); while(!arena->IsFull() && tempPlayerVec[0].size() && team >= 0) { plr = *tempPlayerVec[0].begin(); tempPlayerVec[0].pop_front(); plr->m_bgTeam=team; arena->AddPlayer(plr, team); team = arena->GetFreeTeam(); // remove from the main queue (painful!) ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]); } } } else { #ifdef ONLY_ONE_PERSON_REQUIRED_TO_JOIN_DEBUG if(tempPlayerVec[0].size() >= 1 || tempPlayerVec[1].size() >= 1) #else if(tempPlayerVec[0].size() >= BGMinimumPlayers[i] && tempPlayerVec[1].size() >= BGMinimumPlayers[i]) #endif { if(CanCreateInstance(i,j)) { bg = CreateInstance(i,j); if( bg == NULL ) { // creation failed for(k = 0; k < 2; ++k) { while(tempPlayerVec[k].size()) { plr = *tempPlayerVec[k].begin(); tempPlayerVec[k].pop_front(); ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]); } } } else { // push as many as possible in for(k = 0; k < 2; ++k) { while(tempPlayerVec[k].size() && bg->HasFreeSlots(k)) { plr = *tempPlayerVec[k].begin(); tempPlayerVec[k].pop_front(); plr->m_bgTeam=k; bg->AddPlayer(plr, k); ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]); } } } } } } } } /* Handle paired arena team joining */ list<uint32>::iterator itz; list<uint32>::iterator itp; for(i = BATTLEGROUND_ARENA_2V2; i < BATTLEGROUND_ARENA_5V5+1; ++i) { // We need at least this many :( if(m_queuedGroups[i].size() < 2) continue; list<uint32> removegroups; for(itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end(); itz++) { Group * pGroup = objmgr.GetGroupById(*itz); if(!pGroup || !pGroup->m_isqueued || !pGroup->GetLeader() || pGroup->GetLeader()->arenaTeam[i - 4] == NULL) continue; uint32 maxRange = pGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange; pGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange += 100; vector<uint32> inRangeGroups; uint32 rating = pGroup->GetLeader()->arenaTeam[i - 4]->m_stat_rating; for(itp = m_queuedGroups[i].begin(); itp != m_queuedGroups[i].end();) { Group * tGrp = objmgr.GetGroupById(*itp); if(!tGrp || !tGrp->m_isqueued || !tGrp->GetLeader() || tGrp->GetLeader()->arenaTeam[i - 4] == NULL) { itp = m_queuedGroups[i].erase(itp); continue; } ++itp; if( pGroup == tGrp ) continue; uint32 tRating = tGrp->GetLeader()->arenaTeam[i - 4]->m_stat_rating; int32 diff = (int32)tRating - (int32)rating; if(diff < 0) diff = -diff; if(diff > (int32)maxRange) continue; //Log.Notice("Debug", "EventQueueUpdate added 1 in range arena"); inRangeGroups.push_back(tGrp->GetID()); } // K, we have a giant list of groups that we could group with, hopefully! // or not, we can't go on :( if(!inRangeGroups.size()) continue; // But if we're here, we can :D uint32 r = 0; if( inRangeGroups.size() > 1 ) r = RandomUInt((uint32)inRangeGroups.size() - 1); Group * pairGroup = objmgr.GetGroupById(inRangeGroups[r]); if(!pairGroup) continue; // Now, let's create this rated Arena Match :) //Log.Notice("Debug", "EventQueueUpdate creating arena"); Arena * arena = (Arena*)CreateInstance(i, LEVEL_GROUP_70); ArenaTeam *pTeamPair[2]; if(arena) { //Log.Notice("Debug", "EventQueueUpdate arena created"); removegroups.push_back(pGroup->GetID()); removegroups.push_back(pairGroup->GetID()); pGroup->m_isqueued = false; pairGroup->m_isqueued = false; arena->rated_match = true; if( pGroup->GetLeader()->arenaTeam[i - 4] != NULL ) { arena->m_ratedTeams[0] = pGroup->GetLeader()->arenaTeam[i - 4]->m_id; pTeamPair[0] = pGroup->GetLeader()->arenaTeam[i - 4]; } else pTeamPair[0] = NULL; if( pairGroup->GetLeader()->arenaTeam[i - 4] != NULL ) { arena->m_ratedTeams[1] = pairGroup->GetLeader()->arenaTeam[i - 4]->m_id; pTeamPair[1] = pairGroup->GetLeader()->arenaTeam[i - 4]; } else pTeamPair[1] = NULL; pGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange = 100; pairGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange = 100; GroupMembersSet::iterator gitr; pGroup->Lock(); for(gitr = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); gitr != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); gitr++) { PlayerInfo * pi = (*gitr); if(!pi->m_loggedInPlayer) continue; //Log.Notice("Debug", "EventQueueUpdate player lewp"); pi->m_loggedInPlayer->m_bgTeam = 0; if(arena->HasFreeSlots(0)) { arena->AddPlayer(pi->m_loggedInPlayer, 0); arena->m_RatedPlayers[0].insert(pi); if( pTeamPair[0] != NULL ) { ArenaTeamMember * atm = pTeamPair[0]->GetMember(pi); if(atm) { atm->Played_ThisSeason++; atm->Played_ThisWeek++; } //Log.Notice("Debug", "EventQueueUpdate added player %s", pi->m_loggedInPlayer->GetName()); } } } pGroup->Unlock(); pairGroup->Lock(); for(gitr = pairGroup->GetSubGroup(0)->GetGroupMembersBegin(); gitr != pairGroup->GetSubGroup(0)->GetGroupMembersEnd(); gitr++) { PlayerInfo * pi = (*gitr); if(!pi->m_loggedInPlayer || pi->arenaTeam[i-4] == NULL) continue; pi->m_loggedInPlayer->m_bgTeam = 1; if(arena->HasFreeSlots(1)) { arena->AddPlayer(pi->m_loggedInPlayer, 1); arena->m_RatedPlayers[1].insert(pi); if( pTeamPair[1] != NULL ) { ArenaTeamMember * atm = pTeamPair[1]->GetMember(pi); if(atm) { atm->Played_ThisSeason++; atm->Played_ThisWeek++; } } } } pairGroup->Unlock(); } } for(itz = removegroups.begin(); itz != removegroups.end(); itz++) { m_queuedGroups[i].remove(*itz); } } m_queueLock.Release(); m_instanceLock.Release(); }
void WorldSession::HandleUseItemOpcode(WorldPacket & recvPacket) { CHECK_INWORLD_RETURN typedef std::list<Aura*> AuraList; Player* p_User = GetPlayer(); LOG_DETAIL("WORLD: got use Item packet, data length = %i", recvPacket.size()); int8 tmp1, slot; uint8 unk; //Alice : added in 3.0.2 uint64 item_guid; uint8 cn; uint32 spellId = 0; uint32 glyphIndex; bool found = false; recvPacket >> tmp1; recvPacket >> slot; recvPacket >> cn; recvPacket >> spellId; recvPacket >> item_guid; recvPacket >> glyphIndex; recvPacket >> unk; Item* tmpItem = NULL; tmpItem = p_User->GetItemInterface()->GetInventoryItem(tmp1, slot); if(!tmpItem) tmpItem = p_User->GetItemInterface()->GetInventoryItem(slot); if(!tmpItem) return; ItemPrototype* itemProto = tmpItem->GetProto(); // only some consumable items can be used in arenas if( ( itemProto->Class == ITEM_CLASS_CONSUMABLE ) && !itemProto->HasFlag( ITEM_FLAG_USEABLE_IN_ARENA ) && ( GetPlayer()->m_bg != NULL ) && IS_ARENA( GetPlayer()->m_bg->GetType() ) ) { GetPlayer()->GetItemInterface()->BuildInventoryChangeError(tmpItem, NULL, INV_ERR_NOT_DURING_ARENA_MATCH); return; } if(tmpItem->IsSoulbound()) // SouldBind item will be used after SouldBind() { if(sScriptMgr.CallScriptedItem(tmpItem, _player)) return; } if(_player->getDeathState() == CORPSE) return; if(itemProto->Bonding == ITEM_BIND_ON_USE) tmpItem->SoulBind(); if(sScriptMgr.CallScriptedItem(tmpItem, _player)) return; if(itemProto->InventoryType != 0 && !_player->GetItemInterface()->IsEquipped(itemProto->ItemId)) //Equipable items cannot be used before they're equipped. Prevents exploits return;//Prevents exploits such as keeping an on-use trinket in your bag and using WPE to use it from your bag in mid-combat. if(itemProto->QuestId) { // Item Starter Quest* qst = QuestStorage.LookupEntry(itemProto->QuestId); if(!qst) return; WorldPacket data; sQuestMgr.BuildQuestDetails(&data, qst, tmpItem, 0, language, _player); SendPacket(&data); } // Let's check if the item even has that spell for(int i = 0; i < 5; ++i) { if(itemProto->Spells[i].Trigger == USE && itemProto->Spells[i].Id == spellId) { found = true; break;//found 1 already } } // Let's see if it is an onuse spellid if(tmpItem->HasOnUseSpellID(spellId)) found = true; // We didn't find the spell, so the player is probably trying to cheat // with an edited itemcache.wdb // // Altough this could also happen after a DB update // if he/she didn't delete his/her cache. if(found == false) { this->Disconnect(); Anticheat_Log->writefromsession(this, "Player tried to use an item with a spell that didn't match the spell in the database."); Anticheat_Log->writefromsession(this, "Possibly corrupted or intentionally altered itemcache.wdb"); Anticheat_Log->writefromsession(this, "Itemid: %lu", itemProto->ItemId); Anticheat_Log->writefromsession(this, "Spellid: %lu", spellId); Anticheat_Log->writefromsession(this, "Player was disconnected"); return; } SpellCastTargets targets(recvPacket, _player->GetGUID()); SpellEntry* spellInfo = dbcSpell.LookupEntryForced(spellId); if(spellInfo == NULL) { LOG_DETAIL("ERROR: WORLD: unknown spell id %i", spellId); return; } if(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_ON_STAND_UP) { if(p_User->CombatStatus.IsInCombat() || p_User->IsMounted()) { _player->GetItemInterface()->BuildInventoryChangeError(tmpItem, NULL, INV_ERR_CANT_DO_IN_COMBAT); return; } if(p_User->GetStandState() != 1) p_User->SetStandState(STANDSTATE_SIT); // loop through the auras and removing existing eating spells } else // cebernic: why not stand up { if(!p_User->CombatStatus.IsInCombat() && !p_User->IsMounted()) { if(p_User->GetStandState()) { p_User->SetStandState(STANDSTATE_STAND); } } } // cebernic: remove stealth on using item if(!(spellInfo->AuraInterruptFlags & ATTRIBUTESEX_NOT_BREAK_STEALTH)) { if(p_User->IsStealth()) p_User->RemoveAllAuraType(SPELL_AURA_MOD_STEALTH); } if(itemProto->RequiredLevel) { if(_player->getLevel() < itemProto->RequiredLevel) { _player->GetItemInterface()->BuildInventoryChangeError(tmpItem, NULL, INV_ERR_ITEM_RANK_NOT_ENOUGH); return; } } if(itemProto->RequiredSkill) { if(!_player->_HasSkillLine(itemProto->RequiredSkill)) { _player->GetItemInterface()->BuildInventoryChangeError(tmpItem, NULL, INV_ERR_ITEM_RANK_NOT_ENOUGH); return; } if(itemProto->RequiredSkillRank) { if(_player->_GetSkillLineCurrent(itemProto->RequiredSkill, false) < itemProto->RequiredSkillRank) { _player->GetItemInterface()->BuildInventoryChangeError(tmpItem, NULL, INV_ERR_ITEM_RANK_NOT_ENOUGH); return; } } } if((itemProto->AllowableClass && !(_player->getClassMask() & itemProto->AllowableClass)) || (itemProto->AllowableRace && !(_player->getRaceMask() & itemProto->AllowableRace))) { _player->GetItemInterface()->BuildInventoryChangeError(tmpItem, NULL, INV_ERR_YOU_CAN_NEVER_USE_THAT_ITEM); return; } if(!_player->Cooldown_CanCast(spellInfo)) { _player->SendCastResult(spellInfo->Id, SPELL_FAILED_NOT_READY, cn, 0); return; } if(_player->m_currentSpell) { _player->SendCastResult(spellInfo->Id, SPELL_FAILED_SPELL_IN_PROGRESS, cn, 0); return; } if(itemProto->ForcedPetId >= 0) { if(itemProto->ForcedPetId == 0) { if(_player->GetGUID() != targets.m_unitTarget) { _player->SendCastResult(spellInfo->Id, SPELL_FAILED_BAD_TARGETS, cn, 0); return; } } else { if(!_player->GetSummon() || _player->GetSummon()->GetEntry() != (uint32)itemProto->ForcedPetId) { _player->SendCastResult(spellInfo->Id, SPELL_FAILED_SPELL_IN_PROGRESS, cn, 0); return; } } } Spell* spell = sSpellFactoryMgr.NewSpell(_player, spellInfo, false, NULL); spell->extra_cast_number = cn; spell->i_caster = tmpItem; spell->m_glyphslot = glyphIndex; //GetPlayer()->setCurrentSpell(spell); spell->prepare(&targets); #ifdef ENABLE_ACHIEVEMENTS _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, itemProto->ItemId, 0, 0); #endif }
void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data) { ArenaTeam * team; uint32 teamId; recv_data >> teamId; team = objmgr.GetArenaTeamById(teamId); if( !team || team->m_type >= NUM_ARENA_TEAM_TYPES ) { GetPlayer()->SoftDisconnect(); return; } if( (team = _player->m_arenaTeams[team->m_type]) == NULL ) { SystemMessage("You are not in an arena team of this type."); return; } if(team->m_leader != _player->GetLowGUID()) { SystemMessage("You aren't the captain of this team."); return; } //if there is anyone inside an arena match then do not destroy it for( uint32 i=0;i<team->m_memberCount;i++) { ArenaTeamMember *member = team->GetMemberBySlot( i ); if( member && member->Info && member->Info->m_loggedInPlayer && member->Info->m_loggedInPlayer->m_bg && IS_ARENA( member->Info->m_loggedInPlayer->m_bg->GetType() ) ) { SystemMessage("Someone is playing an active Arena match."); return; } } team->Destroy(); }
void WorldSession::HandleArenaTeamRemoveMemberOpcode(WorldPacket & recv_data) { ArenaTeam * team; uint8 slot; uint32 teamId; string name; PlayerInfo * inf; recv_data >> teamId >> name; team = objmgr.GetArenaTeamById(teamId); if( !team || team->m_type >= NUM_ARENA_TEAM_TYPES ) { GetPlayer()->SoftDisconnect(); return; } slot = team->m_type; if( (team = _player->m_arenaTeams[slot]) == NULL ) { SystemMessage("You are not in an arena team of this type."); return; } if(team->m_leader != _player->GetLowGUID()) { SystemMessage("You are not the leader of this team."); return; } if( (inf = objmgr.GetPlayerInfoByName(name.c_str())) == NULL ) { SystemMessage("That player cannot be found."); return; } if(!team->HasMember(inf->guid)) { SystemMessage("That player is not in your arena team."); return; } //if there is anyone inside an arena match then do not destroy it if( inf->m_loggedInPlayer && inf->m_loggedInPlayer->m_bg && IS_ARENA( inf->m_loggedInPlayer->m_bg->GetType() ) ) { SystemMessage("The player is playing an active match."); return; } if(team->RemoveMember(inf)) { char buffer[1024]; WorldPacket * data; snprintf(buffer,1024,"%s was removed from the arena team '%s'.", inf->name, team->m_name.c_str()); data = sChatHandler.FillSystemMessageData(buffer); team->SendPacket(data); delete data; data = NULL; SystemMessage("Removed %s from the arena team '%s'.", inf->name, team->m_name.c_str()); } }
CBattleground* CBattlegroundManager::CreateInstance(uint32 Type, uint32 LevelGroup) { if (bgMaps.find(Type) == bgMaps.end()) { if (!IS_ARENA(Type)) { LOG_ERROR("BattlegroundManager", "No map Id is registered for Battleground type %u", Type); return NULL; } } BattlegroundFactoryMethod cfunc = NULL; if (!IS_ARENA(Type)) if (bgFactories.find(bgMaps[Type]) != bgFactories.end()) cfunc = bgFactories[bgMaps[Type]]; MapMgr* mgr = NULL; CBattleground* bg; bool isWeekend = false; struct tm tm; uint32 iid; time_t t; int n; if (IS_ARENA(Type)) { /* arenas follow a different procedure. */ uint32 arenaMapCount = arenaMaps.size(); if (arenaMapCount == 0) { LOG_ERROR("BattlegroundManager", "There are no Arenas registered. Cannot create Arena."); return NULL; } uint32 index = RandomUInt(arenaMapCount - 1); uint32 mapid = arenaMaps[index]; ArenaFactoryMethod arenaFactory = arenaFactories[index]; uint32 players_per_side; mgr = sInstanceMgr.CreateBattlegroundInstance(mapid); if (mgr == NULL) { sLog.Error("BattlegroundManager", "Arena CreateInstance() call failed for map %u, type %u, level group %u", mapid, Type, LevelGroup); return NULL; // Shouldn't happen } players_per_side = GetMaximumPlayers(Type); iid = ++m_maxBattlegroundId[Type]; bg = arenaFactory(mgr, iid, LevelGroup, Type, players_per_side); mgr->m_battleground = bg; Log.Notice("BattlegroundManager", "Created arena battleground type %u for level group %u on map %u.", Type, LevelGroup, mapid); sEventMgr.AddEvent(bg, &CBattleground::EventCreate, EVENT_BATTLEGROUND_QUEUE_UPDATE, 1, 1, 0); m_instanceLock.Acquire(); m_instances[Type].insert(make_pair(iid, bg)); m_instanceLock.Release(); return bg; } if (cfunc == NULL) { sLog.Error("BattlegroundManager", "Could not find CreateBattlegroundFunc pointer for type %u level group %u", Type, LevelGroup); return NULL; } t = time(NULL); #ifdef WIN32 // localtime_s(&tm, &t); //zack : some luv for vs2k3 compiler tm = *localtime(&t); #else localtime_r(&t, &tm); #endif switch (Type) { case BATTLEGROUND_WARSONG_GULCH: n = 0; break; case BATTLEGROUND_ARATHI_BASIN: n = 1; break; case BATTLEGROUND_EYE_OF_THE_STORM: n = 2; break; case BATTLEGROUND_STRAND_OF_THE_ANCIENT: n = 3; break; default: n = 0; break; } if (((tm.tm_yday / 7) % 4) == n) { /* Set weekend from Thursday night at midnight until Tuesday morning */ isWeekend = tm.tm_wday >= 5 || tm.tm_wday < 2; } /* Create Map Manager */ mgr = sInstanceMgr.CreateBattlegroundInstance(bgMaps[Type]); if (mgr == NULL) { sLog.Error("BattlegroundManager", "CreateInstance() call failed for map %u, type %u, level group %u", bgMaps[Type], Type, LevelGroup); return NULL; // Shouldn't happen } /* Call the create function */ iid = ++m_maxBattlegroundId[Type]; bg = cfunc(mgr, iid, LevelGroup, Type); bg->SetIsWeekend(isWeekend); mgr->m_battleground = bg; sEventMgr.AddEvent(bg, &CBattleground::EventCreate, EVENT_BATTLEGROUND_QUEUE_UPDATE, 1, 1, 0); Log.Notice("BattlegroundManager", "Created battleground type %u for level group %u.", Type, LevelGroup); m_instanceLock.Acquire(); m_instances[Type].insert(make_pair(iid, bg)); m_instanceLock.Release(); return bg; }
void CBattlegroundManager::HandleBattlegroundListPacket(WorldSession* m_session, uint32 BattlegroundType, uint8 from) { WorldPacket data(SMSG_BATTLEFIELD_LIST, 18); // Send 0 instead of GUID when using the BG UI instead of Battlemaster if (from == 0) data << uint64(m_session->GetPlayer()->GetGUID()); else data << uint64(0); data << from; data << uint32(BattlegroundType); // typeid data << uint8(0); // unk data << uint8(0); // unk // Rewards data << uint8(0); // 3.3.3 hasWin data << uint32(0); // 3.3.3 winHonor data << uint32(0); // 3.3.3 winArena data << uint32(0); // 3.3.3 lossHonor uint8 isRandom = 0; data << uint8(isRandom); // 3.3.3 isRandom // Random bgs if (isRandom == 1) { // rewards data << uint8(0); // win random data << uint32(0); // Reward honor if won data << uint32(0); // Reward arena point if won data << uint32(0); // Lost honor if lost } if (IS_ARENA(BattlegroundType)) { data << uint32(0); m_session->SendPacket(&data); return; } if (BattlegroundType >= BATTLEGROUND_NUM_TYPES) return; //VLack: Nasty hackers might try to abuse this packet to crash us... uint32 Count = 0; size_t pos = data.wpos(); data << uint32(0); // Count /* Append the battlegrounds */ m_instanceLock.Acquire(); for (map<uint32, CBattleground*>::iterator itr = m_instances[BattlegroundType].begin(); itr != m_instances[BattlegroundType].end(); ++itr) { if (itr->second->CanPlayerJoin(m_session->GetPlayer(), BattlegroundType) && !itr->second->HasEnded()) { data << uint32(itr->first); ++Count; } } m_instanceLock.Release(); data.put< uint32 >(pos, Count); m_session->SendPacket(&data); }
void CBattlegroundManager::EventQueueUpdate(bool forceStart) { deque<uint32> tempPlayerVec[2]; uint32 i, j, k; Player* plr; CBattleground* bg; list<uint32>::iterator it3, it4; map<uint32, CBattleground*>::iterator iitr; Arena* arena; int32 team; uint32 plrguid; uint32 factionMap[MAX_PLAYER_TEAMS]; uint32 count; std::queue< uint32 > teams[MAX_PLAYER_TEAMS]; m_queueLock.Acquire(); m_instanceLock.Acquire(); for (i = 0; i < BATTLEGROUND_NUM_TYPES; ++i) { for (j = 0; j < MAX_LEVEL_GROUP; ++j) { if (!m_queuedPlayers[i][j].size()) continue; tempPlayerVec[0].clear(); tempPlayerVec[1].clear(); // We try to add the players who queued for a specific Bg/Arena instance to // the Bg/Arena where they queued to, and add the rest to another list for (it3 = m_queuedPlayers[i][j].begin(); it3 != m_queuedPlayers[i][j].end();) { it4 = it3++; plrguid = *it4; plr = objmgr.GetPlayer(plrguid); // Player has left the game or switched level group since queuing (by leveling for example) if (!plr || GetLevelGrouping(plr->getLevel()) != j) { m_queuedPlayers[i][j].erase(it4); continue; } // queued to a specific instance id? if (plr->m_bgQueueInstanceId != 0) { iitr = m_instances[i].find(plr->m_bgQueueInstanceId); if (iitr == m_instances[i].end()) { // queue no longer valid, since instance has closed since queuing plr->GetSession()->SystemMessage(plr->GetSession()->LocalizedWorldSrv(52), plr->m_bgQueueInstanceId); plr->m_bgIsQueued = false; plr->m_bgQueueType = 0; plr->m_bgQueueInstanceId = 0; m_queuedPlayers[i][j].erase(it4); continue; } // can we join the specified Bg instance? bg = iitr->second; if (bg->CanPlayerJoin(plr, bg->GetType())) { bg->AddPlayer(plr, plr->GetTeam()); m_queuedPlayers[i][j].erase(it4); } } else { if (IS_ARENA(i)) tempPlayerVec[plr->GetTeam()].push_back(plrguid); else if (!plr->HasAura(BG_DESERTER)) tempPlayerVec[plr->GetTeam()].push_back(plrguid); } } // Now that we have a list of players who didn't queue for a specific instance // try to add them to a Bg/Arena that is already under way for (iitr = m_instances[i].begin(); iitr != m_instances[i].end(); ++iitr) { if (iitr->second->HasEnded() || iitr->second->GetLevelGroup() != j) continue; if (IS_ARENA(i)) { arena = TO< Arena* >(iitr->second); if (arena->Rated()) continue; factionMap[0] = arena->GetTeamFaction(0); factionMap[1] = arena->GetTeamFaction(1); team = arena->GetFreeTeam(); while ((team >= 0) && (tempPlayerVec[factionMap[team]].size() > 0)) { plrguid = *tempPlayerVec[factionMap[team]].begin(); tempPlayerVec[factionMap[team]].pop_front(); plr = objmgr.GetPlayer(plrguid); if (plr) { plr->m_bgTeam = team; arena->AddPlayer(plr, team); team = arena->GetFreeTeam(); } ErasePlayerFromList(plrguid, &m_queuedPlayers[i][j]); } } else { bg = iitr->second; int size = (int)min(tempPlayerVec[0].size(), tempPlayerVec[1].size()); for (int counter = 0; (counter < size) && (bg->IsFull() == false); counter++) { AddPlayerToBgTeam(bg, &tempPlayerVec[0], i, j, 0); AddPlayerToBgTeam(bg, &tempPlayerVec[1], i, j, 1); } while (tempPlayerVec[0].size() > 0 && bg->HasFreeSlots(0, bg->GetType())) { AddPlayerToBgTeam(bg, &tempPlayerVec[0], i, j, 0); } while (tempPlayerVec[1].size() > 0 && bg->HasFreeSlots(1, bg->GetType())) { AddPlayerToBgTeam(bg, &tempPlayerVec[1], i, j, 1); } } } // Now that that we added everyone we could to a running Bg/Arena // We shall see if we can start a new one! if (IS_ARENA(i)) { // enough players to start a round? uint32 minPlayers = BattlegroundManager.GetMinimumPlayers(i); if (!forceStart && ((tempPlayerVec[0].size() + tempPlayerVec[1].size()) < (minPlayers * 2))) continue; if (CanCreateInstance(i, j)) { arena = TO< Arena* >(CreateInstance(i, j)); if (arena == NULL) { sLog.Error("BattlegroundMgr", "%s (%u): Couldn't create Arena Instance", __FILE__, __LINE__); m_queueLock.Release(); m_instanceLock.Release(); return; } // No alliance in the queue if (tempPlayerVec[0].size() == 0) { count = GetMaximumPlayers(i) * 2; while ((count > 0) && (tempPlayerVec[1].size() > 0)) { if (teams[0].size() > teams[1].size()) teams[1].push(tempPlayerVec[1].front()); else teams[0].push(tempPlayerVec[1].front()); tempPlayerVec[1].pop_front(); count--; } } else // No horde in the queue if (tempPlayerVec[1].size() == 0) { count = GetMaximumPlayers(i) * 2; while ((count > 0) && (tempPlayerVec[0].size() > 0)) { if (teams[0].size() > teams[1].size()) teams[1].push(tempPlayerVec[0].front()); else teams[0].push(tempPlayerVec[0].front()); tempPlayerVec[0].pop_front(); count--; } } else // There are both alliance and horde players in the queue { count = GetMaximumPlayers(i); while ((count > 0) && (tempPlayerVec[0].size() > 0) && (tempPlayerVec[1].size() > 0)) { teams[0].push(tempPlayerVec[0].front()); teams[1].push(tempPlayerVec[1].front()); tempPlayerVec[0].pop_front(); tempPlayerVec[1].pop_front(); count--; } } // Now we just need to add the players to the Arena instance while (teams[0].size() > 0) { for (uint32 team = 0; team < 2; team++) { plrguid = teams[team].front(); teams[team].pop(); plr = objmgr.GetPlayer(plrguid); if (plr == NULL) continue; plr->m_bgTeam = team; arena->AddPlayer(plr, plr->m_bgTeam); // remove from the main queue (painful!) ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]); } } } } else { uint32 minPlayers = BattlegroundManager.GetMinimumPlayers(i); if (forceStart || (tempPlayerVec[0].size() >= minPlayers && tempPlayerVec[1].size() >= minPlayers)) { if (CanCreateInstance(i, j)) { bg = CreateInstance(i, j); if (bg == NULL) { m_queueLock.Release(); m_instanceLock.Release(); return; } // push as many as possible in if (forceStart) { for (k = 0; k < 2; ++k) { while (tempPlayerVec[k].size() && bg->HasFreeSlots(k, bg->GetType())) { AddPlayerToBgTeam(bg, &tempPlayerVec[k], i, j, k); } } } else { int size = (int)min(tempPlayerVec[0].size(), tempPlayerVec[1].size()); for (int counter = 0; (counter < size) && (bg->IsFull() == false); counter++) { AddPlayerToBgTeam(bg, &tempPlayerVec[0], i, j, 0); AddPlayerToBgTeam(bg, &tempPlayerVec[1], i, j, 1); } } } } } } } /* Handle paired arena team joining */ Group* group1, *group2; uint32 teamids[2] = { 0, 0 }; uint32 avgRating[2] = { 0, 0 }; uint32 n; list<uint32>::iterator itz; for (i = BATTLEGROUND_ARENA_2V2; i <= BATTLEGROUND_ARENA_5V5; ++i) { if (!forceStart && m_queuedGroups[i].size() < 2) /* got enough to have an arena battle ;P */ { continue; } for (j = 0; j < (uint32)m_queuedGroups[i].size(); j++) { group1 = group2 = NULL; n = RandomUInt((uint32)m_queuedGroups[i].size()) - 1; for (itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end() && n > 0; ++itz) --n; if (itz == m_queuedGroups[i].end()) itz = m_queuedGroups[i].begin(); if (itz == m_queuedGroups[i].end()) { sLog.Error("BattlegroundMgr", "Internal error at %s:%u", __FILE__, __LINE__); m_queueLock.Release(); m_instanceLock.Release(); return; } group1 = objmgr.GetGroupById(*itz); if (group1 == NULL) { continue; } if (forceStart && m_queuedGroups[i].size() == 1) { if (CreateArenaType(i, group1, NULL) == -1) return; m_queuedGroups[i].remove(group1->GetID()); continue; } teamids[0] = GetArenaGroupQInfo(group1, i, &avgRating[0]); list<uint32> possibleGroups; for (itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end(); ++itz) { group2 = objmgr.GetGroupById(*itz); if (group2) { teamids[1] = GetArenaGroupQInfo(group2, i, &avgRating[1]); uint32 delta = abs((int32)avgRating[0] - (int32)avgRating[1]); if (teamids[0] != teamids[1] && delta <= sWorld.ArenaQueueDiff) { possibleGroups.push_back(group2->GetID()); } } } if (possibleGroups.size() > 0) { n = RandomUInt((uint32)possibleGroups.size()) - 1; for (itz = possibleGroups.begin(); itz != possibleGroups.end() && n > 0; ++itz) --n; if (itz == possibleGroups.end()) itz = possibleGroups.begin(); if (itz == possibleGroups.end()) { sLog.Error("BattlegroundMgr", "Internal error at %s:%u", __FILE__, __LINE__); m_queueLock.Release(); m_instanceLock.Release(); return; } group2 = objmgr.GetGroupById(*itz); if (group2) { if (CreateArenaType(i, group1, group2) == -1) return; m_queuedGroups[i].remove(group1->GetID()); m_queuedGroups[i].remove(group2->GetID()); } } } } m_queueLock.Release(); m_instanceLock.Release(); }
void CBattlegroundManager::HandleGetBattlegroundQueueCommand(WorldSession* m_session) { std::stringstream ss; uint32 i, j; Player* plr; list<uint32>::iterator it3, it4; m_queueLock.Acquire(); bool foundSomething = false; for (i = 0; i < BATTLEGROUND_NUM_TYPES; ++i) { for (j = 0; j < MAX_LEVEL_GROUP; ++j) { if (!m_queuedPlayers[i][j].size()) continue; foundSomething = true; ss << m_session->LocalizedWorldSrv(GetBattlegroundCaption((BattleGroundTypes)i)); switch (j) { case 0: ss << " (<10)"; break; case 1: ss << " (<20)"; break; case 2: ss << " (<30)"; break; case 3: ss << " (<40)"; break; case 4: ss << " (<50)"; break; case 5: ss << " (<60)"; break; case 6: ss << " (<70)"; break; case 7: ss << " (<80)"; break; } ss << ": "; ss << (uint32)m_queuedPlayers[i][j].size() << " players queued"; if (!IS_ARENA(i)) { int ally = 0, horde = 0; for (it3 = m_queuedPlayers[i][j].begin(); it3 != m_queuedPlayers[i][j].end();) { it4 = it3++; plr = objmgr.GetPlayer(*it4); if (!plr || GetLevelGrouping(plr->getLevel()) != j) { continue; } if (plr->IsTeamAlliance()) ally++; else horde++; } ss << " (Alliance: " << ally << " Horde: " << horde; if ((int)m_queuedPlayers[i][j].size() > (ally + horde)) ss << " Unknown: " << ((int)m_queuedPlayers[i][j].size() - ally - horde); ss << ")"; } m_session->SystemMessage(ss.str().c_str()); ss.rdbuf()->str(""); } if (IS_ARENA(i)) { if (m_queuedGroups[i].size()) { foundSomething = true; ss << m_session->LocalizedWorldSrv(GetBattlegroundCaption((BattleGroundTypes)i)) << " (rated): "; ss << (uint32)m_queuedGroups[i].size() << " groups queued"; m_session->SystemMessage(ss.str().c_str()); ss.rdbuf()->str(""); } } } m_queueLock.Release(); if (!foundSomething) m_session->SystemMessage("There's nobody queued."); }
void CBattlegroundManager::SendBattlefieldStatus(Player* plr, BattleGroundStatus Status, uint32 Type, uint32 InstanceID, uint32 Time, uint32 MapId, uint8 RatedMatch) { WorldPacket data(SMSG_BATTLEFIELD_STATUS, 30); if (Status == 0) data << uint32(0) << uint64(0); else { if (IS_ARENA(Type)) { data << uint32(0); // Queue Slot 0..2. Only the first slot is used in arcemu! switch (Type) { case BATTLEGROUND_ARENA_2V2: data << uint8(2); break; case BATTLEGROUND_ARENA_3V3: data << uint8(3); break; case BATTLEGROUND_ARENA_5V5: data << uint8(5); break; } data << uint8(0xC); data << uint32(6); data << uint16(0x1F90); data << uint8(0); // 3.3.0 data << uint8(0); // 3.3.0 data << uint32(11); data << uint8(RatedMatch); // 1 = rated match } else { data << uint32(0); data << uint8(0) << uint8(2); data << Type; data << uint8(0); // 3.3.0 data << uint8(0); // 3.3.0 data << uint16(0x1F90); data << InstanceID; data << uint8(0); } data << uint32(Status); switch (Status) { case BGSTATUS_INQUEUE: // Waiting in queue data << uint32(60) << uint32(0); // Time / Elapsed time break; case BGSTATUS_READY: // Ready to join! data << MapId; data << uint64(0); data << Time; break; case BGSTATUS_TIME: data << MapId; data << uint64(0); data << uint32(0); data << Time; if (IS_ARENA(Type)) data << uint8(0); else data << uint8(1); break; case BGSTATUS_NOFLAGS: break; } } plr->GetSession()->SendPacket(&data); }
void CBattleground::BuildPvPUpdateDataPacket(WorldPacket* data) { ARCEMU_ASSERT(data != NULL); data->Initialize(MSG_PVP_LOG_DATA); data->reserve(10 * (m_players[0].size() + m_players[1].size()) + 50); BGScore* bs; if(IS_ARENA(m_type)) { if(!m_ended) { return; } *data << uint8(1); //In 3.1 this should be the uint32(negative rating), uint32(positive rating), uint32(0)[<-this is the new field in 3.1], and a name if available / which is a null-terminated string, and we send an uint8(0), so we provide a zero length name string / if(!Rated()) { *data << uint32(0) << uint32(0) << uint32(0) << uint8(0); *data << uint32(0) << uint32(0) << uint32(0) << uint8(0); } else { /* Grab some arena teams */ ArenaTeam** teams = TO< Arena* >(this)->GetTeams(); if(teams[0]) { *data << uint32(0) << uint32(3000 + m_deltaRating[0]) << uint32(0) << uint8(0); } else { *data << uint32(0) << uint32(0) << uint32(0) << uint8(0); } if(teams[1]) { *data << uint32(0) << uint32(3000 + m_deltaRating[1]) << uint32(0) << uint8(0); } else { *data << uint32(0) << uint32(0) << uint32(0) << uint8(0); } } *data << uint8(1); *data << uint8(m_winningteam); *data << uint32((m_players[0].size() + m_players[1].size()) - m_invisGMs); for(uint32 i = 0; i < 2; ++i) { for(set<Player*>::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr) { if((*itr)->m_isGmInvisible)continue; *data << (*itr)->GetGUID(); bs = &(*itr)->m_bgScore; *data << bs->KillingBlows; *data << uint8((*itr)->m_bgTeam); *data << bs->DamageDone; *data << bs->HealingDone; *data << uint32(0); } } } else { *data << uint8(0); if(m_ended) { *data << uint8(1); *data << uint8(m_winningteam ? 0 : 1); } else *data << uint8(0); // If the game has ended - this will be 1 *data << uint32((m_players[0].size() + m_players[1].size()) - m_invisGMs); uint32 FieldCount = GetFieldCount(GetType()); for(uint32 i = 0; i < 2; ++i) { for(set<Player*>::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr) { ARCEMU_ASSERT(*itr != NULL); if((*itr)->m_isGmInvisible) continue; *data << (*itr)->GetGUID(); bs = &(*itr)->m_bgScore; *data << bs->KillingBlows; *data << bs->HonorableKills; *data << bs->Deaths; *data << bs->BonusHonor; *data << bs->DamageDone; *data << bs->HealingDone; *data << FieldCount; for(uint32 x = 0; x < FieldCount; ++x) *data << bs->MiscData[x]; } } } }