aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Time
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Time')
-rw-r--r--src/server/game/Time/GameTime.cpp17
-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
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