void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos) { WorldPackets::Auth::AuthResponse response; response.Result = code; if (queued) { response.WaitInfo = boost::in_place(); response.WaitInfo->WaitCount = queuePos; } if (code == AUTH_OK) { response.SuccessInfo = boost::in_place(); response.SuccessInfo->AccountExpansionLevel = GetExpansion(); response.SuccessInfo->ActiveExpansionLevel = GetExpansion(); response.SuccessInfo->VirtualRealmAddress = GetVirtualRealmAddress(); std::string realmName = sObjectMgr->GetRealmName(realmHandle.Index); // Send current home realm. Also there is no need to send it later in realm queries. response.SuccessInfo->VirtualRealms.emplace_back(GetVirtualRealmAddress(), true, false, realmName, realmName); if (HasPermission(rbac::RBAC_PERM_USE_CHARACTER_TEMPLATES)) for (auto& templ : sObjectMgr->GetCharacterTemplates()) response.SuccessInfo->Templates.emplace_back(templ.second); response.SuccessInfo->AvailableClasses = &sObjectMgr->GetClassExpansionRequirements(); response.SuccessInfo->AvailableRaces = &sObjectMgr->GetRaceExpansionRequirements(); } SendPacket(response.Write()); }
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::BattlePet::BattlePet const& pet) { data << pet.Guid; data << pet.Species; data << pet.CreatureID; data << pet.CollarID; data << pet.Breed; data << pet.Level; data << pet.Exp; data << pet.Flags; data << pet.Power; data << pet.Health; data << pet.MaxHealth; data << pet.Speed; data << pet.Quality; data.WriteBits(pet.Name.size(), 7); data.WriteBit(!pet.Owner.IsEmpty()); // HasOwnerInfo data.WriteBit(pet.Name.empty()); // NoRename data.FlushBits(); if (!pet.Owner.IsEmpty()) { data << pet.Owner; data << GetVirtualRealmAddress(); // Virtual data << GetVirtualRealmAddress(); // Native } data.WriteString(pet.Name); return data; }
void PlayerAchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) const { // Don't send for achievements with ACHIEVEMENT_FLAG_HIDDEN if (achievement->Flags & ACHIEVEMENT_FLAG_HIDDEN) return; TC_LOG_DEBUG("criteria.achievement", "PlayerAchievementMgr::SendAchievementEarned(%u)", achievement->ID); if (!(achievement->Flags & ACHIEVEMENT_FLAG_TRACKING_FLAG)) { if (Guild* guild = sGuildMgr->GetGuildById(_owner->GetGuildId())) { Trinity::BroadcastTextBuilder _builder(_owner, CHAT_MSG_GUILD_ACHIEVEMENT, BROADCAST_TEXT_ACHIEVEMENT_EARNED, _owner->getGender(), _owner, achievement->ID); Trinity::LocalizedPacketDo<Trinity::BroadcastTextBuilder> _localizer(_builder); guild->BroadcastWorker(_localizer, _owner); } if (achievement->Flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL | ACHIEVEMENT_FLAG_REALM_FIRST_REACH)) { // broadcast realm first reached WorldPackets::Achievement::ServerFirstAchievement serverFirstAchievement; serverFirstAchievement.Name = _owner->GetName(); serverFirstAchievement.PlayerGUID = _owner->GetGUID(); serverFirstAchievement.AchievementID = achievement->ID; sWorld->SendGlobalMessage(serverFirstAchievement.Write()); } // if player is in world he can tell his friends about new achievement else if (_owner->IsInWorld()) { Trinity::BroadcastTextBuilder _builder(_owner, CHAT_MSG_ACHIEVEMENT, BROADCAST_TEXT_ACHIEVEMENT_EARNED, _owner->getGender(), _owner, achievement->ID); Trinity::LocalizedPacketDo<Trinity::BroadcastTextBuilder> _localizer(_builder); Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::BroadcastTextBuilder>> _worker(_owner, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), _localizer); Cell::VisitWorldObjects(_owner, _worker, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY)); } } WorldPackets::Achievement::AchievementEarned achievementEarned; achievementEarned.Sender = _owner->GetGUID(); achievementEarned.Earner = _owner->GetGUID(); achievementEarned.EarnerNativeRealm = achievementEarned.EarnerVirtualRealm = GetVirtualRealmAddress(); achievementEarned.AchievementID = achievement->ID; achievementEarned.Time = time(NULL); if (!(achievement->Flags & ACHIEVEMENT_FLAG_TRACKING_FLAG)) _owner->SendMessageToSetInRange(achievementEarned.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); else _owner->SendDirectMessage(achievementEarned.Write()); }
void PlayerAchievementMgr::SendAchievementInfo(Player* receiver, uint32 /*achievementId = 0 */) const { VisibleAchievementCheck filterInvisible; WorldPackets::Achievement::RespondInspectAchievements inspectedAchievements; inspectedAchievements.Player = _owner->GetGUID(); inspectedAchievements.Data.Earned.reserve(_completedAchievements.size()); inspectedAchievements.Data.Progress.reserve(_criteriaProgress.size()); for (auto itr = _completedAchievements.begin(); itr != _completedAchievements.end(); ++itr) { AchievementEntry const* achievement = filterInvisible(*itr); if (!achievement) continue; WorldPackets::Achievement::EarnedAchievement earned; earned.Id = itr->first; earned.Date = itr->second.Date; if (!(achievement->Flags & ACHIEVEMENT_FLAG_ACCOUNT)) { earned.Owner = _owner->GetGUID(); earned.VirtualRealmAddress = earned.NativeRealmAddress = GetVirtualRealmAddress(); } inspectedAchievements.Data.Earned.push_back(earned); } for (auto itr = _criteriaProgress.begin(); itr != _criteriaProgress.end(); ++itr) { WorldPackets::Achievement::CriteriaProgress progress; progress.Id = itr->first; progress.Quantity = itr->second.Counter; progress.Player = itr->second.PlayerGUID; progress.Flags = 0; progress.Date = itr->second.Date; progress.TimeFromStart = 0; progress.TimeFromCreate = 0; inspectedAchievements.Data.Progress.push_back(progress); } receiver->SendDirectMessage(inspectedAchievements.Write()); }
void Channel::List(Player const* player) { ObjectGuid const& guid = player->GetGUID(); if (!IsOn(guid)) { NotMemberAppend appender; ChannelNameBuilder<NotMemberAppend> builder(this, appender); SendToOne(builder, guid); return; } std::string channelName = GetName(player->GetSession()->GetSessionDbcLocale()); TC_LOG_DEBUG("chat.system", "SMSG_CHANNEL_LIST %s Channel: %s", player->GetSession()->GetPlayerInfo().c_str(), channelName.c_str()); WorldPackets::Channel::ChannelListResponse list; list._Display = true; /// always true? list._Channel = channelName; list._ChannelFlags = GetFlags(); uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST); list._Members.reserve(_playersStore.size()); for (PlayerContainer::value_type const& i : _playersStore) { Player* member = ObjectAccessor::FindConnectedPlayer(i.first); // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all if (member && (player->GetSession()->HasPermission(rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) || member->GetSession()->GetSecurity() <= AccountTypes(gmLevelInWhoList)) && member->IsVisibleGloballyFor(player)) { list._Members.emplace_back(i.first, GetVirtualRealmAddress(), i.second.GetFlags()); } } player->SendDirectMessage(list.Write()); }
void WorldSession::HandleWhoOpcode(WorldPackets::Who::WhoRequestPkt& whoRequest) { WorldPackets::Who::WhoRequest& request = whoRequest.Request; TC_LOG_DEBUG("network", "WorldSession::HandleWhoOpcode: MinLevel: %u, MaxLevel: %u, Name: %s (VirtualRealmName: %s), Guild: %s (GuildVirtualRealmName: %s), RaceFilter: %d, ClassFilter: %d, Areas: " SZFMTD ", Words: " SZFMTD ".", request.MinLevel, request.MaxLevel, request.Name.c_str(), request.VirtualRealmName.c_str(), request.Guild.c_str(), request.GuildVirtualRealmName.c_str(), request.RaceFilter, request.ClassFilter, whoRequest.Areas.size(), request.Words.size()); // zones count, client limit = 10 (2.0.10) // can't be received from real client or broken packet if (whoRequest.Areas.size() > 10) return; // user entered strings count, client limit=4 (checked on 2.0.10) // can't be received from real client or broken packet if (request.Words.size() > 4) return; /// @todo: handle following packet values /// VirtualRealmNames /// ShowEnemies /// ShowArenaPlayers /// ExactName /// ServerInfo std::vector<std::wstring> wWords; wWords.resize(request.Words.size()); for (size_t i = 0; i < request.Words.size(); ++i) { TC_LOG_DEBUG("network", "WorldSession::HandleWhoOpcode: Word: %s", request.Words[i].Word.c_str()); // user entered string, it used as universal search pattern(guild+player name)? if (!Utf8toWStr(request.Words[i].Word, wWords[i])) continue; wstrToLower(wWords[i]); } std::wstring wPlayerName; std::wstring wGuildName; if (!(Utf8toWStr(request.Name, wPlayerName) && Utf8toWStr(request.Guild, wGuildName))) return; wstrToLower(wPlayerName); wstrToLower(wGuildName); // client send in case not set max level value 100 but Trinity supports 255 max level, // update it to show GMs with characters after 100 level if (whoRequest.Request.MaxLevel >= MAX_LEVEL) whoRequest.Request.MaxLevel = STRONG_MAX_LEVEL; uint32 team = _player->GetTeam(); uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST); WorldPackets::Who::WhoResponsePkt response; boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock()); HashMapHolder<Player>::MapType const& m = ObjectAccessor::GetPlayers(); for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) { Player* target = itr->second; // player can see member of other team only if has RBAC_PERM_TWO_SIDE_WHO_LIST if (target->GetTeam() != team && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_WHO_LIST)) continue; // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if has RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS if (target->GetSession()->GetSecurity() > AccountTypes(gmLevelInWhoList) && !HasPermission(rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS)) continue; // do not process players which are not in world if (!target->IsInWorld()) continue; // check if target is globally visible for player if (!target->IsVisibleGloballyFor(_player)) continue; // check if target's level is in level range uint8 lvl = target->getLevel(); if (lvl < request.MinLevel || lvl > request.MaxLevel) continue; // check if class matches classmask if (request.ClassFilter >= 0 && !(request.ClassFilter & (1 << target->getClass()))) continue; // check if race matches racemask if (request.RaceFilter >= 0 && !(request.RaceFilter & (1 << target->getRace()))) continue; if (!whoRequest.Areas.empty()) { if (std::find(whoRequest.Areas.begin(), whoRequest.Areas.end(), target->GetZoneId()) == whoRequest.Areas.end()) continue; } std::wstring wTargetName; if (!Utf8toWStr(target->GetName(), wTargetName)) continue; wstrToLower(wTargetName); if (!wPlayerName.empty() && wTargetName.find(wPlayerName) == std::wstring::npos) continue; Guild* targetGuild = target->GetGuild(); std::wstring wTargetGuildName; if (!Utf8toWStr(targetGuild ? targetGuild->GetName() : "", wTargetGuildName)) continue; wstrToLower(wTargetGuildName); if (!wGuildName.empty() && wTargetGuildName.find(wGuildName) == std::wstring::npos) continue; if (!wWords.empty()) { std::string aName; if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(target->GetZoneId())) aName = areaEntry->AreaName_lang; bool show = false; for (size_t i = 0; i < wWords.size(); ++i) { if (!wWords[i].empty()) { if (wTargetName.find(wWords[i]) != std::wstring::npos || wTargetGuildName.find(wWords[i]) != std::wstring::npos || Utf8FitTo(aName, wWords[i])) { show = true; break; } } } if (!show) continue; } WorldPackets::Who::WhoEntry whoEntry; if (!whoEntry.PlayerData.Initialize(target->GetGUID(), target)) continue; if (targetGuild) { whoEntry.GuildGUID = targetGuild->GetGUID(); whoEntry.GuildVirtualRealmAddress = GetVirtualRealmAddress(); whoEntry.GuildName = targetGuild->GetName(); } whoEntry.AreaID = target->GetZoneId(); whoEntry.IsGM = target->IsGameMaster(); response.Response.Entries.push_back(whoEntry); // 50 is maximum player count sent to client - can be overridden // through config, but is unstable if (response.Response.Entries.size() >= sWorld->getIntConfig(CONFIG_MAX_WHO)) break; } SendPacket(response.Write()); }