diff --git a/conf/ServerAutoShutdown.conf.dist b/conf/ServerAutoShutdown.conf.dist
index 78da4da..33dd179 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 = -1
+
#
# ServerAutoShutdown.Time
# Description: Time (in HH:MM:SS) - 24 hours format
diff --git a/src/ServerAutoShutdown.cpp b/src/ServerAutoShutdown.cpp
index da548a2..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,20 +36,44 @@ 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 restartHour, uint8 restartMinute, uint8 restartSecond)
+ {
+ 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 > 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 = restartHour;
+ timeLocal.tm_min = restartMinute;
+ timeLocal.tm_sec = restartSecond;
+ time_t result = mktime(&timeLocal);
+ return result;
+ }
}
/*static*/ ServerAutoShutdown* ServerAutoShutdown::instance()
@@ -91,41 +116,60 @@ void ServerAutoShutdown::Init()
return;
}
- 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));
+ int weekday = sConfigMgr->GetOption("ServerAutoShutdown.Weekday", -1);
+ 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));
- if (day < 1 || day > 365)
+ auto nowTime = time(nullptr);
+ uint64 nextResetTime = 0;
+
+ if (weekday >= 0 && weekday <= 6)
{
- LOG_ERROR("module", "> ServerAutoShutdown: Incorrect day in config option 'ServerAutoShutdown.EveryDays' - '{}'", day);
+ nextResetTime = GetNextWeekdayTime(nowTime, weekday, restartHour, restartMinute, restartSecond);
+ }
+ else
+ {
+ if (restartDays < 1 || restartDays > 365)
+ {
+ LOG_ERROR("module", "> ServerAutoShutdown: Incorrect day in config option 'ServerAutoShutdown.EveryDays' - '{}'", restartDays);
+ _isEnableModule = false;
+ return;
+ }
+ nextResetTime = GetNextResetTime(nowTime, restartDays, restartHour, restartMinute, restartSecond);
+ }
+
+ if (restartDays < 1 || restartDays > 365)
+ {
+ 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;
}
- 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 += WEEK;
+ else
+ nextResetTime += DAY * restartDays;
diffToShutdown = nextResetTime - static_cast(nowTime);
}
@@ -140,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;