diff options
Diffstat (limited to 'src/server/game/Time')
-rw-r--r-- | src/server/game/Time/GameTime.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Time/GameTime.h | 6 | ||||
-rw-r--r-- | src/server/game/Time/WowTime.cpp | 219 | ||||
-rw-r--r-- | src/server/game/Time/WowTime.h | 90 |
4 files changed, 332 insertions, 0 deletions
diff --git a/src/server/game/Time/GameTime.cpp b/src/server/game/Time/GameTime.cpp index 399be3196b3..3175c0e5571 100644 --- a/src/server/game/Time/GameTime.cpp +++ b/src/server/game/Time/GameTime.cpp @@ -17,7 +17,9 @@ #include "GameTime.h" #include "Timer.h" +#include "Timezone.h" #include "Util.h" +#include "WowTime.h" namespace GameTime { @@ -31,6 +33,9 @@ namespace GameTime tm DateTime; + WowTime UtcWow; + WowTime Wow; + time_t GetStartTime() { return StartTime; @@ -84,6 +89,16 @@ namespace GameTime return &DateTime; } + WowTime const* GetUtcWowTime() + { + return &UtcWow; + } + + WowTime const* GetWowTime() + { + return &Wow; + } + void UpdateGameTimers() { GameTime = time(nullptr); @@ -91,5 +106,7 @@ namespace GameTime GameTimeSystemPoint = std::chrono::system_clock::now(); GameTimeSteadyPoint = std::chrono::steady_clock::now(); localtime_r(&GameTime, &DateTime); + UtcWow.SetUtcTimeFromUnixTime(GameTime); + Wow = UtcWow + Trinity::Timezone::GetSystemZoneOffsetAt(GameTimeSystemPoint); } } diff --git a/src/server/game/Time/GameTime.h b/src/server/game/Time/GameTime.h index 4229872e016..7b18b030d2c 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 @@ -47,6 +49,10 @@ namespace GameTime TC_GAME_API tm const* GetDateAndTime(); + TC_GAME_API WowTime const* GetUtcWowTime(); + + TC_GAME_API WowTime const* GetWowTime(); + void UpdateGameTimers(); } 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 |