Core/Calendar: Implement different timezone support for ingame calendar

Closes #8390
Closes #29427
This commit is contained in:
Shauren
2023-11-21 12:25:22 +01:00
parent 8c072b93af
commit b888b1b09f
47 changed files with 1182 additions and 456 deletions
+1 -1
View File
@@ -29,7 +29,7 @@ else()
set(BOOST_REQUIRED_VERSION 1.71)
endif()
find_package(Boost ${BOOST_REQUIRED_VERSION} REQUIRED system filesystem program_options iostreams regex)
find_package(Boost ${BOOST_REQUIRED_VERSION} REQUIRED system filesystem program_options iostreams regex locale)
if(NOT Boost_FOUND)
if(NOT DEFINED ENV{BOOST_ROOT} AND NOT DEFINED Boost_DIR AND NOT DEFINED BOOST_ROOT AND NOT DEFINED BOOSTROOT)
+3 -1
View File
@@ -46,6 +46,7 @@ CREATE TABLE `account` (
`muteby` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`locale` tinyint unsigned NOT NULL DEFAULT '0',
`os` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`timezone_offset` smallint NOT NULL DEFAULT '0',
`recruiter` int unsigned NOT NULL DEFAULT '0',
`battlenet_account` int unsigned DEFAULT NULL,
`battlenet_index` tinyint unsigned DEFAULT NULL,
@@ -2760,7 +2761,8 @@ INSERT INTO `updates` VALUES
('2023_11_14_00_auth.sql','192D729737C5E3332D7B5B9B7F9DBDD9626D7B98','ARCHIVED','2023-11-14 11:36:05',0),
('2023_11_15_00_auth.sql','85CE6DCBE9391F0FB3819C7579067E2775D7C20E','ARCHIVED','2023-11-15 00:48:07',0),
('2023_11_15_01_auth.sql','622218EB74372055943D7B62AD30B52F959CC94B','ARCHIVED','2023-11-15 00:53:47',0),
('2023_11_16_00_auth.sql','2EF3FE83B74EFC10B8536E2EB6AFAE7074FC59BD','RELEASED','2023-11-16 23:19:09',0);
('2023_11_16_00_auth.sql','2EF3FE83B74EFC10B8536E2EB6AFAE7074FC59BD','RELEASED','2023-11-16 23:19:09',0),
('2023_11_21_00_auth.sql','146E5E6EF94C5DB78343372A8FDB32B062B80040','RELEASED','2023-11-21 11:24:11',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
@@ -0,0 +1 @@
ALTER TABLE `account` ADD `timezone_offset` smallint NOT NULL DEFAULT '0' AFTER `os`;
+179
View File
@@ -0,0 +1,179 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Timezone.h"
#include "Hash.h"
#include "MapUtils.h"
#include "Util.h"
#include <boost/locale/date_time_facet.hpp>
#include <boost/locale/generator.hpp>
#include <chrono>
#include <unordered_map>
namespace
{
std::unordered_map<uint32, Minutes, std::identity> InitTimezoneHashDb()
{
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
// Generate our hash db to match values sent in client authentication packets
std::unordered_map<uint32, Minutes, std::identity> hashToOffset;
std::chrono::system_clock::time_point dummmy;
for (std::chrono::time_zone const& zone : std::chrono::get_tzdb().zones)
{
std::chrono::sys_info sysInfo = zone.get_info(dummmy);
Minutes offsetMinutes = std::chrono::duration_cast<Minutes>(sysInfo.offset);
std::string offsetStr = Trinity::ToString(offsetMinutes.count());
hashToOffset.emplace(Trinity::HashFnv1a(offsetStr), offsetMinutes);
}
#else
// Pre-generated list of timezone offsets and their hashes for compilers (and their stl implementations) that dont support timezone api yet
std::unordered_map<uint32, Minutes, std::identity> hashToOffset =
{
{ 0xAADC2D37u, -720min },
{ 0x362F107Bu, -690min },
{ 0x2C44C70Cu, -660min },
{ 0xB84A209Eu, -640min },
{ 0xBA3D57D1u, -630min },
{ 0x4040695Au, -600min },
{ 0xB65A75D0u, -570min },
{ 0xC8614DEBu, -540min },
{ 0x3A68BD26u, -510min },
{ 0x51E8096Cu, -480min },
{ 0x4DD8F896u, -420min },
{ 0x674B7C0Fu, -360min },
{ 0x633C6B39u, -300min },
{ 0x0BAD340Au, -240min },
{ 0x74B25683u, -225min },
{ 0x09B9FCD7u, -210min },
{ 0x150C169Bu, -180min },
{ 0x191B2771u, -120min },
{ 0xD7D3B14Eu, -60min },
{ 0x47CE5170u, -44min },
{ 0x350CA8AFu, 0min },
{ 0x15E8E23Bu, 60min },
{ 0x733864AEu, 120min },
{ 0xF71F9C94u, 180min },
{ 0xBDE50F54u, 210min },
{ 0x2BDD6DB9u, 240min },
{ 0xB1E07F42u, 270min },
{ 0x454FF132u, 300min },
{ 0x3F4DA929u, 330min },
{ 0xD1554AC4u, 360min },
{ 0xBB667143u, 390min },
{ 0x9E2B78C9u, 420min },
{ 0x1C377816u, 450min },
{ 0x1A4440E3u, 480min },
{ 0xB49DF789u, 525min },
{ 0xC3A28C54u, 540min },
{ 0x35A9FB8Fu, 570min },
{ 0x889BD751u, 600min },
{ 0x8CAAE827u, 660min },
{ 0x7285EE60u, 690min },
{ 0x1CC2DEF4u, 720min },
{ 0x89B8FD2Fu, 765min },
{ 0x98DBA70Eu, 780min },
{ 0xC59585BBu, 840min }
};
#endif
return hashToOffset;
}
std::unordered_map<uint32, Minutes, std::identity> const _timezoneOffsetsByHash = InitTimezoneHashDb();
using ClientSupportedTimezone = std::pair<Minutes, std::string>;
std::array<ClientSupportedTimezone, 11> const _clientSupportedTimezones =
{{
{ -480min, "America/Los_Angeles" },
{ -420min, "America/Denver" },
{ -360min, "America/Chicago" },
{ -300min, "America/New_York" },
{ -180min, "America/Sao_Paulo" },
{ 0min, "Etc/UTC" },
{ 60min, "Europe/Paris" },
{ 480min, "Asia/Shanghai" },
{ 480min, "Asia/Taipei" },
{ 540min, "Asia/Seoul" },
{ 600min, "Australia/Melbourne" },
}};
}
namespace Trinity::Timezone
{
Minutes GetOffsetByHash(uint32 hash)
{
if (Minutes const* offset = Containers::MapGetValuePtr(_timezoneOffsetsByHash, hash))
return *offset;
return 0min;
}
Minutes GetSystemZoneOffsetAt(SystemTimePoint date)
{
Seconds offset;
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
offset = std::chrono::current_zone()->get_info(date).offset;
#else
tm buf = TimeBreakdown(std::chrono::system_clock::to_time_t(date));
offset = Seconds(buf.tm_gmtoff);
#endif
return std::chrono::duration_cast<Minutes>(offset);
}
Minutes GetSystemZoneOffset(bool applyDst /*= true*/)
{
std::chrono::system_clock::time_point date = std::chrono::system_clock::from_time_t(std::time_t(0));
if (applyDst)
date = std::chrono::system_clock::now();
return GetSystemZoneOffsetAt(date);
}
std::string GetSystemZoneName()
{
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
return std::string(std::chrono::current_zone()->name());
#else
static std::locale calendarLocale = boost::locale::generator().generate("");
std::unique_ptr<boost::locale::abstract_calendar> p(std::use_facet<class boost::locale::calendar_facet>(calendarLocale).create_calendar());
return p->get_timezone();
#endif
}
std::string_view FindClosestClientSupportedTimezone(std::string_view currentTimezone, Minutes currentTimezoneOffset)
{
// try exact match
auto itr = std::find_if(_clientSupportedTimezones.begin(), _clientSupportedTimezones.end(), [currentTimezone](ClientSupportedTimezone const& tz)
{
return tz.second == currentTimezone;
});
if (itr != _clientSupportedTimezones.end())
return itr->second;
// try closest offset
itr = std::min_element(_clientSupportedTimezones.begin(), _clientSupportedTimezones.end(), [currentTimezoneOffset](ClientSupportedTimezone const& left, ClientSupportedTimezone const& right)
{
Minutes leftDiff = left.first - currentTimezoneOffset;
Minutes rightDiff = right.first - currentTimezoneOffset;
return std::abs(leftDiff.count()) < std::abs(rightDiff.count());
});
return itr->second;
}
}
+37
View File
@@ -0,0 +1,37 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRINITYCORE_TIMEZONE_H
#define TRINITYCORE_TIMEZONE_H
#include "Define.h"
#include "Duration.h"
namespace Trinity::Timezone
{
TC_COMMON_API Minutes GetOffsetByHash(uint32 hash);
// Returns the time offset that must be added to UTC time to get localtime
TC_COMMON_API Minutes GetSystemZoneOffsetAt(SystemTimePoint date);
TC_COMMON_API Minutes GetSystemZoneOffset(bool applyDst = true);
TC_COMMON_API std::string GetSystemZoneName();
TC_COMMON_API std::string_view FindClosestClientSupportedTimezone(std::string_view currentTimezone, Minutes currentTimezoneOffset);
}
#endif // TRINITYCORE_TIMEZONE_H
+12
View File
@@ -19,6 +19,7 @@
#define TrinityCore_Hash_h__
#include <functional>
#include <string_view>
#include <utility>
namespace Trinity
@@ -28,6 +29,17 @@ namespace Trinity
{
seed ^= std::hash<T>()(val) + 0x9E3779B9 + (seed << 6) + (seed >> 2);
}
inline std::uint32_t HashFnv1a(std::string_view data)
{
std::uint32_t hash = 0x811C9DC5u;
for (char c : data)
{
hash ^= c;
hash *= 0x1000193u;
}
return hash;
}
}
//! Hash implementation for std::pair to allow using pairs in unordered_set or as key for unordered_map
+12 -12
View File
@@ -58,9 +58,20 @@ std::vector<std::string_view> Trinity::Tokenize(std::string_view str, char sep,
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
struct tm* localtime_r(time_t const* time, struct tm *result)
{
localtime_s(result, time);
if (localtime_s(result, time) != 0)
return nullptr;
return result;
}
struct tm* gmtime_r(time_t const* time, struct tm* result)
{
if (gmtime_s(result, time) != 0)
return nullptr;
return result;
}
time_t timegm(struct tm* tm)
{
return _mkgmtime(tm);
}
#endif
tm TimeBreakdown(time_t time)
@@ -70,17 +81,6 @@ tm TimeBreakdown(time_t time)
return timeLocal;
}
time_t LocalTimeToUTCTime(time_t time)
{
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
return time + _timezone;
#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
return timegm(gmtime(&time));
#else
return time + timezone;
#endif
}
time_t GetLocalHourTimestamp(time_t time, uint8 hour, bool onlyAfterTime)
{
tm timeLocal = TimeBreakdown(time);
+2 -1
View File
@@ -54,8 +54,9 @@ TC_COMMON_API Optional<int64> MoneyStringToMoney(std::string const& moneyString)
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
TC_COMMON_API struct tm* localtime_r(time_t const* time, struct tm *result);
TC_COMMON_API struct tm* gmtime_r(time_t const* time, struct tm *result);
TC_COMMON_API time_t timegm(struct tm* tm);
#endif
TC_COMMON_API time_t LocalTimeToUTCTime(time_t time);
TC_COMMON_API time_t GetLocalHourTimestamp(time_t time, uint8 hour, bool onlyAfterTime = true);
TC_COMMON_API tm TimeBreakdown(time_t t);
+28 -3
View File
@@ -21,13 +21,17 @@
#include "CryptoRandom.h"
#include "DatabaseEnv.h"
#include "Errors.h"
#include "Hash.h"
#include "IPLocation.h"
#include "QueryCallback.h"
#include "LoginRESTService.h"
#include "MapUtils.h"
#include "ProtobufJSON.h"
#include "QueryCallback.h"
#include "RealmList.h"
#include "ServiceDispatcher.h"
#include "RealmList.pb.h"
#include "ServiceDispatcher.h"
#include "Timezone.h"
#include <rapidjson/document.h>
#include <zlib.h>
void Battlenet::Session::AccountInfo::LoadResult(PreparedQueryResult result)
@@ -229,6 +233,26 @@ uint32 Battlenet::Session::HandleLogon(authentication::v1::LogonRequest const* l
_os = logonRequest->platform();
_build = logonRequest->application_version();
_timezoneOffset = [&]
{
if (!logonRequest->has_device_id())
return 0min;
rapidjson::Document doc;
doc.Parse(logonRequest->device_id());
if (doc.HasParseError())
return 0min;
auto itr = doc.FindMember("UTCO");
if (itr == doc.MemberEnd())
return 0min;
if (!itr->value.IsUint())
return 0min;
return Trinity::Timezone::GetOffsetByHash(itr->value.GetUint());
}();
if (logonRequest->has_cached_web_credentials())
return VerifyWebCredentials(logonRequest->cached_web_credentials(), continuation);
@@ -670,7 +694,8 @@ uint32 Battlenet::Session::GetRealmList(std::unordered_map<std::string, Variant
uint32 Battlenet::Session::JoinRealm(std::unordered_map<std::string, Variant const*> const& params, game_utilities::v1::ClientResponse* response)
{
if (Variant const* realmAddress = GetParam(params, "Param_RealmAddress"))
return sRealmList->JoinRealm(realmAddress->uint_value(), _build, GetRemoteIpAddress(), _clientSecret, GetLocaleByName(_locale), _os, _gameAccountInfo->Name, response);
return sRealmList->JoinRealm(realmAddress->uint_value(), _build, GetRemoteIpAddress(), _clientSecret, GetLocaleByName(_locale),
_os, _timezoneOffset, _gameAccountInfo->Name, response);
return ERROR_WOW_SERVICES_INVALID_JOIN_TICKET;
}
+2
View File
@@ -19,6 +19,7 @@
#define Session_h__
#include "AsyncCallbackProcessor.h"
#include "Duration.h"
#include "Realm.h"
#include "SslContext.h"
#include "SslSocket.h"
@@ -173,6 +174,7 @@ namespace Battlenet
std::string _locale;
std::string _os;
uint32 _build;
Minutes _timezoneOffset;
std::string _ipCountry;
@@ -39,7 +39,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_UPD_LOGON, "UPDATE account SET salt = ?, verifier = ? WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT a.id, a.session_key_bnet, ba.last_ip, ba.locked, ba.lock_country, a.expansion, a.mutetime, ba.locale, a.recruiter, a.os, ba.id, aa.SecurityLevel, "
PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT a.id, a.session_key_bnet, ba.last_ip, ba.locked, ba.lock_country, a.expansion, a.mutetime, ba.locale, a.recruiter, a.os, a.timezone_offset, ba.id, aa.SecurityLevel, "
"bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id "
"FROM account a LEFT JOIN account r ON a.id = r.recruiter LEFT JOIN battlenet_accounts ba ON a.battlenet_account = ba.id "
"LEFT JOIN account_access aa ON a.id = aa.AccountID AND aa.RealmID IN (-1, ?) LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 "
@@ -129,7 +129,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
" FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account a ON ba.id = a.battlenet_account"
" LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account_access aa ON a.id = aa.AccountID AND aa.RealmID = -1 WHERE ba.LoginTicket = ? ORDER BY a.id", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO, "UPDATE battlenet_accounts SET last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_BNET_GAME_ACCOUNT_LOGIN_INFO, "UPDATE account SET session_key_bnet = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_UPD_BNET_GAME_ACCOUNT_LOGIN_INFO, "UPDATE account SET session_key_bnet = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ?, timezone_offset = ? WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_ACCOUNT_ID, "SELECT rc.acctid, rc.numchars, r.id, r.Region, r.Battlegroup FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id WHERE rc.acctid = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID, "SELECT rc.acctid, rc.numchars, r.id, r.Region, r.Battlegroup FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id LEFT JOIN account a ON rc.acctid = a.id WHERE a.battlenet_account = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_BNET_LAST_PLAYER_CHARACTERS, "SELECT lpc.accountId, lpc.region, lpc.battlegroup, lpc.realmId, lpc.characterName, lpc.characterGUID, lpc.lastPlayedTime FROM account_last_played_character lpc LEFT JOIN account a ON lpc.accountId = a.id WHERE a.battlenet_account = ?", CONNECTION_ASYNC);
+87 -65
View File
@@ -377,42 +377,42 @@ void PlayerAchievementMgr::SendAllData(Player const* /*receiver*/) const
if (!achievement)
continue;
WorldPackets::Achievement::EarnedAchievement earned;
WorldPackets::Achievement::EarnedAchievement& earned = achievementData.Data.Earned.emplace_back();
earned.Id = completedAchievement.first;
earned.Date = completedAchievement.second.Date;
earned.Date.SetUtcTimeFromUnixTime(completedAchievement.second.Date);
earned.Date += _owner->GetSession()->GetTimezoneOffset();
if (!(achievement->Flags & ACHIEVEMENT_FLAG_ACCOUNT))
{
earned.Owner = _owner->GetGUID();
earned.VirtualRealmAddress = earned.NativeRealmAddress = GetVirtualRealmAddress();
}
achievementData.Data.Earned.push_back(earned);
}
for (std::pair<uint32 const, CriteriaProgress> const& criteriaProgres : _criteriaProgress)
{
Criteria const* criteria = sCriteriaMgr->GetCriteria(criteriaProgres.first);
WorldPackets::Achievement::CriteriaProgress progress;
WorldPackets::Achievement::CriteriaProgress& progress = achievementData.Data.Progress.emplace_back();
progress.Id = criteriaProgres.first;
progress.Quantity = criteriaProgres.second.Counter;
progress.Player = criteriaProgres.second.PlayerGUID;
progress.Flags = 0;
progress.Date = criteriaProgres.second.Date;
progress.Date.SetUtcTimeFromUnixTime(criteriaProgres.second.Date);
progress.Date += _owner->GetSession()->GetTimezoneOffset();
progress.TimeFromStart = Seconds::zero();
progress.TimeFromCreate = Seconds::zero();
achievementData.Data.Progress.push_back(progress);
if (criteria->FlagsCu & CRITERIA_FLAG_CU_ACCOUNT)
{
WorldPackets::Achievement::CriteriaProgress progress;
progress.Id = criteriaProgres.first;
progress.Quantity = criteriaProgres.second.Counter;
progress.Player = _owner->GetSession()->GetBattlenetAccountGUID();
progress.Flags = 0;
progress.Date = criteriaProgres.second.Date;
progress.TimeFromStart = Seconds::zero();
progress.TimeFromCreate = Seconds::zero();
allAccountCriteria.Progress.push_back(progress);
WorldPackets::Achievement::CriteriaProgress& accountProgress = allAccountCriteria.Progress.emplace_back();
accountProgress.Id = criteriaProgres.first;
accountProgress.Quantity = criteriaProgres.second.Counter;
accountProgress.Player = _owner->GetSession()->GetBattlenetAccountGUID();
accountProgress.Flags = 0;
accountProgress.Date.SetUtcTimeFromUnixTime(criteriaProgres.second.Date);
accountProgress.Date += _owner->GetSession()->GetTimezoneOffset();
accountProgress.TimeFromStart = Seconds::zero();
accountProgress.TimeFromCreate = Seconds::zero();
}
}
@@ -436,28 +436,28 @@ void PlayerAchievementMgr::SendAchievementInfo(Player* receiver, uint32 /*achiev
if (!achievement)
continue;
WorldPackets::Achievement::EarnedAchievement earned;
WorldPackets::Achievement::EarnedAchievement& earned = inspectedAchievements.Data.Earned.emplace_back();
earned.Id = completedAchievement.first;
earned.Date = completedAchievement.second.Date;
earned.Date.SetUtcTimeFromUnixTime(completedAchievement.second.Date);
earned.Date += receiver->GetSession()->GetTimezoneOffset();
if (!(achievement->Flags & ACHIEVEMENT_FLAG_ACCOUNT))
{
earned.Owner = _owner->GetGUID();
earned.VirtualRealmAddress = earned.NativeRealmAddress = GetVirtualRealmAddress();
}
inspectedAchievements.Data.Earned.push_back(earned);
}
for (std::pair<uint32 const, CriteriaProgress> const& criteriaProgres : _criteriaProgress)
{
WorldPackets::Achievement::CriteriaProgress progress;
WorldPackets::Achievement::CriteriaProgress& progress = inspectedAchievements.Data.Progress.emplace_back();
progress.Id = criteriaProgres.first;
progress.Quantity = criteriaProgres.second.Counter;
progress.Player = criteriaProgres.second.PlayerGUID;
progress.Flags = 0;
progress.Date = criteriaProgres.second.Date;
progress.Date.SetUtcTimeFromUnixTime(criteriaProgres.second.Date);
progress.Date += receiver->GetSession()->GetTimezoneOffset();
progress.TimeFromStart = Seconds::zero();
progress.TimeFromCreate = Seconds::zero();
inspectedAchievements.Data.Progress.push_back(progress);
}
receiver->SendDirectMessage(inspectedAchievements.Write());
@@ -578,7 +578,8 @@ void PlayerAchievementMgr::SendCriteriaUpdate(Criteria const* criteria, Criteria
if (criteria->Entry->StartTimer)
criteriaUpdate.Progress.Flags = timedCompleted ? 1 : 0; // 1 is for keeping the counter at 0 in client
criteriaUpdate.Progress.Date = progress->Date;
criteriaUpdate.Progress.Date.SetUtcTimeFromUnixTime(progress->Date);
criteriaUpdate.Progress.Date += _owner->GetSession()->GetTimezoneOffset();
criteriaUpdate.Progress.TimeFromStart = timeElapsed;
criteriaUpdate.Progress.TimeFromCreate = Seconds::zero();
@@ -595,7 +596,8 @@ void PlayerAchievementMgr::SendCriteriaUpdate(Criteria const* criteria, Criteria
if (criteria->Entry->StartTimer)
criteriaUpdate.Flags = timedCompleted ? 1 : 0; // 1 is for keeping the counter at 0 in client
criteriaUpdate.CurrentTime = progress->Date;
criteriaUpdate.CurrentTime.SetUtcTimeFromUnixTime(progress->Date);
criteriaUpdate.CurrentTime += _owner->GetSession()->GetTimezoneOffset();
criteriaUpdate.ElapsedTime = timeElapsed;
criteriaUpdate.CreationTime = 0;
@@ -646,16 +648,26 @@ void PlayerAchievementMgr::SendAchievementEarned(AchievementEntry const* achieve
}
}
WorldPackets::Achievement::AchievementEarned achievementEarned;
achievementEarned.Sender = _owner->GetGUID();
achievementEarned.Earner = _owner->GetGUID();
achievementEarned.EarnerNativeRealm = achievementEarned.EarnerVirtualRealm = GetVirtualRealmAddress();
achievementEarned.AchievementID = achievement->ID;
achievementEarned.Time = GameTime::GetGameTime();
auto achievementEarnedBuilder = [&](Player const* receiver)
{
WorldPackets::Achievement::AchievementEarned achievementEarned;
achievementEarned.Sender = _owner->GetGUID();
achievementEarned.Earner = _owner->GetGUID();
achievementEarned.EarnerNativeRealm = achievementEarned.EarnerVirtualRealm = GetVirtualRealmAddress();
achievementEarned.AchievementID = achievement->ID;
achievementEarned.Time = *GameTime::GetUtcWowTime();
achievementEarned.Time += receiver->GetSession()->GetTimezoneOffset();
receiver->SendDirectMessage(achievementEarned.Write());
};
if (!(achievement->Flags & ACHIEVEMENT_FLAG_TRACKING_FLAG))
_owner->SendMessageToSetInRange(achievementEarned.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true);
{
float dist = sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY);
Trinity::MessageDistDeliverer notifier(_owner, achievementEarnedBuilder, dist);
Cell::VisitWorldObjects(_owner, notifier, dist);
}
else
_owner->SendDirectMessage(achievementEarned.Write());
achievementEarnedBuilder(_owner);
}
void PlayerAchievementMgr::SendPacket(WorldPacket const* data) const
@@ -679,11 +691,16 @@ void GuildAchievementMgr::Reset()
ObjectGuid guid = _owner->GetGUID();
for (std::pair<uint32 const, CompletedAchievementData> const& completedAchievement : _completedAchievements)
{
WorldPackets::Achievement::GuildAchievementDeleted guildAchievementDeleted;
guildAchievementDeleted.AchievementID = completedAchievement.first;
guildAchievementDeleted.GuildGUID = guid;
guildAchievementDeleted.TimeDeleted = GameTime::GetGameTime();
SendPacket(guildAchievementDeleted.Write());
auto packetBuilder = [&](Player const* receiver)
{
WorldPackets::Achievement::GuildAchievementDeleted guildAchievementDeleted;
guildAchievementDeleted.AchievementID = completedAchievement.first;
guildAchievementDeleted.GuildGUID = guid;
guildAchievementDeleted.TimeDeleted = *GameTime::GetUtcWowTime();
guildAchievementDeleted.TimeDeleted += receiver->GetSession()->GetTimezoneOffset();
receiver->SendDirectMessage(guildAchievementDeleted.Write());
};
_owner->BroadcastWorker(packetBuilder);
}
_achievementPoints = 0;
@@ -830,10 +847,10 @@ void GuildAchievementMgr::SendAllData(Player const* receiver) const
if (!achievement)
continue;
WorldPackets::Achievement::EarnedAchievement earned;
WorldPackets::Achievement::EarnedAchievement& earned = allGuildAchievements.Earned.emplace_back();
earned.Id = completedAchievement.first;
earned.Date = completedAchievement.second.Date;
allGuildAchievements.Earned.push_back(earned);
earned.Date.SetUtcTimeFromUnixTime(completedAchievement.second.Date);
earned.Date += receiver->GetSession()->GetTimezoneOffset();
}
receiver->SendDirectMessage(allGuildAchievements.Write());
@@ -846,23 +863,22 @@ void GuildAchievementMgr::SendAchievementInfo(Player* receiver, uint32 achieveme
{
if (CriteriaTree const* tree = sCriteriaMgr->GetCriteriaTree(achievement->CriteriaTree))
{
CriteriaMgr::WalkCriteriaTree(tree, [this, &guildCriteriaUpdate](CriteriaTree const* node)
CriteriaMgr::WalkCriteriaTree(tree, [this, &guildCriteriaUpdate, receiver](CriteriaTree const* node)
{
if (node->Criteria)
{
auto progress = this->_criteriaProgress.find(node->Criteria->ID);
if (progress != this->_criteriaProgress.end())
{
WorldPackets::Achievement::GuildCriteriaProgress guildCriteriaProgress;
WorldPackets::Achievement::GuildCriteriaProgress& guildCriteriaProgress = guildCriteriaUpdate.Progress.emplace_back();
guildCriteriaProgress.CriteriaID = node->Criteria->ID;
guildCriteriaProgress.DateCreated = 0;
guildCriteriaProgress.DateStarted = 0;
guildCriteriaProgress.DateUpdated = progress->second.Date;
guildCriteriaProgress.DateUpdated.SetUtcTimeFromUnixTime(progress->second.Date);
guildCriteriaProgress.DateUpdated += receiver->GetSession()->GetTimezoneOffset();
guildCriteriaProgress.Quantity = progress->second.Counter;
guildCriteriaProgress.PlayerGUID = progress->second.PlayerGUID;
guildCriteriaProgress.Flags = 0;
guildCriteriaUpdate.Progress.push_back(guildCriteriaProgress);
}
}
});
@@ -883,16 +899,15 @@ void GuildAchievementMgr::SendAllTrackedCriterias(Player* receiver, std::set<uin
if (progress == _criteriaProgress.end())
continue;
WorldPackets::Achievement::GuildCriteriaProgress guildCriteriaProgress;
WorldPackets::Achievement::GuildCriteriaProgress& guildCriteriaProgress = guildCriteriaUpdate.Progress.emplace_back();
guildCriteriaProgress.CriteriaID = criteriaId;
guildCriteriaProgress.DateCreated = 0;
guildCriteriaProgress.DateStarted = 0;
guildCriteriaProgress.DateUpdated = progress->second.Date;
guildCriteriaProgress.DateUpdated.SetUtcTimeFromUnixTime(progress->second.Date);
guildCriteriaProgress.DateUpdated += receiver->GetSession()->GetTimezoneOffset();
guildCriteriaProgress.Quantity = progress->second.Counter;
guildCriteriaProgress.PlayerGUID = progress->second.PlayerGUID;
guildCriteriaProgress.Flags = 0;
guildCriteriaUpdate.Progress.push_back(guildCriteriaProgress);
}
receiver->SendDirectMessage(guildCriteriaUpdate.Write());
@@ -956,19 +971,21 @@ void GuildAchievementMgr::CompletedAchievement(AchievementEntry const* achieveme
void GuildAchievementMgr::SendCriteriaUpdate(Criteria const* entry, CriteriaProgress const* progress, Seconds /*timeElapsed*/, bool /*timedCompleted*/) const
{
WorldPackets::Achievement::GuildCriteriaUpdate guildCriteriaUpdate;
guildCriteriaUpdate.Progress.resize(1);
for (Player const* member : _owner->GetMembersTrackingCriteria(entry->ID))
{
WorldPackets::Achievement::GuildCriteriaUpdate guildCriteriaUpdate;
WorldPackets::Achievement::GuildCriteriaProgress& guildCriteriaProgress = guildCriteriaUpdate.Progress.emplace_back();
guildCriteriaProgress.CriteriaID = entry->ID;
guildCriteriaProgress.DateCreated = 0;
guildCriteriaProgress.DateStarted = 0;
guildCriteriaProgress.DateUpdated.SetUtcTimeFromUnixTime(progress->Date);
guildCriteriaProgress.DateUpdated += member->GetSession()->GetTimezoneOffset();
guildCriteriaProgress.Quantity = progress->Counter;
guildCriteriaProgress.PlayerGUID = progress->PlayerGUID;
guildCriteriaProgress.Flags = 0;
WorldPackets::Achievement::GuildCriteriaProgress& guildCriteriaProgress = guildCriteriaUpdate.Progress[0];
guildCriteriaProgress.CriteriaID = entry->ID;
guildCriteriaProgress.DateCreated = 0;
guildCriteriaProgress.DateStarted = 0;
guildCriteriaProgress.DateUpdated = progress->Date;
guildCriteriaProgress.Quantity = progress->Counter;
guildCriteriaProgress.PlayerGUID = progress->PlayerGUID;
guildCriteriaProgress.Flags = 0;
_owner->BroadcastPacketIfTrackingAchievement(guildCriteriaUpdate.Write(), entry->ID);
member->SendDirectMessage(guildCriteriaUpdate.Write());
}
}
void GuildAchievementMgr::SendCriteriaProgressRemoved(uint32 criteriaId)
@@ -992,11 +1009,16 @@ void GuildAchievementMgr::SendAchievementEarned(AchievementEntry const* achievem
sWorld->SendGlobalMessage(serverFirstAchievement.Write());
}
WorldPackets::Achievement::GuildAchievementEarned guildAchievementEarned;
guildAchievementEarned.AchievementID = achievement->ID;
guildAchievementEarned.GuildGUID = _owner->GetGUID();
guildAchievementEarned.TimeEarned = GameTime::GetGameTime();
SendPacket(guildAchievementEarned.Write());
auto guildAchievementEarnedBuilder = [&](Player const* receiver)
{
WorldPackets::Achievement::GuildAchievementEarned guildAchievementEarned;
guildAchievementEarned.AchievementID = achievement->ID;
guildAchievementEarned.GuildGUID = _owner->GetGUID();
guildAchievementEarned.TimeEarned = *GameTime::GetUtcWowTime();
guildAchievementEarned.TimeEarned += receiver->GetSession()->GetTimezoneOffset();
receiver->SendDirectMessage(guildAchievementEarned.Write());
};
_owner->BroadcastWorker(guildAchievementEarnedBuilder);
}
void GuildAchievementMgr::SendPacket(WorldPacket const* data) const
@@ -51,6 +51,7 @@
#include "World.h"
#include "WorldSession.h"
#include "WorldStateMgr.h"
#include "WowTime.h"
bool CriteriaData::IsValid(Criteria const* criteria)
{
@@ -2242,14 +2243,12 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
break;
case ModifierTreeType::TimeBetween: // 109
{
ByteBuffer unpacker;
unpacker << reqValue;
time_t from = unpacker.ReadPackedTime();
unpacker.rpos(0);
unpacker.wpos(0);
unpacker << secondaryAsset;
time_t to = unpacker.ReadPackedTime();
if (GameTime::GetGameTime() < from || GameTime::GetGameTime() > to)
WowTime from;
from.SetPackedTime(reqValue);
WowTime to;
to.SetPackedTime(secondaryAsset);
if (!GameTime::GetWowTime()->IsInRange(from, to))
return false;
break;
}
@@ -34,11 +34,11 @@
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "Realm.h"
#include "ScriptMgr.h"
#include "Timezone.h"
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "WowTime.h"
#include <boost/dynamic_bitset.hpp>
#include <numeric>
#include <sstream>
@@ -1916,13 +1916,13 @@ void AuctionHouseObject::SendAuctionInvoice(AuctionPosting const* auction, Playe
// owner exist (online or offline)
if ((owner || sCharacterCache->HasCharacterCacheEntry(auction->Owner)) && !sAuctionBotConfig->IsBotChar(auction->Owner))
{
ByteBuffer tempBuffer;
tempBuffer.AppendPackedTime(GameTime::GetGameTime() + sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY));
uint32 eta = tempBuffer.read<uint32>();
WowTime eta = *GameTime::GetUtcWowTime();
eta += Seconds(sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY));
eta += owner->GetSession()->GetTimezoneOffset();
MailDraft(AuctionHouseMgr::BuildItemAuctionMailSubject(AuctionMailType::Invoice, auction),
AuctionHouseMgr::BuildAuctionInvoiceMailBody(auction->Bidder, auction->BidAmount, auction->BuyoutOrUnitPrice, auction->Deposit,
CalculateAuctionHouseCut(auction->BidAmount), sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY), eta))
CalculateAuctionHouseCut(auction->BidAmount), sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY), eta.GetPackedTime()))
.SendMailTo(trans, MailReceiver(owner, auction->Owner), this, MAIL_CHECK_MASK_COPIED);
}
}
+177 -108
View File
@@ -24,12 +24,16 @@
#include "GuildMgr.h"
#include "Log.h"
#include "Mail.h"
#include "MapUtils.h"
#include "ObjectAccessor.h"
#include "Player.h"
#include "StringConvert.h"
#include "WorldSession.h"
#include "WowTime.h"
#include <sstream>
CalendarInvite::CalendarInvite() : _inviteId(1), _eventId(0), _invitee(), _senderGUID(), _responseTime(0),
_status(CALENDAR_STATUS_INVITED), _rank(CALENDAR_RANK_PLAYER), _note("") { }
_status(CALENDAR_STATUS_INVITED), _rank(CALENDAR_RANK_PLAYER), _note() { }
CalendarInvite::~CalendarInvite()
{
@@ -184,7 +188,6 @@ void CalendarMgr::RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover)
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabasePreparedStatement* stmt;
MailDraft mail(calendarEvent->BuildCalendarMailSubject(remover), calendarEvent->BuildCalendarMailBody());
CalendarInviteStore& eventInvites = _invites[calendarEvent->GetEventId()];
for (size_t i = 0; i < eventInvites.size(); ++i)
@@ -197,7 +200,10 @@ void CalendarMgr::RemoveEvent(CalendarEvent* calendarEvent, ObjectGuid remover)
// guild events only? check invite status here?
// When an event is deleted, all invited (accepted/declined? - verify) guildies are notified via in-game mail. (wowwiki)
if (!remover.IsEmpty() && invite->GetInviteeGUID() != remover)
{
MailDraft mail(calendarEvent->BuildCalendarMailSubject(remover), calendarEvent->BuildCalendarMailBody(ObjectAccessor::FindConnectedPlayer(invite->GetInviteeGUID())));
mail.SendMailTo(trans, MailReceiver(invite->GetInviteeGUID().GetCounter()), calendarEvent, MAIL_CHECK_MASK_COPIED);
}
delete invite;
}
@@ -375,7 +381,7 @@ void CalendarMgr::DeleteOldEvents()
}
}
CalendarEventStore CalendarMgr::GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents)
CalendarEventStore CalendarMgr::GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents) const
{
CalendarEventStore result;
for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr)
@@ -385,7 +391,7 @@ CalendarEventStore CalendarMgr::GetEventsCreatedBy(ObjectGuid guid, bool include
return result;
}
CalendarEventStore CalendarMgr::GetGuildEvents(ObjectGuid::LowType guildId)
CalendarEventStore CalendarMgr::GetGuildEvents(ObjectGuid::LowType guildId) const
{
CalendarEventStore result;
@@ -400,7 +406,7 @@ CalendarEventStore CalendarMgr::GetGuildEvents(ObjectGuid::LowType guildId)
return result;
}
CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid)
CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid) const
{
CalendarEventStore events;
@@ -419,12 +425,16 @@ CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid)
return events;
}
CalendarInviteStore const& CalendarMgr::GetEventInvites(uint64 eventId)
CalendarInviteStore CalendarMgr::GetEventInvites(uint64 eventId) const
{
return _invites[eventId];
CalendarInviteStore invites;
if (CalendarInviteStore const* invitesStore = Trinity::Containers::MapGetValuePtr(_invites, eventId))
invites = *invitesStore;
return invites;
}
CalendarInviteStore CalendarMgr::GetPlayerInvites(ObjectGuid guid)
CalendarInviteStore CalendarMgr::GetPlayerInvites(ObjectGuid guid) const
{
CalendarInviteStore invites;
@@ -465,20 +475,17 @@ std::string CalendarEvent::BuildCalendarMailSubject(ObjectGuid remover) const
return strm.str();
}
std::string CalendarEvent::BuildCalendarMailBody() const
std::string CalendarEvent::BuildCalendarMailBody(Player const* invitee) const
{
WorldPacket data;
uint32 time;
std::ostringstream strm;
WowTime time;
time.SetUtcTimeFromUnixTime(_date);
if (invitee)
time += invitee->GetSession()->GetTimezoneOffset();
// we are supposed to send PackedTime so i used WorldPacket to pack it
data.AppendPackedTime(_date);
data >> time;
strm << time;
return strm.str();
return Trinity::ToString(time.GetPackedTime());
}
void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite)
void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite) const
{
CalendarEvent* calendarEvent = GetEvent(invite.GetEventId());
@@ -487,71 +494,103 @@ void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite)
uint8 level = player ? player->GetLevel() : sCharacterCache->GetCharacterLevelByGuid(invitee);
WorldPackets::Calendar::CalendarInviteAdded packet;
packet.EventID = calendarEvent ? calendarEvent->GetEventId() : 0;
packet.InviteGuid = invitee;
packet.InviteID = calendarEvent ? invite.GetInviteId() : 0;
packet.Level = level;
packet.ResponseTime = invite.GetResponseTime();
packet.Status = invite.GetStatus();
packet.Type = calendarEvent ? calendarEvent->IsGuildEvent() : 0; // Correct ?
packet.ClearPending = calendarEvent ? !calendarEvent->IsGuildEvent() : true; // Correct ?
auto packetBuilder = [&](Player const* receiver)
{
WorldPackets::Calendar::CalendarInviteAdded packet;
packet.EventID = calendarEvent ? calendarEvent->GetEventId() : 0;
packet.InviteGuid = invitee;
packet.InviteID = calendarEvent ? invite.GetInviteId() : 0;
packet.Level = level;
packet.ResponseTime.SetUtcTimeFromUnixTime(invite.GetResponseTime());
packet.ResponseTime += receiver->GetSession()->GetTimezoneOffset();
packet.Status = invite.GetStatus();
packet.Type = calendarEvent ? calendarEvent->IsGuildEvent() : 0; // Correct ?
packet.ClearPending = calendarEvent ? !calendarEvent->IsGuildEvent() : true; // Correct ?
receiver->SendDirectMessage(packet.Write());
};
if (!calendarEvent) // Pre-invite
{
if (Player* playerSender = ObjectAccessor::FindConnectedPlayer(invite.GetSenderGUID()))
playerSender->SendDirectMessage(packet.Write());
packetBuilder(playerSender);
}
else
{
if (calendarEvent->GetOwnerGUID() != invite.GetInviteeGUID()) // correct?
SendPacketToAllEventRelatives(packet.Write(), *calendarEvent);
for (Player* receiver : GetAllEventRelatives(*calendarEvent))
packetBuilder(receiver);
}
}
void CalendarMgr::SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, time_t originalDate)
void CalendarMgr::SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, time_t originalDate) const
{
WorldPackets::Calendar::CalendarEventUpdatedAlert packet;
packet.ClearPending = true; // FIXME
packet.Date = calendarEvent.GetDate();
packet.Description = calendarEvent.GetDescription();
packet.EventClubID = calendarEvent.GetGuildId();
packet.EventID = calendarEvent.GetEventId();
packet.EventName = calendarEvent.GetTitle();
packet.EventType = calendarEvent.GetType();
packet.Flags = calendarEvent.GetFlags();
packet.LockDate = calendarEvent.GetLockDate(); // Always 0 ?
packet.OriginalDate = originalDate;
packet.TextureID = calendarEvent.GetTextureId();
auto packetBuilder = [&](Player const* receiver)
{
WorldPackets::Calendar::CalendarEventUpdatedAlert packet;
packet.ClearPending = true; // FIXME
packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
packet.Date += receiver->GetSession()->GetTimezoneOffset();
packet.Description = calendarEvent.GetDescription();
packet.EventClubID = calendarEvent.GetGuildId();
packet.EventID = calendarEvent.GetEventId();
packet.EventName = calendarEvent.GetTitle();
packet.EventType = calendarEvent.GetType();
packet.Flags = calendarEvent.GetFlags();
packet.LockDate.SetUtcTimeFromUnixTime(calendarEvent.GetLockDate()); // Always 0 ?
if (calendarEvent.GetLockDate())
packet.LockDate += receiver->GetSession()->GetTimezoneOffset();
packet.OriginalDate.SetUtcTimeFromUnixTime(originalDate);
packet.OriginalDate += receiver->GetSession()->GetTimezoneOffset();
packet.TextureID = calendarEvent.GetTextureId();
SendPacketToAllEventRelatives(packet.Write(), calendarEvent);
receiver->SendDirectMessage(packet.Write());
};
for (Player* receiver : GetAllEventRelatives(calendarEvent))
packetBuilder(receiver);
}
void CalendarMgr::SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite)
void CalendarMgr::SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const
{
WorldPackets::Calendar::CalendarInviteStatus packet;
packet.ClearPending = true; // FIXME
packet.Date = calendarEvent.GetDate();
packet.EventID = calendarEvent.GetEventId();
packet.Flags = calendarEvent.GetFlags();
packet.InviteGuid = invite.GetInviteeGUID();
packet.ResponseTime = invite.GetResponseTime();
packet.Status = invite.GetStatus();
auto packetBuilder = [&](Player const* receiver)
{
WorldPackets::Calendar::CalendarInviteStatus packet;
packet.ClearPending = true; // FIXME
packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
packet.Date += receiver->GetSession()->GetTimezoneOffset();
packet.EventID = calendarEvent.GetEventId();
packet.Flags = calendarEvent.GetFlags();
packet.InviteGuid = invite.GetInviteeGUID();
packet.ResponseTime.SetUtcTimeFromUnixTime(invite.GetResponseTime());
packet.ResponseTime += receiver->GetSession()->GetTimezoneOffset();
packet.Status = invite.GetStatus();
SendPacketToAllEventRelatives(packet.Write(), calendarEvent);
receiver->SendDirectMessage(packet.Write());
};
for (Player* receiver : GetAllEventRelatives(calendarEvent))
packetBuilder(receiver);
}
void CalendarMgr::SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent)
void CalendarMgr::SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent) const
{
WorldPackets::Calendar::CalendarEventRemovedAlert packet;
packet.ClearPending = true; // FIXME
packet.Date = calendarEvent.GetDate();
packet.EventID = calendarEvent.GetEventId();
auto packetBuilder = [&](Player const* receiver)
{
WorldPackets::Calendar::CalendarEventRemovedAlert packet;
packet.ClearPending = true; // FIXME
packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
packet.Date += receiver->GetSession()->GetTimezoneOffset();
packet.EventID = calendarEvent.GetEventId();
SendPacketToAllEventRelatives(packet.Write(), calendarEvent);
receiver->SendDirectMessage(packet.Write());
};
for (Player* receiver : GetAllEventRelatives(calendarEvent))
packetBuilder(receiver);
}
void CalendarMgr::SendCalendarEventInviteRemove(CalendarEvent const& calendarEvent, CalendarInvite const& invite, uint32 flags)
void CalendarMgr::SendCalendarEventInviteRemove(CalendarEvent const& calendarEvent, CalendarInvite const& invite, uint32 flags) const
{
WorldPackets::Calendar::CalendarInviteRemoved packet;
packet.ClearPending = true; // FIXME
@@ -562,7 +601,7 @@ void CalendarMgr::SendCalendarEventInviteRemove(CalendarEvent const& calendarEve
SendPacketToAllEventRelatives(packet.Write(), calendarEvent);
}
void CalendarMgr::SendCalendarEventModeratorStatusAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite)
void CalendarMgr::SendCalendarEventModeratorStatusAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const
{
WorldPackets::Calendar::CalendarModeratorStatus packet;
packet.ClearPending = true; // FIXME
@@ -573,82 +612,94 @@ void CalendarMgr::SendCalendarEventModeratorStatusAlert(CalendarEvent const& cal
SendPacketToAllEventRelatives(packet.Write(), calendarEvent);
}
void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite)
void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const
{
WorldPackets::Calendar::CalendarInviteAlert packet;
packet.Date = calendarEvent.GetDate();
packet.EventID = calendarEvent.GetEventId();
packet.EventName = calendarEvent.GetTitle();
packet.EventType = calendarEvent.GetType();
packet.Flags = calendarEvent.GetFlags();
packet.InviteID = invite.GetInviteId();
packet.InvitedByGuid = invite.GetSenderGUID();
packet.ModeratorStatus = invite.GetRank();
packet.OwnerGuid = calendarEvent.GetOwnerGUID();
packet.Status = invite.GetStatus();
packet.TextureID = calendarEvent.GetTextureId();
packet.EventClubID = calendarEvent.GetGuildId();
auto packetBuilder = [&](Player const* receiver)
{
WorldPackets::Calendar::CalendarInviteAlert packet;
packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
packet.Date += receiver->GetSession()->GetTimezoneOffset();
packet.EventID = calendarEvent.GetEventId();
packet.EventName = calendarEvent.GetTitle();
packet.EventType = calendarEvent.GetType();
packet.Flags = calendarEvent.GetFlags();
packet.InviteID = invite.GetInviteId();
packet.InvitedByGuid = invite.GetSenderGUID();
packet.ModeratorStatus = invite.GetRank();
packet.OwnerGuid = calendarEvent.GetOwnerGUID();
packet.Status = invite.GetStatus();
packet.TextureID = calendarEvent.GetTextureId();
packet.EventClubID = calendarEvent.GetGuildId();
receiver->SendDirectMessage(packet.Write());
};
if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement())
{
if (Guild* guild = sGuildMgr->GetGuildById(calendarEvent.GetGuildId()))
guild->BroadcastPacket(packet.Write());
guild->BroadcastWorker(packetBuilder);
}
else if (Player* player = ObjectAccessor::FindConnectedPlayer(invite.GetInviteeGUID()))
player->SendDirectMessage(packet.Write());
packetBuilder(player);
}
void CalendarMgr::SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType)
void CalendarMgr::SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType) const
{
Player* player = ObjectAccessor::FindConnectedPlayer(guid);
if (!player)
return;
CalendarInviteStore const& eventInviteeList = _invites[calendarEvent.GetEventId()];
WorldPackets::Calendar::CalendarSendEvent packet;
packet.Date = calendarEvent.GetDate();
packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
packet.Date += player->GetSession()->GetTimezoneOffset();
packet.Description = calendarEvent.GetDescription();
packet.EventID = calendarEvent.GetEventId();
packet.EventName = calendarEvent.GetTitle();
packet.EventType = sendType;
packet.Flags = calendarEvent.GetFlags();
packet.GetEventType = calendarEvent.GetType();
packet.LockDate = calendarEvent.GetLockDate(); // Always 0 ?
packet.LockDate.SetUtcTimeFromUnixTime(calendarEvent.GetLockDate()); // Always 0 ?
if (calendarEvent.GetLockDate())
packet.LockDate += player->GetSession()->GetTimezoneOffset();
packet.OwnerGuid = calendarEvent.GetOwnerGUID();
packet.TextureID = calendarEvent.GetTextureId();
packet.EventClubID = calendarEvent.GetGuildId();
for (auto const& calendarInvite : eventInviteeList)
if (CalendarInviteStore const* eventInviteeList = Trinity::Containers::MapGetValuePtr(_invites, calendarEvent.GetEventId()))
{
ObjectGuid inviteeGuid = calendarInvite->GetInviteeGUID();
Player* invitee = ObjectAccessor::FindPlayer(inviteeGuid);
for (CalendarInvite const* calendarInvite : *eventInviteeList)
{
ObjectGuid inviteeGuid = calendarInvite->GetInviteeGUID();
Player* invitee = ObjectAccessor::FindPlayer(inviteeGuid);
uint8 inviteeLevel = invitee ? invitee->GetLevel() : sCharacterCache->GetCharacterLevelByGuid(inviteeGuid);
ObjectGuid::LowType inviteeGuildId = invitee ? invitee->GetGuildId() : sCharacterCache->GetCharacterGuildIdByGuid(inviteeGuid);
uint8 inviteeLevel = invitee ? invitee->GetLevel() : sCharacterCache->GetCharacterLevelByGuid(inviteeGuid);
ObjectGuid::LowType inviteeGuildId = invitee ? invitee->GetGuildId() : sCharacterCache->GetCharacterGuildIdByGuid(inviteeGuid);
WorldPackets::Calendar::CalendarEventInviteInfo inviteInfo;
inviteInfo.Guid = inviteeGuid;
inviteInfo.Level = inviteeLevel;
inviteInfo.Status = calendarInvite->GetStatus();
inviteInfo.Moderator = calendarInvite->GetRank();
inviteInfo.InviteType = calendarEvent.IsGuildEvent() && calendarEvent.GetGuildId() == inviteeGuildId;
inviteInfo.InviteID = calendarInvite->GetInviteId();
inviteInfo.ResponseTime = calendarInvite->GetResponseTime();
inviteInfo.Notes = calendarInvite->GetNote();
WorldPackets::Calendar::CalendarEventInviteInfo inviteInfo;
inviteInfo.Guid = inviteeGuid;
inviteInfo.Level = inviteeLevel;
inviteInfo.Status = calendarInvite->GetStatus();
inviteInfo.Moderator = calendarInvite->GetRank();
inviteInfo.InviteType = calendarEvent.IsGuildEvent() && calendarEvent.GetGuildId() == inviteeGuildId;
inviteInfo.InviteID = calendarInvite->GetInviteId();
inviteInfo.ResponseTime.SetUtcTimeFromUnixTime(calendarInvite->GetResponseTime());
inviteInfo.ResponseTime += player->GetSession()->GetTimezoneOffset();
inviteInfo.Notes = calendarInvite->GetNote();
packet.Invites.push_back(inviteInfo);
packet.Invites.push_back(inviteInfo);
}
}
player->SendDirectMessage(packet.Write());
}
void CalendarMgr::SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status)
void CalendarMgr::SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status) const
{
if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
WorldPackets::Calendar::CalendarInviteRemovedAlert packet;
packet.Date = calendarEvent.GetDate();
packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
packet.Date += player->GetSession()->GetTimezoneOffset();
packet.EventID = calendarEvent.GetEventId();
packet.Flags = calendarEvent.GetFlags();
packet.Status = status;
@@ -657,13 +708,13 @@ void CalendarMgr::SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEv
}
}
void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid)
void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid) const
{
if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
player->SendDirectMessage(WorldPackets::Calendar::CalendarClearPendingAction().Write());
}
void CalendarMgr::SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param /*= nullptr*/)
void CalendarMgr::SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param /*= nullptr*/) const
{
if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
{
@@ -686,17 +737,35 @@ void CalendarMgr::SendCalendarCommandResult(ObjectGuid guid, CalendarError err,
}
}
void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket const* packet, CalendarEvent const& calendarEvent)
void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket const* packet, CalendarEvent const& calendarEvent) const
{
for (Player* player : GetAllEventRelatives(calendarEvent))
player->SendDirectMessage(packet);
}
std::vector<Player*> CalendarMgr::GetAllEventRelatives(CalendarEvent const& calendarEvent) const
{
std::vector<Player*> relatedPlayers;
// Send packet to all guild members
if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement())
{
if (Guild* guild = sGuildMgr->GetGuildById(calendarEvent.GetGuildId()))
guild->BroadcastPacket(packet);
{
auto memberCollector = [&](Player* player) { relatedPlayers.push_back(player); };
guild->BroadcastWorker(memberCollector);
}
}
// Send packet to all invitees if event is non-guild, in other case only to non-guild invitees (packet was broadcasted for them)
CalendarInviteStore invites = _invites[calendarEvent.GetEventId()];
for (CalendarInviteStore::iterator itr = invites.begin(); itr != invites.end(); ++itr)
if (Player* player = ObjectAccessor::FindConnectedPlayer((*itr)->GetInviteeGUID()))
if (!calendarEvent.IsGuildEvent() || player->GetGuildId() != calendarEvent.GetGuildId())
player->SendDirectMessage(packet);
if (auto itr =_invites.find(calendarEvent.GetEventId()); itr != _invites.end())
{
CalendarInviteStore invites = itr->second;
for (CalendarInvite const* invite : invites)
if (Player* player = ObjectAccessor::FindConnectedPlayer(invite->GetInviteeGUID()))
if (!calendarEvent.IsGuildEvent() || player->GetGuildId() != calendarEvent.GetGuildId())
relatedPlayers.push_back(player);
}
return relatedPlayers;
}
+41 -21
View File
@@ -26,6 +26,7 @@
#include <set>
#include <vector>
class Player;
class WorldPacket;
enum CalendarMailAnswers
@@ -159,7 +160,13 @@ struct TC_GAME_API CalendarInvite
CalendarInvite(uint64 inviteId, uint64 eventId, ObjectGuid invitee, ObjectGuid senderGUID, time_t responseTime,
CalendarInviteStatus status, CalendarModerationRank rank, std::string note) :
_inviteId(inviteId), _eventId(eventId), _invitee(invitee), _senderGUID(senderGUID), _responseTime(responseTime),
_status(status), _rank(rank), _note(note) { }
_status(status), _rank(rank), _note(std::move(note)) { }
CalendarInvite(CalendarInvite const&) = delete;
CalendarInvite(CalendarInvite&&) = delete;
CalendarInvite& operator=(CalendarInvite const&) = delete;
CalendarInvite& operator=(CalendarInvite&&) = delete;
~CalendarInvite();
@@ -218,10 +225,16 @@ struct TC_GAME_API CalendarEvent
CalendarEvent(uint64 eventId, ObjectGuid ownerGUID, ObjectGuid::LowType guildId, CalendarEventType type, int32 textureId,
time_t date, uint32 flags, std::string title, std::string description, time_t lockDate) :
_eventId(eventId), _ownerGUID(ownerGUID), _eventGuildId(guildId), _eventType(type), _textureId(textureId),
_date(date), _flags(flags), _title(title), _description(description), _lockDate(lockDate) { }
_date(date), _flags(flags), _title(std::move(title)), _description(std::move(description)), _lockDate(lockDate) { }
CalendarEvent() : _eventId(1), _ownerGUID(), _eventGuildId(UI64LIT(0)), _eventType(CALENDAR_TYPE_OTHER), _textureId(-1), _date(0),
_flags(0), _title(""), _description(""), _lockDate(0) { }
_flags(0), _title(), _description(), _lockDate(0) { }
CalendarEvent(CalendarEvent const&) = delete;
CalendarEvent(CalendarEvent&&) = delete;
CalendarEvent& operator=(CalendarEvent const&) = delete;
CalendarEvent& operator=(CalendarEvent&&) = delete;
~CalendarEvent();
@@ -263,7 +276,7 @@ struct TC_GAME_API CalendarEvent
static bool IsGuildAnnouncement(uint32 flags) { return (flags & CALENDAR_FLAG_WITHOUT_INVITES) != 0; }
std::string BuildCalendarMailSubject(ObjectGuid remover) const;
std::string BuildCalendarMailBody() const;
std::string BuildCalendarMailBody(Player const* invitee) const;
private:
uint64 _eventId;
@@ -296,20 +309,26 @@ class TC_GAME_API CalendarMgr
uint64 _maxInviteId;
public:
CalendarMgr(CalendarMgr const&) = delete;
CalendarMgr(CalendarMgr&&) = delete;
CalendarMgr& operator=(CalendarMgr const&) = delete;
CalendarMgr& operator=(CalendarMgr&&) = delete;
static CalendarMgr* instance();
void LoadFromDB();
CalendarEvent* GetEvent(uint64 eventId) const;
CalendarEventStore const& GetEvents() const { return _events; }
CalendarEventStore GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents = false);
CalendarEventStore GetPlayerEvents(ObjectGuid guid);
CalendarEventStore GetGuildEvents(ObjectGuid::LowType guildId);
CalendarEventStore GetEventsCreatedBy(ObjectGuid guid, bool includeGuildEvents = false) const;
CalendarEventStore GetPlayerEvents(ObjectGuid guid) const;
CalendarEventStore GetGuildEvents(ObjectGuid::LowType guildId) const;
CalendarInvite* GetInvite(uint64 inviteId) const;
CalendarEventInviteStore const& GetInvites() const { return _invites; }
CalendarInviteStore const& GetEventInvites(uint64 eventId);
CalendarInviteStore GetPlayerInvites(ObjectGuid guid);
CalendarInviteStore GetEventInvites(uint64 eventId) const;
CalendarInviteStore GetPlayerInvites(ObjectGuid guid) const;
void FreeEventId(uint64 id);
uint64 GetFreeEventId();
@@ -332,19 +351,20 @@ class TC_GAME_API CalendarMgr
void RemoveAllPlayerEventsAndInvites(ObjectGuid guid);
void RemovePlayerGuildEventsAndSignups(ObjectGuid guid, ObjectGuid::LowType guildId);
void SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType);
void SendCalendarEventInvite(CalendarInvite const& invite);
void SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite);
void SendCalendarEventInviteRemove(CalendarEvent const& calendarEvent, CalendarInvite const& invite, uint32 flags);
void SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status);
void SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, time_t originalDate);
void SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite);
void SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent);
void SendCalendarEventModeratorStatusAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite);
void SendCalendarClearPendingAction(ObjectGuid guid);
void SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param = nullptr);
void SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType) const;
void SendCalendarEventInvite(CalendarInvite const& invite) const;
void SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const;
void SendCalendarEventInviteRemove(CalendarEvent const& calendarEvent, CalendarInvite const& invite, uint32 flags) const;
void SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status) const;
void SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, time_t originalDate) const;
void SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const;
void SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent) const;
void SendCalendarEventModeratorStatusAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const;
void SendCalendarClearPendingAction(ObjectGuid guid) const;
void SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param = nullptr) const;
void SendPacketToAllEventRelatives(WorldPacket const* packet, CalendarEvent const& calendarEvent);
void SendPacketToAllEventRelatives(WorldPacket const* packet, CalendarEvent const& calendarEvent) const;
std::vector<Player*> GetAllEventRelatives(CalendarEvent const& calendarEvent) const;
};
#define sCalendarMgr CalendarMgr::instance()
+15 -11
View File
@@ -19,12 +19,12 @@
#include "AchievementMgr.h"
#include "AreaTrigger.h"
#include "AreaTriggerDataStore.h"
#include "Battleground.h"
#include "BattlePetMgr.h"
#include "Battleground.h"
#include "Containers.h"
#include "ConversationDataStore.h"
#include "DatabaseEnv.h"
#include "DB2Stores.h"
#include "DatabaseEnv.h"
#include "GameEventMgr.h"
#include "GameObject.h"
#include "GameTime.h"
@@ -32,8 +32,8 @@
#include "InstanceScenario.h"
#include "InstanceScript.h"
#include "Item.h"
#include "LanguageMgr.h"
#include "LFGMgr.h"
#include "LanguageMgr.h"
#include "Log.h"
#include "LootMgr.h"
#include "Map.h"
@@ -53,6 +53,7 @@
#include "World.h"
#include "WorldSession.h"
#include "WorldStateMgr.h"
#include "WowTime.h"
#include <random>
#include <sstream>
@@ -3264,15 +3265,18 @@ bool ConditionMgr::IsPlayerMeetingCondition(Player const* player, PlayerConditio
if (condition->Time[0])
{
ByteBuffer unpacker;
unpacker << condition->Time[0];
time_t from = unpacker.ReadPackedTime();
unpacker.rpos(0);
unpacker.wpos(0);
unpacker << condition->Time[1];
time_t to = unpacker.ReadPackedTime();
WowTime time0;
time0.SetPackedTime(condition->Time[0]);
if (GameTime::GetGameTime() < from || GameTime::GetGameTime() > to)
if (condition->Time[1])
{
WowTime time1;
time1.SetPackedTime(condition->Time[1]);
if (!GameTime::GetWowTime()->IsInRange(time0, time1))
return false;
}
else if (*GameTime::GetWowTime() != time0)
return false;
}
+2 -2
View File
@@ -24023,8 +24023,8 @@ void Player::SendInitialPacketsBeforeAddToMap()
static float const TimeSpeed = 0.01666667f;
WorldPackets::Misc::LoginSetTimeSpeed loginSetTimeSpeed;
loginSetTimeSpeed.NewSpeed = TimeSpeed;
loginSetTimeSpeed.GameTime = GameTime::GetGameTime();
loginSetTimeSpeed.ServerTime = GameTime::GetGameTime();
loginSetTimeSpeed.GameTime = *GameTime::GetWowTime();
loginSetTimeSpeed.ServerTime = *GameTime::GetWowTime();
loginSetTimeSpeed.GameTimeHolidayOffset = 0; /// @todo
loginSetTimeSpeed.ServerTimeHolidayOffset = 0; /// @todo
SendDirectMessage(loginSetTimeSpeed.Write());
+22 -8
View File
@@ -226,7 +226,7 @@ void Guild::NewsLogEntry::WritePacket(WorldPackets::Guild::GuildNews& newsPacket
WorldPackets::Guild::GuildNewsEvent newsEvent;
newsEvent.Id = int32(GetGUID());
newsEvent.MemberGuid = GetPlayerGuid();
newsEvent.CompletedDate = uint32(GetTimestamp());
newsEvent.CompletedDate.SetUtcTimeFromUnixTime(GetTimestamp());
newsEvent.Flags = int32(GetFlags());
newsEvent.Type = int32(GetType());
@@ -1306,7 +1306,8 @@ void Guild::HandleRoster(WorldSession* session)
WorldPackets::Guild::GuildRoster roster;
roster.NumAccounts = int32(m_accountsNumber);
roster.CreateDate = uint32(m_createdDate);
roster.CreateDate.SetUtcTimeFromUnixTime(m_createdDate);
roster.CreateDate += session->GetTimezoneOffset();
roster.GuildFlags = 0;
roster.MemberData.reserve(m_members.size());
@@ -2183,7 +2184,10 @@ void Guild::SendNewsUpdate(WorldSession* session) const
packet.NewsEvents.reserve(newsLog.size());
for (NewsLogEntry const& newsLogEntry : newsLog)
{
newsLogEntry.WritePacket(packet);
packet.NewsEvents.back().CompletedDate += session->GetTimezoneOffset();
}
session->SendPacket(packet.Write());
@@ -2688,12 +2692,15 @@ void Guild::BroadcastPacket(WorldPacket const* packet) const
player->SendDirectMessage(packet);
}
void Guild::BroadcastPacketIfTrackingAchievement(WorldPacket const* packet, uint32 criteriaId) const
std::vector<Player*> Guild::GetMembersTrackingCriteria(uint32 criteriaId) const
{
std::vector<Player*> members;
for (auto const& [guid, member] : m_members)
if (member.IsTrackingCriteriaId(criteriaId))
if (Player* player = member.FindPlayer())
player->GetSession()->SendPacket(packet);
members.push_back(player);
return members;
}
void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, GuildRankOrder minRank)
@@ -3599,10 +3606,16 @@ void Guild::AddGuildNews(uint8 type, ObjectGuid guid, uint32 flags, uint32 value
NewsLogEntry& news = m_newsLog.AddEvent(trans, m_id, m_newsLog.GetNextGUID(), GuildNews(type), guid, flags, value);
CharacterDatabase.CommitTransaction(trans);
WorldPackets::Guild::GuildNews newsPacket;
newsPacket.NewsEvents.reserve(1);
news.WritePacket(newsPacket);
BroadcastPacket(newsPacket.Write());
auto packetBuilder = [&](Player const* receiver)
{
WorldPackets::Guild::GuildNews newsPacket;
newsPacket.NewsEvents.reserve(1);
news.WritePacket(newsPacket);
newsPacket.NewsEvents.back().CompletedDate += receiver->GetSession()->GetTimezoneOffset();
receiver->SendDirectMessage(newsPacket.Write());
};
BroadcastWorker(packetBuilder);
}
bool Guild::HasAchieved(uint32 achievementId) const
@@ -3637,5 +3650,6 @@ void Guild::HandleNewsSetSticky(WorldSession* session, uint32 newsId, bool stick
WorldPackets::Guild::GuildNews newsPacket;
newsPacket.NewsEvents.reserve(1);
itr->WritePacket(newsPacket);
newsPacket.NewsEvents.back().CompletedDate += session->GetTimezoneOffset();
session->SendPacket(newsPacket.Write());
}
+1 -1
View File
@@ -810,7 +810,6 @@ class TC_GAME_API Guild
void BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std::string_view msg, std::string_view prefix, bool isLogged) const;
void BroadcastPacketToRank(WorldPacket const* packet, GuildRankId rankId) const;
void BroadcastPacket(WorldPacket const* packet) const;
void BroadcastPacketIfTrackingAchievement(WorldPacket const* packet, uint32 criteriaId) const;
void MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, GuildRankOrder minRank);
@@ -831,6 +830,7 @@ class TC_GAME_API Guild
bool IsMember(ObjectGuid guid) const;
uint32 GetMembersCount() const { return uint32(m_members.size()); }
uint64 GetMemberAvailableMoneyForRepairItems(ObjectGuid guid) const;
std::vector<Player*> GetMembersTrackingCriteria(uint32 criteriaId) const;
// Bank
void SwapItems(Player* player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount);
+8 -5
View File
@@ -26,6 +26,7 @@
#include "RBAC.h"
#include "Realm.h"
#include "SystemPackets.h"
#include "Timezone.h"
#include "World.h"
void WorldSession::SendAuthResponse(uint32 code, bool queued, uint32 queuePos)
@@ -89,12 +90,14 @@ void WorldSession::SendClientCacheVersion(uint32 version)
void WorldSession::SendSetTimeZoneInformation()
{
/// @todo: replace dummy values
WorldPackets::System::SetTimeZoneInformation packet;
packet.ServerTimeTZ = "Europe/Paris";
packet.GameTimeTZ = "Europe/Paris";
packet.ServerRegionalTZ = "Europe/Paris";
Minutes timezoneOffset = Trinity::Timezone::GetSystemZoneOffset(false);
std::string realTimezone = Trinity::Timezone::GetSystemZoneName();
std::string_view clientSupportedTZ = Trinity::Timezone::FindClosestClientSupportedTimezone(realTimezone, timezoneOffset);
WorldPackets::System::SetTimeZoneInformation packet;
packet.ServerTimeTZ = clientSupportedTZ;
packet.GameTimeTZ = clientSupportedTZ;
packet.ServerRegionalTZ = clientSupportedTZ;
SendPacket(packet.Write());
}
+13 -18
View File
@@ -39,7 +39,6 @@ Copied events should probably have a new owner
#include "CalendarPackets.h"
#include "CharacterCache.h"
#include "DatabaseEnv.h"
#include "DB2Stores.h"
#include "GameTime.h"
#include "Guild.h"
#include "GuildMgr.h"
@@ -49,16 +48,14 @@ Copied events should probably have a new owner
#include "ObjectMgr.h"
#include "Player.h"
#include "SocialMgr.h"
#include "Util.h"
#include "World.h"
void WorldSession::HandleCalendarGetCalendar(WorldPackets::Calendar::CalendarGetCalendar& /*calendarGetCalendar*/)
{
ObjectGuid guid = _player->GetGUID();
time_t currTime = GameTime::GetGameTime();
WorldPackets::Calendar::CalendarSendCalendar packet;
packet.ServerTime = currTime;
packet.ServerTime = *GameTime::GetWowTime();
CalendarInviteStore playerInvites = sCalendarMgr->GetPlayerInvites(guid);
for (CalendarInvite const* invite : playerInvites)
@@ -78,7 +75,8 @@ void WorldSession::HandleCalendarGetCalendar(WorldPackets::Calendar::CalendarGet
{
WorldPackets::Calendar::CalendarSendCalendarEventInfo& eventInfo = packet.Events.emplace_back();
eventInfo.EventID = event->GetEventId();
eventInfo.Date = event->GetDate();
eventInfo.Date.SetUtcTimeFromUnixTime(event->GetDate());
eventInfo.Date += GetTimezoneOffset();
eventInfo.EventClubID = event->GetGuildId();
eventInfo.EventName = event->GetTitle();
eventInfo.EventType = event->GetType();
@@ -117,11 +115,10 @@ void WorldSession::HandleCalendarAddEvent(WorldPackets::Calendar::CalendarAddEve
{
ObjectGuid guid = _player->GetGUID();
calendarAddEvent.EventInfo.Time = uint32(LocalTimeToUTCTime(calendarAddEvent.EventInfo.Time));
calendarAddEvent.EventInfo.Time -= GetTimezoneOffset();
// prevent events in the past
// To Do: properly handle timezones and remove the "- time_t(86400L)" hack
if (calendarAddEvent.EventInfo.Time < (GameTime::GetGameTime() - time_t(86400L)))
if (calendarAddEvent.EventInfo.Time < *GameTime::GetUtcWowTime())
{
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
return;
@@ -163,7 +160,7 @@ void WorldSession::HandleCalendarAddEvent(WorldPackets::Calendar::CalendarAddEve
SetCalendarEventCreationCooldown(GameTime::GetGameTime() + CALENDAR_CREATE_EVENT_COOLDOWN);
CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, UI64LIT(0), CalendarEventType(calendarAddEvent.EventInfo.EventType), calendarAddEvent.EventInfo.TextureID,
calendarAddEvent.EventInfo.Time, calendarAddEvent.EventInfo.Flags, calendarAddEvent.EventInfo.Title, calendarAddEvent.EventInfo.Description, time_t(0));
calendarAddEvent.EventInfo.Time.GetUnixTimeFromUtcTime(), calendarAddEvent.EventInfo.Flags, calendarAddEvent.EventInfo.Title, calendarAddEvent.EventInfo.Description, time_t(0));
if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement())
calendarEvent->SetGuildId(_player->GetGuildId());
@@ -201,11 +198,10 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPackets::Calendar::CalendarUpd
ObjectGuid guid = _player->GetGUID();
time_t oldEventTime = time_t(0);
calendarUpdateEvent.EventInfo.Time = uint32(LocalTimeToUTCTime(calendarUpdateEvent.EventInfo.Time));
calendarUpdateEvent.EventInfo.Time -= GetTimezoneOffset();
// prevent events in the past
// To Do: properly handle timezones and remove the "- time_t(86400L)" hack
if (calendarUpdateEvent.EventInfo.Time < (GameTime::GetGameTime() - time_t(86400L)))
if (calendarUpdateEvent.EventInfo.Time < *GameTime::GetUtcWowTime())
return;
if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarUpdateEvent.EventInfo.EventID))
@@ -214,7 +210,7 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPackets::Calendar::CalendarUpd
calendarEvent->SetType(CalendarEventType(calendarUpdateEvent.EventInfo.EventType));
calendarEvent->SetFlags(calendarUpdateEvent.EventInfo.Flags);
calendarEvent->SetDate(calendarUpdateEvent.EventInfo.Time);
calendarEvent->SetDate(calendarUpdateEvent.EventInfo.Time.GetUnixTimeFromUtcTime());
calendarEvent->SetTextureId(calendarUpdateEvent.EventInfo.TextureID);
calendarEvent->SetTitle(calendarUpdateEvent.EventInfo.Title);
calendarEvent->SetDescription(calendarUpdateEvent.EventInfo.Description);
@@ -236,11 +232,10 @@ void WorldSession::HandleCalendarCopyEvent(WorldPackets::Calendar::CalendarCopyE
{
ObjectGuid guid = _player->GetGUID();
calendarCopyEvent.Date = uint32(LocalTimeToUTCTime(calendarCopyEvent.Date));
calendarCopyEvent.Date -= GetTimezoneOffset();
// prevent events in the past
// To Do: properly handle timezones and remove the "- time_t(86400L)" hack
if (calendarCopyEvent.Date < (GameTime::GetGameTime() - time_t(86400L)))
if (calendarCopyEvent.Date < *GameTime::GetUtcWowTime())
{
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
return;
@@ -292,7 +287,7 @@ void WorldSession::HandleCalendarCopyEvent(WorldPackets::Calendar::CalendarCopyE
SetCalendarEventCreationCooldown(GameTime::GetGameTime() + CALENDAR_CREATE_EVENT_COOLDOWN);
CalendarEvent* newEvent = new CalendarEvent(*oldEvent, sCalendarMgr->GetFreeEventId());
newEvent->SetDate(calendarCopyEvent.Date);
newEvent->SetDate(calendarCopyEvent.Date.GetUnixTimeFromUtcTime());
sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY);
CalendarInviteStore invites = sCalendarMgr->GetEventInvites(calendarCopyEvent.EventID);
@@ -550,7 +545,7 @@ void WorldSession::HandleSetSavedInstanceExtend(WorldPackets::Calendar::SetSaved
return;
WorldPackets::Calendar::CalendarRaidLockoutUpdated calendarRaidLockoutUpdated;
calendarRaidLockoutUpdated.ServerTime = GameTime::GetGameTime();
calendarRaidLockoutUpdated.ServerTime = *GameTime::GetWowTime();
calendarRaidLockoutUpdated.MapID = setSavedInstanceExtend.MapID;
calendarRaidLockoutUpdated.DifficultyID = setSavedInstanceExtend.DifficultyID;
calendarRaidLockoutUpdated.OldTimeRemaining = std::max(std::chrono::duration_cast<Seconds>(expiryTimes.first - GameTime::GetSystemTime()).count(), SI64LIT(0));
@@ -25,6 +25,7 @@
#include "Map.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "WorldSession.h"
QuestObjectiveCriteriaMgr::QuestObjectiveCriteriaMgr(Player* owner) : _owner(owner)
{
@@ -187,7 +188,8 @@ void QuestObjectiveCriteriaMgr::SendAllData(Player const* /*receiver*/) const
criteriaUpdate.PlayerGUID = _owner->GetGUID();
criteriaUpdate.Flags = 0;
criteriaUpdate.CurrentTime = criteriaProgres.second.Date;
criteriaUpdate.CurrentTime.SetUtcTimeFromUnixTime(criteriaProgres.second.Date);
criteriaUpdate.CurrentTime += _owner->GetSession()->GetTimezoneOffset();
criteriaUpdate.CreationTime = 0;
SendPacket(criteriaUpdate.Write());
@@ -222,7 +224,8 @@ void QuestObjectiveCriteriaMgr::SendCriteriaUpdate(Criteria const* criteria, Cri
if (criteria->Entry->StartTimer)
criteriaUpdate.Flags = timedCompleted ? 1 : 0; // 1 is for keeping the counter at 0 in client
criteriaUpdate.CurrentTime = progress->Date;
criteriaUpdate.CurrentTime.SetUtcTimeFromUnixTime(progress->Date);
criteriaUpdate.CurrentTime += _owner->GetSession()->GetTimezoneOffset();
criteriaUpdate.ElapsedTime = timeElapsed;
criteriaUpdate.CreationTime = 0;
+48 -35
View File
@@ -23,6 +23,7 @@
#include "Player.h"
#include "ScenarioMgr.h"
#include "ScenarioPackets.h"
#include "WorldSession.h"
Scenario::Scenario(Map* map, ScenarioData const* scenarioData) : _map(map), _data(scenarioData),
_guid(ObjectGuid::Create<HighGuid::Scenario>(map->GetId(), scenarioData->Entry->ID, map->GenerateLowGuid<HighGuid::Scenario>())),
@@ -100,9 +101,12 @@ void Scenario::SetStep(ScenarioStepEntry const* step)
player->StartCriteria(CriteriaStartEvent::BeginScenarioStep, step->ID);
}
WorldPackets::Scenario::ScenarioState scenarioState;
BuildScenarioState(&scenarioState);
SendPacket(scenarioState.Write());
DoForAllPlayers([&](Player const* receiver)
{
WorldPackets::Scenario::ScenarioState scenarioState;
BuildScenarioStateFor(receiver, &scenarioState);
receiver->SendDirectMessage(scenarioState.Write());
});
}
void Scenario::OnPlayerEnter(Player* player)
@@ -117,7 +121,7 @@ void Scenario::OnPlayerExit(Player* player)
SendBootPlayer(player);
}
bool Scenario::IsComplete()
bool Scenario::IsComplete() const
{
for (std::pair<uint8 const, ScenarioStepEntry const*> const& scenarioStep : _data->Steps)
{
@@ -136,7 +140,7 @@ ScenarioEntry const* Scenario::GetEntry() const
return _data->Entry;
}
ScenarioStepState Scenario::GetStepState(ScenarioStepEntry const* step)
ScenarioStepState Scenario::GetStepState(ScenarioStepEntry const* step) const
{
auto itr = _stepStates.find(step);
if (itr == _stepStates.end())
@@ -145,20 +149,24 @@ ScenarioStepState Scenario::GetStepState(ScenarioStepEntry const* step)
return itr->second;
}
void Scenario::SendCriteriaUpdate(Criteria const * criteria, CriteriaProgress const * progress, Seconds timeElapsed, bool timedCompleted) const
void Scenario::SendCriteriaUpdate(Criteria const* criteria, CriteriaProgress const* progress, Seconds timeElapsed, bool timedCompleted) const
{
WorldPackets::Scenario::ScenarioProgressUpdate progressUpdate;
progressUpdate.CriteriaProgress.Id = criteria->ID;
progressUpdate.CriteriaProgress.Quantity = progress->Counter;
progressUpdate.CriteriaProgress.Player = progress->PlayerGUID;
progressUpdate.CriteriaProgress.Date = progress->Date;
if (criteria->Entry->StartTimer)
progressUpdate.CriteriaProgress.Flags = timedCompleted ? 1 : 0;
DoForAllPlayers([=](Player const* receiver)
{
WorldPackets::Scenario::ScenarioProgressUpdate progressUpdate;
progressUpdate.CriteriaProgress.Id = criteria->ID;
progressUpdate.CriteriaProgress.Quantity = progress->Counter;
progressUpdate.CriteriaProgress.Player = progress->PlayerGUID;
progressUpdate.CriteriaProgress.Date.SetUtcTimeFromUnixTime(progress->Date);
progressUpdate.CriteriaProgress.Date += receiver->GetSession()->GetTimezoneOffset();
if (criteria->Entry->StartTimer)
progressUpdate.CriteriaProgress.Flags = timedCompleted ? 1 : 0;
progressUpdate.CriteriaProgress.TimeFromStart = timeElapsed;
progressUpdate.CriteriaProgress.TimeFromCreate = Seconds::zero();
progressUpdate.CriteriaProgress.TimeFromStart = timeElapsed;
progressUpdate.CriteriaProgress.TimeFromCreate = Seconds::zero();
SendPacket(progressUpdate.Write());
receiver->SendDirectMessage(progressUpdate.Write());
});
}
bool Scenario::CanUpdateCriteriaTree(Criteria const * /*criteria*/, CriteriaTree const * tree, Player * /*referencePlayer*/) const
@@ -220,20 +228,28 @@ bool Scenario::IsCompletedStep(ScenarioStepEntry const* step)
return IsCompletedCriteriaTree(tree);
}
void Scenario::SendPacket(WorldPacket const* data) const
void Scenario::DoForAllPlayers(std::function<void(Player*)> const& worker) const
{
for (ObjectGuid guid : _players)
if (Player* player = ObjectAccessor::GetPlayer(_map, guid))
player->SendDirectMessage(data);
worker(player);
}
void Scenario::BuildScenarioState(WorldPackets::Scenario::ScenarioState* scenarioState)
void Scenario::SendPacket(WorldPacket const* data) const
{
DoForAllPlayers([data](Player const* player)
{
player->SendDirectMessage(data);
});
}
void Scenario::BuildScenarioStateFor(Player const* player, WorldPackets::Scenario::ScenarioState* scenarioState) const
{
scenarioState->ScenarioGUID = _guid;
scenarioState->ScenarioID = _data->Entry->ID;
if (ScenarioStepEntry const* step = GetStep())
scenarioState->CurrentStep = step->ID;
scenarioState->CriteriaProgress = GetCriteriasProgress();
scenarioState->CriteriaProgress = GetCriteriasProgressFor(player);
scenarioState->BonusObjectives = GetBonusObjectivesData();
// Don't know exactly what this is for, but seems to contain list of scenario steps that we're either on or that are completed
for (std::pair<ScenarioStepEntry const* const, ScenarioStepState> const& state : _stepStates)
@@ -288,14 +304,14 @@ ScenarioStepEntry const* Scenario::GetLastStep() const
return lastStep;
}
void Scenario::SendScenarioState(Player* player)
void Scenario::SendScenarioState(Player const* player) const
{
WorldPackets::Scenario::ScenarioState scenarioState;
BuildScenarioState(&scenarioState);
BuildScenarioStateFor(player, &scenarioState);
player->SendDirectMessage(scenarioState.Write());
}
std::vector<WorldPackets::Scenario::BonusObjectiveData> Scenario::GetBonusObjectivesData()
std::vector<WorldPackets::Scenario::BonusObjectiveData> Scenario::GetBonusObjectivesData() const
{
std::vector<WorldPackets::Scenario::BonusObjectiveData> bonusObjectivesData;
for (std::pair<uint8 const, ScenarioStepEntry const*> const& scenarioStep : _data->Steps)
@@ -315,21 +331,18 @@ std::vector<WorldPackets::Scenario::BonusObjectiveData> Scenario::GetBonusObject
return bonusObjectivesData;
}
std::vector<WorldPackets::Achievement::CriteriaProgress> Scenario::GetCriteriasProgress()
std::vector<WorldPackets::Achievement::CriteriaProgress> Scenario::GetCriteriasProgressFor(Player const* player) const
{
std::vector<WorldPackets::Achievement::CriteriaProgress> criteriasProgress;
if (!_criteriaProgress.empty())
for (auto const& [criteriaId, progress] : _criteriaProgress)
{
for (std::pair<uint32 const, CriteriaProgress> const& progressPair : _criteriaProgress)
{
WorldPackets::Achievement::CriteriaProgress criteriaProgress;
criteriaProgress.Id = progressPair.first;
criteriaProgress.Quantity = progressPair.second.Counter;
criteriaProgress.Date = progressPair.second.Date;
criteriaProgress.Player = progressPair.second.PlayerGUID;
criteriasProgress.push_back(criteriaProgress);
}
WorldPackets::Achievement::CriteriaProgress& criteriaProgress = criteriasProgress.emplace_back();
criteriaProgress.Id = criteriaId;
criteriaProgress.Quantity = progress.Counter;
criteriaProgress.Date.SetUtcTimeFromUnixTime(progress.Date);
criteriaProgress.Date += player->GetSession()->GetTimezoneOffset();
criteriaProgress.Player = progress.PlayerGUID;
}
return criteriasProgress;
@@ -340,7 +353,7 @@ CriteriaList const& Scenario::GetCriteriaByType(CriteriaType type, uint32 /*asse
return sCriteriaMgr->GetScenarioCriteriaByTypeAndScenario(type, _data->Entry->ID);
}
void Scenario::SendBootPlayer(Player* player)
void Scenario::SendBootPlayer(Player const* player) const
{
WorldPackets::Scenario::ScenarioVacate scenarioBoot;
scenarioBoot.ScenarioGUID = _guid;
+8 -7
View File
@@ -65,17 +65,17 @@ class TC_GAME_API Scenario : public CriteriaHandler
virtual void OnPlayerExit(Player* player);
virtual void Update(uint32 /*diff*/) { }
bool IsComplete();
bool IsComplete() const;
bool IsCompletedStep(ScenarioStepEntry const* step);
void SetStepState(ScenarioStepEntry const* step, ScenarioStepState state) { _stepStates[step] = state; }
ScenarioEntry const* GetEntry() const;
ScenarioStepState GetStepState(ScenarioStepEntry const* step);
ScenarioStepState GetStepState(ScenarioStepEntry const* step) const;
ScenarioStepEntry const* GetStep() const { return _currentstep; }
ScenarioStepEntry const* GetFirstStep() const;
ScenarioStepEntry const* GetLastStep() const;
void SendScenarioState(Player* player);
void SendBootPlayer(Player* player);
void SendScenarioState(Player const* player) const;
void SendBootPlayer(Player const* player) const;
protected:
Map const* _map;
@@ -89,14 +89,15 @@ class TC_GAME_API Scenario : public CriteriaHandler
void CompletedCriteriaTree(CriteriaTree const* tree, Player* referencePlayer) override;
void AfterCriteriaTreeUpdate(CriteriaTree const* /*tree*/, Player* /*referencePlayer*/) override { }
void DoForAllPlayers(std::function<void(Player*)> const& worker) const;
void SendPacket(WorldPacket const* data) const override;
void SendAllData(Player const* /*receiver*/) const override { }
void BuildScenarioState(WorldPackets::Scenario::ScenarioState* scenarioState);
void BuildScenarioStateFor(Player const* player, WorldPackets::Scenario::ScenarioState* scenarioState) const;
std::vector<WorldPackets::Scenario::BonusObjectiveData> GetBonusObjectivesData();
std::vector<WorldPackets::Achievement::CriteriaProgress> GetCriteriasProgress();
std::vector<WorldPackets::Scenario::BonusObjectiveData> GetBonusObjectivesData() const;
std::vector<WorldPackets::Achievement::CriteriaProgress> GetCriteriasProgressFor(Player const* player) const;
CriteriaList const& GetCriteriaByType(CriteriaType type, uint32 asset) const override;
ScenarioData const* _data;
@@ -17,24 +17,26 @@
#include "AchievementPackets.h"
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Achievement::EarnedAchievement const& earned)
namespace WorldPackets::Achievement
{
ByteBuffer& operator<<(ByteBuffer& data, EarnedAchievement const& earned)
{
data << uint32(earned.Id);
data.AppendPackedTime(earned.Date);
data << earned.Date;
data << earned.Owner;
data << uint32(earned.VirtualRealmAddress);
data << uint32(earned.NativeRealmAddress);
return data;
}
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Achievement::CriteriaProgress const& criteria)
ByteBuffer& operator<<(ByteBuffer& data, CriteriaProgress const& criteria)
{
data << uint32(criteria.Id);
data << uint64(criteria.Quantity);
data << criteria.Player;
data << uint32(criteria.Unused_10_1_5);
data << uint32(criteria.Flags);
data.AppendPackedTime(criteria.Date);
data << criteria.Date;
data << criteria.TimeFromStart;
data << criteria.TimeFromCreate;
data.WriteBit(criteria.RafAcceptanceID.has_value());
@@ -46,37 +48,37 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Achievement::CriteriaProg
return data;
}
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Achievement::AllAchievements const& allAchievements)
ByteBuffer& operator<<(ByteBuffer& data, AllAchievements const& allAchievements)
{
data << uint32(allAchievements.Earned.size());
data << uint32(allAchievements.Progress.size());
for (WorldPackets::Achievement::EarnedAchievement const& earned : allAchievements.Earned)
for (EarnedAchievement const& earned : allAchievements.Earned)
data << earned;
for (WorldPackets::Achievement::CriteriaProgress const& progress : allAchievements.Progress)
for (CriteriaProgress const& progress : allAchievements.Progress)
data << progress;
return data;
}
WorldPacket const* WorldPackets::Achievement::AllAchievementData::Write()
WorldPacket const* AllAchievementData::Write()
{
_worldPacket << Data;
return &_worldPacket;
}
WorldPacket const* WorldPackets::Achievement::AllAccountCriteria::Write()
WorldPacket const* AllAccountCriteria::Write()
{
_worldPacket << uint32(Progress.size());
for (WorldPackets::Achievement::CriteriaProgress const& progress : Progress)
for (CriteriaProgress const& progress : Progress)
_worldPacket << progress;
return &_worldPacket;
}
WorldPacket const* WorldPackets::Achievement::RespondInspectAchievements::Write()
WorldPacket const* RespondInspectAchievements::Write()
{
_worldPacket << Player;
_worldPacket << Data;
@@ -84,14 +86,14 @@ WorldPacket const* WorldPackets::Achievement::RespondInspectAchievements::Write(
return &_worldPacket;
}
WorldPacket const* WorldPackets::Achievement::CriteriaUpdate::Write()
WorldPacket const* CriteriaUpdate::Write()
{
_worldPacket << uint32(CriteriaID);
_worldPacket << uint64(Quantity);
_worldPacket << PlayerGUID;
_worldPacket << uint32(Unused_10_1_5);
_worldPacket << uint32(Flags);
_worldPacket.AppendPackedTime(CurrentTime);
_worldPacket << CurrentTime;
_worldPacket << ElapsedTime;
_worldPacket << CreationTime;
_worldPacket.WriteBit(RafAcceptanceID.has_value());
@@ -103,21 +105,21 @@ WorldPacket const* WorldPackets::Achievement::CriteriaUpdate::Write()
return &_worldPacket;
}
WorldPacket const* WorldPackets::Achievement::AccountCriteriaUpdate::Write()
WorldPacket const* AccountCriteriaUpdate::Write()
{
_worldPacket << Progress;
return &_worldPacket;
}
WorldPacket const* WorldPackets::Achievement::CriteriaDeleted::Write()
WorldPacket const* CriteriaDeleted::Write()
{
_worldPacket << uint32(CriteriaID);
return &_worldPacket;
}
WorldPacket const* WorldPackets::Achievement::AchievementDeleted::Write()
WorldPacket const* AchievementDeleted::Write()
{
_worldPacket << uint32(AchievementID);
_worldPacket << uint32(Immunities);
@@ -125,12 +127,12 @@ WorldPacket const* WorldPackets::Achievement::AchievementDeleted::Write()
return &_worldPacket;
}
WorldPacket const* WorldPackets::Achievement::AchievementEarned::Write()
WorldPacket const* AchievementEarned::Write()
{
_worldPacket << Sender;
_worldPacket << Earner;
_worldPacket << uint32(AchievementID);
_worldPacket.AppendPackedTime(Time);
_worldPacket << Time;
_worldPacket << uint32(EarnerNativeRealm);
_worldPacket << uint32(EarnerVirtualRealm);
_worldPacket.WriteBit(Initial);
@@ -139,7 +141,7 @@ WorldPacket const* WorldPackets::Achievement::AchievementEarned::Write()
return &_worldPacket;
}
WorldPacket const* WorldPackets::Achievement::BroadcastAchievement::Write()
WorldPacket const* BroadcastAchievement::Write()
{
_worldPacket.WriteBits(Name.length(), 7);
_worldPacket.WriteBit(GuildAchievement);
@@ -150,7 +152,7 @@ WorldPacket const* WorldPackets::Achievement::BroadcastAchievement::Write()
return &_worldPacket;
}
WorldPacket const* WorldPackets::Achievement::GuildCriteriaUpdate::Write()
WorldPacket const* GuildCriteriaUpdate::Write()
{
_worldPacket << uint32(Progress.size());
@@ -159,8 +161,7 @@ WorldPacket const* WorldPackets::Achievement::GuildCriteriaUpdate::Write()
_worldPacket << int32(progress.CriteriaID);
_worldPacket << progress.DateCreated;
_worldPacket << progress.DateStarted;
_worldPacket.AppendPackedTime(progress.DateUpdated);
_worldPacket << uint32(0); // this is a hack. this is a packed time written as int64 (progress.DateUpdated)
_worldPacket << int64(progress.DateUpdated.GetPackedTime());
_worldPacket << uint64(progress.Quantity);
_worldPacket << progress.PlayerGUID;
_worldPacket << int32(progress.Unused_10_1_5);
@@ -170,7 +171,7 @@ WorldPacket const* WorldPackets::Achievement::GuildCriteriaUpdate::Write()
return &_worldPacket;
}
WorldPacket const* WorldPackets::Achievement::GuildCriteriaDeleted::Write()
WorldPacket const* GuildCriteriaDeleted::Write()
{
_worldPacket << GuildGUID;
_worldPacket << int32(CriteriaID);
@@ -178,30 +179,30 @@ WorldPacket const* WorldPackets::Achievement::GuildCriteriaDeleted::Write()
return &_worldPacket;
}
void WorldPackets::Achievement::GuildSetFocusedAchievement::Read()
void GuildSetFocusedAchievement::Read()
{
_worldPacket >> AchievementID;
}
WorldPacket const* WorldPackets::Achievement::GuildAchievementDeleted::Write()
WorldPacket const* GuildAchievementDeleted::Write()
{
_worldPacket << GuildGUID;
_worldPacket << uint32(AchievementID);
_worldPacket.AppendPackedTime(TimeDeleted);
_worldPacket << TimeDeleted;
return &_worldPacket;
}
WorldPacket const* WorldPackets::Achievement::GuildAchievementEarned::Write()
WorldPacket const* GuildAchievementEarned::Write()
{
_worldPacket << GuildGUID;
_worldPacket << uint32(AchievementID);
_worldPacket.AppendPackedTime(TimeEarned);
_worldPacket << TimeEarned;
return &_worldPacket;
}
WorldPacket const* WorldPackets::Achievement::AllGuildAchievements::Write()
WorldPacket const* AllGuildAchievements::Write()
{
_worldPacket << uint32(Earned.size());
@@ -211,20 +212,20 @@ WorldPacket const* WorldPackets::Achievement::AllGuildAchievements::Write()
return &_worldPacket;
}
void WorldPackets::Achievement::GuildGetAchievementMembers::Read()
void GuildGetAchievementMembers::Read()
{
_worldPacket >> PlayerGUID;
_worldPacket >> GuildGUID;
_worldPacket >> AchievementID;
}
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Achievement::GuildAchievementMember const& guildAchievementMember)
ByteBuffer& operator<<(ByteBuffer& data, GuildAchievementMember const& guildAchievementMember)
{
data << guildAchievementMember.MemberGUID;
return data;
}
WorldPacket const* WorldPackets::Achievement::GuildAchievementMembers::Write()
WorldPacket const* GuildAchievementMembers::Write()
{
_worldPacket << GuildGUID;
_worldPacket << int32(AchievementID);
@@ -234,3 +235,4 @@ WorldPacket const* WorldPackets::Achievement::GuildAchievementMembers::Write()
return &_worldPacket;
}
}
@@ -22,6 +22,7 @@
#include "ObjectGuid.h"
#include "Optional.h"
#include "PacketUtilities.h"
#include "WowTime.h"
namespace WorldPackets
{
@@ -30,7 +31,7 @@ namespace WorldPackets
struct EarnedAchievement
{
uint32 Id = 0;
time_t Date = time_t(0);
WowTime Date;
ObjectGuid Owner;
uint32 VirtualRealmAddress = 0;
uint32 NativeRealmAddress = 0;
@@ -43,7 +44,7 @@ namespace WorldPackets
ObjectGuid Player;
uint32 Unused_10_1_5 = 0;
uint32 Flags = 0;
time_t Date = time_t(0);
WowTime Date;
Duration<Seconds> TimeFromStart;
Duration<Seconds> TimeFromCreate;
Optional<uint64> RafAcceptanceID;
@@ -98,7 +99,7 @@ namespace WorldPackets
ObjectGuid PlayerGUID;
uint32 Unused_10_1_5 = 0;
uint32 Flags = 0;
time_t CurrentTime = time_t(0);
WowTime CurrentTime;
Duration<Seconds> ElapsedTime;
Timestamp<> CreationTime;
Optional<uint64> RafAcceptanceID;
@@ -146,7 +147,7 @@ namespace WorldPackets
uint32 EarnerNativeRealm = 0;
uint32 EarnerVirtualRealm = 0;
uint32 AchievementID = 0;
time_t Time = time_t(0);
WowTime Time;
bool Initial = false;
ObjectGuid Sender;
};
@@ -169,7 +170,7 @@ namespace WorldPackets
int32 CriteriaID = 0;
Timestamp<> DateCreated;
Timestamp<> DateStarted;
time_t DateUpdated = 0;
WowTime DateUpdated;
uint64 Quantity = 0;
ObjectGuid PlayerGUID;
int32 Unused_10_1_5 = 0;
@@ -216,7 +217,7 @@ namespace WorldPackets
ObjectGuid GuildGUID;
uint32 AchievementID = 0;
time_t TimeDeleted = time_t(0);
WowTime TimeDeleted;
};
class GuildAchievementEarned final : public ServerPacket
@@ -228,7 +229,7 @@ namespace WorldPackets
uint32 AchievementID = 0;
ObjectGuid GuildGUID;
time_t TimeEarned = time_t(0);
WowTime TimeEarned;
};
class AllGuildAchievements final : public ServerPacket
@@ -272,9 +273,9 @@ namespace WorldPackets
int32 AchievementID = 0;
std::vector<GuildAchievementMember> Member;
};
ByteBuffer& operator<<(ByteBuffer& data, CriteriaProgress const& criteria);
}
}
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Achievement::CriteriaProgress const& criteria);
#endif // game_AchievementPackets_h__
@@ -21,7 +21,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Calendar::CalendarSendCal
{
data << uint64(eventInfo.EventID);
data << uint8(eventInfo.EventType);
data.AppendPackedTime(eventInfo.Date);
data << eventInfo.Date;
data << uint32(eventInfo.Flags);
data << int32(eventInfo.TextureID);
data << uint64(eventInfo.EventClubID);
@@ -67,8 +67,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Calendar::CalendarEventIn
data << uint8(inviteInfo.Status);
data << uint8(inviteInfo.Moderator);
data << uint8(inviteInfo.InviteType);
data.AppendPackedTime(inviteInfo.ResponseTime);
data << inviteInfo.ResponseTime;
data.WriteBits(inviteInfo.Notes.size(), 8);
data.FlushBits();
@@ -121,7 +120,7 @@ ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Calendar::CalendarAddEv
buffer >> addEventInfo.ClubID;
buffer >> addEventInfo.EventType;
buffer >> addEventInfo.TextureID;
addEventInfo.Time = buffer.ReadPackedTime();
buffer >> addEventInfo.Time;
buffer >> addEventInfo.Flags;
addEventInfo.Invites.resize(buffer.read<uint32>());
@@ -150,7 +149,7 @@ ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Calendar::CalendarUpdat
buffer >> updateEventInfo.ModeratorID;
buffer >> updateEventInfo.EventType;
buffer >> updateEventInfo.TextureID;
updateEventInfo.Time = buffer.ReadPackedTime();
buffer >> updateEventInfo.Time;
buffer >> updateEventInfo.Flags;
uint8 titleLen = buffer.ReadBits(8);
@@ -181,7 +180,7 @@ void WorldPackets::Calendar::CalendarCopyEvent::Read()
_worldPacket >> EventID;
_worldPacket >> ModeratorID;
_worldPacket >> EventClubID;
Date = _worldPacket.ReadPackedTime();
_worldPacket >> Date;
}
void WorldPackets::Calendar::CalendarRSVP::Read()
@@ -252,7 +251,7 @@ WorldPacket const* WorldPackets::Calendar::CalendarInviteAdded::Write()
_worldPacket << uint8(Level);
_worldPacket << uint8(Status);
_worldPacket << uint8(Type);
_worldPacket.AppendPackedTime(ResponseTime);
_worldPacket << ResponseTime;
_worldPacket.WriteBit(ClearPending);
_worldPacket.FlushBits();
@@ -262,7 +261,7 @@ WorldPacket const* WorldPackets::Calendar::CalendarInviteAdded::Write()
WorldPacket const* WorldPackets::Calendar::CalendarSendCalendar::Write()
{
_worldPacket.AppendPackedTime(ServerTime);
_worldPacket << ServerTime;
_worldPacket << uint32(Invites.size());
_worldPacket << uint32(Events.size());
_worldPacket << uint32(RaidLockouts.size());
@@ -287,8 +286,8 @@ WorldPacket const* WorldPackets::Calendar::CalendarSendEvent::Write()
_worldPacket << uint8(GetEventType);
_worldPacket << int32(TextureID);
_worldPacket << uint32(Flags);
_worldPacket.AppendPackedTime(Date);
_worldPacket << uint32(LockDate);
_worldPacket << Date;
_worldPacket << LockDate;
_worldPacket << uint64(EventClubID);
_worldPacket << uint32(Invites.size());
_worldPacket.WriteBits(EventName.size(), 8);
@@ -307,7 +306,7 @@ WorldPacket const* WorldPackets::Calendar::CalendarSendEvent::Write()
WorldPacket const* WorldPackets::Calendar::CalendarInviteAlert::Write()
{
_worldPacket << uint64(EventID);
_worldPacket.AppendPackedTime(Date);
_worldPacket << Date;
_worldPacket << uint32(Flags);
_worldPacket << uint8(EventType);
_worldPacket << int32(TextureID);
@@ -331,10 +330,10 @@ WorldPacket const* WorldPackets::Calendar::CalendarInviteStatus::Write()
{
_worldPacket << InviteGuid;
_worldPacket << uint64(EventID);
_worldPacket.AppendPackedTime(Date);
_worldPacket << Date;
_worldPacket << uint32(Flags);
_worldPacket << uint8(Status);
_worldPacket.AppendPackedTime(ResponseTime);
_worldPacket << ResponseTime;
_worldPacket.WriteBit(ClearPending);
_worldPacket.FlushBits();
@@ -369,7 +368,7 @@ WorldPacket const* WorldPackets::Calendar::CalendarModeratorStatus::Write()
WorldPacket const* WorldPackets::Calendar::CalendarInviteRemovedAlert::Write()
{
_worldPacket << uint64(EventID);
_worldPacket.AppendPackedTime(Date);
_worldPacket << Date;
_worldPacket << uint32(Flags);
_worldPacket << uint8(Status);
@@ -381,9 +380,9 @@ WorldPacket const* WorldPackets::Calendar::CalendarEventUpdatedAlert::Write()
_worldPacket << uint64(EventClubID);
_worldPacket << uint64(EventID);
_worldPacket.AppendPackedTime(OriginalDate);
_worldPacket.AppendPackedTime(Date);
_worldPacket << uint32(LockDate);
_worldPacket << OriginalDate;
_worldPacket << Date;
_worldPacket << LockDate;
_worldPacket << uint32(Flags);
_worldPacket << uint32(TextureID);
_worldPacket << uint8(EventType);
@@ -402,7 +401,7 @@ WorldPacket const* WorldPackets::Calendar::CalendarEventUpdatedAlert::Write()
WorldPacket const* WorldPackets::Calendar::CalendarEventRemovedAlert::Write()
{
_worldPacket << uint64(EventID);
_worldPacket.AppendPackedTime(Date);
_worldPacket << Date;
_worldPacket.WriteBit(ClearPending);
_worldPacket.FlushBits();
@@ -450,7 +449,7 @@ WorldPacket const* WorldPackets::Calendar::CalendarRaidLockoutRemoved::Write()
WorldPacket const* WorldPackets::Calendar::CalendarRaidLockoutUpdated::Write()
{
_worldPacket.AppendPackedTime(ServerTime);
_worldPacket << ServerTime;
_worldPacket << int32(MapID);
_worldPacket << uint32(DifficultyID);
_worldPacket << int32(OldTimeRemaining);
@@ -474,7 +473,7 @@ WorldPacket const* WorldPackets::Calendar::CalendarCommunityInvite::Write()
WorldPacket const* WorldPackets::Calendar::CalendarInviteStatusAlert::Write()
{
_worldPacket << uint64(EventID);
_worldPacket.AppendPackedTime(Date);
_worldPacket << Date;
_worldPacket << uint32(Flags);
_worldPacket << uint8(Status);
@@ -23,6 +23,7 @@
#include "ObjectGuid.h"
#include "Optional.h"
#include "PacketUtilities.h"
#include "WowTime.h"
namespace WorldPackets
{
@@ -76,7 +77,7 @@ namespace WorldPackets
std::string Description;
uint8 EventType = 0;
int32 TextureID = 0;
time_t Time = time_t(0);
WowTime Time;
uint32 Flags = 0;
Array<CalendarAddEventInviteInfo, CALENDAR_MAX_INVITES> Invites;
};
@@ -101,7 +102,7 @@ namespace WorldPackets
std::string Description;
uint8 EventType = 0;
uint32 TextureID = 0;
time_t Time = time_t(0);
WowTime Time;
uint32 Flags = 0;
};
@@ -139,7 +140,7 @@ namespace WorldPackets
uint64 ModeratorID = 0;
uint64 EventID = 0;
uint64 EventClubID = 0;
time_t Date = time_t(0);
WowTime Date;
};
class CalendarInviteAdded final : public ServerPacket
@@ -150,7 +151,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
uint64 InviteID = 0;
time_t ResponseTime = time_t(0);
WowTime ResponseTime;
uint8 Level = 100;
ObjectGuid InviteGuid;
uint64 EventID = 0;
@@ -183,7 +184,7 @@ namespace WorldPackets
uint64 EventID = 0;
std::string EventName;
uint8 EventType = 0;
time_t Date = time_t(0);
WowTime Date;
uint32 Flags = 0;
int32 TextureID = 0;
uint64 EventClubID = 0;
@@ -197,7 +198,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
time_t ServerTime = time_t(0);
WowTime ServerTime;
std::vector<CalendarSendCalendarInviteInfo> Invites;
std::vector<CalendarSendCalendarRaidLockoutInfo> RaidLockouts;
std::vector<CalendarSendCalendarEventInfo> Events;
@@ -207,7 +208,7 @@ namespace WorldPackets
{
ObjectGuid Guid;
uint64 InviteID = 0;
time_t ResponseTime = time_t(0);
WowTime ResponseTime;
uint8 Level = 1;
uint8 Status = 0;
uint8 Moderator = 0;
@@ -225,8 +226,8 @@ namespace WorldPackets
ObjectGuid OwnerGuid;
uint64 EventClubID = 0;
uint64 EventID = 0;
time_t Date = time_t(0);
time_t LockDate = time_t(0);
WowTime Date;
WowTime LockDate;
uint32 Flags = 0;
int32 TextureID = 0;
uint8 GetEventType = 0;
@@ -249,7 +250,7 @@ namespace WorldPackets
uint64 InviteID = 0;
uint64 EventID = 0;
uint32 Flags = 0;
time_t Date = time_t(0);
WowTime Date;
int32 TextureID = 0;
uint8 Status = 0;
uint8 EventType = 0;
@@ -295,8 +296,8 @@ namespace WorldPackets
uint64 EventID = 0;
uint8 Status = 0;
bool ClearPending = false;
time_t ResponseTime = time_t(0);
time_t Date = time_t(0);
WowTime ResponseTime;
WowTime Date;
ObjectGuid InviteGuid;
};
@@ -334,7 +335,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
uint64 EventID = 0;
time_t Date = time_t(0);
WowTime Date;
uint32 Flags = 0;
uint8 Status = 0;
};
@@ -356,10 +357,10 @@ namespace WorldPackets
uint64 EventClubID = 0;
uint64 EventID = 0;
time_t Date = time_t(0);
WowTime Date;
uint32 Flags = 0;
time_t LockDate = time_t(0);
time_t OriginalDate = time_t(0);
WowTime LockDate;
WowTime OriginalDate;
int32 TextureID = 0;
uint8 EventType = 0;
bool ClearPending = false;
@@ -375,7 +376,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
uint64 EventID = 0;
time_t Date = time_t(0);
WowTime Date;
bool ClearPending = false;
};
@@ -509,7 +510,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
time_t ServerTime = 0;
WowTime ServerTime;
int32 MapID = 0;
uint32 DifficultyID = 0;
int32 NewTimeRemaining = 0;
@@ -543,7 +544,7 @@ namespace WorldPackets
uint64 EventID = 0;
uint32 Flags = 0;
time_t Date = time_t(0);
WowTime Date;
uint8 Status = 0;
};
@@ -64,7 +64,7 @@ WorldPacket const* WorldPackets::Guild::QueryGuildInfoResponse::Write()
WorldPacket const* WorldPackets::Guild::GuildRoster::Write()
{
_worldPacket << int32(NumAccounts);
_worldPacket.AppendPackedTime(CreateDate);
_worldPacket << CreateDate;
_worldPacket << int32(GuildFlags);
_worldPacket << uint32(MemberData.size());
_worldPacket.WriteBits(WelcomeText.length(), 11);
@@ -871,7 +871,7 @@ void WorldPackets::Guild::GuildQueryNews::Read()
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildNewsEvent const& newsEvent)
{
data << int32(newsEvent.Id);
data.AppendPackedTime(newsEvent.CompletedDate);
data << newsEvent.CompletedDate;
data << int32(newsEvent.Type);
data << int32(newsEvent.Flags);
@@ -24,6 +24,7 @@
#include "MythicPlusPacketsCommon.h"
#include "ObjectGuid.h"
#include "PacketUtilities.h"
#include "WowTime.h"
namespace WorldPackets
{
@@ -130,7 +131,7 @@ namespace WorldPackets
std::vector<GuildRosterMemberData> MemberData;
std::string WelcomeText;
std::string InfoText;
uint32 CreateDate = 0;
WowTime CreateDate;
int32 NumAccounts = 0;
int32 GuildFlags = 0;
};
@@ -1073,7 +1074,7 @@ namespace WorldPackets
struct GuildNewsEvent
{
int32 Id = 0;
uint32 CompletedDate = 0;
WowTime CompletedDate;
int32 Type = 0;
int32 Flags = 0;
std::array<int32, 2> Data = { };
@@ -36,8 +36,8 @@ WorldPacket const* WorldPackets::Misc::InvalidatePlayer::Write()
WorldPacket const* WorldPackets::Misc::LoginSetTimeSpeed::Write()
{
_worldPacket.AppendPackedTime(ServerTime);
_worldPacket.AppendPackedTime(GameTime);
_worldPacket << ServerTime;
_worldPacket << GameTime;
_worldPacket << float(NewSpeed);
_worldPacket << uint32(ServerTimeHolidayOffset);
_worldPacket << uint32(GameTimeHolidayOffset);
+3 -2
View File
@@ -28,6 +28,7 @@
#include "Player.h"
#include "Position.h"
#include "SharedDefines.h"
#include "WowTime.h"
#include <array>
#include <map>
@@ -81,8 +82,8 @@ namespace WorldPackets
float NewSpeed = 0.0f;
int32 ServerTimeHolidayOffset = 0;
uint32 GameTime = 0;
uint32 ServerTime = 0;
WowTime GameTime;
WowTime ServerTime;
int32 GameTimeHolidayOffset = 0;
};
@@ -234,9 +234,9 @@ namespace WorldPackets
WorldPacket const* Write() override;
std::string ServerTimeTZ;
std::string GameTimeTZ;
std::string ServerRegionalTZ;
std::string_view ServerTimeTZ;
std::string_view GameTimeTZ;
std::string_view ServerRegionalTZ;
};
}
}
+4 -3
View File
@@ -106,7 +106,7 @@ bool WorldSessionFilter::Process(WorldPacket* packet)
/// WorldSession constructor
WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccountId, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time,
std::string os, LocaleConstant locale, uint32 recruiter, bool isARecruiter):
std::string os, Minutes timezoneOffset, LocaleConstant locale, uint32 recruiter, bool isARecruiter):
m_muteTime(mute_time),
m_timeOutTime(0),
AntiDOS(this),
@@ -118,7 +118,7 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun
_battlenetAccountId(battlenetAccountId),
m_accountExpansion(expansion),
m_expansion(std::min<uint8>(expansion, sWorld->getIntConfig(CONFIG_EXPANSION))),
_os(os),
_os(std::move(os)),
_battlenetRequestToken(0),
_logoutTime(0),
m_inQueue(false),
@@ -127,6 +127,7 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun
m_playerSave(false),
m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)),
m_sessionDbLocaleIndex(locale),
_timezoneOffset(timezoneOffset),
m_latency(0),
_tutorialsChanged(TUTORIALS_FLAG_NONE),
_filterAddonMessages(false),
@@ -153,7 +154,7 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun
LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = {};", GetAccountId()); // One-time query
}
m_Socket[CONNECTION_TYPE_REALM] = sock;
m_Socket[CONNECTION_TYPE_REALM] = std::move(sock);
_instanceConnectKey.Raw = UI64LIT(0);
}
+5 -1
View File
@@ -960,7 +960,7 @@ class TC_GAME_API WorldSession
{
public:
WorldSession(uint32 id, std::string&& name, uint32 battlenetAccountId, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time,
std::string os, LocaleConstant locale, uint32 recruiter, bool isARecruiter);
std::string os, Minutes timezoneOffset, LocaleConstant locale, uint32 recruiter, bool isARecruiter);
~WorldSession();
bool PlayerLoading() const { return !m_playerLoading.IsEmpty(); }
@@ -1143,6 +1143,9 @@ class TC_GAME_API WorldSession
// Locales
LocaleConstant GetSessionDbcLocale() const { return m_sessionDbcLocale; }
LocaleConstant GetSessionDbLocaleIndex() const { return m_sessionDbLocaleIndex; }
Minutes GetTimezoneOffset() const { return _timezoneOffset; }
char const* GetTrinityString(uint32 entry) const;
uint32 GetLatency() const { return m_latency; }
@@ -1937,6 +1940,7 @@ class TC_GAME_API WorldSession
bool m_playerSave;
LocaleConstant m_sessionDbcLocale;
LocaleConstant m_sessionDbLocaleIndex;
Minutes _timezoneOffset;
std::atomic<uint32> m_latency;
AccountData _accountData[NUM_ACCOUNT_DATA_TYPES];
uint32 _tutorials[MAX_ACCOUNT_TUTORIAL_VALUES];
+16 -11
View File
@@ -626,6 +626,7 @@ struct AccountInfo
int64 MuteTime;
uint32 Recruiter;
std::string OS;
Minutes TimezoneOffset;
bool IsRectuiter;
AccountTypes Security;
bool IsBanned;
@@ -633,11 +634,11 @@ struct AccountInfo
bool IsBanned() const { return BattleNet.IsBanned || Game.IsBanned; }
explicit AccountInfo(Field* fields)
explicit AccountInfo(Field const* fields)
{
// 0 1 2 3 4 5 6 7 8 9 10 11
// SELECT a.id, a.session_key, ba.last_ip, ba.locked, ba.lock_country, a.expansion, a.mutetime, ba.locale, a.recruiter, a.os, ba.id, aa.SecurityLevel,
// 12 13 14
// 0 1 2 3 4 5 6 7 8 9 10 11 12
// SELECT a.id, a.session_key, ba.last_ip, ba.locked, ba.lock_country, a.expansion, a.mutetime, ba.locale, a.recruiter, a.os, a.timezone_offset, ba.id, aa.SecurityLevel,
// 13 14 15
// bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id
// FROM account a LEFT JOIN battlenet_accounts ba ON a.battlenet_account = ba.id LEFT JOIN account_access aa ON a.id = aa.AccountID AND aa.RealmID IN (-1, ?)
// LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account_banned ab ON a.id = ab.id LEFT JOIN account r ON a.id = r.recruiter
@@ -652,11 +653,12 @@ struct AccountInfo
BattleNet.Locale = LocaleConstant(fields[7].GetUInt8());
Game.Recruiter = fields[8].GetUInt32();
Game.OS = fields[9].GetString();
BattleNet.Id = fields[10].GetUInt32();
Game.Security = AccountTypes(fields[11].GetUInt8());
BattleNet.IsBanned = fields[12].GetUInt32() != 0;
Game.IsBanned = fields[13].GetUInt32() != 0;
Game.IsRectuiter = fields[14].GetUInt32() != 0;
Game.TimezoneOffset = Minutes(fields[10].GetInt16());
BattleNet.Id = fields[11].GetUInt32();
Game.Security = AccountTypes(fields[12].GetUInt8());
BattleNet.IsBanned = fields[13].GetUInt32() != 0;
Game.IsBanned = fields[14].GetUInt32() != 0;
Game.IsRectuiter = fields[15].GetUInt32() != 0;
if (BattleNet.Locale >= TOTAL_LOCALES)
BattleNet.Locale = LOCALE_enUS;
@@ -670,7 +672,10 @@ void WorldSocket::HandleAuthSession(std::shared_ptr<WorldPackets::Auth::AuthSess
stmt->setInt32(0, int32(realm.Id.Realm));
stmt->setString(1, authSession->RealmJoinTicket);
_queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1)));
_queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback([this, authSession = std::move(authSession)](PreparedQueryResult result) mutable
{
HandleAuthSessionCallback(std::move(authSession), std::move(result));
}));
}
void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth::AuthSession> authSession, PreparedQueryResult result)
@@ -868,7 +873,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth::
_authed = true;
_worldSession = new WorldSession(account.Game.Id, std::move(authSession->RealmJoinTicket), account.BattleNet.Id, shared_from_this(), account.Game.Security,
account.Game.Expansion, mutetime, account.Game.OS, account.BattleNet.Locale, account.Game.Recruiter, account.Game.IsRectuiter);
account.Game.Expansion, mutetime, account.Game.OS, account.Game.TimezoneOffset, account.BattleNet.Locale, account.Game.Recruiter, account.Game.IsRectuiter);
// Initialize Warden system only if it is enabled by config
if (wardenActive)
@@ -126,7 +126,7 @@ uint32 Battlenet::GameUtilitiesService::HandleRealmJoinRequest(std::unordered_ma
{
if (Variant const* realmAddress = GetParam(params, "Param_RealmAddress"))
return sRealmList->JoinRealm(uint32(realmAddress->uint_value()), realm.Build, Trinity::Net::make_address(_session->GetRemoteAddress()), _session->GetRealmListSecret(),
_session->GetSessionDbcLocale(), _session->GetOS(), _session->GetAccountName(), response);
_session->GetSessionDbcLocale(), _session->GetOS(), _session->GetTimezoneOffset(), _session->GetAccountName(), response);
return ERROR_WOW_SERVICES_INVALID_JOIN_TICKET;
}
+17
View File
@@ -17,7 +17,9 @@
#include "GameTime.h"
#include "Timer.h"
#include "Timezone.h"
#include "Util.h"
#include "WowTime.h"
namespace GameTime
{
@@ -31,6 +33,9 @@ namespace GameTime
tm DateTime;
WowTime UtcWow;
WowTime Wow;
time_t GetStartTime()
{
return StartTime;
@@ -84,6 +89,16 @@ namespace GameTime
return &DateTime;
}
WowTime const* GetUtcWowTime()
{
return &UtcWow;
}
WowTime const* GetWowTime()
{
return &Wow;
}
void UpdateGameTimers()
{
GameTime = time(nullptr);
@@ -91,5 +106,7 @@ namespace GameTime
GameTimeSystemPoint = std::chrono::system_clock::now();
GameTimeSteadyPoint = std::chrono::steady_clock::now();
localtime_r(&GameTime, &DateTime);
UtcWow.SetUtcTimeFromUnixTime(GameTime);
Wow = UtcWow + Trinity::Timezone::GetSystemZoneOffsetAt(GameTimeSystemPoint);
}
}
+6
View File
@@ -21,6 +21,8 @@
#include "Define.h"
#include "Duration.h"
class WowTime;
namespace GameTime
{
// Server start time
@@ -47,6 +49,10 @@ namespace GameTime
TC_GAME_API tm const* GetDateAndTime();
TC_GAME_API WowTime const* GetUtcWowTime();
TC_GAME_API WowTime const* GetWowTime();
void UpdateGameTimers();
}
+219
View File
@@ -0,0 +1,219 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "WowTime.h"
#include "ByteBuffer.h"
#include "Errors.h"
#include "Util.h"
uint32 WowTime::GetPackedTime() const
{
return ((_year % 100) & 0x1F) << 24
| (_month & 0xF) << 20
| (_monthDay & 0x3F) << 14
| (_weekDay & 0x7) << 11
| (_hour & 0x1F) << 6
| (_minute & 0x3F)
| (_flags & 0x3) << 29;
}
void WowTime::SetPackedTime(uint32 packedTime)
{
_year = (packedTime >> 24) & 0x1F;
if (_year == 31)
_year = -1;
_month = (packedTime >> 20) & 0xF;
if (_month == 15)
_month = -1;
_monthDay = (packedTime >> 14) & 0x3F;
if (_monthDay == 63)
_monthDay = -1;
_weekDay = (packedTime >> 11) & 0x7;
if (_weekDay == 7)
_weekDay = -1;
_hour = (packedTime >> 6) & 0x1F;
if (_hour == 31)
_hour = -1;
_minute = packedTime & 0x3F;
if (_minute == 63)
_minute = -1;
_flags = (packedTime >> 29) & 0x3;
if (_flags == 3)
_flags = -1;
}
std::time_t WowTime::GetUnixTimeFromUtcTime() const
{
if (_year < 0 || _month < 0 || _monthDay < 0)
return 0;
std::tm buf{};
buf.tm_year = _year + 100;
buf.tm_mon = _month;
buf.tm_mday = _monthDay + 1;
if (_hour >= 0)
{
buf.tm_hour = _hour;
if (_minute >= 0)
buf.tm_min = _minute;
}
buf.tm_isdst = -1;
buf.tm_wday = _weekDay;
return timegm(&buf);
}
void WowTime::SetUtcTimeFromUnixTime(std::time_t unixTime)
{
std::tm buf;
if (!::gmtime_r(&unixTime, &buf))
return;
_year = (buf.tm_year - 100) % 100;
_month = buf.tm_mon;
_monthDay = buf.tm_mday - 1;
_weekDay = buf.tm_wday;
_hour = buf.tm_hour;
_minute = buf.tm_min;
}
void WowTime::SetYear(int32 year)
{
ASSERT(year == -1 || (year >= 0 && year < 32));
_year = year;
}
void WowTime::SetMonth(int8 month)
{
ASSERT(month == -1 || (month >= 0 && month < 12));
_month = month;
}
void WowTime::SetMonthDay(int8 monthDay)
{
ASSERT(monthDay == -1 || (monthDay >= 0 && monthDay < 32));
_monthDay = monthDay;
}
void WowTime::SetWeekDay(int8 weekDay)
{
ASSERT(weekDay == -1 || (weekDay >= 0 && weekDay < 7));
_weekDay = weekDay;
}
void WowTime::SetHour(int8 hour)
{
ASSERT(hour == -1 || (hour >= 0 && hour < 24));
_hour = hour;
}
void WowTime::SetMinute(int8 minute)
{
ASSERT(minute == -1 || (minute >= 0 && minute < 60));
_minute = minute;
}
void WowTime::SetFlags(int8 flags)
{
ASSERT(flags == -1 || (flags >= 0 && flags < 3));
_flags = flags;
}
std::strong_ordering operator<=>(WowTime const& left, WowTime const& right)
{
auto compareFieldIfSet = [&]<typename T>(T WowTime::*field) -> std::strong_ordering
{
if (left.*field < 0 || right.*field < 0)
return std::strong_ordering::equal;
return left.*field <=> right.*field;
};
if (std::strong_ordering cmp = compareFieldIfSet(&WowTime::_year); advstd::is_neq(cmp))
return cmp;
if (std::strong_ordering cmp = compareFieldIfSet(&WowTime::_month); advstd::is_neq(cmp))
return cmp;
if (std::strong_ordering cmp = compareFieldIfSet(&WowTime::_monthDay); advstd::is_neq(cmp))
return cmp;
if (std::strong_ordering cmp = compareFieldIfSet(&WowTime::_weekDay); advstd::is_neq(cmp))
return cmp;
if (std::strong_ordering cmp = compareFieldIfSet(&WowTime::_year); advstd::is_neq(cmp))
return cmp;
if (std::strong_ordering cmp = compareFieldIfSet(&WowTime::_hour); advstd::is_neq(cmp))
return cmp;
return std::strong_ordering::equal;
}
bool WowTime::IsInRange(WowTime const& from, WowTime const& to) const
{
if (from > to)
return *this >= from || *this < to;
return *this >= from && *this < to;
}
WowTime& WowTime::operator+=(Seconds seconds)
{
time_t unixTime = GetUnixTimeFromUtcTime();
unixTime += seconds.count();
SetUtcTimeFromUnixTime(unixTime);
return *this;
}
WowTime WowTime::operator+(Seconds seconds) const
{
return WowTime(*this) += seconds;
}
WowTime& WowTime::operator-=(Seconds seconds)
{
time_t unixTime = GetUnixTimeFromUtcTime();
unixTime -= seconds.count();
SetUtcTimeFromUnixTime(unixTime);
return *this;
}
WowTime WowTime::operator-(Seconds seconds) const
{
return WowTime(*this) -= seconds;
}
ByteBuffer& operator<<(ByteBuffer& data, WowTime const& wowTime)
{
data << uint32(wowTime.GetPackedTime());
return data;
}
ByteBuffer& operator>>(ByteBuffer& data, WowTime& wowTime)
{
uint32 packedTime = 0;
data >> packedTime;
wowTime.SetPackedTime(packedTime);
return data;
}
+90
View File
@@ -0,0 +1,90 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRINITYCORE_WOWTIME_H
#define TRINITYCORE_WOWTIME_H
#include "Define.h"
#include "Duration.h"
#include "advstd.h"
#include <compare>
#include <ctime>
class ByteBuffer;
class WowTime
{
public:
uint32 GetPackedTime() const;
void SetPackedTime(uint32 packedTime);
std::time_t GetUnixTimeFromUtcTime() const;
void SetUtcTimeFromUnixTime(std::time_t unixTime);
int32 GetYear() const { return _year; }
void SetYear(int32 year);
int8 GetMonth() const { return _month; }
void SetMonth(int8 month);
int8 GetMonthDay() const { return _monthDay; }
void SetMonthDay(int8 monthDay);
int8 GetWeekDay() const { return _weekDay; }
void SetWeekDay(int8 weekDay);
int8 GetHour() const { return _hour; }
void SetHour(int8 hour);
int8 GetMinute() const { return _minute; }
void SetMinute(int8 minute);
int8 GetFlags() const { return _flags; }
void SetFlags(int8 flags);
int8 GetHolidayOffset() const { return _holidayOffset; }
void SetHolidayOffset(int8 holidayOffset) { _holidayOffset = holidayOffset; }
friend TC_GAME_API std::strong_ordering operator<=>(WowTime const& left, WowTime const& right);
friend TC_GAME_API bool operator==(WowTime const& left, WowTime const& right)
{
return advstd::is_eq(left <=> right);
}
bool IsInRange(WowTime const& from, WowTime const& to) const;
WowTime& operator+=(Seconds seconds);
WowTime operator+(Seconds seconds) const;
WowTime& operator-=(Seconds seconds);
WowTime operator-(Seconds seconds) const;
friend TC_GAME_API ByteBuffer& operator<<(ByteBuffer& data, WowTime const& wowTime);
friend TC_GAME_API ByteBuffer& operator>>(ByteBuffer& data, WowTime& wowTime);
private:
int32 _year = -1;
int8 _month = -1;
int8 _monthDay = -1;
int8 _weekDay = -1;
int8 _hour = -1;
int8 _minute = -1;
int8 _flags = -1;
int8 _holidayOffset = 0;
};
#endif // TRINITYCORE_WOWTIME_H
-23
View File
@@ -23,7 +23,6 @@
#include <utf8.h>
#include <sstream>
#include <cmath>
#include <ctime>
ByteBuffer::ByteBuffer(MessageBuffer&& buffer) : _rpos(0), _wpos(0), _bitpos(InitialBitPos), _curbitval(0), _storage(buffer.Move())
{
@@ -92,21 +91,6 @@ std::string ByteBuffer::ReadString(uint32 length, bool requireValidUtf8 /*= true
return value;
}
uint32 ByteBuffer::ReadPackedTime()
{
uint32 packedDate = read<uint32>();
tm lt = tm();
lt.tm_min = packedDate & 0x3F;
lt.tm_hour = (packedDate >> 6) & 0x1F;
//lt.tm_wday = (packedDate >> 11) & 7;
lt.tm_mday = ((packedDate >> 14) & 0x3F) + 1;
lt.tm_mon = (packedDate >> 20) & 0xF;
lt.tm_year = ((packedDate >> 24) & 0x1F) + 100;
return uint32(mktime(&lt));
}
void ByteBuffer::append(uint8 const* src, size_t cnt)
{
ASSERT(src, "Attempted to put a NULL-pointer in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", _wpos, size());
@@ -134,13 +118,6 @@ void ByteBuffer::append(uint8 const* src, size_t cnt)
_wpos = newSize;
}
void ByteBuffer::AppendPackedTime(time_t time)
{
tm lt;
localtime_r(&time, &lt);
append<uint32>((lt.tm_year - 100) << 24 | lt.tm_mon << 20 | (lt.tm_mday - 1) << 14 | lt.tm_wday << 11 | lt.tm_hour << 6 | lt.tm_min);
}
void ByteBuffer::put(size_t pos, uint8 const* src, size_t cnt)
{
ASSERT(pos + cnt <= size(), "Attempted to put value with size: " SZFMTD " in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", cnt, pos, size());
-4
View File
@@ -519,8 +519,6 @@ class TC_SHARED_API ByteBuffer
std::string ReadString(uint32 length, bool requireValidUtf8 = true);
uint32 ReadPackedTime();
uint8* contents()
{
if (_storage.empty())
@@ -624,8 +622,6 @@ class TC_SHARED_API ByteBuffer
return resultSize;
}
void AppendPackedTime(time_t time);
void put(size_t pos, uint8 const* src, size_t cnt);
void print_storage() const;
+6 -4
View File
@@ -369,7 +369,7 @@ std::vector<uint8> RealmList::GetRealmList(uint32 build, std::string const& subR
}
uint32 RealmList::JoinRealm(uint32 realmAddress, uint32 build, boost::asio::ip::address const& clientAddress, std::array<uint8, 32> const& clientSecret,
LocaleConstant locale, std::string const& os, std::string accountName, bgs::protocol::game_utilities::v1::ClientResponse* response) const
LocaleConstant locale, std::string const& os, Minutes timezoneOffset, std::string const& accountName, bgs::protocol::game_utilities::v1::ClientResponse* response) const
{
std::shared_lock<std::shared_mutex> lock(_realmsMutex);
if (Realm const* realm = GetRealm(Battlenet::RealmHandle(realmAddress)))
@@ -400,15 +400,17 @@ uint32 RealmList::JoinRealm(uint32 realmAddress, uint32 build, boost::asio::ip::
std::array<uint8, 32> serverSecret = Trinity::Crypto::GetRandomBytes<32>();
std::array<uint8, 64> keyData;
memcpy(&keyData[0], clientSecret.data(), 32);
memcpy(&keyData[32], serverSecret.data(), 32);
auto keyDestItr = keyData.begin();
keyDestItr = std::copy(clientSecret.begin(), clientSecret.end(), keyDestItr);
keyDestItr = std::copy(serverSecret.begin(), serverSecret.end(), keyDestItr);
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_GAME_ACCOUNT_LOGIN_INFO);
stmt->setBinary(0, keyData);
stmt->setString(1, clientAddress.to_string());
stmt->setUInt8(2, locale);
stmt->setString(3, os);
stmt->setString(4, accountName);
stmt->setInt16(4, timezoneOffset.count());
stmt->setString(5, accountName);
LoginDatabase.DirectExecute(stmt);
bgs::protocol::Attribute* attribute = response->add_attribute();
+3 -1
View File
@@ -19,6 +19,7 @@
#define _REALMLIST_H
#include "Define.h"
#include "Duration.h"
#include "Realm.h"
#include <array>
#include <map>
@@ -91,7 +92,8 @@ public:
std::vector<uint8> GetRealmEntryJSON(Battlenet::RealmHandle const& id, uint32 build) const;
std::vector<uint8> GetRealmList(uint32 build, std::string const& subRegion) const;
uint32 JoinRealm(uint32 realmAddress, uint32 build, boost::asio::ip::address const& clientAddress, std::array<uint8, 32> const& clientSecret,
LocaleConstant locale, std::string const& os, std::string accountName, bgs::protocol::game_utilities::v1::ClientResponse* response) const;
LocaleConstant locale, std::string const& os, Minutes timezoneOffset, std::string const& accountName,
bgs::protocol::game_utilities::v1::ClientResponse* response) const;
private:
RealmList();