diff --git a/src/game/ChatCommands/BanAndKickCommands.cpp b/src/game/ChatCommands/BanAndKickCommands.cpp index 835dff542..32bc7b0ec 100644 --- a/src/game/ChatCommands/BanAndKickCommands.cpp +++ b/src/game/ChatCommands/BanAndKickCommands.cpp @@ -88,22 +88,25 @@ bool ChatHandler::HandleBanListHelper(QueryResult* result) Field* fields2 = banInfo->Fetch(); do { - time_t t_ban = fields2[0].GetUInt64(); - tm* aTm_ban = localtime(&t_ban); + time_t timeBan = fields2[0].GetUInt64(); + tm tmBan; + localtime_r(&timeBan, &tmBan); if (fields2[0].GetUInt64() == fields2[1].GetUInt64()) { PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", - account_name.c_str(), aTm_ban->tm_year % 100, aTm_ban->tm_mon + 1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, + account_name.c_str(), tmBan.tm_year % 100, tmBan.tm_mon + 1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min, fields2[2].GetString(), fields2[3].GetString()); } else { - time_t t_unban = fields2[1].GetUInt64(); - tm* aTm_unban = localtime(&t_unban); + time_t timeUnban = fields2[1].GetUInt64(); + tm tmUnban; + localtime_r(&timeUnban, &tmUnban); + PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", - account_name.c_str(), aTm_ban->tm_year % 100, aTm_ban->tm_mon + 1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, - aTm_unban->tm_year % 100, aTm_unban->tm_mon + 1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min, + account_name.c_str(), tmBan.tm_year % 100, tmBan.tm_mon + 1, tmBan.tm_mday, tmBan.tm_hour, tmBan.tm_min, + tmUnban.tm_year % 100, tmUnban.tm_mon + 1, tmUnban.tm_mday, tmUnban.tm_hour, tmUnban.tm_min, fields2[2].GetString(), fields2[3].GetString()); } } diff --git a/src/game/Object/ObjectMgr.cpp b/src/game/Object/ObjectMgr.cpp index e9e5372c4..984c126fa 100644 --- a/src/game/Object/ObjectMgr.cpp +++ b/src/game/Object/ObjectMgr.cpp @@ -5098,8 +5098,12 @@ void ObjectMgr::LoadGossipTextLocales() /// @param serverUp true if the server is already running, false when the server is started void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) { - time_t basetime = time(NULL); - DEBUG_LOG("Returning mails current time: hour: %d, minute: %d, second: %d ", localtime(&basetime)->tm_hour, localtime(&basetime)->tm_min, localtime(&basetime)->tm_sec); + time_t curTime = time(NULL); + tm lt; + localtime_r(&curTime, <); + uint64 basetime(curTime); + sLog.outString("Returning mails current time: hour: %d, minute: %d, second: %d ", lt.tm_hour, lt.tm_min, lt.tm_sec); + // delete all old mails without item and without body immediately, if starting server if (!serverUp) { diff --git a/src/game/WorldHandlers/Weather.cpp b/src/game/WorldHandlers/Weather.cpp index b143590ea..5cf9a72bf 100644 --- a/src/game/WorldHandlers/Weather.cpp +++ b/src/game/WorldHandlers/Weather.cpp @@ -108,8 +108,9 @@ bool Weather::ReGenerate() // 78 days between January 1st and March 20nd; 365/4=91 days by season // season source http://aa.usno.navy.mil/data/docs/EarthSeasons.html time_t gtime = sWorld.GetGameTime(); - struct tm* ltime = localtime(>ime); - uint32 season = ((ltime->tm_yday - 78 + 365) / 91) % 4; + struct tm ltime; + localtime_r(>ime, <ime); + uint32 season = ((ltime.tm_yday - 78 + 365) / 91) % 4; static char const* seasonName[WEATHER_SEASONS] = { "spring", "summer", "fall", "winter" }; diff --git a/src/game/WorldHandlers/Weather.h b/src/game/WorldHandlers/Weather.h index bf444e91e..0191ee85e 100644 --- a/src/game/WorldHandlers/Weather.h +++ b/src/game/WorldHandlers/Weather.h @@ -32,6 +32,7 @@ #include "Common.h" #include "SharedDefines.h" #include "Timer.h" +#include "Util.h" class Player; class Map; diff --git a/src/game/WorldHandlers/World.cpp b/src/game/WorldHandlers/World.cpp index d6a038fe5..ce183b1c2 100644 --- a/src/game/WorldHandlers/World.cpp +++ b/src/game/WorldHandlers/World.cpp @@ -2308,7 +2308,9 @@ void World::InitDailyQuestResetTime() // generate time by config time_t curTime = time(NULL); - tm localTm = *localtime(&curTime); + tm localTm; + localtime_r(&curTime, &localTm); + localTm.tm_hour = getConfig(CONFIG_UINT32_QUEST_DAILY_RESET_HOUR); localTm.tm_min = 0; localTm.tm_sec = 0; diff --git a/src/shared/Log/Log.cpp b/src/shared/Log/Log.cpp index 1ff0ba9f1..aa23d0f36 100644 --- a/src/shared/Log/Log.cpp +++ b/src/shared/Log/Log.cpp @@ -358,8 +358,9 @@ FILE* Log::openGmlogPerAccount(uint32 account) void Log::outTimestamp(FILE* file) { time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::tm aTm = localtime_r(tt); + std::tm aTm; + localtime_r(&tt, &aTm); // YYYY year // MM month (2 digits 01-12) // DD day (2 digits 01-31) @@ -372,8 +373,9 @@ void Log::outTimestamp(FILE* file) void Log::outTime() { time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::tm aTm = localtime_r(tt); + std::tm aTm; + localtime_r(&tt, &aTm); // YYYY year // MM month (2 digits 01-12) // DD day (2 digits 01-31) @@ -386,8 +388,9 @@ void Log::outTime() std::string Log::GetTimestampStr() { time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::tm aTm = localtime_r(tt); + std::tm aTm; + localtime_r(&tt, &aTm); // YYYY year // MM month (2 digits 01-12) // DD day (2 digits 01-31) diff --git a/src/shared/Utilities/ByteBuffer.h b/src/shared/Utilities/ByteBuffer.h index 5ba6ad6f4..566d65f87 100644 --- a/src/shared/Utilities/ByteBuffer.h +++ b/src/shared/Utilities/ByteBuffer.h @@ -476,6 +476,11 @@ class ByteBuffer return _rpos; } + void rfinish() + { + _rpos = wpos(); + } + /** * @brief * diff --git a/src/shared/Utilities/Util.cpp b/src/shared/Utilities/Util.cpp index 4f318ee5b..2ebf31c3a 100644 --- a/src/shared/Utilities/Util.cpp +++ b/src/shared/Utilities/Util.cpp @@ -154,15 +154,83 @@ void stripLineInvisibleChars(std::string& str) } } -std::tm localtime_r(const time_t& time) -{ - std::tm tm_snapshot; +/** + * It's a wrapper for the localtime_r function that works on Windows + * + * @param time The time to convert. + * @param result A pointer to a tm structure to receive the broken-down time. + * + * @return A pointer to the result. + */ #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) - localtime_s(&tm_snapshot, &time); -#else - localtime_r(&time, &tm_snapshot); // POSIX +struct tm* localtime_r(time_t const* time, struct tm *result) +{ + localtime_s(result, time); + return result; +} #endif - return tm_snapshot; + +/** + * It takes a time_t value and returns a tm structure with the same time, but in local time + * + * @param time The time to break down. + * + * @return A struct tm + */ +tm TimeBreakdown(time_t time) +{ + tm timeLocal; + localtime_r(&time, &timeLocal); + return timeLocal; +} + +/** + * Convert local time to UTC time. + * + * @param time The time to convert. + * + * @return The time in UTC. + */ +time_t LocalTimeToUTCTime(time_t time) +{ + #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) + return time + _timezone; + #else + return time + timezone; + #endif +} + +/** + * "Get the timestamp of the next time the given hour occurs in the local timezone." + * + * The function takes a timestamp, an hour, and a boolean. The timestamp is the time you want to find + * the next occurrence of the given hour. The hour is the hour you want to find the next occurrence of. + * The boolean is whether or not you want to find the next occurrence of the hour after the given + * timestamp + * + * @param time The time you want to get the hour timestamp for. + * @param hour The hour of the day you want to get the timestamp for. + * @param onlyAfterTime If true, the function will return the next hour after the current time. If + * false, it will return the current hour. + * + * @return A timestamp for the given hour of the day. + */ +time_t GetLocalHourTimestamp(time_t time, uint8 hour, bool onlyAfterTime) +{ + tm timeLocal = TimeBreakdown(time); + timeLocal.tm_hour = 0; + timeLocal.tm_min = 0; + timeLocal.tm_sec = 0; + + time_t midnightLocal = mktime(&timeLocal); + time_t hourLocal = midnightLocal + hour * HOUR; + + if (onlyAfterTime && hourLocal < time) + { + hourLocal += DAY; + } + + return hourLocal; } std::string secsToTimeString(time_t timeInSecs, TimeFormat timeFormat, bool hoursOnly) @@ -316,7 +384,8 @@ uint32 TimeStringToSecs(const std::string& timestring) std::string TimeToTimestampStr(time_t t) { - tm aTm = localtime_r(t); + tm aTm; + localtime_r(&t, &aTm); // YYYY year // MM month (2 digits 01-12) // DD day (2 digits 01-31) diff --git a/src/shared/Utilities/Util.h b/src/shared/Utilities/Util.h index a83d46fff..831cd77d7 100644 --- a/src/shared/Utilities/Util.h +++ b/src/shared/Utilities/Util.h @@ -79,12 +79,11 @@ float GetFloatValueFromArray(Tokens const& data, uint16 index); */ void stripLineInvisibleChars(std::string& src); -/** - * @brief - * - * @param localtime - */ -std::tm localtime_r(const time_t& time); +struct tm* localtime_r(const time_t* time, struct tm* result); + +time_t LocalTimeToUTCTime(time_t time); +time_t GetLocalHourTimestamp(time_t time, uint8 hour, bool onlyAfterTime = true); +tm TimeBreakdown(time_t t); /** * @brief