From 07767cb5c7f710bb82922264fc52c34ddaebefdc Mon Sep 17 00:00:00 2001 From: Icemansparks Date: Mon, 26 May 2025 20:30:22 +0200 Subject: [PATCH 1/3] allow setting a fixed day in the week for weekly restarts instead of "restart every x days" as an alternative option --- conf/ServerAutoShutdown.conf.dist | 9 ++++++ src/ServerAutoShutdown.cpp | 53 ++++++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/conf/ServerAutoShutdown.conf.dist b/conf/ServerAutoShutdown.conf.dist index 78da4da..a55976c 100644 --- a/conf/ServerAutoShutdown.conf.dist +++ b/conf/ServerAutoShutdown.conf.dist @@ -23,6 +23,15 @@ ServerAutoShutdown.Enabled = 0 ServerAutoShutdown.EveryDays = 1 +# +# ServerAutoShutdown.Weekday +# Description: If set (0-6, where 0=Sunday, 1=Monday, ... 6=Saturday), the server will restart on this weekday at the configured time. +# Overrides ServerAutoShutdown.EveryDays if set to a valid value. +# Default: -1 (disabled) +# + +ServerAutoShutdown.Weekday = 3 + # # ServerAutoShutdown.Time # Description: Time (in HH:MM:SS) - 24 hours format diff --git a/src/ServerAutoShutdown.cpp b/src/ServerAutoShutdown.cpp index da548a2..6759eec 100644 --- a/src/ServerAutoShutdown.cpp +++ b/src/ServerAutoShutdown.cpp @@ -49,6 +49,30 @@ namespace return midnightLocal; } + + // Returns the next time_t for the given weekday (0=Sunday, 1=Monday, ..., 6=Saturday) at the given hour/min/sec + time_t GetNextWeekdayTime(time_t now, int weekday, uint8 hour, uint8 minute, uint8 second) + { + tm timeLocal = Acore::Time::TimeBreakdown(now); + int currentWeekday = timeLocal.tm_wday; + int daysUntil = (weekday - currentWeekday + 7) % 7; + if (daysUntil == 0) + { + // If today, check if the time has already passed + if (timeLocal.tm_hour > hour || + (timeLocal.tm_hour == hour && timeLocal.tm_min > minute) || + (timeLocal.tm_hour == hour && timeLocal.tm_min == minute && timeLocal.tm_sec >= second)) + { + daysUntil = 7; + } + } + timeLocal.tm_mday += daysUntil; + timeLocal.tm_hour = hour; + timeLocal.tm_min = minute; + timeLocal.tm_sec = second; + time_t result = mktime(&timeLocal); + return result; + } } /*static*/ ServerAutoShutdown* ServerAutoShutdown::instance() @@ -91,11 +115,30 @@ void ServerAutoShutdown::Init() return; } + int weekday = sConfigMgr->GetOption("ServerAutoShutdown.Weekday", -1); uint32 day = sConfigMgr->GetOption("ServerAutoShutdown.EveryDays", 1); uint8 hour = *Acore::StringTo(tokens.at(0)); uint8 minute = *Acore::StringTo(tokens.at(1)); uint8 second = *Acore::StringTo(tokens.at(2)); + auto nowTime = time(nullptr); + uint64 nextResetTime = 0; + + if (weekday >= 0 && weekday <= 6) + { + nextResetTime = GetNextWeekdayTime(nowTime, weekday, hour, minute, second); + } + else + { + if (day < 1 || day > 365) + { + LOG_ERROR("module", "> ServerAutoShutdown: Incorrect day in config option 'ServerAutoShutdown.EveryDays' - '{}'", day); + _isEnableModule = false; + return; + } + nextResetTime = GetNextResetTime(nowTime, day, hour, minute, second); + } + if (day < 1 || day > 365) { LOG_ERROR("module", "> ServerAutoShutdown: Incorrect day in config option 'ServerAutoShutdown.EveryDays' - '{}'", day); @@ -117,15 +160,15 @@ void ServerAutoShutdown::Init() _isEnableModule = false; } - auto nowTime = time(nullptr); - //Seconds nowTime = GameTime::GetGameTime(); - uint64 nextResetTime = GetNextResetTime(nowTime, day, hour, minute, second); uint32 diffToShutdown = nextResetTime - static_cast(nowTime); if (diffToShutdown < 10) { - LOG_WARN("module", "> ServerAutoShutdown: Next time to shutdown < 10 seconds, Set next day"); - nextResetTime += 86400 * day; + LOG_WARN("module", "> ServerAutoShutdown: Next time to shutdown < 10 seconds, Set next period"); + if (weekday >= 0 && weekday <= 6) + nextResetTime += 7 * 86400; + else + nextResetTime += 86400 * day; diffToShutdown = nextResetTime - static_cast(nowTime); } From f9baabc1e5e0b5f9d397be15a0943af70baf9b64 Mon Sep 17 00:00:00 2001 From: Icemansparks Date: Sun, 1 Jun 2025 14:32:27 +0200 Subject: [PATCH 2/3] set default value to disabled (-1) disable fixed day restarts as default. --- conf/ServerAutoShutdown.conf.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/ServerAutoShutdown.conf.dist b/conf/ServerAutoShutdown.conf.dist index a55976c..33dd179 100644 --- a/conf/ServerAutoShutdown.conf.dist +++ b/conf/ServerAutoShutdown.conf.dist @@ -30,7 +30,7 @@ ServerAutoShutdown.EveryDays = 1 # Default: -1 (disabled) # -ServerAutoShutdown.Weekday = 3 +ServerAutoShutdown.Weekday = -1 # # ServerAutoShutdown.Time From d8b1bf57b4da96f57cb3cfa0fdfaeeaf832807d6 Mon Sep 17 00:00:00 2001 From: Tecc Date: Tue, 24 Jun 2025 15:16:55 +0200 Subject: [PATCH 3/3] refactor ServerAutoShutdown timing functions for clarity and consistency and use of common.h --- src/ServerAutoShutdown.cpp | 63 +++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/src/ServerAutoShutdown.cpp b/src/ServerAutoShutdown.cpp index 6759eec..456b343 100644 --- a/src/ServerAutoShutdown.cpp +++ b/src/ServerAutoShutdown.cpp @@ -15,6 +15,7 @@ * with this program. If not, see . */ +#include "Common.h" #include "Config.h" #include "Duration.h" #include "GameEventMgr.h" @@ -35,23 +36,23 @@ namespace // Scheduler - for update TaskScheduler scheduler; - time_t GetNextResetTime(time_t time, uint32 day, uint8 hour, uint8 minute, uint8 second) + time_t GetNextResetTime(time_t time, uint32 restartDays, uint8 restartHour, uint8 restartMinute, uint8 restartSecond) { tm timeLocal = Acore::Time::TimeBreakdown(time); - timeLocal.tm_hour = hour; - timeLocal.tm_min = minute; - timeLocal.tm_sec = second; + timeLocal.tm_hour = restartHour; + timeLocal.tm_min = restartMinute; + timeLocal.tm_sec = restartSecond; time_t midnightLocal = mktime(&timeLocal); - if (day > 1 || midnightLocal <= time) - midnightLocal += 86400 * day; + if (restartDays > 1 || midnightLocal <= time) + midnightLocal += DAY * restartDays; return midnightLocal; } // Returns the next time_t for the given weekday (0=Sunday, 1=Monday, ..., 6=Saturday) at the given hour/min/sec - time_t GetNextWeekdayTime(time_t now, int weekday, uint8 hour, uint8 minute, uint8 second) + time_t GetNextWeekdayTime(time_t now, int weekday, uint8 restartHour, uint8 restartMinute, uint8 restartSecond) { tm timeLocal = Acore::Time::TimeBreakdown(now); int currentWeekday = timeLocal.tm_wday; @@ -59,17 +60,17 @@ namespace if (daysUntil == 0) { // If today, check if the time has already passed - if (timeLocal.tm_hour > hour || - (timeLocal.tm_hour == hour && timeLocal.tm_min > minute) || - (timeLocal.tm_hour == hour && timeLocal.tm_min == minute && timeLocal.tm_sec >= second)) + if (timeLocal.tm_hour > restartHour || + (timeLocal.tm_hour == restartHour && timeLocal.tm_min > restartMinute) || + (timeLocal.tm_hour == restartHour && timeLocal.tm_min == restartMinute && timeLocal.tm_sec >= restartSecond)) { daysUntil = 7; } } timeLocal.tm_mday += daysUntil; - timeLocal.tm_hour = hour; - timeLocal.tm_min = minute; - timeLocal.tm_sec = second; + timeLocal.tm_hour = restartHour; + timeLocal.tm_min = restartMinute; + timeLocal.tm_sec = restartSecond; time_t result = mktime(&timeLocal); return result; } @@ -116,45 +117,45 @@ void ServerAutoShutdown::Init() } int weekday = sConfigMgr->GetOption("ServerAutoShutdown.Weekday", -1); - uint32 day = sConfigMgr->GetOption("ServerAutoShutdown.EveryDays", 1); - uint8 hour = *Acore::StringTo(tokens.at(0)); - uint8 minute = *Acore::StringTo(tokens.at(1)); - uint8 second = *Acore::StringTo(tokens.at(2)); + uint32 restartDays = sConfigMgr->GetOption("ServerAutoShutdown.EveryDays", 1); + uint8 restartHour = *Acore::StringTo(tokens.at(0)); + uint8 restartMinute = *Acore::StringTo(tokens.at(1)); + uint8 restartSecond = *Acore::StringTo(tokens.at(2)); auto nowTime = time(nullptr); uint64 nextResetTime = 0; if (weekday >= 0 && weekday <= 6) { - nextResetTime = GetNextWeekdayTime(nowTime, weekday, hour, minute, second); + nextResetTime = GetNextWeekdayTime(nowTime, weekday, restartHour, restartMinute, restartSecond); } else { - if (day < 1 || day > 365) + if (restartDays < 1 || restartDays > 365) { - LOG_ERROR("module", "> ServerAutoShutdown: Incorrect day in config option 'ServerAutoShutdown.EveryDays' - '{}'", day); + LOG_ERROR("module", "> ServerAutoShutdown: Incorrect day in config option 'ServerAutoShutdown.EveryDays' - '{}'", restartDays); _isEnableModule = false; return; } - nextResetTime = GetNextResetTime(nowTime, day, hour, minute, second); + nextResetTime = GetNextResetTime(nowTime, restartDays, restartHour, restartMinute, restartSecond); } - if (day < 1 || day > 365) + if (restartDays < 1 || restartDays > 365) { - LOG_ERROR("module", "> ServerAutoShutdown: Incorrect day in config option 'ServerAutoShutdown.EveryDays' - '{}'", day); + LOG_ERROR("module", "> ServerAutoShutdown: Incorrect day in config option 'ServerAutoShutdown.EveryDays' - '{}'", restartDays); _isEnableModule = false; } - else if (hour > 23) + else if (restartHour > 23) { LOG_ERROR("module", "> ServerAutoShutdown: Incorrect hour in config option 'ServerAutoShutdown.Time' - '{}'", configTime); _isEnableModule = false; } - else if (minute >= 60) + else if (restartMinute >= 60) { LOG_ERROR("module", "> ServerAutoShutdown: Incorrect minute in config option 'ServerAutoShutdown.Time' - '{}'", configTime); _isEnableModule = false; } - else if (second >= 60) + else if (restartSecond >= 60) { LOG_ERROR("module", "> ServerAutoShutdown: Incorrect second in config option 'ServerAutoShutdown.Time' - '{}'", configTime); _isEnableModule = false; @@ -166,9 +167,9 @@ void ServerAutoShutdown::Init() { LOG_WARN("module", "> ServerAutoShutdown: Next time to shutdown < 10 seconds, Set next period"); if (weekday >= 0 && weekday <= 6) - nextResetTime += 7 * 86400; + nextResetTime += WEEK; else - nextResetTime += 86400 * day; + nextResetTime += DAY * restartDays; diffToShutdown = nextResetTime - static_cast(nowTime); } @@ -183,11 +184,11 @@ void ServerAutoShutdown::Init() LOG_INFO("module", "> ServerAutoShutdown: Remaining time to shutdown - {}", Acore::Time::ToTimeString(diffToShutdown)); LOG_INFO("module", " "); - uint32 preAnnounceSeconds = sConfigMgr->GetOption("ServerAutoShutdown.PreAnnounce.Seconds", 3600); - if (preAnnounceSeconds > 86400) + uint32 preAnnounceSeconds = sConfigMgr->GetOption("ServerAutoShutdown.PreAnnounce.Seconds", HOUR); + if (preAnnounceSeconds > DAY) { LOG_ERROR("module", "> ServerAutoShutdown: Ahah, how could this happen? Time to preannouce has been set to more than 1 day? ({}). Change to 1 hour (3600)", preAnnounceSeconds); - preAnnounceSeconds = 3600; + preAnnounceSeconds = HOUR; } uint32 timeToPreAnnounce = static_cast(nextResetTime) - preAnnounceSeconds;