aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dep/boost/CMakeLists.txt2
-rw-r--r--sql/base/auth_database.sql4
-rw-r--r--sql/updates/auth/master/2023_11_21_00_auth.sql1
-rw-r--r--src/common/Time/Timer.h (renamed from src/common/Utilities/Timer.h)0
-rw-r--r--src/common/Time/Timezone.cpp180
-rw-r--r--src/common/Time/Timezone.h38
-rw-r--r--src/common/Utilities/Hash.h12
-rw-r--r--src/common/Utilities/Util.cpp24
-rw-r--r--src/common/Utilities/Util.h5
-rw-r--r--src/server/authserver/Server/AuthSession.cpp21
-rw-r--r--src/server/authserver/Server/AuthSession.h9
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.cpp4
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp47
-rw-r--r--src/server/game/Achievements/AchievementMgr.h2
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp10
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.cpp18
-rw-r--r--src/server/game/Calendar/CalendarMgr.cpp447
-rw-r--r--src/server/game/Calendar/CalendarMgr.h150
-rw-r--r--src/server/game/Entities/Object/ObjectGuid.cpp6
-rw-r--r--src/server/game/Entities/Object/ObjectGuid.h11
-rw-r--r--src/server/game/Entities/Player/Player.cpp6
-rw-r--r--src/server/game/Guilds/Guild.cpp30
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp613
-rw-r--r--src/server/game/Maps/Map.cpp2
-rw-r--r--src/server/game/Server/Packets/AllPackets.h1
-rw-r--r--src/server/game/Server/Packets/CalendarPackets.cpp471
-rw-r--r--src/server/game/Server/Packets/CalendarPackets.h605
-rw-r--r--src/server/game/Server/Packets/GuildPackets.cpp2
-rw-r--r--src/server/game/Server/Packets/GuildPackets.h6
-rw-r--r--src/server/game/Server/Packets/MiscPackets.cpp2
-rw-r--r--src/server/game/Server/Packets/MiscPackets.h3
-rw-r--r--src/server/game/Server/WorldSession.cpp10
-rw-r--r--src/server/game/Server/WorldSession.h67
-rw-r--r--src/server/game/Server/WorldSocket.cpp23
-rw-r--r--src/server/game/Time/GameTime.cpp18
-rw-r--r--src/server/game/Time/GameTime.h6
-rw-r--r--src/server/game/Time/WowTime.cpp219
-rw-r--r--src/server/game/Time/WowTime.h90
-rw-r--r--src/server/shared/Packets/ByteBuffer.cpp23
-rw-r--r--src/server/shared/Packets/ByteBuffer.h10
-rw-r--r--src/server/shared/Realm/RealmList.h1
41 files changed, 2394 insertions, 805 deletions
diff --git a/dep/boost/CMakeLists.txt b/dep/boost/CMakeLists.txt
index 65d5c9355e4..330c14f6d51 100644
--- a/dep/boost/CMakeLists.txt
+++ b/dep/boost/CMakeLists.txt
@@ -35,7 +35,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)
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index 0018c699df4..3e2f026cfb8 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -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(3) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
+ `timezone_offset` smallint NOT NULL DEFAULT '0',
`recruiter` int unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
@@ -2008,7 +2009,8 @@ INSERT INTO `updates` VALUES
('2023_02_05_00_auth.sql','DC8A2046EB4201D55342C541A0E9C398499E12B1','ARCHIVED','2023-02-05 14:50:30',0),
('2023_02_05_01_auth.sql','336E62A8850A3E78A1D0BD3E81FFD5769184BDF8','ARCHIVED','2023-02-05 15:58:32',0),
('2023_05_05_00_auth.sql','DEEB1D5533658E3479FC3C988EF4B9816C511BC3','ARCHIVED','2023-05-07 11:52:00',0),
-('2023_06_14_00_auth.sql','BB8A7EB214F4F3632C4F54EA596CB7C8FBA305D5','ARCHIVED','2023-06-14 19:34:24',0);
+('2023_06_14_00_auth.sql','BB8A7EB214F4F3632C4F54EA596CB7C8FBA305D5','ARCHIVED','2023-06-14 19:34:24',0),
+('2023_11_21_00_auth.sql','146E5E6EF94C5DB78343372A8FDB32B062B80040','RELEASED','2023-11-21 11:24:11',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/auth/master/2023_11_21_00_auth.sql b/sql/updates/auth/master/2023_11_21_00_auth.sql
new file mode 100644
index 00000000000..1dc190782d7
--- /dev/null
+++ b/sql/updates/auth/master/2023_11_21_00_auth.sql
@@ -0,0 +1 @@
+ALTER TABLE `account` ADD `timezone_offset` smallint NOT NULL DEFAULT '0' AFTER `os`;
diff --git a/src/common/Utilities/Timer.h b/src/common/Time/Timer.h
index 89fa2a0ef1a..89fa2a0ef1a 100644
--- a/src/common/Utilities/Timer.h
+++ b/src/common/Time/Timer.h
diff --git a/src/common/Time/Timezone.cpp b/src/common/Time/Timezone.cpp
new file mode 100644
index 00000000000..6bc5773edc3
--- /dev/null
+++ b/src/common/Time/Timezone.cpp
@@ -0,0 +1,180 @@
+/*
+ * 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 "StringConvert.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;
+}
+}
diff --git a/src/common/Time/Timezone.h b/src/common/Time/Timezone.h
new file mode 100644
index 00000000000..3515617ab13
--- /dev/null
+++ b/src/common/Time/Timezone.h
@@ -0,0 +1,38 @@
+/*
+ * 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"
+#include <string>
+
+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
diff --git a/src/common/Utilities/Hash.h b/src/common/Utilities/Hash.h
index 0486d338a70..5aa3ba05331 100644
--- a/src/common/Utilities/Hash.h
+++ b/src/common/Utilities/Hash.h
@@ -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
diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp
index 9c77e9f9821..8ca639ba6a4 100644
--- a/src/common/Utilities/Util.cpp
+++ b/src/common/Utilities/Util.cpp
@@ -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);
diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h
index 62c8655b65f..14d633e2ae8 100644
--- a/src/common/Utilities/Util.h
+++ b/src/common/Utilities/Util.h
@@ -51,8 +51,11 @@ namespace Trinity
TC_COMMON_API Optional<int32> 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 time_t LocalTimeToUTCTime(time_t time);
+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 GetLocalHourTimestamp(time_t time, uint8 hour, bool onlyAfterTime = true);
TC_COMMON_API tm TimeBreakdown(time_t t);
diff --git a/src/server/authserver/Server/AuthSession.cpp b/src/server/authserver/Server/AuthSession.cpp
index d9058b3392a..ba2ef766ac7 100644
--- a/src/server/authserver/Server/AuthSession.cpp
+++ b/src/server/authserver/Server/AuthSession.cpp
@@ -18,21 +18,19 @@
#include "AuthSession.h"
#include "AES.h"
#include "AuthCodes.h"
+#include "ByteBuffer.h"
#include "Config.h"
#include "CryptoGenerics.h"
+#include "CryptoHash.h"
#include "CryptoRandom.h"
#include "DatabaseEnv.h"
-#include "Errors.h"
-#include "CryptoHash.h"
#include "IPLocation.h"
#include "Log.h"
#include "RealmList.h"
#include "SecretMgr.h"
-#include "Timer.h"
#include "TOTP.h"
#include "Util.h"
#include <boost/lexical_cast.hpp>
-#include <openssl/crypto.h>
using boost::asio::ip::tcp;
@@ -161,7 +159,7 @@ void AccountInfo::LoadResult(Field* fields)
}
AuthSession::AuthSession(tcp::socket&& socket) : Socket(std::move(socket)),
-_status(STATUS_CHALLENGE), _build(0), _expversion(0) { }
+_status(STATUS_CHALLENGE), _build(0), _timezoneOffset(0min), _expversion(0) { }
void AuthSession::Start()
{
@@ -300,11 +298,14 @@ bool AuthSession::HandleLogonChallenge()
for (int i = 0; i < 4; ++i)
_localizationName[i] = challenge->country[4 - i - 1];
+ _timezoneOffset = Minutes(challenge->timezone_bias);
+
// Get the account details from the account table
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGONCHALLENGE);
stmt->setString(0, login);
- _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&AuthSession::LogonChallengeCallback, this, std::placeholders::_1)));
+ _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback([this](PreparedQueryResult result) { LogonChallengeCallback(std::move(result)); }));
return true;
}
@@ -513,7 +514,8 @@ bool AuthSession::HandleLogonProof()
stmt->setString(1, address);
stmt->setUInt32(2, GetLocaleByName(_localizationName));
stmt->setString(3, _os);
- stmt->setString(4, _accountInfo.Login);
+ stmt->setInt16(4, _timezoneOffset.count());
+ stmt->setString(5, _accountInfo.Login);
LoginDatabase.DirectExecute(stmt);
// Finish SRP6 and send the final result to the client
@@ -636,11 +638,14 @@ bool AuthSession::HandleReconnectChallenge()
for (int i = 0; i < 4; ++i)
_localizationName[i] = challenge->country[4 - i - 1];
+ _timezoneOffset = Minutes(challenge->timezone_bias);
+
// Get the account details from the account table
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RECONNECTCHALLENGE);
stmt->setString(0, login);
- _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&AuthSession::ReconnectChallengeCallback, this, std::placeholders::_1)));
+ _queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt)
+ .WithPreparedCallback([this](PreparedQueryResult result) { ReconnectChallengeCallback(std::move(result)); }));
return true;
}
diff --git a/src/server/authserver/Server/AuthSession.h b/src/server/authserver/Server/AuthSession.h
index 71af8272501..844de0ed787 100644
--- a/src/server/authserver/Server/AuthSession.h
+++ b/src/server/authserver/Server/AuthSession.h
@@ -19,20 +19,18 @@
#define __AUTHSESSION_H__
#include "AsyncCallbackProcessor.h"
-#include "BigNumber.h"
-#include "ByteBuffer.h"
#include "Common.h"
#include "CryptoHash.h"
+#include "DatabaseEnvFwd.h"
+#include "Duration.h"
#include "Optional.h"
#include "Socket.h"
#include "SRP6.h"
-#include "QueryResult.h"
-#include <memory>
#include <boost/asio/ip/tcp.hpp>
using boost::asio::ip::tcp;
-class Field;
+class ByteBuffer;
struct AuthHandler;
enum AuthStatus
@@ -102,6 +100,7 @@ private:
std::string _os;
std::string _ipCountry;
uint16 _build;
+ Minutes _timezoneOffset;
uint8 _expversion;
QueryCallbackProcessor _queryProcessor;
diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp
index 6939c2120aa..71023e8e9e2 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/database/Database/Implementation/LoginDatabase.cpp
@@ -36,7 +36,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_INS_ACCOUNT_AUTO_BANNED, "INSERT INTO account_banned (id, bandate, unbandate, bannedby, banreason, active) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity Auth', 'Failed login autoban', 1)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_DEL_ACCOUNT_BANNED, "DELETE FROM account_banned WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_LOGON, "UPDATE account SET salt = ?, verifier = ? WHERE id = ?", CONNECTION_ASYNC);
- PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET session_key_auth = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET session_key_auth = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ?, timezone_offset = ? WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.id, a.username, a.locked, a.lock_country, a.last_ip, a.failed_logins, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, "
"ab.unbandate = ab.bandate, aa.SecurityLevel, a.totp_secret, a.salt, a.verifier "
"FROM account a LEFT JOIN account_access aa ON a.id = aa.AccountID LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 WHERE a.username = ?", CONNECTION_ASYNC);
@@ -46,7 +46,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_UPD_FAILEDLOGINS, "UPDATE account SET failed_logins = failed_logins + 1 WHERE username = ?", 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_auth, a.last_ip, a.locked, a.lock_country, a.expansion, a.mutetime, a.locale, a.recruiter, a.os, aa.SecurityLevel, "
+ PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT a.id, a.session_key_auth, a.last_ip, a.locked, a.lock_country, a.expansion, a.mutetime, a.locale, a.recruiter, a.os, a.timezone_offset, aa.SecurityLevel, "
"ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id FROM account a LEFT JOIN account_access aa ON a.id = aa.AccountID AND aa.RealmID IN (-1, ?) "
"LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account r ON a.id = r.recruiter WHERE a.username = ? AND a.session_key_auth IS NOT NULL ORDER BY aa.RealmID DESC LIMIT 1", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, "SELECT id, username FROM account WHERE email = ?", CONNECTION_SYNCH);
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 5db2f3dcc6c..a7c9960abf9 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -44,6 +44,7 @@
#include "SpellMgr.h"
#include "World.h"
#include "WorldSession.h"
+#include "WowTime.h"
bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
{
@@ -705,16 +706,30 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
Cell::VisitWorldObjects(GetPlayer(), _worker, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY));
}
- WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8);
- data << GetPlayer()->GetPackGUID();
- data << uint32(achievement->ID);
- data.AppendPackedTime(GameTime::GetGameTime());
- data << uint32(0);
- GetPlayer()->SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true);
+ auto achievementEarnedBuilder = [&](Player const* receiver)
+ {
+ WowTime now = *GameTime::GetUtcWowTime();
+ now += receiver->GetSession()->GetTimezoneOffset();
+
+ WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8 + 4 + 8);
+ data << GetPlayer()->GetPackGUID();
+ data << uint32(achievement->ID);
+ data << now;
+ data << uint32(0);
+ receiver->SendDirectMessage(&data);
+ };
+
+ float dist = sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY);
+ Trinity::PlayerDistWorker notifier(GetPlayer(), dist, achievementEarnedBuilder);
+ Cell::VisitWorldObjects(GetPlayer(), notifier, dist);
}
void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const
{
+ WowTime date;
+ date.SetUtcTimeFromUnixTime(progress->date);
+ date += GetPlayer()->GetSession()->GetTimezoneOffset();
+
WorldPacket data(SMSG_CRITERIA_UPDATE, 8 + 4 + 8);
data << uint32(entry->ID);
@@ -726,7 +741,7 @@ void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, C
data << uint32(0);
else
data << uint32(timedCompleted ? 1 : 0); // this are some flags, 1 is for keeping the counter at 0 in client
- data.AppendPackedTime(progress->date);
+ data << date;
data << uint32(timeElapsed); // time elapsed in seconds
data << uint32(0); // unk
GetPlayer()->SendDirectMessage(&data);
@@ -1575,7 +1590,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
void AchievementMgr::SendAllAchievementData() const
{
WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, m_completedAchievements.size() * 8 + 4 + m_criteriaProgress.size() * 38 + 4);
- BuildAllDataPacket(&data);
+ BuildAllDataPacket(GetPlayer(), &data);
GetPlayer()->SendDirectMessage(&data);
}
@@ -1583,14 +1598,14 @@ void AchievementMgr::SendRespondInspectAchievements(Player* player) const
{
WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 9 + m_completedAchievements.size() * 8 + 4 + m_criteriaProgress.size() * 38 + 4);
data << GetPlayer()->GetPackGUID();
- BuildAllDataPacket(&data);
+ BuildAllDataPacket(player, &data);
player->SendDirectMessage(&data);
}
/**
* used by SMSG_RESPOND_INSPECT_ACHIEVEMENT and SMSG_ALL_ACHIEVEMENT_DATA
*/
-void AchievementMgr::BuildAllDataPacket(WorldPacket* data) const
+void AchievementMgr::BuildAllDataPacket(Player const* receiver, WorldPacket* data) const
{
for (std::pair<uint32 const, CompletedAchievementData> const& completedAchievement : m_completedAchievements)
{
@@ -1599,18 +1614,26 @@ void AchievementMgr::BuildAllDataPacket(WorldPacket* data) const
if (!achievement || achievement->Flags & ACHIEVEMENT_FLAG_HIDDEN)
continue;
+ WowTime date;
+ date.SetUtcTimeFromUnixTime(completedAchievement.second.date);
+ date += receiver->GetSession()->GetTimezoneOffset();
+
*data << uint32(completedAchievement.first);
- data->AppendPackedTime(completedAchievement.second.date);
+ *data << date;
}
*data << int32(-1);
for (std::pair<uint32 const, CriteriaProgress> const& criteriaProgress : m_criteriaProgress)
{
+ WowTime date;
+ date.SetUtcTimeFromUnixTime(criteriaProgress.second.date);
+ date += receiver->GetSession()->GetTimezoneOffset();
+
*data << uint32(criteriaProgress.first);
data->appendPackGUID(criteriaProgress.second.counter);
*data << GetPlayer()->GetPackGUID();
*data << uint32(0);
- data->AppendPackedTime(criteriaProgress.second.date);
+ *data << date;
*data << uint32(0);
*data << uint32(0);
}
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index 1daaf0b3703..28041c35e77 100644
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -302,7 +302,7 @@ class TC_GAME_API AchievementMgr
bool IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement);
bool IsCompletedAchievement(AchievementEntry const* entry);
bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint32 miscValue1, uint32 miscValue2, WorldObject const* ref);
- void BuildAllDataPacket(WorldPacket* data) const;
+ void BuildAllDataPacket(Player const* receiver, WorldPacket* data) const;
bool ConditionsSatisfied(AchievementCriteriaEntry const* criteria) const;
bool RequirementsSatisfied(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint32 miscValue1, uint32 miscValue2, WorldObject const* ref) const;
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index a05e4a0b5b1..a797cc2c8de 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -31,11 +31,10 @@
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Player.h"
-#include "Realm.h"
#include "ScriptMgr.h"
#include "World.h"
-#include "WorldPacket.h"
#include "WorldSession.h"
+#include "WowTime.h"
enum eAuctionHouse
{
@@ -195,12 +194,13 @@ void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry* auction, Characte
// owner exist (online or offline)
if ((owner || owner_accId) && !sAuctionBotConfig->IsBotChar(auction->owner))
{
- ByteBuffer timePacker;
- timePacker.AppendPackedTime(GameTime::GetGameTime() + sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY));
+ WowTime eta = *GameTime::GetUtcWowTime();
+ eta += Seconds(sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY));
+ eta += owner->GetSession()->GetTimezoneOffset();
MailDraft(auction->BuildAuctionMailSubject(AUCTION_SALE_PENDING),
AuctionEntry::BuildAuctionInvoiceMailBody(ObjectGuid::Create<HighGuid::Player>(auction->bidder), auction->bid, auction->buyout, auction->deposit,
- auction->GetAuctionCut(), sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY), timePacker.read<uint32>()))
+ auction->GetAuctionCut(), sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY), eta.GetPackedTime()))
.SendMailTo(trans, MailReceiver(owner, auction->owner), auction, MAIL_CHECK_MASK_COPIED);
}
}
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
index ed14ea64729..f9901f3c422 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
@@ -18,6 +18,7 @@
#include "ArenaTeam.h"
#include "ArenaTeamMgr.h"
#include "BattlegroundMgr.h"
+#include "CalendarPackets.h"
#include "CharacterCache.h"
#include "DatabaseEnv.h"
#include "Group.h"
@@ -27,7 +28,6 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "World.h"
-#include "WorldPacket.h"
#include "WorldSession.h"
ArenaTeam::ArenaTeam()
@@ -581,19 +581,13 @@ void ArenaTeam::BroadcastEvent(ArenaTeamEvents event, ObjectGuid guid, uint8 str
void ArenaTeam::MassInviteToEvent(WorldSession* session)
{
- WorldPacket data(SMSG_CALENDAR_ARENA_TEAM, (Members.size() - 1) * (4 + 8 + 1));
- data << uint32(Members.size() - 1);
+ WorldPackets::Calendar::CalendarEventInitialInvites packet(false);
- for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
- {
- if (itr->Guid != session->GetPlayer()->GetGUID())
- {
- data << itr->Guid.WriteAsPacked();
- data << uint8(0); // unk
- }
- }
+ for (ArenaTeamMember const& member : Members)
+ if (member.Guid != session->GetPlayer()->GetGUID())
+ packet.Invites.emplace_back(member.Guid, 0);
- session->SendPacket(&data);
+ session->SendPacket(packet.Write());
}
uint8 ArenaTeam::GetSlotByType(uint32 type)
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp
index 535004696ab..3b10ccff017 100644
--- a/src/server/game/Calendar/CalendarMgr.cpp
+++ b/src/server/game/Calendar/CalendarMgr.cpp
@@ -16,6 +16,7 @@
*/
#include "CalendarMgr.h"
+#include "CalendarPackets.h"
#include "CharacterCache.h"
#include "DatabaseEnv.h"
#include "GameTime.h"
@@ -23,13 +24,15 @@
#include "GuildMgr.h"
#include "Log.h"
#include "Mail.h"
+#include "MapUtils.h"
#include "ObjectAccessor.h"
-#include "Opcodes.h"
#include "Player.h"
-#include "WorldPacket.h"
+#include "StringConvert.h"
+#include "WorldSession.h"
+#include "WowTime.h"
-CalendarInvite::CalendarInvite() : _inviteId(1), _eventId(0), _invitee(), _senderGUID(), _statusTime(GameTime::GetGameTime()),
-_status(CALENDAR_STATUS_INVITED), _rank(CALENDAR_RANK_PLAYER), _text("") { }
+CalendarInvite::CalendarInvite() : _inviteId(1), _eventId(0), _invitee(), _senderGUID(), _responseTime(0),
+_status(CALENDAR_STATUS_INVITED), _rank(CALENDAR_RANK_PLAYER), _note() { }
CalendarInvite::~CalendarInvite()
{
@@ -75,24 +78,24 @@ void CalendarMgr::LoadFromDB()
{
Field* fields = result->Fetch();
- uint64 eventId = fields[0].GetUInt64();
- ObjectGuid creatorGUID = ObjectGuid(HighGuid::Player, fields[1].GetUInt32());
+ uint64 eventID = fields[0].GetUInt64();
+ ObjectGuid ownerGUID = ObjectGuid::Create<HighGuid::Player>(fields[1].GetUInt32());
std::string title = fields[2].GetString();
std::string description = fields[3].GetString();
CalendarEventType type = CalendarEventType(fields[4].GetUInt8());
- int32 dungeonId = fields[5].GetInt32();
- uint32 eventTime = fields[6].GetUInt32();
+ int32 textureID = fields[5].GetInt32();
+ time_t date = fields[6].GetUInt32();
uint32 flags = fields[7].GetUInt32();
- uint32 timezoneTime = fields[8].GetUInt32();
- ObjectGuid::LowType guildId = 0;
+ time_t lockDate = fields[8].GetUInt32();
+ ObjectGuid::LowType guildID = UI64LIT(0);
if (flags & CALENDAR_FLAG_GUILD_EVENT || flags & CALENDAR_FLAG_WITHOUT_INVITES)
- guildId = sCharacterCache->GetCharacterGuildIdByGuid(creatorGUID);
+ guildID = sCharacterCache->GetCharacterGuildIdByGuid(ownerGUID);
- CalendarEvent* calendarEvent = new CalendarEvent(eventId, creatorGUID, guildId, type, dungeonId, time_t(eventTime), flags, time_t(timezoneTime), title, description);
+ CalendarEvent* calendarEvent = new CalendarEvent(eventID, ownerGUID, guildID, type, textureID, date, flags, title, description, lockDate);
_events.insert(calendarEvent);
- _maxEventId = std::max(_maxEventId, eventId);
+ _maxEventId = std::max(_maxEventId, eventID);
++count;
}
@@ -110,14 +113,14 @@ void CalendarMgr::LoadFromDB()
uint64 inviteId = fields[0].GetUInt64();
uint64 eventId = fields[1].GetUInt64();
- ObjectGuid invitee = ObjectGuid(HighGuid::Player, fields[2].GetUInt32());
- ObjectGuid senderGUID = ObjectGuid(HighGuid::Player, fields[3].GetUInt32());
+ ObjectGuid invitee = ObjectGuid::Create<HighGuid::Player>(fields[2].GetUInt32());
+ ObjectGuid senderGUID = ObjectGuid::Create<HighGuid::Player>(fields[3].GetUInt32());
CalendarInviteStatus status = CalendarInviteStatus(fields[4].GetUInt8());
- uint32 statusTime = fields[5].GetUInt32();
+ time_t responseTime = fields[5].GetUInt32();
CalendarModerationRank rank = CalendarModerationRank(fields[6].GetUInt8());
- std::string text = fields[7].GetString();
+ std::string note = fields[7].GetString();
- CalendarInvite* invite = new CalendarInvite(inviteId, eventId, invitee, senderGUID, time_t(statusTime), status, rank, text);
+ CalendarInvite* invite = new CalendarInvite(inviteId, eventId, invitee, senderGUID, responseTime, status, rank, note);
_invites[eventId].push_back(invite);
_maxInviteId = std::max(_maxInviteId, inviteId);
@@ -141,7 +144,7 @@ void CalendarMgr::AddEvent(CalendarEvent* calendarEvent, CalendarSendEventType s
{
_events.insert(calendarEvent);
UpdateEvent(calendarEvent);
- SendCalendarEvent(calendarEvent->GetCreatorGUID(), *calendarEvent, sendType);
+ SendCalendarEvent(calendarEvent->GetOwnerGUID(), *calendarEvent, sendType);
}
void CalendarMgr::AddInvite(CalendarEvent* calendarEvent, CalendarInvite* invite, CharacterDatabaseTransaction trans)
@@ -149,7 +152,7 @@ void CalendarMgr::AddInvite(CalendarEvent* calendarEvent, CalendarInvite* invite
if (!calendarEvent->IsGuildAnnouncement())
SendCalendarEventInvite(*invite);
- if (!calendarEvent->IsGuildEvent() || invite->GetInviteeGUID() == calendarEvent->GetCreatorGUID())
+ if (!calendarEvent->IsGuildEvent() || invite->GetInviteeGUID() == calendarEvent->GetOwnerGUID())
SendCalendarEventInviteAlert(*calendarEvent, *invite);
if (!calendarEvent->IsGuildAnnouncement())
@@ -184,7 +187,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)
@@ -196,8 +198,11 @@ 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 && invite->GetInviteeGUID() != remover)
+ 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;
}
@@ -252,14 +257,14 @@ void CalendarMgr::UpdateEvent(CalendarEvent* calendarEvent)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CALENDAR_EVENT);
stmt->setUInt64(0, calendarEvent->GetEventId());
- stmt->setUInt32(1, calendarEvent->GetCreatorGUID().GetCounter());
+ stmt->setUInt32(1, calendarEvent->GetOwnerGUID().GetCounter());
stmt->setString(2, calendarEvent->GetTitle());
stmt->setString(3, calendarEvent->GetDescription());
stmt->setUInt8(4, calendarEvent->GetType());
- stmt->setInt32(5, calendarEvent->GetDungeonId());
- stmt->setUInt32(6, uint32(calendarEvent->GetEventTime()));
+ stmt->setInt32(5, calendarEvent->GetTextureId());
+ stmt->setUInt32(6, calendarEvent->GetDate());
stmt->setUInt32(7, calendarEvent->GetFlags());
- stmt->setUInt32(8, calendarEvent->GetTimeZoneTime()); // correct?
+ stmt->setUInt32(8, calendarEvent->GetLockDate());
CharacterDatabase.Execute(stmt);
}
@@ -271,9 +276,9 @@ void CalendarMgr::UpdateInvite(CalendarInvite* invite, CharacterDatabaseTransact
stmt->setUInt32(2, invite->GetInviteeGUID().GetCounter());
stmt->setUInt32(3, invite->GetSenderGUID().GetCounter());
stmt->setUInt8(4, invite->GetStatus());
- stmt->setUInt32(5, uint32(invite->GetStatusTime()));
+ stmt->setUInt32(5, invite->GetResponseTime());
stmt->setUInt8(6, invite->GetRank());
- stmt->setString(7, invite->GetText());
+ stmt->setString(7, invite->GetNote());
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
@@ -283,7 +288,7 @@ void CalendarMgr::RemoveAllPlayerEventsAndInvites(ObjectGuid guid)
{
CalendarEvent* event = *itr;
++itr;
- if (event->GetCreatorGUID() == guid)
+ if (event->GetOwnerGUID() == guid)
RemoveEvent(event, ObjectGuid::Empty); // don't send mail if removing a character
}
@@ -295,7 +300,7 @@ void CalendarMgr::RemoveAllPlayerEventsAndInvites(ObjectGuid guid)
void CalendarMgr::RemovePlayerGuildEventsAndSignups(ObjectGuid guid, ObjectGuid::LowType guildId)
{
for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr)
- if ((*itr)->GetCreatorGUID() == guid && ((*itr)->IsGuildEvent() || (*itr)->IsGuildAnnouncement()))
+ if ((*itr)->GetOwnerGUID() == guid && ((*itr)->IsGuildEvent() || (*itr)->IsGuildAnnouncement()))
RemoveEvent((*itr)->GetEventId(), guid);
CalendarInviteStore playerInvites = GetPlayerInvites(guid);
@@ -370,22 +375,22 @@ void CalendarMgr::DeleteOldEvents()
{
CalendarEvent* event = *itr;
++itr;
- if (event->GetEventTime() < oldEventsTime)
+ if (event->GetDate() < oldEventsTime)
RemoveEvent(event, ObjectGuid::Empty);
}
}
-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)
- if ((*itr)->GetCreatorGUID() == guid && (includeGuildEvents || (!(*itr)->IsGuildEvent() && !(*itr)->IsGuildAnnouncement())))
+ if ((*itr)->GetOwnerGUID() == guid && (includeGuildEvents || (!(*itr)->IsGuildEvent() && !(*itr)->IsGuildAnnouncement())))
result.insert(*itr);
return result;
}
-CalendarEventStore CalendarMgr::GetGuildEvents(ObjectGuid::LowType guildId)
+CalendarEventStore CalendarMgr::GetGuildEvents(ObjectGuid::LowType guildId) const
{
CalendarEventStore result;
@@ -400,7 +405,7 @@ CalendarEventStore CalendarMgr::GetGuildEvents(ObjectGuid::LowType guildId)
return result;
}
-CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid)
+CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid) const
{
CalendarEventStore events;
@@ -419,12 +424,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;
@@ -460,254 +469,298 @@ uint32 CalendarMgr::GetPlayerNumPending(ObjectGuid guid)
std::string CalendarEvent::BuildCalendarMailSubject(ObjectGuid remover) const
{
- std::ostringstream strm;
- strm << remover.GetRawValue() << ':' << _title;
- return strm.str();
+ return Trinity::StringFormat("{}:{}", remover.GetRawValue(), _title);
}
-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(_eventTime);
- 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());
- time_t statusTime = invite.GetStatusTime();
- bool hasStatusTime = statusTime != 946684800; // 01/01/2000 00:00:00
ObjectGuid invitee = invite.GetInviteeGUID();
Player* player = ObjectAccessor::FindConnectedPlayer(invitee);
uint8 level = player ? player->GetLevel() : sCharacterCache->GetCharacterLevelByGuid(invitee);
- WorldPacket data(SMSG_CALENDAR_EVENT_INVITE, 8 + 8 + 8 + 1 + 1 + 1 + (4) + 1);
- data << invitee.WriteAsPacked();
- data << uint64(invite.GetEventId());
- data << uint64(invite.GetInviteId());
- data << uint8(level);
- data << uint8(invite.GetStatus());
- data << uint8(hasStatusTime);
- if (hasStatusTime)
- data.AppendPackedTime(statusTime);
- data << uint8(invite.GetSenderGUID() != invite.GetInviteeGUID()); // false only if the invite is sign-up
+ 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;
+ packet.ClearPending = invite.GetSenderGUID() != invite.GetInviteeGUID();
+
+ receiver->SendDirectMessage(packet.Write());
+ };
if (!calendarEvent) // Pre-invite
{
if (Player* playerSender = ObjectAccessor::FindConnectedPlayer(invite.GetSenderGUID()))
- playerSender->SendDirectMessage(&data);
+ packetBuilder(playerSender);
}
else
{
- if (calendarEvent->GetCreatorGUID() != invite.GetInviteeGUID()) // correct?
- SendPacketToAllEventRelatives(data, *calendarEvent);
+ if (calendarEvent->GetOwnerGUID() != invite.GetInviteeGUID()) // correct?
+ for (Player* receiver : GetAllEventRelatives(*calendarEvent))
+ packetBuilder(receiver);
}
}
-void CalendarMgr::SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, time_t oldEventTime)
+void CalendarMgr::SendCalendarEventUpdateAlert(CalendarEvent const& calendarEvent, time_t originalDate) const
{
- WorldPacket data(SMSG_CALENDAR_EVENT_UPDATED_ALERT, 1 + 8 + 4 + 4 + 4 + 1 + 4 +
- calendarEvent.GetTitle().size() + calendarEvent.GetDescription().size() + 1 + 4 + 4);
- data << uint8(1); // unk
- data << uint64(calendarEvent.GetEventId());
- data.AppendPackedTime(oldEventTime);
- data << uint32(calendarEvent.GetFlags());
- data.AppendPackedTime(calendarEvent.GetEventTime());
- data << uint8(calendarEvent.GetType());
- data << int32(calendarEvent.GetDungeonId());
- data << calendarEvent.GetTitle();
- data << calendarEvent.GetDescription();
- data << uint8(CALENDAR_REPEAT_NEVER); // repeatable
- data << uint32(CALENDAR_MAX_INVITES);
- data << uint32(0); // unk
-
- SendPacketToAllEventRelatives(data, calendarEvent);
-}
+ auto packetBuilder = [&](Player const* receiver)
+ {
+ WorldPackets::Calendar::CalendarEventUpdatedAlert packet;
+ packet.ClearPending = calendarEvent.GetOwnerGUID() == receiver->GetGUID();
+ packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
+ packet.Date += receiver->GetSession()->GetTimezoneOffset();
+ packet.Description = calendarEvent.GetDescription();
+ 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();
+
+ receiver->SendDirectMessage(packet.Write());
+ };
+
+ for (Player* receiver : GetAllEventRelatives(calendarEvent))
+ packetBuilder(receiver);
+}
+
+void CalendarMgr::SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const
+{
+ auto packetBuilder = [&](Player const* receiver)
+ {
+ WorldPackets::Calendar::CalendarInviteStatus packet;
+ packet.ClearPending = invite.GetInviteeGUID() == receiver->GetGUID();
+ 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();
-void CalendarMgr::SendCalendarEventStatus(CalendarEvent const& calendarEvent, CalendarInvite const& invite)
-{
- WorldPacket data(SMSG_CALENDAR_EVENT_STATUS, 8 + 8 + 4 + 4 + 1 + 1 + 4);
- data << invite.GetInviteeGUID().WriteAsPacked();
- data << uint64(calendarEvent.GetEventId());
- data.AppendPackedTime(calendarEvent.GetEventTime());
- data << uint32(calendarEvent.GetFlags());
- data << uint8(invite.GetStatus());
- data << uint8(invite.GetRank());
- data.AppendPackedTime(invite.GetStatusTime());
+ receiver->SendDirectMessage(packet.Write());
+ };
- SendPacketToAllEventRelatives(data, calendarEvent);
+ for (Player* receiver : GetAllEventRelatives(calendarEvent))
+ packetBuilder(receiver);
}
-void CalendarMgr::SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent)
+void CalendarMgr::SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent) const
{
- WorldPacket data(SMSG_CALENDAR_EVENT_REMOVED_ALERT, 1 + 8 + 1);
- data << uint8(1); // FIXME: If true does not SignalEvent(EVENT_CALENDAR_ACTION_PENDING)
- data << uint64(calendarEvent.GetEventId());
- data.AppendPackedTime(calendarEvent.GetEventTime());
+ auto packetBuilder = [&](Player const* receiver)
+ {
+ WorldPackets::Calendar::CalendarEventRemovedAlert packet;
+ packet.ClearPending = calendarEvent.GetOwnerGUID() == receiver->GetGUID();
+ packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
+ packet.Date += receiver->GetSession()->GetTimezoneOffset();
+ packet.EventID = calendarEvent.GetEventId();
+
+ receiver->SendDirectMessage(packet.Write());
+ };
- SendPacketToAllEventRelatives(data, calendarEvent);
+ 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
{
- WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_REMOVED, 8 + 4 + 4 + 1);
- data << invite.GetInviteeGUID().WriteAsPacked();
- data << uint64(invite.GetEventId());
- data << uint32(flags);
- data << uint8(1); // FIXME
+ WorldPackets::Calendar::CalendarInviteRemoved packet;
+ packet.ClearPending = true; // FIXME
+ packet.EventID = calendarEvent.GetEventId();
+ packet.Flags = flags;
+ packet.InviteGuid = invite.GetInviteeGUID();
- SendPacketToAllEventRelatives(data, calendarEvent);
+ SendPacketToAllEventRelatives(packet.Write(), calendarEvent);
}
-void CalendarMgr::SendCalendarEventModeratorStatusAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite)
+void CalendarMgr::SendCalendarEventModeratorStatusAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const
{
- WorldPacket data(SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT, 8 + 8 + 1 + 1);
- data << invite.GetInviteeGUID().WriteAsPacked();
- data << uint64(invite.GetEventId());
- data << uint8(invite.GetRank());
- data << uint8(1); // Unk boolean - Display to client?
+ WorldPackets::Calendar::CalendarModeratorStatus packet;
+ packet.ClearPending = true; // FIXME
+ packet.EventID = calendarEvent.GetEventId();
+ packet.InviteGuid = invite.GetInviteeGUID();
+ packet.Status = invite.GetStatus();
- SendPacketToAllEventRelatives(data, calendarEvent);
+ SendPacketToAllEventRelatives(packet.Write(), calendarEvent);
}
-void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite)
+void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite) const
{
- WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_ALERT);
- data << uint64(calendarEvent.GetEventId());
- data << calendarEvent.GetTitle();
- data.AppendPackedTime(calendarEvent.GetEventTime());
- data << uint32(calendarEvent.GetFlags());
- data << uint32(calendarEvent.GetType());
- data << int32(calendarEvent.GetDungeonId());
- data << uint64(invite.GetInviteId());
- data << uint8(invite.GetStatus());
- data << uint8(invite.GetRank());
- data << calendarEvent.GetCreatorGUID().WriteAsPacked();
- data << invite.GetSenderGUID().WriteAsPacked();
+ 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();
+
+ receiver->SendDirectMessage(packet.Write());
+ };
if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement())
{
if (Guild* guild = sGuildMgr->GetGuildById(calendarEvent.GetGuildId()))
- guild->BroadcastPacket(&data);
+ guild->BroadcastWorker(packetBuilder);
}
- else
- if (Player* player = ObjectAccessor::FindConnectedPlayer(invite.GetInviteeGUID()))
- player->SendDirectMessage(&data);
+ else if (Player* player = ObjectAccessor::FindConnectedPlayer(invite.GetInviteeGUID()))
+ 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()];
-
- WorldPacket data(SMSG_CALENDAR_SEND_EVENT, 60 + eventInviteeList.size() * 32);
- data << uint8(sendType);
- data << calendarEvent.GetCreatorGUID().WriteAsPacked();
- data << uint64(calendarEvent.GetEventId());
- data << calendarEvent.GetTitle();
- data << calendarEvent.GetDescription();
- data << uint8(calendarEvent.GetType());
- data << uint8(CALENDAR_REPEAT_NEVER); // repeatable
- data << uint32(CALENDAR_MAX_INVITES);
- data << int32(calendarEvent.GetDungeonId());
- data << uint32(calendarEvent.GetFlags());
- data.AppendPackedTime(calendarEvent.GetEventTime());
- data.AppendPackedTime(calendarEvent.GetTimeZoneTime());
- data << uint32(calendarEvent.GetGuildId());
-
- data << uint32(eventInviteeList.size());
- for (CalendarInviteStore::const_iterator itr = eventInviteeList.begin(); itr != eventInviteeList.end(); ++itr)
+ WorldPackets::Calendar::CalendarSendEvent packet;
+ 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.SetUtcTimeFromUnixTime(calendarEvent.GetLockDate()); // Always 0 ?
+ if (calendarEvent.GetLockDate())
+ packet.LockDate += player->GetSession()->GetTimezoneOffset();
+ packet.OwnerGuid = calendarEvent.GetOwnerGUID();
+ packet.TextureID = calendarEvent.GetTextureId();
+ packet.EventGuildID = calendarEvent.GetGuildId();
+
+ if (CalendarInviteStore const* eventInviteeList = Trinity::Containers::MapGetValuePtr(_invites, calendarEvent.GetEventId()))
{
- CalendarInvite const* calendarInvite = (*itr);
- 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);
-
- data << inviteeGuid.WriteAsPacked();
- data << uint8(inviteeLevel);
- data << uint8(calendarInvite->GetStatus());
- data << uint8(calendarInvite->GetRank());
- data << uint8(calendarEvent.IsGuildEvent() && calendarEvent.GetGuildId() == inviteeGuildId);
- data << uint64(calendarInvite->GetInviteId());
- data.AppendPackedTime(calendarInvite->GetStatusTime());
- data << calendarInvite->GetText();
+ 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);
+
+ 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);
+ }
}
- player->SendDirectMessage(&data);
+ 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))
{
- WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT, 8 + 4 + 4 + 1);
- data << uint64(calendarEvent.GetEventId());
- data.AppendPackedTime(calendarEvent.GetEventTime());
- data << uint32(calendarEvent.GetFlags());
- data << uint8(status);
-
- player->SendDirectMessage(&data);
+ WorldPackets::Calendar::CalendarInviteRemovedAlert packet;
+ packet.Date.SetUtcTimeFromUnixTime(calendarEvent.GetDate());
+ packet.Date += player->GetSession()->GetTimezoneOffset();
+ packet.EventID = calendarEvent.GetEventId();
+ packet.Flags = calendarEvent.GetFlags();
+ packet.Status = status;
+
+ player->SendDirectMessage(packet.Write());
}
}
-void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid)
+void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid) const
{
if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
- {
- WorldPacket data(SMSG_CALENDAR_CLEAR_PENDING_ACTION, 0);
- player->SendDirectMessage(&data);
- }
+ 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))
{
- WorldPacket data(SMSG_CALENDAR_COMMAND_RESULT, 0);
- data << uint32(0);
- data << uint8(0);
+ WorldPackets::Calendar::CalendarCommandResult packet;
+ packet.Command = 1; // FIXME
+ packet.Result = err;
+
switch (err)
{
case CALENDAR_ERROR_OTHER_INVITES_EXCEEDED:
case CALENDAR_ERROR_ALREADY_INVITED_TO_EVENT_S:
case CALENDAR_ERROR_IGNORING_YOU_S:
- data << param;
+ packet.Name = param;
break;
default:
- data << uint8(0);
break;
}
- data << uint32(err);
-
- player->SendDirectMessage(&data);
+ player->SendDirectMessage(packet.Write());
}
}
-void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket& 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;
}
diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h
index 056218217cb..22c5dbc6bf1 100644
--- a/src/server/game/Calendar/CalendarMgr.h
+++ b/src/server/game/Calendar/CalendarMgr.h
@@ -26,6 +26,7 @@
#include <set>
#include <vector>
+class Player;
class WorldPacket;
enum CalendarMailAnswers
@@ -136,6 +137,8 @@ enum CalendarLimits
CALENDAR_OLD_EVENTS_DELETION_TIME = 1 * MONTH,
};
+#define CALENDAR_DEFAULT_RESPONSE_TIME 946684800 // 01/01/2000 00:00:00
+
struct TC_GAME_API CalendarInvite
{
public:
@@ -145,18 +148,24 @@ struct TC_GAME_API CalendarInvite
_eventId = eventId;
_invitee = calendarInvite.GetInviteeGUID();
_senderGUID = calendarInvite.GetSenderGUID();
- _statusTime = calendarInvite.GetStatusTime();
+ _responseTime = calendarInvite.GetResponseTime();
_status = calendarInvite.GetStatus();
_rank = calendarInvite.GetRank();
- _text = calendarInvite.GetText();
+ _note = calendarInvite.GetNote();
}
CalendarInvite();
CalendarInvite(uint64 inviteId, uint64 eventId, ObjectGuid invitee, ObjectGuid senderGUID, time_t statusTime,
- CalendarInviteStatus status, CalendarModerationRank rank, std::string text) :
- _inviteId(inviteId), _eventId(eventId), _invitee(invitee), _senderGUID(senderGUID), _statusTime(statusTime),
- _status(status), _rank(rank), _text(text) { }
+ CalendarInviteStatus status, CalendarModerationRank rank, std::string note) :
+ _inviteId(inviteId), _eventId(eventId), _invitee(invitee), _senderGUID(senderGUID), _responseTime(statusTime),
+ _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();
@@ -172,11 +181,11 @@ struct TC_GAME_API CalendarInvite
void SetInvitee(ObjectGuid guid) { _invitee = guid; }
ObjectGuid GetInviteeGUID() const { return _invitee; }
- void SetStatusTime(time_t statusTime) { _statusTime = statusTime; }
- time_t GetStatusTime() const { return _statusTime; }
+ void SetResponseTime(time_t statusTime) { _responseTime = statusTime; }
+ time_t GetResponseTime() const { return _responseTime; }
- void SetText(const std::string& text) { _text = text; }
- std::string GetText() const { return _text; }
+ void SetNote(std::string const& note) { _note = note; }
+ std::string GetNote() const { return _note; }
void SetStatus(CalendarInviteStatus status) { _status = status; }
CalendarInviteStatus GetStatus() const { return _status; }
@@ -189,10 +198,10 @@ struct TC_GAME_API CalendarInvite
uint64 _eventId;
ObjectGuid _invitee;
ObjectGuid _senderGUID;
- time_t _statusTime;
+ time_t _responseTime;
CalendarInviteStatus _status;
CalendarModerationRank _rank;
- std::string _text;
+ std::string _note;
};
struct TC_GAME_API CalendarEvent
@@ -201,78 +210,84 @@ struct TC_GAME_API CalendarEvent
CalendarEvent(CalendarEvent const& calendarEvent, uint64 eventId)
{
_eventId = eventId;
- _creatorGUID = calendarEvent.GetCreatorGUID();
- _guildId = calendarEvent.GetGuildId();
- _type = calendarEvent.GetType();
- _dungeonId = calendarEvent.GetDungeonId();
- _eventTime = calendarEvent.GetEventTime();
+ _ownerGUID = calendarEvent.GetOwnerGUID();
+ _eventGuildId = calendarEvent.GetGuildId();
+ _eventType = calendarEvent.GetType();
+ _textureId = calendarEvent.GetTextureId();
+ _date = calendarEvent.GetDate();
_flags = calendarEvent.GetFlags();
- _timezoneTime = calendarEvent.GetTimeZoneTime();
_title = calendarEvent.GetTitle();
_description = calendarEvent.GetDescription();
+ _lockDate = calendarEvent.GetLockDate();
}
- CalendarEvent(uint64 eventId, ObjectGuid creatorGUID, ObjectGuid::LowType guildId, CalendarEventType type, int32 dungeonId,
- time_t eventTime, uint32 flags, time_t timezoneTime, std::string title, std::string description) :
- _eventId(eventId), _creatorGUID(creatorGUID), _guildId(guildId), _type(type), _dungeonId(dungeonId),
- _eventTime(eventTime), _flags(flags), _timezoneTime(timezoneTime), _title(title),
- _description(description) { }
+ 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(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) { }
+
+ CalendarEvent(CalendarEvent const&) = delete;
+ CalendarEvent(CalendarEvent&&) = delete;
- CalendarEvent() : _eventId(1), _creatorGUID(), _guildId(0), _type(CALENDAR_TYPE_OTHER), _dungeonId(-1), _eventTime(0),
- _flags(0), _timezoneTime(0), _title(""), _description("") { }
+ CalendarEvent& operator=(CalendarEvent const&) = delete;
+ CalendarEvent& operator=(CalendarEvent&&) = delete;
~CalendarEvent();
void SetEventId(uint64 eventId) { _eventId = eventId; }
uint64 GetEventId() const { return _eventId; }
- void SetCreatorGUID(ObjectGuid guid) { _creatorGUID = guid; }
- ObjectGuid GetCreatorGUID() const { return _creatorGUID; }
+ void SetOwnerGUID(ObjectGuid guid) { _ownerGUID = guid; }
+ ObjectGuid GetOwnerGUID() const { return _ownerGUID; }
- void SetGuildId(ObjectGuid::LowType guildId) { _guildId = guildId; }
- ObjectGuid::LowType GetGuildId() const { return _guildId; }
+ void SetGuildId(ObjectGuid::LowType guildId) { _eventGuildId = guildId; }
+ ObjectGuid::LowType GetGuildId() const { return _eventGuildId; }
- void SetTitle(const std::string& title) { _title = title; }
+ void SetTitle(std::string const& title) { _title = title; }
std::string GetTitle() const { return _title; }
- void SetDescription(const std::string& description) { _description = description; }
+ void SetDescription(std::string const& description) { _description = description; }
std::string GetDescription() const { return _description; }
- void SetType(CalendarEventType type) { _type = type; }
- CalendarEventType GetType() const { return _type; }
+ void SetType(CalendarEventType eventType) { _eventType = eventType; }
+ CalendarEventType GetType() const { return _eventType; }
- void SetDungeonId(int32 dungeonId) { _dungeonId = dungeonId; }
- int32 GetDungeonId() const { return _dungeonId; }
+ void SetTextureId(int32 textureId) { _textureId = textureId; }
+ int32 GetTextureId() const { return _textureId; }
- void SetEventTime(time_t eventTime) { _eventTime = eventTime; }
- time_t GetEventTime() const { return _eventTime; }
+ void SetDate(time_t date) { _date = date; }
+ time_t GetDate() const { return _date; }
void SetFlags(uint32 flags) { _flags = flags; }
uint32 GetFlags() const { return _flags; }
- void SetTimeZoneTime(time_t timezoneTime) { _timezoneTime = timezoneTime; }
- time_t GetTimeZoneTime() const { return _timezoneTime; }
-
bool IsGuildEvent() const { return (_flags & CALENDAR_FLAG_GUILD_EVENT) != 0; }
bool IsGuildAnnouncement() const { return (_flags & CALENDAR_FLAG_WITHOUT_INVITES) != 0; }
+ bool IsLocked() const { return (_flags & CALENDAR_FLAG_INVITES_LOCKED) != 0; }
+
+ void SetLockDate(time_t lockDate) { _lockDate = lockDate; }
+ time_t GetLockDate() const { return _lockDate; }
static bool IsGuildEvent(uint32 flags) { return (flags & CALENDAR_FLAG_GUILD_EVENT) != 0; }
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;
- ObjectGuid _creatorGUID;
- ObjectGuid::LowType _guildId;
- CalendarEventType _type;
- int32 _dungeonId;
- time_t _eventTime;
+ ObjectGuid _ownerGUID;
+ ObjectGuid::LowType _eventGuildId;
+ CalendarEventType _eventType;
+ int32 _textureId;
+ time_t _date;
uint32 _flags;
- time_t _timezoneTime;
std::string _title;
std::string _description;
+ time_t _lockDate;
};
typedef std::vector<CalendarInvite*> CalendarInviteStore;
typedef std::set<CalendarEvent*> CalendarEventStore;
@@ -293,20 +308,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();
@@ -329,19 +350,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 oldEventTime);
- 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 SendPacketToAllEventRelatives(WorldPacket& packet, CalendarEvent const& calendarEvent);
+ 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) const;
+ std::vector<Player*> GetAllEventRelatives(CalendarEvent const& calendarEvent) const;
};
#define sCalendarMgr CalendarMgr::instance()
diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp
index cf59885158b..ba0a75f2db2 100644
--- a/src/server/game/Entities/Object/ObjectGuid.cpp
+++ b/src/server/game/Entities/Object/ObjectGuid.cpp
@@ -85,6 +85,12 @@ ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid)
return buf;
}
+ByteBuffer& operator<<(ByteBuffer& buf, PackedGuidWriter const& guid)
+{
+ buf.appendPackGUID(guid.Guid.GetRawValue());
+ return buf;
+}
+
ByteBuffer& operator>>(ByteBuffer& buf, PackedGuidReader const& guid)
{
buf.readPackGUID(reinterpret_cast<uint64&>(guid.Guid));
diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h
index 1a6ccb775b2..965040adee7 100644
--- a/src/server/game/Entities/Object/ObjectGuid.h
+++ b/src/server/game/Entities/Object/ObjectGuid.h
@@ -115,6 +115,12 @@ struct PackedGuidReader
ObjectGuid& Guid;
};
+struct PackedGuidWriter
+{
+ explicit PackedGuidWriter(ObjectGuid const& guid) : Guid(guid) { }
+ ObjectGuid const& Guid;
+};
+
class TC_GAME_API ObjectGuid
{
public:
@@ -139,7 +145,7 @@ class TC_GAME_API ObjectGuid
void Set(uint64 guid) { _guid = guid; }
void Clear() { _guid = 0; }
- PackedGuid WriteAsPacked() const;
+ PackedGuidWriter WriteAsPacked() const { return PackedGuidWriter(*this); }
uint64 GetRawValue() const { return _guid; }
HighGuid GetHigh() const { return HighGuid((_guid >> 48) & 0x0000FFFF); }
@@ -293,10 +299,9 @@ TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid);
TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid);
TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid);
+TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, PackedGuidWriter const& guid);
TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, PackedGuidReader const& guid);
-inline PackedGuid ObjectGuid::WriteAsPacked() const { return PackedGuid(*this); }
-
namespace std
{
template<>
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 5543652b36e..661a7ddb6c9 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -18887,7 +18887,7 @@ void Player::UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficu
}
if (itr->second.perm)
- GetSession()->SendCalendarRaidLockout(itr->second.save, false);
+ GetSession()->SendCalendarRaidLockoutRemoved(itr->second.save);
itr->second.save->RemovePlayer(this); // save can become invalid
m_boundInstances[difficulty].erase(itr++);
@@ -18972,7 +18972,7 @@ void Player::BindToInstance()
if (!IsGameMaster())
{
BindToInstance(mapSave, true, EXTEND_STATE_KEEP);
- GetSession()->SendCalendarRaidLockout(mapSave, true);
+ GetSession()->SendCalendarRaidLockoutAdded(mapSave);
}
}
@@ -22728,7 +22728,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
static float const TimeSpeed = 0.01666667f;
WorldPackets::Misc::LoginSetTimeSpeed loginSetTimeSpeed;
loginSetTimeSpeed.NewSpeed = TimeSpeed;
- loginSetTimeSpeed.GameTime = GameTime::GetGameTime();
+ loginSetTimeSpeed.GameTime = *GameTime::GetWowTime();
loginSetTimeSpeed.GameTimeHolidayOffset = 0; /// @todo
SendDirectMessage(loginSetTimeSpeed.Write());
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 672f5888ec1..568194d1f04 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -19,6 +19,7 @@
#include "AccountMgr.h"
#include "Bag.h"
#include "CalendarMgr.h"
+#include "CalendarPackets.h"
#include "CharacterCache.h"
#include "Chat.h"
#include "Config.h"
@@ -1794,7 +1795,8 @@ void Guild::SendInfo(WorldSession* session) const
{
WorldPackets::Guild::GuildInfoResponse guildInfo;
guildInfo.GuildName = m_name;
- guildInfo.CreateDate = m_createdDate;
+ guildInfo.CreateDate.SetUtcTimeFromUnixTime(m_createdDate);
+ guildInfo.CreateDate += session->GetTimezoneOffset();
guildInfo.NumMembers = int32(m_members.size());
guildInfo.NumAccounts = m_accountsNumber;
@@ -2163,34 +2165,32 @@ void Guild::BroadcastPacket(WorldPacket const* packet) const
void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, uint32 minRank)
{
- uint32 count = 0;
-
- WorldPacket data(SMSG_CALENDAR_FILTER_GUILD);
- data << uint32(count); // count placeholder
+ WorldPackets::Calendar::CalendarEventInitialInvites packet(true);
for (auto const& [guid, member] : m_members)
{
// not sure if needed, maybe client checks it as well
- if (count >= CALENDAR_MAX_INVITES)
+ if (packet.Invites.size() >= CALENDAR_MAX_INVITES)
{
if (Player* player = session->GetPlayer())
sCalendarMgr->SendCalendarCommandResult(player->GetGUID(), CALENDAR_ERROR_INVITES_EXCEEDED);
return;
}
+ if (member.GetGUID() == session->GetPlayer()->GetGUID())
+ continue;
+
uint32 level = sCharacterCache->GetCharacterLevelByGuid(member.GetGUID());
+ if (level < minLevel || level > maxLevel)
+ continue;
- if (member.GetGUID() != session->GetPlayer()->GetGUID() && level >= minLevel && level <= maxLevel && member.IsRankNotLower(minRank))
- {
- data.appendPackGUID(member.GetGUID().GetRawValue());
- data << uint8(0); // unk
- ++count;
- }
- }
+ if (!member.IsRankNotLower(minRank))
+ continue;
- data.put<uint32>(0, count);
+ packet.Invites.emplace_back(member.GetGUID(), level);
+ }
- session->SendPacket(&data);
+ session->SendPacket(packet.Write());
}
// Members handling
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index 7044f8c0fb5..11d9f9ac99e 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -37,6 +37,7 @@ Copied events should probably have a new owner
#include "WorldSession.h"
#include "ArenaTeamMgr.h"
#include "CalendarMgr.h"
+#include "CalendarPackets.h"
#include "CharacterCache.h"
#include "DatabaseEnv.h"
#include "DBCStores.h"
@@ -53,56 +54,45 @@ Copied events should probably have a new owner
#include "SocialMgr.h"
#include "World.h"
-void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/)
+void WorldSession::HandleCalendarGetCalendar(WorldPackets::Calendar::CalendarGetCalendar& /*calendarGetCalendar*/)
{
ObjectGuid guid = _player->GetGUID();
TC_LOG_DEBUG("network", "CMSG_CALENDAR_GET_CALENDAR [{}]", guid.ToString());
time_t currTime = GameTime::GetGameTime();
- WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR, 1000); // Average size if no instance
+ WorldPackets::Calendar::CalendarSendCalendar packet;
+ packet.ServerTime = *GameTime::GetWowTime();
+ packet.ServerNow = currTime;
+ packet.RaidOrigin = 1135753200; // Constant date, unk (28.12.2005 07:00)
- CalendarInviteStore invites = sCalendarMgr->GetPlayerInvites(guid);
- data << uint32(invites.size());
- for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr)
+ CalendarInviteStore playerInvites = sCalendarMgr->GetPlayerInvites(guid);
+ for (CalendarInvite const* invite : playerInvites)
{
- data << uint64((*itr)->GetEventId());
- data << uint64((*itr)->GetInviteId());
- data << uint8((*itr)->GetStatus());
- data << uint8((*itr)->GetRank());
-
- if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent((*itr)->GetEventId()))
- {
- data << uint8(calendarEvent->IsGuildEvent());
- data << calendarEvent->GetCreatorGUID().WriteAsPacked();
- }
- else
- {
- data << uint8(0);
- data << (*itr)->GetSenderGUID().WriteAsPacked();
- }
+ WorldPackets::Calendar::CalendarSendCalendarInviteInfo& inviteInfo = packet.Invites.emplace_back();
+ inviteInfo.EventID = invite->GetEventId();
+ inviteInfo.InviteID = invite->GetInviteId();
+ inviteInfo.InviterGuid = invite->GetSenderGUID();
+ inviteInfo.Status = invite->GetStatus();
+ inviteInfo.Moderator = invite->GetRank();
+ if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(invite->GetEventId()))
+ inviteInfo.InviteType = calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == _player->GetGuildId();
}
CalendarEventStore playerEvents = sCalendarMgr->GetPlayerEvents(guid);
- data << uint32(playerEvents.size());
- for (CalendarEventStore::const_iterator itr = playerEvents.begin(); itr != playerEvents.end(); ++itr)
+ for (CalendarEvent const* event : playerEvents)
{
- CalendarEvent* calendarEvent = *itr;
-
- data << uint64(calendarEvent->GetEventId());
- data << calendarEvent->GetTitle();
- data << uint32(calendarEvent->GetType());
- data.AppendPackedTime(calendarEvent->GetEventTime());
- data << uint32(calendarEvent->GetFlags());
- data << int32(calendarEvent->GetDungeonId());
- data << calendarEvent->GetCreatorGUID().WriteAsPacked();
+ WorldPackets::Calendar::CalendarSendCalendarEventInfo& eventInfo = packet.Events.emplace_back();
+ eventInfo.EventID = event->GetEventId();
+ eventInfo.Date.SetUtcTimeFromUnixTime(event->GetDate());
+ eventInfo.Date += GetTimezoneOffset();
+ eventInfo.EventName = event->GetTitle();
+ eventInfo.EventType = event->GetType();
+ eventInfo.Flags = event->GetFlags();
+ eventInfo.OwnerGuid = event->GetOwnerGUID();
+ eventInfo.TextureID = event->GetTextureId();
}
- data << uint32(currTime); // server time
- data.AppendPackedTime(currTime); // zone time
-
- ByteBuffer dataBuffer;
- uint32 boundCounter = 0;
for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
{
Player::BoundInstancesMap boundInstances = _player->GetBoundInstances(Difficulty(i));
@@ -111,24 +101,16 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/)
if (itr->second.perm)
{
InstanceSave const* save = itr->second.save;
- dataBuffer << uint32(save->GetMapId());
- dataBuffer << uint32(save->GetDifficulty());
- dataBuffer << uint32(save->GetResetTime() - currTime);
- dataBuffer << uint64(save->GetInstanceId()); // instance save id as unique instance copy id
- ++boundCounter;
+ WorldPackets::Calendar::CalendarSendCalendarRaidLockoutInfo& lockoutInfo = packet.RaidLockouts.emplace_back();
+ lockoutInfo.MapID = save->GetMapId();
+ lockoutInfo.DifficultyID = save->GetDifficulty();
+ lockoutInfo.ExpireTime = int32(std::max(save->GetResetTime() - currTime, SI64LIT(0)));
+ lockoutInfo.InstanceID = save->GetInstanceId();
}
}
}
- data << uint32(boundCounter);
- data.append(dataBuffer);
-
- data << uint32(1135753200); // Constant date, unk (28.12.2005 07:00)
-
- // Reuse variables
- boundCounter = 0;
std::set<uint32> sentMaps;
- dataBuffer.clear();
ResetTimeByMapDifficultyMap const& resets = sInstanceSaveMgr->GetResetTimeMap();
for (ResetTimeByMapDifficultyMap::const_iterator itr = resets.begin(); itr != resets.end(); ++itr)
@@ -143,128 +125,94 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/)
sentMaps.insert(mapId);
- dataBuffer << int32(mapId);
- dataBuffer << int32(itr->second - currTime);
- dataBuffer << int32(0); // Never seen anything else in sniffs - still unknown
- ++boundCounter;
+ WorldPackets::Calendar::CalendarSendCalendarRaidResetInfo& reset = packet.RaidResets.emplace_back();
+ reset.MapID = mapId;
+ reset.Duration = itr->second - currTime;
+ reset.Offset = 0; // Never seen anything else in sniffs - still unknown
}
- data << uint32(boundCounter);
- data.append(dataBuffer);
-
- data << uint32(sGameEventMgr->modifiedHolidays.size());
for (uint32 entry : sGameEventMgr->modifiedHolidays)
{
HolidaysEntry const* holiday = sHolidaysStore.LookupEntry(entry);
- data << uint32(holiday->ID); // m_ID
- data << uint32(holiday->Region); // m_region, might be looping
- data << uint32(holiday->Looping); // m_looping, might be region
- data << uint32(holiday->Priority); // m_priority
- data << uint32(holiday->CalendarFilterType); // m_calendarFilterType
+ WorldPackets::Calendar::CalendarSendCalendarHolidayInfo& holidayInfo = packet.Holidays.emplace_back();
+ holidayInfo.HolidayID = holiday->ID;
+ holidayInfo.Region = holiday->Region;
+ holidayInfo.Looping = holiday->Looping;
+ holidayInfo.Priority = holiday->Priority;
+ holidayInfo.FilterType = holiday->CalendarFilterType;
for (uint8 j = 0; j < MAX_HOLIDAY_DATES; ++j)
- data << uint32(holiday->Date[j]); // 26 * m_date -- WritePackedTime ?
+ holidayInfo.Date[j].SetPackedTime(holiday->Date[j]);
for (uint8 j = 0; j < MAX_HOLIDAY_DURATIONS; ++j)
- data << uint32(holiday->Duration[j]); // 10 * m_duration
+ holidayInfo.Duration[j] = holiday->Duration[j];
for (uint8 j = 0; j < MAX_HOLIDAY_FLAGS; ++j)
- data << uint32(holiday->CalendarFlags[j]); // 10 * m_calendarFlags
+ holidayInfo.CalendarFlags[j] = holiday->CalendarFlags[j];
- data << holiday->TextureFilename; // m_textureFilename (holiday name)
+ holidayInfo.TextureFilename = holiday->TextureFilename;
}
- SendPacket(&data);
+ SendPacket(packet.Write());
}
-void WorldSession::HandleCalendarGetEvent(WorldPacket& recvData)
+void WorldSession::HandleCalendarGetEvent(WorldPackets::Calendar::CalendarGetEvent& calendarGetEvent)
{
- uint64 eventId;
- recvData >> eventId;
-
- TC_LOG_DEBUG("network", "CMSG_CALENDAR_GET_EVENT. Player [{}] Event [{}]", _player->GetGUID().ToString(), eventId);
+ TC_LOG_DEBUG("network", "CMSG_CALENDAR_GET_EVENT. Player [{}] Event [{}]", _player->GetGUID().ToString(), calendarGetEvent.EventID);
- if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
+ if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarGetEvent.EventID))
sCalendarMgr->SendCalendarEvent(_player->GetGUID(), *calendarEvent, CALENDAR_SENDTYPE_GET);
else
sCalendarMgr->SendCalendarCommandResult(_player->GetGUID(), CALENDAR_ERROR_EVENT_INVALID);
}
-void WorldSession::HandleCalendarGuildFilter(WorldPacket& recvData)
+void WorldSession::HandleCalendarGuildFilter(WorldPackets::Calendar::CalendarGuildFilter& calendarGuildFilter)
{
- TC_LOG_DEBUG("network", "CMSG_CALENDAR_GUILD_FILTER [{}]", _player->GetGUID().ToString());
-
- uint32 minLevel;
- uint32 maxLevel;
- uint32 minRank;
-
- recvData >> minLevel >> maxLevel >> minRank;
-
if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
- guild->MassInviteToEvent(this, minLevel, maxLevel, minRank);
+ guild->MassInviteToEvent(this, calendarGuildFilter.MinLevel, calendarGuildFilter.MaxLevel, calendarGuildFilter.MaxRankOrder);
- TC_LOG_DEBUG("network", "CMSG_CALENDAR_GUILD_FILTER: Min level [{}], Max level [{}], Min rank [{}]", minLevel, maxLevel, minRank);
+ TC_LOG_DEBUG("network", "CMSG_CALENDAR_GUILD_FILTER: Min level [{}], Max level [{}], Min rank [{}]",
+ calendarGuildFilter.MinLevel, calendarGuildFilter.MaxLevel, calendarGuildFilter.MaxRankOrder);
}
-void WorldSession::HandleCalendarArenaTeam(WorldPacket& recvData)
+void WorldSession::HandleCalendarArenaTeam(WorldPackets::Calendar::CalendarArenaTeam& calendarArenaTeam)
{
TC_LOG_DEBUG("network", "CMSG_CALENDAR_ARENA_TEAM [{}]", _player->GetGUID().ToString());
- uint32 arenaTeamId;
- recvData >> arenaTeamId;
-
- if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
+ if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(calendarArenaTeam.ArenaTeamId))
team->MassInviteToEvent(this);
}
-void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
+void WorldSession::HandleCalendarAddEvent(WorldPackets::Calendar::CalendarAddEvent& calendarAddEvent)
{
ObjectGuid guid = _player->GetGUID();
- std::string title;
- std::string description;
- uint8 type;
- uint8 repeatable;
- uint32 maxInvites;
- int32 dungeonId;
- uint32 eventPackedTime;
- uint32 unkPackedTime;
- uint32 flags;
-
- recvData >> title >> description >> type >> repeatable >> maxInvites >> dungeonId;
- recvData.ReadPackedTime(eventPackedTime);
- recvData.ReadPackedTime(unkPackedTime);
- recvData >> flags;
-
- eventPackedTime = uint32(LocalTimeToUTCTime(eventPackedTime));
+ calendarAddEvent.Time -= GetTimezoneOffset();
+ calendarAddEvent.LockDate -= GetTimezoneOffset();
// prevent events in the past
- // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
- if (time_t(eventPackedTime) < (GameTime::GetGameTime() - time_t(86400L)))
+ if (calendarAddEvent.Time < *GameTime::GetUtcWowTime())
{
- recvData.rfinish();
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
return;
}
// If the event is a guild event, check if the player is in a guild
- if (CalendarEvent::IsGuildEvent(flags) || CalendarEvent::IsGuildAnnouncement(flags))
+ if (CalendarEvent::IsGuildEvent(calendarAddEvent.Flags) || CalendarEvent::IsGuildAnnouncement(calendarAddEvent.Flags))
{
if (!_player->GetGuildId())
{
- recvData.rfinish();
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD);
return;
}
}
// Check if the player reached the max number of events allowed to create
- if (CalendarEvent::IsGuildEvent(flags) || CalendarEvent::IsGuildAnnouncement(flags))
+ if (CalendarEvent::IsGuildEvent(calendarAddEvent.Flags) || CalendarEvent::IsGuildAnnouncement(calendarAddEvent.Flags))
{
if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
{
- recvData.rfinish();
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
return;
}
@@ -273,7 +221,6 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
{
if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
{
- recvData.rfinish();
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
return;
}
@@ -281,165 +228,102 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
if (GetCalendarEventCreationCooldown() > GameTime::GetGameTime())
{
- recvData.rfinish();
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
return;
}
SetCalendarEventCreationCooldown(GameTime::GetGameTime() + CALENDAR_CREATE_EVENT_COOLDOWN);
- CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
- time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description);
+ CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(calendarAddEvent.EventType), calendarAddEvent.TextureID,
+ calendarAddEvent.Time.GetUnixTimeFromUtcTime(), calendarAddEvent.Flags, calendarAddEvent.Title, calendarAddEvent.Description, calendarAddEvent.LockDate.GetUnixTimeFromUtcTime());
if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement())
calendarEvent->SetGuildId(_player->GetGuildId());
if (calendarEvent->IsGuildAnnouncement())
{
- // 946684800 is 01/01/2000 00:00:00 - default response time
- CalendarInvite invite(0, calendarEvent->GetEventId(), ObjectGuid::Empty, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
+ CalendarInvite invite(0, calendarEvent->GetEventId(), ObjectGuid::Empty, guid, CALENDAR_DEFAULT_RESPONSE_TIME, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
// WARNING: By passing pointer to a local variable, the underlying method(s) must NOT perform any kind
// of storage of the pointer as it will lead to memory corruption
sCalendarMgr->AddInvite(calendarEvent, &invite);
}
else
{
- // client limits the amount of players to be invited to 100
-
- uint32 inviteCount;
- ObjectGuid invitee[CALENDAR_MAX_INVITES];
- uint8 status[CALENDAR_MAX_INVITES];
- uint8 rank[CALENDAR_MAX_INVITES];
-
- memset(status, 0, sizeof(status));
- memset(rank, 0, sizeof(rank));
-
- try
- {
- recvData >> inviteCount;
-
- for (uint32 i = 0; i < inviteCount && i < CALENDAR_MAX_INVITES; ++i)
- {
- recvData >> invitee[i].ReadAsPacked();
- recvData >> status[i] >> rank[i];
- }
- }
- catch (ByteBufferException const&)
- {
- delete calendarEvent;
- calendarEvent = nullptr;
- throw;
- }
-
CharacterDatabaseTransaction trans;
- if (inviteCount > 1)
+ if (calendarAddEvent.Invites.size() > 1)
trans = CharacterDatabase.BeginTransaction();
- for (uint32 i = 0; i < inviteCount && i < CALENDAR_MAX_INVITES; ++i)
+ for (uint32 i = 0; i < calendarAddEvent.Invites.size(); ++i)
{
- // 946684800 is 01/01/2000 00:00:00 - default response time
- CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee[i], guid, 946684800, CalendarInviteStatus(status[i]), CalendarModerationRank(rank[i]), "");
+ CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), calendarAddEvent.Invites[i].Guid,
+ guid, CALENDAR_DEFAULT_RESPONSE_TIME, CalendarInviteStatus(calendarAddEvent.Invites[i].Status),
+ CalendarModerationRank(calendarAddEvent.Invites[i].Moderator), "");
sCalendarMgr->AddInvite(calendarEvent, invite, trans);
}
- if (inviteCount > 1)
+ if (calendarAddEvent.Invites.size() > 1)
CharacterDatabase.CommitTransaction(trans);
}
sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD);
}
-void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData)
+void WorldSession::HandleCalendarUpdateEvent(WorldPackets::Calendar::CalendarUpdateEvent& calendarUpdateEvent)
{
- ObjectGuid guid = _player->GetGUID();
- time_t oldEventTime;
-
- uint64 eventId;
- uint64 inviteId;
- std::string title;
- std::string description;
- uint8 type;
- uint8 repetitionType;
- uint32 maxInvites;
- int32 dungeonId;
- uint32 eventPackedTime;
- uint32 timeZoneTime;
- uint32 flags;
-
- recvData >> eventId >> inviteId >> title >> description >> type >> repetitionType >> maxInvites >> dungeonId;
- recvData.ReadPackedTime(eventPackedTime);
- recvData.ReadPackedTime(timeZoneTime);
- recvData >> flags;
-
- eventPackedTime = uint32(LocalTimeToUTCTime(eventPackedTime));
+ calendarUpdateEvent.Time -= GetTimezoneOffset();
+ calendarUpdateEvent.LockDate -= GetTimezoneOffset();
// prevent events in the past
- // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
- if (time_t(eventPackedTime) < (GameTime::GetGameTime() - time_t(86400L)))
- {
- recvData.rfinish();
+ if (calendarUpdateEvent.Time < *GameTime::GetUtcWowTime())
return;
- }
TC_LOG_DEBUG("network", "CMSG_CALENDAR_UPDATE_EVENT [{}] EventId [{}], "
- "InviteId [{}] Title {}, Description {}, type {} "
- "Repeatable {}, MaxInvites {}, Dungeon ID {}, Time {} "
- "Time2 {}, Flags {}", guid.ToString(), eventId, inviteId, title,
- description, type, repetitionType, maxInvites, dungeonId,
- eventPackedTime, timeZoneTime, flags);
+ "InviteId [{}] Title {}, Description {}, EventType {} "
+ "Dungeon ID {}, Time {} LockDate {}, Flags {}", _player->GetGUID().ToString(), calendarUpdateEvent.EventID, calendarUpdateEvent.ModeratorID,
+ calendarUpdateEvent.Title, calendarUpdateEvent.Description, calendarUpdateEvent.EventType, calendarUpdateEvent.TextureID,
+ calendarUpdateEvent.Time.GetUnixTimeFromUtcTime(), calendarUpdateEvent.LockDate.GetUnixTimeFromUtcTime(), calendarUpdateEvent.Flags);
- if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
+ if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarUpdateEvent.EventID))
{
- oldEventTime = calendarEvent->GetEventTime();
+ time_t oldEventTime = calendarEvent->GetDate();
- calendarEvent->SetType(CalendarEventType(type));
- calendarEvent->SetFlags(flags);
- calendarEvent->SetEventTime(time_t(eventPackedTime));
- calendarEvent->SetTimeZoneTime(time_t(timeZoneTime)); // Not sure, seems constant from the little sniffs we have
- calendarEvent->SetDungeonId(dungeonId);
- calendarEvent->SetTitle(title);
- calendarEvent->SetDescription(description);
+ calendarEvent->SetType(CalendarEventType(calendarUpdateEvent.EventType));
+ calendarEvent->SetFlags(calendarUpdateEvent.Flags);
+ calendarEvent->SetDate(calendarUpdateEvent.Time.GetUnixTimeFromUtcTime());
+ calendarEvent->SetLockDate(calendarUpdateEvent.LockDate.GetUnixTimeFromUtcTime()); // Not sure, seems constant from the little sniffs we have
+ calendarEvent->SetTextureId(calendarUpdateEvent.TextureID);
+ calendarEvent->SetTitle(calendarUpdateEvent.Title);
+ calendarEvent->SetDescription(calendarUpdateEvent.Description);
sCalendarMgr->UpdateEvent(calendarEvent);
sCalendarMgr->SendCalendarEventUpdateAlert(*calendarEvent, oldEventTime);
}
else
- sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
+ sCalendarMgr->SendCalendarCommandResult(_player->GetGUID(), CALENDAR_ERROR_EVENT_INVALID);
}
-void WorldSession::HandleCalendarRemoveEvent(WorldPacket& recvData)
+void WorldSession::HandleCalendarRemoveEvent(WorldPackets::Calendar::CalendarRemoveEvent& calendarRemoveEvent)
{
ObjectGuid guid = _player->GetGUID();
- uint64 eventId;
-
- recvData >> eventId;
- recvData.rfinish(); // Skip flags & invite ID, we don't use them
-
- sCalendarMgr->RemoveEvent(eventId, guid);
+ sCalendarMgr->RemoveEvent(calendarRemoveEvent.EventID, guid);
}
-void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData)
+void WorldSession::HandleCalendarCopyEvent(WorldPackets::Calendar::CalendarCopyEvent& calendarCopyEvent)
{
ObjectGuid guid = _player->GetGUID();
- uint64 eventId;
- uint64 inviteId;
- uint32 eventTime;
-
- recvData >> eventId >> inviteId;
- recvData.ReadPackedTime(eventTime);
- TC_LOG_DEBUG("network", "CMSG_CALENDAR_COPY_EVENT [{}], EventId [{}] inviteId [{}] Time: {}",
- guid.ToString(), eventId, inviteId, eventTime);
- eventTime = uint32(LocalTimeToUTCTime(eventTime));
+ calendarCopyEvent.Date -= GetTimezoneOffset();
// prevent events in the past
- // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
- if (time_t(eventTime) < (GameTime::GetGameTime() - time_t(86400L)))
+ if (calendarCopyEvent.Date < *GameTime::GetUtcWowTime())
{
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
return;
}
- if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(eventId))
+ TC_LOG_DEBUG("network", "CMSG_CALENDAR_COPY_EVENT [{}], EventId [{}] inviteId [{}] Time: {}",
+ guid.ToString(), calendarCopyEvent.EventID, calendarCopyEvent.ModeratorID, calendarCopyEvent.Date.GetUnixTimeFromUtcTime());
+
+ if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(calendarCopyEvent.EventID))
{
// Ensure that the player has access to the event
if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
@@ -452,7 +336,7 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData)
}
else
{
- if (oldEvent->GetCreatorGUID() != guid)
+ if (oldEvent->GetOwnerGUID() != guid)
{
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
return;
@@ -485,10 +369,10 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData)
SetCalendarEventCreationCooldown(GameTime::GetGameTime() + CALENDAR_CREATE_EVENT_COOLDOWN);
CalendarEvent* newEvent = new CalendarEvent(*oldEvent, sCalendarMgr->GetFreeEventId());
- newEvent->SetEventTime(time_t(eventTime));
+ newEvent->SetDate(calendarCopyEvent.Date.GetUnixTimeFromUtcTime());
sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY);
- CalendarInviteStore invites = sCalendarMgr->GetEventInvites(eventId);
+ CalendarInviteStore invites = sCalendarMgr->GetEventInvites(calendarCopyEvent.EventID);
CharacterDatabaseTransaction trans;
if (invites.size() > 1)
trans = CharacterDatabase.BeginTransaction();
@@ -504,113 +388,100 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData)
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
}
-void WorldSession::HandleCalendarEventInvite(WorldPacket& recvData)
+void WorldSession::HandleCalendarEventInvite(WorldPackets::Calendar::CalendarInvite& calendarEventInvite)
{
- TC_LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_INVITE");
-
ObjectGuid playerGuid = _player->GetGUID();
- uint64 eventId;
- uint64 inviteId;
- std::string name;
- bool isPreInvite;
- bool isGuildEvent;
+ Optional<uint64> eventId;
+ if (!calendarEventInvite.Creating)
+ eventId = calendarEventInvite.EventID;
- ObjectGuid inviteeGuid;
- uint32 inviteeTeam = 0;
- uint32 inviteeGuildId = 0;
+ bool isSignUp = calendarEventInvite.IsSignUp;
- recvData >> eventId >> inviteId >> name >> isPreInvite >> isGuildEvent;
+ std::string inviteeName = calendarEventInvite.Name;
- if (!normalizePlayerName(name))
+ if (!normalizePlayerName(calendarEventInvite.Name))
return;
- if (Player* player = ObjectAccessor::FindConnectedPlayerByName(name))
- {
- // Invitee is online
- inviteeGuid = player->GetGUID();
- inviteeTeam = player->GetTeam();
- inviteeGuildId = player->GetGuildId();
- }
- else
+ auto createInvite = [this, playerGuid, inviteeName, eventId, isSignUp](ObjectGuid const& inviteeGuid, uint32 inviteeTeam, ObjectGuid::LowType inviteeGuildId, bool inviteeIsIngoring)
{
- // Invitee offline, get data from storage
- ObjectGuid guid = sCharacterCache->GetCharacterGuidByName(name);
- if (!guid.IsEmpty())
+ if (!_player || _player->GetGUID() != playerGuid)
+ return;
+
+ if (_player->GetTeam() != inviteeTeam && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR))
{
- if (CharacterCacheEntry const* characterInfo = sCharacterCache->GetCharacterCacheByGuid(guid))
- {
- inviteeGuid = guid;
- inviteeTeam = Player::TeamForRace(characterInfo->Race);
- inviteeGuildId = characterInfo->GuildId;
- }
+ sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NOT_ALLIED);
+ return;
}
- }
-
- if (!inviteeGuid)
- {
- sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_PLAYER_NOT_FOUND);
- return;
- }
- if (_player->GetTeam() != inviteeTeam && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR))
- {
- sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NOT_ALLIED);
- return;
- }
-
- if (QueryResult result = CharacterDatabase.PQuery("SELECT flags FROM character_social WHERE guid = {} AND friend = {}", inviteeGuid.GetCounter(), playerGuid.GetCounter()))
- {
- Field* fields = result->Fetch();
- if (fields[0].GetUInt8() & SOCIAL_FLAG_IGNORED)
+ if (inviteeIsIngoring)
{
- sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_IGNORING_YOU_S, name.c_str());
+ sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_IGNORING_YOU_S, inviteeName.c_str());
return;
}
- }
- if (!isPreInvite)
- {
- if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
+ if (eventId)
+ {
+ if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(*eventId))
+ {
+ if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == inviteeGuildId)
+ {
+ // we can't invite guild members to guild events
+ sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
+ return;
+ }
+
+ CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), *eventId, inviteeGuid, playerGuid, CALENDAR_DEFAULT_RESPONSE_TIME, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
+ sCalendarMgr->AddInvite(calendarEvent, invite);
+ }
+ else
+ sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_INVALID);
+ }
+ else
{
- if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == inviteeGuildId)
+ if (isSignUp && inviteeGuildId == _player->GetGuildId())
{
- // we can't invite guild members to guild events
sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
return;
}
- // 946684800 is 01/01/2000 00:00:00 - default response time
- CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
- sCalendarMgr->AddInvite(calendarEvent, invite);
+ CalendarInvite invite(sCalendarMgr->GetFreeInviteId(), 0L, inviteeGuid, playerGuid, CALENDAR_DEFAULT_RESPONSE_TIME, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
+ sCalendarMgr->SendCalendarEventInvite(invite);
}
- else
- sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_INVALID);
+ };
+
+ if (Player* player = ObjectAccessor::FindConnectedPlayerByName(calendarEventInvite.Name))
+ {
+ // Invitee is online
+ createInvite(player->GetGUID(), player->GetTeam(), player->GetGuildId(), player->GetSocial()->HasIgnore(playerGuid));
}
else
{
- if (isGuildEvent && inviteeGuildId == _player->GetGuildId())
+ // Invitee offline, get data from storage
+ CharacterCacheEntry const* characterInfo = sCharacterCache->GetCharacterCacheByName(inviteeName);
+ if (!characterInfo)
{
- sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
+ sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_PLAYER_NOT_FOUND);
return;
}
- // 946684800 is 01/01/2000 00:00:00 - default response time
- CalendarInvite invite(inviteId, 0, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
- sCalendarMgr->SendCalendarEventInvite(invite);
+ GetQueryProcessor().AddCallback(CharacterDatabase.AsyncQuery(Trinity::StringFormat("SELECT 1 FROM character_social WHERE guid = {} AND friend = {} AND (cs.flags & {}) <> 0",
+ characterInfo->Guid.GetCounter(), playerGuid.GetCounter(), SOCIAL_FLAG_IGNORED).c_str()))
+ .WithCallback([inviteeGuid = characterInfo->Guid, inviteeTeam = Player::TeamForRace(characterInfo->Race), inviteeGuildId = characterInfo->GuildId, continuation = std::move(createInvite)](QueryResult result)
+ {
+ bool isIgnoring = result != nullptr;
+ continuation(inviteeGuid, inviteeTeam, inviteeGuildId, isIgnoring);
+ });
}
}
-void WorldSession::HandleCalendarEventSignup(WorldPacket& recvData)
+void WorldSession::HandleCalendarEventSignup(WorldPackets::Calendar::CalendarEventSignUp& calendarEventSignUp)
{
ObjectGuid guid = _player->GetGUID();
- uint64 eventId;
- bool tentative;
- recvData >> eventId >> tentative;
- TC_LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_SIGNUP [{}] EventId [{}] Tentative {}", guid.ToString(), eventId, tentative);
+ TC_LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_SIGNUP [{}] EventId [{}] Tentative {}", guid.ToString(), calendarEventSignUp.EventID, calendarEventSignUp.Tentative);
- if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
+ if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarEventSignUp.EventID))
{
if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() != _player->GetGuildId())
{
@@ -618,8 +489,8 @@ void WorldSession::HandleCalendarEventSignup(WorldPacket& recvData)
return;
}
- CalendarInviteStatus status = tentative ? CALENDAR_STATUS_TENTATIVE : CALENDAR_STATUS_SIGNED_UP;
- CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, guid, guid, GameTime::GetGameTime(), status, CALENDAR_RANK_PLAYER, "");
+ CalendarInviteStatus status = calendarEventSignUp.Tentative ? CALENDAR_STATUS_TENTATIVE : CALENDAR_STATUS_SIGNED_UP;
+ CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEventSignUp.EventID, guid, guid, GameTime::GetGameTime(), status, CALENDAR_RANK_PLAYER, "");
sCalendarMgr->AddInvite(calendarEvent, invite);
sCalendarMgr->SendCalendarClearPendingAction(guid);
}
@@ -627,30 +498,23 @@ void WorldSession::HandleCalendarEventSignup(WorldPacket& recvData)
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
}
-void WorldSession::HandleCalendarEventRsvp(WorldPacket& recvData)
+void WorldSession::HandleCalendarEventRsvp(WorldPackets::Calendar::CalendarRSVP& calendarRSVP)
{
ObjectGuid guid = _player->GetGUID();
- uint64 eventId;
- uint64 inviteId;
- uint32 status;
-
- recvData >> eventId >> inviteId >> status;
- TC_LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_RSVP [{}] EventId [{}], InviteId [{}], status {}",
- guid.ToString(), eventId, inviteId, status);
- if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
+ if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarRSVP.EventID))
{
- // i think we still should be able to remove self from locked events
- if (status != CALENDAR_STATUS_REMOVED && calendarEvent->GetFlags() & CALENDAR_FLAG_INVITES_LOCKED)
+ // I think we still should be able to remove self from locked events
+ if (calendarRSVP.Status != CALENDAR_STATUS_REMOVED && calendarEvent->IsLocked())
{
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_LOCKED);
return;
}
- if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
+ if (CalendarInvite* invite = sCalendarMgr->GetInvite(calendarRSVP.InviteID))
{
- invite->SetStatus(CalendarInviteStatus(status));
- invite->SetStatusTime(GameTime::GetGameTime());
+ invite->SetStatus(CalendarInviteStatus(calendarRSVP.Status));
+ invite->SetResponseTime(GameTime::GetGameTime());
sCalendarMgr->UpdateInvite(invite);
sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite);
@@ -663,59 +527,43 @@ void WorldSession::HandleCalendarEventRsvp(WorldPacket& recvData)
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
}
-void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket& recvData)
+void WorldSession::HandleCalendarEventRemoveInvite(WorldPackets::Calendar::CalendarRemoveInvite& calendarRemoveInvite)
{
ObjectGuid guid = _player->GetGUID();
- ObjectGuid invitee;
- uint64 eventId;
- uint64 ownerInviteId; // isn't it sender's inviteId?
- uint64 inviteId;
-
- recvData >> invitee.ReadAsPacked();
- recvData >> inviteId >> ownerInviteId >> eventId;
- TC_LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_REMOVE_INVITE [{}] EventId [{}], ownerInviteId [{}], Invitee ([{}] id: [{}])",
- guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId);
+ TC_LOG_DEBUG("network", "CMSG_CALENDAR_REMOVE_INVITE [{}] EventId [{}], ownerInviteId [{}], Invitee ([{}] id: [{}])",
+ guid.ToString(), calendarRemoveInvite.EventID, calendarRemoveInvite.ModeratorID, calendarRemoveInvite.Guid.ToString(), calendarRemoveInvite.InviteID);
- if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
+ if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarRemoveInvite.EventID))
{
- if (calendarEvent->GetCreatorGUID() == invitee)
+ if (calendarEvent->GetOwnerGUID() == calendarRemoveInvite.Guid)
{
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_DELETE_CREATOR_FAILED);
return;
}
- sCalendarMgr->RemoveInvite(inviteId, eventId, guid);
+ sCalendarMgr->RemoveInvite(calendarRemoveInvite.InviteID, calendarRemoveInvite.EventID, guid);
}
else
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE);
}
-void WorldSession::HandleCalendarEventStatus(WorldPacket& recvData)
+void WorldSession::HandleCalendarEventStatus(WorldPackets::Calendar::CalendarStatus& calendarStatus)
{
ObjectGuid guid = _player->GetGUID();
- ObjectGuid invitee;
- uint64 eventId;
- uint64 inviteId;
- uint64 ownerInviteId; // isn't it sender's inviteId?
- uint8 status;
-
- recvData >> invitee.ReadAsPacked();
- recvData >> eventId >> inviteId >> ownerInviteId >> status;
- TC_LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_STATUS [{}] EventId [{}] ownerInviteId [{}], Invitee ([{}] id: [{}], status {}",
- guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId, status);
-
- if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
+
+ TC_LOG_DEBUG("network", "CMSG_CALENDAR_STATUS [{}] EventId [{}] ownerInviteId [{}], Invitee ([{}] id: [{}], status {}",
+ guid.ToString(), calendarStatus.EventID, calendarStatus.ModeratorID, calendarStatus.Guid.ToString(), calendarStatus.InviteID, calendarStatus.Status);
+
+ if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarStatus.EventID))
{
- if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
+ if (CalendarInvite* invite = sCalendarMgr->GetInvite(calendarStatus.InviteID))
{
- invite->SetStatus((CalendarInviteStatus)status);
- // not sure if we should set response time when moderator changes invite status
- //invite->SetStatusTime(time(nullptr));
+ invite->SetStatus((CalendarInviteStatus)calendarStatus.Status);
sCalendarMgr->UpdateInvite(invite);
sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite);
- sCalendarMgr->SendCalendarClearPendingAction(invitee);
+ sCalendarMgr->SendCalendarClearPendingAction(calendarStatus.Guid);
}
else
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
@@ -724,25 +572,19 @@ void WorldSession::HandleCalendarEventStatus(WorldPacket& recvData)
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
}
-void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket& recvData)
+void WorldSession::HandleCalendarEventModeratorStatus(WorldPackets::Calendar::CalendarModeratorStatusQuery& calendarModeratorStatus)
{
ObjectGuid guid = _player->GetGUID();
- ObjectGuid invitee;
- uint64 eventId;
- uint64 inviteId;
- uint64 ownerInviteId; // isn't it sender's inviteId?
- uint8 rank;
-
- recvData >> invitee.ReadAsPacked();
- recvData >> eventId >> inviteId >> ownerInviteId >> rank;
- TC_LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_MODERATOR_STATUS [{}] EventId [{}] ownerInviteId [{}], Invitee ([{}] id: [{}], rank {}",
- guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId, rank);
-
- if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
+
+ TC_LOG_DEBUG("network", "CMSG_CALENDAR_MODERATOR_STATUS [{}] EventID [{}] ModeratorID [{}], Invitee ([{}] InviteID: [{}], Status {}",
+ guid.ToString(), calendarModeratorStatus.EventID, calendarModeratorStatus.ModeratorID, calendarModeratorStatus.Guid.ToString(), calendarModeratorStatus.InviteID,
+ calendarModeratorStatus.Status);
+
+ if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarModeratorStatus.EventID))
{
- if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
+ if (CalendarInvite* invite = sCalendarMgr->GetInvite(calendarModeratorStatus.InviteID))
{
- invite->SetRank(CalendarModerationRank(rank));
+ invite->SetRank(CalendarModerationRank(calendarModeratorStatus.Status));
sCalendarMgr->UpdateInvite(invite);
sCalendarMgr->SendCalendarEventModeratorStatusAlert(*calendarEvent, *invite);
}
@@ -753,46 +595,37 @@ void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket& recvData)
sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
}
-void WorldSession::HandleCalendarComplain(WorldPacket& recvData)
+void WorldSession::HandleCalendarComplain(WorldPackets::Calendar::CalendarComplain& calendarComplain)
{
ObjectGuid guid = _player->GetGUID();
- uint64 eventId;
- ObjectGuid complainGUID;
-
- recvData >> eventId >> complainGUID;
- TC_LOG_DEBUG("network", "CMSG_CALENDAR_COMPLAIN [{}] EventId [{}] guid [{}]",
- guid.ToString(), eventId, complainGUID.ToString());
+ TC_LOG_DEBUG("network", "CMSG_CALENDAR_COMPLAIN [{}] EventId [{}] guid [{}] InviteId [{}]", guid.ToString(), calendarComplain.EventID,
+ calendarComplain.InvitedByGUID.ToString(), calendarComplain.InviteID);
// what to do with complains?
}
-void WorldSession::HandleCalendarGetNumPending(WorldPacket& /*recvData*/)
+void WorldSession::HandleCalendarGetNumPending(WorldPackets::Calendar::CalendarGetNumPending& /*calendarGetNumPending*/)
{
ObjectGuid guid = _player->GetGUID();
uint32 pending = sCalendarMgr->GetPlayerNumPending(guid);
TC_LOG_DEBUG("network", "CMSG_CALENDAR_GET_NUM_PENDING: [{}] Pending: {}", guid.ToString(), pending);
- WorldPacket data(SMSG_CALENDAR_SEND_NUM_PENDING, 4);
- data << uint32(pending);
- SendPacket(&data);
+ SendPacket(WorldPackets::Calendar::CalendarSendNumPending(pending).Write());
}
-void WorldSession::HandleSetSavedInstanceExtend(WorldPacket& recvData)
+void WorldSession::HandleSetSavedInstanceExtend(WorldPackets::Calendar::SetSavedInstanceExtend& setSavedInstanceExtend)
{
- uint32 mapId, difficulty;
- uint8 toggleExtend;
- recvData >> mapId >> difficulty>> toggleExtend;
- TC_LOG_DEBUG("network", "CMSG_SET_SAVED_INSTANCE_EXTEND - MapId: {}, Difficulty: {}, ToggleExtend: {}", mapId, difficulty, toggleExtend ? "On" : "Off");
+ TC_LOG_DEBUG("network", "CMSG_SET_SAVED_INSTANCE_EXTEND - MapId: {}, Difficulty: {}, ToggleExtend: {}", setSavedInstanceExtend.MapID, setSavedInstanceExtend.DifficultyID, setSavedInstanceExtend.Extend ? "On" : "Off");
if (Player* player = GetPlayer())
{
- InstancePlayerBind* instanceBind = player->GetBoundInstance(mapId, Difficulty(difficulty), toggleExtend == 1); // include expired instances if we are toggling extend on
+ InstancePlayerBind* instanceBind = player->GetBoundInstance(setSavedInstanceExtend.MapID, Difficulty(setSavedInstanceExtend.DifficultyID), setSavedInstanceExtend.Extend); // include expired instances if we are toggling extend on
if (!instanceBind || !instanceBind->save || !instanceBind->perm)
return;
BindExtensionState newState;
- if (!toggleExtend || instanceBind->extendState == EXTEND_STATE_EXPIRED)
+ if (!setSavedInstanceExtend.Extend || instanceBind->extendState == EXTEND_STATE_EXPIRED)
newState = EXTEND_STATE_NORMAL;
else
newState = EXTEND_STATE_EXTENDED;
@@ -813,23 +646,25 @@ void WorldSession::HandleSetSavedInstanceExtend(WorldPacket& recvData)
// ----------------------------------- SEND ------------------------------------
-void WorldSession::SendCalendarRaidLockout(InstanceSave const* save, bool add)
+void WorldSession::SendCalendarRaidLockoutAdded(InstanceSave const* save)
{
- TC_LOG_DEBUG("network", "{}", add ? "SMSG_CALENDAR_RAID_LOCKOUT_ADDED" : "SMSG_CALENDAR_RAID_LOCKOUT_REMOVED");
- time_t currTime = GameTime::GetGameTime();
-
- WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_REMOVED, (4) + 4 + 4 + 4 + 8);
- if (add)
- {
- data.SetOpcode(SMSG_CALENDAR_RAID_LOCKOUT_ADDED);
- data.AppendPackedTime(currTime);
- }
+ WorldPackets::Calendar::CalendarRaidLockoutAdded calendarRaidLockoutAdded;
+ calendarRaidLockoutAdded.InstanceID = save->GetInstanceId();
+ calendarRaidLockoutAdded.ServerTime = *GameTime::GetWowTime();
+ calendarRaidLockoutAdded.MapID = int32(save->GetMapId());
+ calendarRaidLockoutAdded.DifficultyID = save->GetDifficulty();
+ calendarRaidLockoutAdded.TimeRemaining = int32(save->GetResetTime() - GameTime::GetGameTime());
+ SendPacket(calendarRaidLockoutAdded.Write());
+}
- data << uint32(save->GetMapId());
- data << uint32(save->GetDifficulty());
- data << uint32(save->GetResetTime() - currTime);
- data << uint64(save->GetInstanceId());
- SendPacket(&data);
+void WorldSession::SendCalendarRaidLockoutRemoved(InstanceSave const* save)
+{
+ WorldPackets::Calendar::CalendarRaidLockoutRemoved calendarRaidLockoutRemoved;
+ calendarRaidLockoutRemoved.InstanceID = save->GetInstanceId();
+ calendarRaidLockoutRemoved.MapID = int32(save->GetMapId());
+ calendarRaidLockoutRemoved.DifficultyID = save->GetDifficulty();
+ calendarRaidLockoutRemoved.TimeRemaining = int32(save->GetResetTime() - GameTime::GetGameTime());
+ SendPacket(calendarRaidLockoutRemoved.Write());
}
void WorldSession::SendCalendarRaidLockoutUpdated(InstanceSave const* save)
@@ -841,13 +676,11 @@ void WorldSession::SendCalendarRaidLockoutUpdated(InstanceSave const* save)
TC_LOG_DEBUG("network", "SMSG_CALENDAR_RAID_LOCKOUT_UPDATED [{}] Map: {}, Difficulty {}",
guid.ToString(), save->GetMapId(), static_cast<uint32>(save->GetDifficulty()));
- time_t currTime = GameTime::GetGameTime();
-
- WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8);
- data.AppendPackedTime(currTime);
- data << uint32(save->GetMapId());
- data << uint32(save->GetDifficulty());
- data << uint32(0); // Amount of seconds that has changed to the reset time
- data << uint32(save->GetResetTime() - currTime);
- SendPacket(&data);
+ WorldPackets::Calendar::CalendarRaidLockoutUpdated calendarRaidLockoutUpdated;
+ calendarRaidLockoutUpdated.ServerTime = *GameTime::GetWowTime();
+ calendarRaidLockoutUpdated.MapID = save->GetMapId();
+ calendarRaidLockoutUpdated.DifficultyID = save->GetDifficulty();
+ calendarRaidLockoutUpdated.OldTimeRemaining = 0;
+ calendarRaidLockoutUpdated.NewTimeRemaining = std::max(save->GetResetTime() - GameTime::GetGameTime(), SI64LIT(0));
+ SendPacket(calendarRaidLockoutUpdated.Write());
}
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 303178adc9c..10d3f1df348 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -4154,7 +4154,7 @@ void InstanceMap::PermBindAllPlayers()
WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
data << uint32(0);
player->SendDirectMessage(&data);
- player->GetSession()->SendCalendarRaidLockout(save, true);
+ player->GetSession()->SendCalendarRaidLockoutAdded(save);
// if group leader is in instance, group also gets bound
if (Group* group = player->GetGroup())
diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h
index 12f1fb37973..1c4d55272ff 100644
--- a/src/server/game/Server/Packets/AllPackets.h
+++ b/src/server/game/Server/Packets/AllPackets.h
@@ -19,6 +19,7 @@
#define AllPackets_h__
#include "BankPackets.h"
+#include "CalendarPackets.h"
#include "CharacterPackets.h"
#include "ChatPackets.h"
#include "CombatLogPackets.h"
diff --git a/src/server/game/Server/Packets/CalendarPackets.cpp b/src/server/game/Server/Packets/CalendarPackets.cpp
new file mode 100644
index 00000000000..dbc96106126
--- /dev/null
+++ b/src/server/game/Server/Packets/CalendarPackets.cpp
@@ -0,0 +1,471 @@
+/*
+ * 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 "CalendarPackets.h"
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Calendar::CalendarSendCalendarEventInfo const& eventInfo)
+{
+ data << uint64(eventInfo.EventID);
+ data << eventInfo.EventName;
+ data << uint32(eventInfo.EventType);
+ data << eventInfo.Date;
+ data << uint32(eventInfo.Flags);
+ data << int32(eventInfo.TextureID);
+ data << eventInfo.OwnerGuid.WriteAsPacked();
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Calendar::CalendarSendCalendarRaidLockoutInfo const& lockoutInfo)
+{
+ data << int32(lockoutInfo.MapID);
+ data << uint32(lockoutInfo.DifficultyID);
+ data << int32(lockoutInfo.ExpireTime);
+ data << uint64(lockoutInfo.InstanceID);
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Calendar::CalendarSendCalendarInviteInfo const& inviteInfo)
+{
+ data << uint64(inviteInfo.EventID);
+ data << uint64(inviteInfo.InviteID);
+ data << uint8(inviteInfo.Status);
+ data << uint8(inviteInfo.Moderator);
+ data << uint8(inviteInfo.InviteType);
+ data << inviteInfo.InviterGuid.WriteAsPacked();
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Calendar::CalendarSendCalendarHolidayInfo const& holidayInfo)
+{
+ data << uint32(holidayInfo.HolidayID);
+ data << uint32(holidayInfo.Region);
+ data << uint32(holidayInfo.Looping);
+ data << uint32(holidayInfo.Priority);
+ data << uint32(holidayInfo.FilterType);
+
+ for (uint8 j = 0; j < MAX_HOLIDAY_DATES; ++j)
+ data << holidayInfo.Date[j];
+
+ data.append(holidayInfo.Duration.data(), holidayInfo.Duration.size());
+ data.append(holidayInfo.CalendarFlags.data(), holidayInfo.CalendarFlags.size());
+
+ data << holidayInfo.TextureFilename;
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Calendar::CalendarSendCalendarRaidResetInfo const& raidResetInfo)
+{
+ data << int32(raidResetInfo.MapID);
+ data << int32(raidResetInfo.Duration);
+ data << int32(raidResetInfo.Offset);
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Calendar::CalendarEventInviteInfo const& inviteInfo)
+{
+ data << inviteInfo.Guid.WriteAsPacked();
+ data << uint8(inviteInfo.Level);
+ data << uint8(inviteInfo.Status);
+ data << uint8(inviteInfo.Moderator);
+ data << uint8(inviteInfo.InviteType);
+ data << uint64(inviteInfo.InviteID);
+ data << inviteInfo.ResponseTime;
+ data << inviteInfo.Notes;
+
+ return data;
+}
+
+void WorldPackets::Calendar::CalendarGetEvent::Read()
+{
+ _worldPacket >> EventID;
+}
+
+void WorldPackets::Calendar::CalendarGuildFilter::Read()
+{
+ _worldPacket >> MinLevel;
+ _worldPacket >> MaxLevel;
+ _worldPacket >> MaxRankOrder;
+}
+
+void WorldPackets::Calendar::CalendarArenaTeam::Read()
+{
+ _worldPacket >> ArenaTeamId;
+}
+
+ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Calendar::CalendarAddEventInviteInfo& invite)
+{
+ buffer >> invite.Guid.ReadAsPacked();
+ buffer >> invite.Status;
+ buffer >> invite.Moderator;
+
+ return buffer;
+}
+
+void WorldPackets::Calendar::CalendarAddEvent::Read()
+{
+ _worldPacket >> Title;
+ _worldPacket >> Description;
+ _worldPacket >> EventType;
+ _worldPacket.read_skip<uint8>(); // Repeatable
+ _worldPacket >> MaxSize;
+ _worldPacket >> TextureID;
+ _worldPacket >> Time;
+ _worldPacket >> LockDate;
+ _worldPacket >> Flags;
+ Invites.resize(_worldPacket.read<uint32>());
+ for (CalendarAddEventInviteInfo& invite : Invites)
+ _worldPacket >> invite;
+}
+
+void WorldPackets::Calendar::CalendarUpdateEvent::Read()
+{
+ _worldPacket >> EventID;
+ _worldPacket >> ModeratorID;
+ _worldPacket >> Title;
+ _worldPacket >> Description;
+ _worldPacket >> EventType;
+ _worldPacket.read_skip<uint8>(); // Repeatable
+ _worldPacket >> MaxSize;
+ _worldPacket >> TextureID;
+ _worldPacket >> Time;
+ _worldPacket >> LockDate;
+ _worldPacket >> Flags;
+}
+
+void WorldPackets::Calendar::CalendarRemoveEvent::Read()
+{
+ _worldPacket >> EventID;
+ _worldPacket >> ModeratorID;
+ _worldPacket >> IsSignUp;
+}
+
+void WorldPackets::Calendar::CalendarCopyEvent::Read()
+{
+ _worldPacket >> EventID;
+ _worldPacket >> ModeratorID;
+ _worldPacket >> Date;
+}
+
+void WorldPackets::Calendar::CalendarRSVP::Read()
+{
+ _worldPacket >> EventID;
+ _worldPacket >> InviteID;
+ _worldPacket >> Status;
+}
+
+void WorldPackets::Calendar::CalendarInvite::Read()
+{
+ _worldPacket >> EventID;
+ _worldPacket >> ModeratorID;
+ _worldPacket >> Name;
+ _worldPacket >> Creating;
+ _worldPacket >> IsSignUp;
+}
+
+void WorldPackets::Calendar::CalendarEventSignUp::Read()
+{
+ _worldPacket >> EventID;
+ _worldPacket >> Tentative;
+}
+
+void WorldPackets::Calendar::CalendarRemoveInvite::Read()
+{
+ _worldPacket >> Guid.ReadAsPacked();
+ _worldPacket >> InviteID;
+ _worldPacket >> ModeratorID;
+ _worldPacket >> EventID;
+}
+
+void WorldPackets::Calendar::CalendarStatus::Read()
+{
+ _worldPacket >> Guid.ReadAsPacked();
+ _worldPacket >> EventID;
+ _worldPacket >> InviteID;
+ _worldPacket >> ModeratorID;
+ _worldPacket >> Status;
+}
+
+void WorldPackets::Calendar::SetSavedInstanceExtend::Read()
+{
+ _worldPacket >> MapID;
+ _worldPacket >> DifficultyID;
+ _worldPacket >> Extend;
+}
+
+void WorldPackets::Calendar::CalendarModeratorStatusQuery::Read()
+{
+ _worldPacket >> Guid.ReadAsPacked();
+ _worldPacket >> EventID;
+ _worldPacket >> InviteID;
+ _worldPacket >> ModeratorID;
+ _worldPacket >> Status;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarInviteAdded::Write()
+{
+ _worldPacket << InviteGuid.WriteAsPacked();
+ _worldPacket << uint64(EventID);
+ _worldPacket << uint64(InviteID);
+ _worldPacket << uint8(Level);
+ _worldPacket << uint8(Status);
+ _worldPacket << uint8(Type);
+ if (Type == 1)
+ _worldPacket << ResponseTime;
+
+ _worldPacket << uint8(ClearPending);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarSendCalendar::Write()
+{
+ _worldPacket << uint32(Invites.size());
+ for (CalendarSendCalendarInviteInfo const& invite : Invites)
+ _worldPacket << invite;
+
+ _worldPacket << uint32(Events.size());
+ for (CalendarSendCalendarEventInfo const& event : Events)
+ _worldPacket << event;
+
+ _worldPacket << uint32(ServerNow);
+ _worldPacket << ServerTime;
+
+ _worldPacket << uint32(RaidLockouts.size());
+ for (CalendarSendCalendarRaidLockoutInfo const& lockout : RaidLockouts)
+ _worldPacket << lockout;
+
+ _worldPacket << uint32(RaidOrigin);
+
+ _worldPacket << uint32(RaidResets.size());
+ for (CalendarSendCalendarRaidResetInfo const& reset : RaidResets)
+ _worldPacket << reset;
+
+ _worldPacket << uint32(Holidays.size());
+ for (CalendarSendCalendarHolidayInfo const& holiday : Holidays)
+ _worldPacket << holiday;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarSendEvent::Write()
+{
+ _worldPacket << uint8(EventType);
+ _worldPacket << OwnerGuid.WriteAsPacked();
+ _worldPacket << uint64(EventID);
+ _worldPacket << EventName;
+ _worldPacket << Description;
+ _worldPacket << uint8(GetEventType);
+ _worldPacket << uint8(CALENDAR_REPEAT_NEVER); // repeatable
+ _worldPacket << uint32(CALENDAR_MAX_INVITES);
+ _worldPacket << int32(TextureID);
+ _worldPacket << uint32(Flags);
+ _worldPacket << Date;
+ _worldPacket << LockDate;
+ _worldPacket << uint32(EventGuildID);
+ _worldPacket << uint32(Invites.size());
+ for (CalendarEventInviteInfo const& invite : Invites)
+ _worldPacket << invite;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarInviteAlert::Write()
+{
+ _worldPacket << uint64(EventID);
+ _worldPacket << EventName;
+ _worldPacket << Date;
+ _worldPacket << uint32(Flags);
+ _worldPacket << uint32(EventType);
+ _worldPacket << int32(TextureID);
+ _worldPacket << uint64(InviteID);
+ _worldPacket << uint8(Status);
+ _worldPacket << uint8(ModeratorStatus);
+ _worldPacket << OwnerGuid.WriteAsPacked();
+ _worldPacket << InvitedByGuid.WriteAsPacked();
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarInviteStatus::Write()
+{
+ _worldPacket << InviteGuid.WriteAsPacked();
+ _worldPacket << uint64(EventID);
+ _worldPacket << Date;
+ _worldPacket << uint32(Flags);
+ _worldPacket << uint8(Status);
+ _worldPacket << uint8(ClearPending);
+ _worldPacket << ResponseTime;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarInviteRemoved::Write()
+{
+ _worldPacket << InviteGuid.WriteAsPacked();
+ _worldPacket << uint64(EventID);
+ _worldPacket << uint32(Flags);
+ _worldPacket << uint8(ClearPending);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarModeratorStatus::Write()
+{
+ _worldPacket << InviteGuid.WriteAsPacked();
+ _worldPacket << uint64(EventID);
+ _worldPacket << uint8(Status);
+ _worldPacket << uint8(ClearPending);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarInviteRemovedAlert::Write()
+{
+ _worldPacket << uint64(EventID);
+ _worldPacket << Date;
+ _worldPacket << uint32(Flags);
+ _worldPacket << uint8(Status);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarEventUpdatedAlert::Write()
+{
+ _worldPacket << uint8(ClearPending);
+ _worldPacket << uint64(EventID);
+ _worldPacket << OriginalDate;
+ _worldPacket << uint32(Flags);
+ _worldPacket << Date;
+ _worldPacket << uint8(EventType);
+ _worldPacket << uint32(TextureID);
+ _worldPacket << EventName;
+ _worldPacket << Description;
+ _worldPacket << uint8(CALENDAR_REPEAT_NEVER); // repeatable
+ _worldPacket << uint32(CALENDAR_MAX_INVITES);
+ _worldPacket << LockDate;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarEventRemovedAlert::Write()
+{
+ _worldPacket << uint8(ClearPending);
+ _worldPacket << uint64(EventID);
+ _worldPacket << Date;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarSendNumPending::Write()
+{
+ _worldPacket << uint32(NumPending);
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarCommandResult::Write()
+{
+ _worldPacket << uint32(Command);
+ _worldPacket << "";
+ _worldPacket << Name;
+ _worldPacket << uint32(Result);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarRaidLockoutAdded::Write()
+{
+ _worldPacket << ServerTime;
+ _worldPacket << int32(MapID);
+ _worldPacket << uint32(DifficultyID);
+ _worldPacket << int32(TimeRemaining);
+ _worldPacket << uint64(InstanceID);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarRaidLockoutRemoved::Write()
+{
+ _worldPacket << int32(MapID);
+ _worldPacket << uint32(DifficultyID);
+ _worldPacket << int32(TimeRemaining);
+ _worldPacket << uint64(InstanceID);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarRaidLockoutUpdated::Write()
+{
+ _worldPacket << ServerTime;
+ _worldPacket << int32(MapID);
+ _worldPacket << uint32(DifficultyID);
+ _worldPacket << int32(OldTimeRemaining);
+ _worldPacket << int32(NewTimeRemaining);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarEventInitialInvites::Write()
+{
+ _worldPacket << uint32(Invites.size());
+ for (CalendarEventInitialInviteInfo const& invite : Invites)
+ {
+ _worldPacket << invite.InviteGuid.WriteAsPacked();
+ _worldPacket << uint8(invite.Level);
+ }
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarInviteStatusAlert::Write()
+{
+ _worldPacket << uint64(EventID);
+ _worldPacket << Date;
+ _worldPacket << uint32(Flags);
+ _worldPacket << uint8(Status);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarInviteNotesAlert::Write()
+{
+ _worldPacket << uint64(EventID);
+ _worldPacket << Notes;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Calendar::CalendarInviteNotes::Write()
+{
+ _worldPacket << InviteGuid.WriteAsPacked();
+ _worldPacket << uint64(EventID);
+ _worldPacket << Notes;
+ _worldPacket << uint8(ClearPending);
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Calendar::CalendarComplain::Read()
+{
+ _worldPacket >> InvitedByGUID;
+ _worldPacket >> EventID;
+ _worldPacket >> InviteID;
+}
diff --git a/src/server/game/Server/Packets/CalendarPackets.h b/src/server/game/Server/Packets/CalendarPackets.h
new file mode 100644
index 00000000000..fd6afc79ad3
--- /dev/null
+++ b/src/server/game/Server/Packets/CalendarPackets.h
@@ -0,0 +1,605 @@
+/*
+ * 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 CalendarPackets_h__
+#define CalendarPackets_h__
+
+#include "Packet.h"
+#include "CalendarMgr.h"
+#include "DBCStructure.h"
+#include "ObjectGuid.h"
+#include "Optional.h"
+#include "PacketUtilities.h"
+#include "WowTime.h"
+
+namespace WorldPackets
+{
+ namespace Calendar
+ {
+ class CalendarGetCalendar final : public ClientPacket
+ {
+ public:
+ CalendarGetCalendar(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_GET_CALENDAR, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class CalendarGetEvent final : public ClientPacket
+ {
+ public:
+ CalendarGetEvent(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_GET_EVENT, std::move(packet)) { }
+
+ void Read() override;
+
+ uint64 EventID = 0;
+ };
+
+ class CalendarGuildFilter final : public ClientPacket
+ {
+ public:
+ CalendarGuildFilter(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_GUILD_FILTER, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 MinLevel = 1;
+ uint32 MaxLevel = 100;
+ uint32 MaxRankOrder = 0;
+ };
+
+ class CalendarArenaTeam final : public ClientPacket
+ {
+ public:
+ CalendarArenaTeam(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_ARENA_TEAM, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 ArenaTeamId = 0;
+ };
+
+ struct CalendarAddEventInviteInfo
+ {
+ ObjectGuid Guid;
+ uint8 Status = 0;
+ uint8 Moderator = 0;
+ };
+
+ class CalendarAddEvent final : public ClientPacket
+ {
+ public:
+ CalendarAddEvent(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_ADD_EVENT, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 MaxSize = 100;
+ std::string Title;
+ std::string Description;
+ uint8 EventType = 0;
+ int32 TextureID = 0;
+ WowTime Time;
+ WowTime LockDate;
+ uint32 Flags = 0;
+ Array<CalendarAddEventInviteInfo, CALENDAR_MAX_INVITES> Invites;
+ };
+
+ class CalendarUpdateEvent final : public ClientPacket
+ {
+ public:
+ CalendarUpdateEvent(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_UPDATE_EVENT, std::move(packet)) { }
+
+ void Read() override;
+
+ uint64 EventID = 0;
+ uint64 ModeratorID = 0;
+ std::string Title;
+ std::string Description;
+ uint8 EventType = 0;
+ uint32 TextureID = 0;
+ WowTime Time;
+ WowTime LockDate;
+ uint32 Flags = 0;
+ uint32 MaxSize = 0;
+ };
+
+ class CalendarRemoveEvent final : public ClientPacket
+ {
+ public:
+ CalendarRemoveEvent(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_REMOVE_EVENT, std::move(packet)) { }
+
+ void Read() override;
+
+ uint64 ModeratorID = 0;
+ uint64 EventID = 0;
+ bool IsSignUp = false;
+ };
+
+ class CalendarCopyEvent final : public ClientPacket
+ {
+ public:
+ CalendarCopyEvent(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_COPY_EVENT, std::move(packet)) { }
+
+ void Read() override;
+
+ uint64 ModeratorID = 0;
+ uint64 EventID = 0;
+ WowTime Date;
+ };
+
+ class CalendarInviteAdded final : public ServerPacket
+ {
+ public:
+ CalendarInviteAdded() : ServerPacket(SMSG_CALENDAR_EVENT_INVITE, 43) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 InviteID = 0;
+ WowTime ResponseTime;
+ uint8 Level = 100;
+ ObjectGuid InviteGuid;
+ uint64 EventID = 0;
+ uint8 Type = 0;
+ bool ClearPending = false;
+ uint8 Status = 0;
+ };
+
+ struct CalendarSendCalendarInviteInfo
+ {
+ uint64 EventID = 0;
+ uint64 InviteID = 0;
+ ObjectGuid InviterGuid;
+ uint8 Status = 0;
+ uint8 Moderator = 0;
+ uint8 InviteType = 0;
+ bool IgnoreFriendAndGuildRestriction = false;
+ };
+
+ struct CalendarSendCalendarRaidLockoutInfo
+ {
+ uint64 InstanceID = 0;
+ int32 MapID = 0;
+ uint32 DifficultyID = 0;
+ int32 ExpireTime = 0;
+ };
+
+ struct CalendarSendCalendarEventInfo
+ {
+ uint64 EventID = 0;
+ std::string EventName;
+ uint8 EventType = 0;
+ WowTime Date;
+ uint32 Flags = 0;
+ int32 TextureID = 0;
+ ObjectGuid OwnerGuid;
+ };
+
+ struct CalendarSendCalendarRaidResetInfo
+ {
+ int32 MapID = 0;
+ uint32 Duration = 0;
+ int32 Offset = 0;
+ };
+
+ struct CalendarSendCalendarHolidayInfo
+ {
+ int32 HolidayID = 0;
+ int32 Region = 0;
+ int32 Looping = 0;
+ int32 Priority = 0;
+ int32 FilterType = 0;
+ std::string_view TextureFilename;
+ std::array<WowTime, MAX_HOLIDAY_DATES> Date = { };
+ std::array<int32, MAX_HOLIDAY_DURATIONS> Duration = { };
+ std::array<int32, MAX_HOLIDAY_FLAGS> CalendarFlags = { };
+ };
+
+ class CalendarSendCalendar final : public ServerPacket
+ {
+ public:
+ CalendarSendCalendar() : ServerPacket(SMSG_CALENDAR_SEND_CALENDAR, 338) { }
+
+ WorldPacket const* Write() override;
+
+ WowTime ServerTime;
+ std::vector<CalendarSendCalendarInviteInfo> Invites;
+ std::vector<CalendarSendCalendarRaidLockoutInfo> RaidLockouts;
+ std::vector<CalendarSendCalendarEventInfo> Events;
+ time_t ServerNow = time_t(0);
+ time_t RaidOrigin = time_t(0);
+ std::vector<CalendarSendCalendarRaidResetInfo> RaidResets;
+ std::vector<CalendarSendCalendarHolidayInfo> Holidays;
+ };
+
+ struct CalendarEventInviteInfo
+ {
+ ObjectGuid Guid;
+ uint64 InviteID = 0;
+ WowTime ResponseTime;
+ uint8 Level = 1;
+ uint8 Status = 0;
+ uint8 Moderator = 0;
+ uint8 InviteType = 0;
+ std::string Notes;
+ };
+
+ class CalendarSendEvent final : public ServerPacket
+ {
+ public:
+ CalendarSendEvent() : ServerPacket(SMSG_CALENDAR_SEND_EVENT, 93) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid OwnerGuid;
+ ObjectGuid::LowType EventGuildID = 0;
+ uint64 EventID = 0;
+ WowTime Date;
+ WowTime LockDate;
+ uint32 Flags = 0;
+ int32 TextureID = 0;
+ uint8 GetEventType = 0;
+ uint8 EventType = 0;
+ std::string Description;
+ std::string EventName;
+ std::vector<CalendarEventInviteInfo> Invites;
+ };
+
+ class CalendarInviteAlert final : public ServerPacket
+ {
+ public:
+ CalendarInviteAlert() : ServerPacket(SMSG_CALENDAR_EVENT_INVITE_ALERT, 80) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid OwnerGuid;
+ ObjectGuid InvitedByGuid;
+ uint64 InviteID = 0;
+ uint64 EventID = 0;
+ uint32 Flags = 0;
+ WowTime Date;
+ int32 TextureID = 0;
+ uint8 Status = 0;
+ uint32 EventType = 0;
+ uint8 ModeratorStatus = 0;
+ std::string EventName;
+ };
+
+ class CalendarInvite final : public ClientPacket
+ {
+ public:
+ CalendarInvite(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_EVENT_INVITE, std::move(packet)) { }
+
+ void Read() override;
+
+ uint64 ModeratorID = 0;
+ bool IsSignUp = false;
+ bool Creating = true;
+ uint64 EventID = 0;
+ std::string Name;
+ };
+
+ class CalendarRSVP final : public ClientPacket
+ {
+ public:
+ CalendarRSVP(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_EVENT_RSVP, std::move(packet)) { }
+
+ void Read() override;
+
+ uint64 InviteID = 0;
+ uint64 EventID = 0;
+ uint8 Status = 0;
+ };
+
+ class CalendarInviteStatus final : public ServerPacket
+ {
+ public:
+ CalendarInviteStatus() : ServerPacket(SMSG_CALENDAR_EVENT_STATUS, 41) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 Flags = 0;
+ uint64 EventID = 0;
+ uint8 Status = 0;
+ bool ClearPending = false;
+ WowTime ResponseTime;
+ WowTime Date;
+ ObjectGuid InviteGuid;
+ };
+
+ class CalendarInviteRemoved final : public ServerPacket
+ {
+ public:
+ CalendarInviteRemoved() : ServerPacket(SMSG_CALENDAR_EVENT_INVITE_REMOVED, 29) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid InviteGuid;
+ uint64 EventID = 0;
+ uint32 Flags = 0;
+ bool ClearPending = false;
+ };
+
+ class CalendarModeratorStatus final : public ServerPacket
+ {
+ public:
+ CalendarModeratorStatus() : ServerPacket(SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT, 26) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid InviteGuid;
+ uint64 EventID = 0;
+ uint8 Status = 0;
+ bool ClearPending = false;
+ };
+
+ class CalendarInviteRemovedAlert final : public ServerPacket
+ {
+ public:
+ CalendarInviteRemovedAlert() : ServerPacket(SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT, 17) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 EventID = 0;
+ WowTime Date;
+ uint32 Flags = 0;
+ uint8 Status = 0;
+ };
+
+ class CalendarClearPendingAction final : public ServerPacket
+ {
+ public:
+ CalendarClearPendingAction() : ServerPacket(SMSG_CALENDAR_CLEAR_PENDING_ACTION, 0) { }
+
+ WorldPacket const* Write() override { return &_worldPacket; }
+ };
+
+ class CalendarEventUpdatedAlert final : public ServerPacket
+ {
+ public:
+ CalendarEventUpdatedAlert() : ServerPacket(SMSG_CALENDAR_EVENT_UPDATED_ALERT, 32) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 EventID = 0;
+ WowTime Date;
+ uint32 Flags = 0;
+ WowTime LockDate;
+ WowTime OriginalDate;
+ int32 TextureID = 0;
+ uint8 EventType = 0;
+ bool ClearPending = false;
+ std::string Description;
+ std::string EventName;
+ };
+
+ class CalendarEventRemovedAlert final : public ServerPacket
+ {
+ public:
+ CalendarEventRemovedAlert() : ServerPacket(SMSG_CALENDAR_EVENT_REMOVED_ALERT, 13) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 EventID = 0;
+ WowTime Date;
+ bool ClearPending = false;
+ };
+
+ class CalendarSendNumPending final : public ServerPacket
+ {
+ public:
+ CalendarSendNumPending() : ServerPacket(SMSG_CALENDAR_SEND_NUM_PENDING, 4) { }
+ CalendarSendNumPending(uint32 numPending) : ServerPacket(SMSG_CALENDAR_SEND_NUM_PENDING, 4), NumPending(numPending) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 NumPending = 0;
+ };
+
+ class CalendarGetNumPending final : public ClientPacket
+ {
+ public:
+ CalendarGetNumPending(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_GET_NUM_PENDING, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class CalendarEventSignUp final : public ClientPacket
+ {
+ public:
+ CalendarEventSignUp(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_EVENT_SIGNUP, std::move(packet)) { }
+
+ void Read() override;
+
+ bool Tentative = false;
+ uint64 EventID = 0;
+ };
+
+ class CalendarRemoveInvite final : public ClientPacket
+ {
+ public:
+ CalendarRemoveInvite(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_EVENT_REMOVE_INVITE, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Guid;
+ uint64 EventID = 0;
+ uint64 ModeratorID = 0;
+ uint64 InviteID = 0;
+ };
+
+ class CalendarStatus final : public ClientPacket
+ {
+ public:
+ CalendarStatus(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_EVENT_STATUS, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Guid;
+ uint64 EventID = 0;
+ uint64 ModeratorID = 0;
+ uint64 InviteID = 0;
+ uint8 Status = 0;
+ };
+
+ class SetSavedInstanceExtend final : public ClientPacket
+ {
+ public:
+ SetSavedInstanceExtend(WorldPacket&& packet) : ClientPacket(CMSG_SET_SAVED_INSTANCE_EXTEND, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 MapID = 0;
+ bool Extend = false;
+ uint32 DifficultyID = 0;
+ };
+
+ class CalendarModeratorStatusQuery final : public ClientPacket
+ {
+ public:
+ CalendarModeratorStatusQuery(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_EVENT_MODERATOR_STATUS, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Guid;
+ uint64 EventID = 0;
+ uint64 InviteID = 0;
+ uint64 ModeratorID = 0;
+ uint8 Status = 0;
+ };
+
+ class CalendarCommandResult final : public ServerPacket
+ {
+ public:
+ CalendarCommandResult() : ServerPacket(SMSG_CALENDAR_COMMAND_RESULT, 3) { }
+ CalendarCommandResult(uint8 command, uint8 result, std::string const& name) : ServerPacket(SMSG_CALENDAR_COMMAND_RESULT, 3), Command(command), Result(result), Name(name) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 Command = 0;
+ uint32 Result = 0;
+ std::string Name;
+ };
+
+ class CalendarRaidLockoutAdded final : public ServerPacket
+ {
+ public:
+ CalendarRaidLockoutAdded() : ServerPacket(SMSG_CALENDAR_RAID_LOCKOUT_ADDED, 8 + 4 + 4 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 InstanceID = 0;
+ uint32 DifficultyID = 0;
+ int32 TimeRemaining = 0;
+ WowTime ServerTime;
+ int32 MapID = 0;
+ };
+
+ class CalendarRaidLockoutRemoved final : public ServerPacket
+ {
+ public:
+ CalendarRaidLockoutRemoved() : ServerPacket(SMSG_CALENDAR_RAID_LOCKOUT_REMOVED, 8 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 InstanceID = 0;
+ int32 MapID = 0;
+ uint32 DifficultyID = 0;
+ int32 TimeRemaining = 0;
+ };
+
+ class CalendarRaidLockoutUpdated final : public ServerPacket
+ {
+ public:
+ CalendarRaidLockoutUpdated() : ServerPacket(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 20) { }
+
+ WorldPacket const* Write() override;
+
+ WowTime ServerTime;
+ int32 MapID = 0;
+ uint32 DifficultyID = 0;
+ int32 NewTimeRemaining = 0;
+ int32 OldTimeRemaining = 0;
+ };
+
+ struct CalendarEventInitialInviteInfo
+ {
+ CalendarEventInitialInviteInfo(ObjectGuid inviteGuid, uint8 level) : InviteGuid(inviteGuid), Level(level) { }
+
+ ObjectGuid InviteGuid;
+ uint8 Level = 100;
+ };
+
+ class CalendarEventInitialInvites final : public ServerPacket
+ {
+ public:
+ CalendarEventInitialInvites(bool guild) : ServerPacket(guild ? SMSG_CALENDAR_FILTER_GUILD : SMSG_CALENDAR_ARENA_TEAM, 17) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<CalendarEventInitialInviteInfo> Invites;
+ };
+
+ class CalendarInviteStatusAlert final : public ServerPacket
+ {
+ public:
+ CalendarInviteStatusAlert() : ServerPacket(SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT, 5) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 EventID = 0;
+ uint32 Flags = 0;
+ WowTime Date;
+ uint8 Status = 0;
+ };
+
+ class CalendarInviteNotesAlert final : public ServerPacket
+ {
+ public:
+ CalendarInviteNotesAlert() : ServerPacket(SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT, 9) { }
+ CalendarInviteNotesAlert(uint64 eventID, std::string const& notes) : ServerPacket(SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT, 8 + notes.size()), EventID(eventID), Notes(notes) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 EventID = 0;
+ std::string Notes;
+ };
+
+ class CalendarInviteNotes final : public ServerPacket
+ {
+ public:
+ CalendarInviteNotes() : ServerPacket(SMSG_CALENDAR_EVENT_INVITE_NOTES, 26) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid InviteGuid;
+ uint64 EventID = 0;
+ std::string Notes;
+ bool ClearPending = false;
+ };
+
+ class CalendarComplain final : public ClientPacket
+ {
+ public:
+ CalendarComplain(WorldPacket&& packet) : ClientPacket(CMSG_CALENDAR_COMPLAIN, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid InvitedByGUID;
+ uint64 InviteID = 0;
+ uint64 EventID = 0;
+ };
+ }
+}
+
+#endif // CalendarPackets_h__
diff --git a/src/server/game/Server/Packets/GuildPackets.cpp b/src/server/game/Server/Packets/GuildPackets.cpp
index 30cc4c941b9..b1965b454dc 100644
--- a/src/server/game/Server/Packets/GuildPackets.cpp
+++ b/src/server/game/Server/Packets/GuildPackets.cpp
@@ -50,7 +50,7 @@ void WorldPackets::Guild::GuildCreate::Read()
WorldPacket const* WorldPackets::Guild::GuildInfoResponse::Write()
{
_worldPacket << GuildName;
- _worldPacket.AppendPackedTime(CreateDate);
+ _worldPacket << CreateDate;
_worldPacket << int32(NumMembers);
_worldPacket << int32(NumAccounts);
diff --git a/src/server/game/Server/Packets/GuildPackets.h b/src/server/game/Server/Packets/GuildPackets.h
index 6815b936531..870af4439de 100644
--- a/src/server/game/Server/Packets/GuildPackets.h
+++ b/src/server/game/Server/Packets/GuildPackets.h
@@ -22,7 +22,7 @@
#include "Guild.h"
#include "ObjectGuid.h"
#include "PacketUtilities.h"
-#include <boost/container/static_vector.hpp>
+#include "WowTime.h"
#include <array>
namespace WorldPackets
@@ -90,7 +90,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
std::string GuildName;
- time_t CreateDate = time_t(0);
+ WowTime CreateDate;
int32 NumMembers = 0;
int32 NumAccounts = 0;
};
@@ -208,7 +208,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
uint8 Type = 0;
- boost::container::static_vector<std::string_view, 3> Params;
+ Array<std::string_view, 3> Params;
ObjectGuid Guid;
};
diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp
index 1ecdd99fbf8..17d667e7c77 100644
--- a/src/server/game/Server/Packets/MiscPackets.cpp
+++ b/src/server/game/Server/Packets/MiscPackets.cpp
@@ -77,7 +77,7 @@ WorldPacket const* WorldPackets::Misc::InvalidatePlayer::Write()
WorldPacket const* WorldPackets::Misc::LoginSetTimeSpeed::Write()
{
- _worldPacket.AppendPackedTime(GameTime);
+ _worldPacket << GameTime;
_worldPacket << float(NewSpeed);
_worldPacket << uint32(GameTimeHolidayOffset);
diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h
index 553fbba3dc1..e8ef57af674 100644
--- a/src/server/game/Server/Packets/MiscPackets.h
+++ b/src/server/game/Server/Packets/MiscPackets.h
@@ -23,6 +23,7 @@
#include "ObjectGuid.h"
#include "Optional.h"
#include "Weather.h"
+#include "WowTime.h"
#include <array>
enum WeatherState : uint32;
@@ -125,7 +126,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
float NewSpeed = 0.0f;
- uint32 GameTime = 0;
+ WowTime GameTime;
int32 GameTimeHolidayOffset = 0;
};
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 081c9693bdb..0ce690bd574 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -107,13 +107,14 @@ bool WorldSessionFilter::Process(WorldPacket* packet)
}
/// WorldSession constructor
-WorldSession::WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter):
+WorldSession::WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time,
+ Minutes timezoneOffset, LocaleConstant locale, uint32 recruiter, bool isARecruiter):
m_muteTime(mute_time),
m_timeOutTime(0),
AntiDOS(this),
m_GUIDLow(0),
_player(nullptr),
- m_Socket(sock),
+ m_Socket(std::move(sock)),
_security(sec),
_accountId(id),
_accountName(std::move(name)),
@@ -126,6 +127,7 @@ WorldSession::WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldS
m_playerSave(false),
m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)),
m_sessionDbLocaleIndex(locale),
+ _timezoneOffset(timezoneOffset),
m_latency(0),
m_TutorialsChanged(TUTORIALS_FLAG_NONE),
recruiterId(recruiter),
@@ -144,9 +146,9 @@ WorldSession::WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldS
{
memset(m_Tutorials, 0, sizeof(m_Tutorials));
- if (sock)
+ if (m_Socket)
{
- m_Address = sock->GetRemoteIpAddress().to_string();
+ m_Address = m_Socket->GetRemoteIpAddress().to_string();
ResetTimeOutTime(false);
LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = {};", GetAccountId()); // One-time query
}
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 10f198e1795..828aa415b1c 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -87,6 +87,27 @@ namespace WorldPackets
class BuyBankSlot;
}
+ namespace Calendar
+ {
+ class CalendarAddEvent;
+ class CalendarCopyEvent;
+ class CalendarInvite;
+ class CalendarModeratorStatusQuery;
+ class CalendarRSVP;
+ class CalendarEventSignUp;
+ class CalendarStatus;
+ class CalendarGetCalendar;
+ class CalendarGetEvent;
+ class CalendarGetNumPending;
+ class CalendarGuildFilter;
+ class CalendarArenaTeam;
+ class CalendarRemoveEvent;
+ class CalendarRemoveInvite;
+ class CalendarUpdateEvent;
+ class SetSavedInstanceExtend;
+ class CalendarComplain;
+ }
+
namespace Character
{
class LogoutCancel;
@@ -400,7 +421,8 @@ struct PacketCounter
class TC_GAME_API WorldSession
{
public:
- WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter);
+ WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time,
+ Minutes timezoneOffset, LocaleConstant locale, uint32 recruiter, bool isARecruiter);
~WorldSession();
bool PlayerLoading() const { return m_playerLoading; }
@@ -571,6 +593,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; }
@@ -1079,26 +1104,27 @@ class TC_GAME_API WorldSession
void HandleAcceptGrantLevel(WorldPacket& recvData);
// Calendar
- void HandleCalendarGetCalendar(WorldPacket& recvData);
- void HandleCalendarGetEvent(WorldPacket& recvData);
- void HandleCalendarGuildFilter(WorldPacket& recvData);
- void HandleCalendarArenaTeam(WorldPacket& recvData);
- void HandleCalendarAddEvent(WorldPacket& recvData);
- void HandleCalendarUpdateEvent(WorldPacket& recvData);
- void HandleCalendarRemoveEvent(WorldPacket& recvData);
- void HandleCalendarCopyEvent(WorldPacket& recvData);
- void HandleCalendarEventInvite(WorldPacket& recvData);
- void HandleCalendarEventRsvp(WorldPacket& recvData);
- void HandleCalendarEventRemoveInvite(WorldPacket& recvData);
- void HandleCalendarEventStatus(WorldPacket& recvData);
- void HandleCalendarEventModeratorStatus(WorldPacket& recvData);
- void HandleCalendarComplain(WorldPacket& recvData);
- void HandleCalendarGetNumPending(WorldPacket& recvData);
- void HandleCalendarEventSignup(WorldPacket& recvData);
-
- void SendCalendarRaidLockout(InstanceSave const* save, bool add);
+ void HandleCalendarGetCalendar(WorldPackets::Calendar::CalendarGetCalendar& calendarGetCalendar);
+ void HandleCalendarGetEvent(WorldPackets::Calendar::CalendarGetEvent& calendarGetEvent);
+ void HandleCalendarGuildFilter(WorldPackets::Calendar::CalendarGuildFilter& calendarGuildFilter);
+ void HandleCalendarArenaTeam(WorldPackets::Calendar::CalendarArenaTeam& calendarArenaTeam);
+ void HandleCalendarAddEvent(WorldPackets::Calendar::CalendarAddEvent& calendarAddEvent);
+ void HandleCalendarUpdateEvent(WorldPackets::Calendar::CalendarUpdateEvent& calendarUpdateEvent);
+ void HandleCalendarRemoveEvent(WorldPackets::Calendar::CalendarRemoveEvent& calendarRemoveEvent);
+ void HandleCalendarCopyEvent(WorldPackets::Calendar::CalendarCopyEvent& calendarCopyEvent);
+ void HandleCalendarEventInvite(WorldPackets::Calendar::CalendarInvite& calendarEventInvite);
+ void HandleCalendarEventRsvp(WorldPackets::Calendar::CalendarRSVP& calendarRSVP);
+ void HandleCalendarEventRemoveInvite(WorldPackets::Calendar::CalendarRemoveInvite& calendarRemoveInvite);
+ void HandleCalendarEventStatus(WorldPackets::Calendar::CalendarStatus& calendarStatus);
+ void HandleCalendarEventModeratorStatus(WorldPackets::Calendar::CalendarModeratorStatusQuery& calendarModeratorStatus);
+ void HandleCalendarComplain(WorldPackets::Calendar::CalendarComplain& calendarComplain);
+ void HandleCalendarGetNumPending(WorldPackets::Calendar::CalendarGetNumPending& calendarGetNumPending);
+ void HandleCalendarEventSignup(WorldPackets::Calendar::CalendarEventSignUp& calendarEventSignUp);
+
+ void SendCalendarRaidLockoutAdded(InstanceSave const* save);
+ void SendCalendarRaidLockoutRemoved(InstanceSave const* save);
void SendCalendarRaidLockoutUpdated(InstanceSave const* save);
- void HandleSetSavedInstanceExtend(WorldPacket& recvData);
+ void HandleSetSavedInstanceExtend(WorldPackets::Calendar::SetSavedInstanceExtend& setSavedInstanceExtend);
void HandleSpellClick(WorldPacket& recvData);
void HandleMirrorImageDataRequest(WorldPacket& recvData);
@@ -1203,6 +1229,7 @@ class TC_GAME_API WorldSession
bool m_playerSave;
LocaleConstant m_sessionDbcLocale;
LocaleConstant m_sessionDbLocaleIndex;
+ Minutes _timezoneOffset;
std::atomic<uint32> m_latency;
AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES];
uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES];
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index 4603e619be5..6b89e04b6ee 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -254,15 +254,16 @@ struct AccountInfo
LocaleConstant Locale;
uint32 Recruiter;
std::string OS;
+ Minutes TimezoneOffset;
bool IsRectuiter;
AccountTypes Security;
bool IsBanned;
- explicit AccountInfo(Field* fields)
+ explicit AccountInfo(Field const* fields)
{
- // 0 1 2 3 4 5 6 7 8 9 10
- // SELECT a.id, a.sessionkey, a.last_ip, a.locked, a.lock_country, a.expansion, a.mutetime, a.locale, a.recruiter, a.os, aa.gmLevel,
- // 11 12
+ // 0 1 2 3 4 5 6 7 8 9 10 11
+ // SELECT a.id, a.sessionkey, a.last_ip, a.locked, a.lock_country, a.expansion, a.mutetime, a.locale, a.recruiter, a.os, a.timezone_offset, aa.SecurityLevel,
+ // 12 13
// ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id
// FROM account a
// LEFT JOIN account_access aa ON a.id = aa.AccountID AND aa.RealmID IN (-1, ?)
@@ -279,9 +280,10 @@ struct AccountInfo
Locale = LocaleConstant(fields[7].GetUInt8());
Recruiter = fields[8].GetUInt32();
OS = fields[9].GetString();
- Security = AccountTypes(fields[10].GetUInt8());
- IsBanned = fields[11].GetUInt64() != 0;
- IsRectuiter = fields[12].GetUInt32() != 0;
+ TimezoneOffset = Minutes(fields[10].GetInt16());
+ Security = AccountTypes(fields[11].GetUInt8());
+ IsBanned = fields[12].GetUInt64() != 0;
+ IsRectuiter = fields[13].GetUInt32() != 0;
uint32 world_expansion = sWorld->getIntConfig(CONFIG_EXPANSION);
if (Expansion > world_expansion)
@@ -442,7 +444,10 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
stmt->setInt32(0, int32(realm.Id.Realm));
stmt->setString(1, authSession->Account);
- _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<AuthSession> authSession, PreparedQueryResult result)
@@ -604,7 +609,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSes
_authed = true;
_worldSession = new WorldSession(account.Id, std::move(authSession->Account), shared_from_this(), account.Security,
- account.Expansion, mutetime, account.Locale, account.Recruiter, account.IsRectuiter);
+ account.Expansion, mutetime, account.TimezoneOffset, account.Locale, account.Recruiter, account.IsRectuiter);
_worldSession->ReadAddonsInfo(authSession->AddonInfo);
// Initialize Warden system only if it is enabled by config
diff --git a/src/server/game/Time/GameTime.cpp b/src/server/game/Time/GameTime.cpp
index 7742cabef20..733f381f796 100644
--- a/src/server/game/Time/GameTime.cpp
+++ b/src/server/game/Time/GameTime.cpp
@@ -17,6 +17,9 @@
#include "GameTime.h"
#include "Timer.h"
+#include "Timezone.h"
+#include "Util.h"
+#include "WowTime.h"
namespace GameTime
{
@@ -28,6 +31,9 @@ namespace GameTime
SystemTimePoint GameTimeSystemPoint = SystemTimePoint ::min();
TimePoint GameTimeSteadyPoint = TimePoint::min();
+ WowTime UtcWow;
+ WowTime Wow;
+
time_t GetStartTime()
{
return StartTime;
@@ -58,11 +64,23 @@ namespace GameTime
return uint32(GameTime - StartTime);
}
+ WowTime const* GetUtcWowTime()
+ {
+ return &UtcWow;
+ }
+
+ WowTime const* GetWowTime()
+ {
+ return &Wow;
+ }
+
void UpdateGameTimers()
{
GameTime = time(nullptr);
GameMSTime = getMSTime();
GameTimeSystemPoint = std::chrono::system_clock::now();
GameTimeSteadyPoint = std::chrono::steady_clock::now();
+ UtcWow.SetUtcTimeFromUnixTime(GameTime);
+ Wow = UtcWow + Trinity::Timezone::GetSystemZoneOffsetAt(GameTimeSystemPoint);
}
}
diff --git a/src/server/game/Time/GameTime.h b/src/server/game/Time/GameTime.h
index 838984be72a..3ff411e867a 100644
--- a/src/server/game/Time/GameTime.h
+++ b/src/server/game/Time/GameTime.h
@@ -21,6 +21,8 @@
#include "Define.h"
#include "Duration.h"
+class WowTime;
+
namespace GameTime
{
// Server start time
@@ -41,6 +43,10 @@ namespace GameTime
/// Uptime (in secs)
TC_GAME_API uint32 GetUptime();
+ TC_GAME_API WowTime const* GetUtcWowTime();
+
+ TC_GAME_API WowTime const* GetWowTime();
+
void UpdateGameTimers();
}
diff --git a/src/server/game/Time/WowTime.cpp b/src/server/game/Time/WowTime.cpp
new file mode 100644
index 00000000000..b88f0c56a8e
--- /dev/null
+++ b/src/server/game/Time/WowTime.cpp
@@ -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;
+}
diff --git a/src/server/game/Time/WowTime.h b/src/server/game/Time/WowTime.h
new file mode 100644
index 00000000000..a273d210d6a
--- /dev/null
+++ b/src/server/game/Time/WowTime.h
@@ -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
diff --git a/src/server/shared/Packets/ByteBuffer.cpp b/src/server/shared/Packets/ByteBuffer.cpp
index aff903f4846..2a784027dc3 100644
--- a/src/server/shared/Packets/ByteBuffer.cpp
+++ b/src/server/shared/Packets/ByteBuffer.cpp
@@ -24,7 +24,6 @@
#include <utf8.h>
#include <sstream>
#include <cmath>
-#include <ctime>
ByteBuffer::ByteBuffer(MessageBuffer&& buffer) : _rpos(0), _wpos(0), _storage(buffer.Move())
{
@@ -90,21 +89,6 @@ std::string ByteBuffer::ReadCString(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());
@@ -130,13 +114,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());
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index aa387d0842b..e19e89ede22 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -392,14 +392,6 @@ class TC_SHARED_API ByteBuffer
std::string ReadCString(bool requireValidUtf8 = true);
- uint32 ReadPackedTime();
-
- ByteBuffer& ReadPackedTime(uint32& time)
- {
- time = ReadPackedTime();
- return *this;
- }
-
uint8* contents()
{
if (_storage.empty())
@@ -488,8 +480,6 @@ class TC_SHARED_API ByteBuffer
append(packGUID, size);
}
- void AppendPackedTime(time_t time);
-
void put(size_t pos, const uint8 *src, size_t cnt);
void print_storage() const;
diff --git a/src/server/shared/Realm/RealmList.h b/src/server/shared/Realm/RealmList.h
index b5ef9c33b7b..056472533e2 100644
--- a/src/server/shared/Realm/RealmList.h
+++ b/src/server/shared/Realm/RealmList.h
@@ -19,6 +19,7 @@
#define _REALMLIST_H
#include "Define.h"
+#include "Duration.h"
#include "Realm.h"
#include <array>
#include <map>