From 8f590fdf0094e80d04300a8ad8383e07c0d42daf Mon Sep 17 00:00:00 2001 From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com> Date: Tue, 18 Aug 2020 11:12:29 +0000 Subject: [PATCH] Addition of gameserver restart schedule configurations. --- .../dist/game/config/main/Server.ini | 28 +++- .../java/org/l2jmobius/Config.java | 18 +++ .../org/l2jmobius/gameserver/GameServer.java | 6 + .../instancemanager/ServerRestartManager.java | 150 ++++++++++++++++++ .../network/clientpackets/EnterWorld.java | 6 + .../dist/game/config/main/Server.ini | 28 +++- .../java/org/l2jmobius/Config.java | 18 +++ .../org/l2jmobius/gameserver/GameServer.java | 6 + .../instancemanager/ServerRestartManager.java | 150 ++++++++++++++++++ .../network/clientpackets/EnterWorld.java | 6 + 10 files changed, 414 insertions(+), 2 deletions(-) create mode 100644 L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/instancemanager/ServerRestartManager.java create mode 100644 L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/instancemanager/ServerRestartManager.java diff --git a/L2J_Mobius_C4_ScionsOfDestiny/dist/game/config/main/Server.ini b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/config/main/Server.ini index 5be43b3ad2..0acc4f745b 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/dist/game/config/main/Server.ini +++ b/L2J_Mobius_C4_ScionsOfDestiny/dist/game/config/main/Server.ini @@ -61,7 +61,6 @@ MaximumDbConnections = 100 # --------------------------------------------------------------------------- # Automatic Database Backup Settings # --------------------------------------------------------------------------- - # Generate database backups when server restarts or shuts down. BackupDatabase = False @@ -157,3 +156,30 @@ ClanNameTemplate = .* # This setting restricts ally names players can set. # See CnameTemplate for details AllyNameTemplate = .* + + +# --------------------------------------------------------------------------- +# Scheduled Server Restart +# --------------------------------------------------------------------------- + +# Enable scheduled server restart. +# Default: False +ServerRestartScheduleEnabled = False + +# Send a message when player enters the game. +# Default: False +ServerRestartScheduleMessage = False + +# Restart time countdown (in seconds). +# Default: 600 (10 minutes) +ServerRestartScheduleCountdown = 600 + +# Scheduled restart schedule. +# You can put more than one value separated by commas (,). +# Example: 12:00, 00:00 +ServerRestartSchedule = 08:00 + +# Specify days that the restart will occur. Values separated by commas (,). +# Example: 1,2,3,4,5,6,7 (SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY) +# Default: 4 (WEDNESDAY) +ServerRestartDays = 4 diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/Config.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/Config.java index bad87eb073..3e42d58640 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/Config.java @@ -41,6 +41,7 @@ import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.commons.util.StringUtil; import org.l2jmobius.gameserver.model.entity.olympiad.OlympiadPeriod; import org.l2jmobius.gameserver.util.FloodProtectorConfig; +import org.l2jmobius.gameserver.util.Util; import org.l2jmobius.loginserver.LoginController; public class Config @@ -1100,6 +1101,11 @@ public class Config public static String PET_NAME_TEMPLATE; public static String CLAN_NAME_TEMPLATE; public static String ALLY_NAME_TEMPLATE; + public static boolean SERVER_RESTART_SCHEDULE_ENABLED; + public static boolean SERVER_RESTART_SCHEDULE_MESSAGE; + public static int SERVER_RESTART_SCHEDULE_COUNTDOWN; + public static String[] SERVER_RESTART_SCHEDULE; + public static List SERVER_RESTART_DAYS; public static int IP_UPDATE_TIME; public static boolean SHOW_LICENCE; @@ -1189,6 +1195,18 @@ public class Config PET_NAME_TEMPLATE = serverConfig.getString("PetNameTemplate", ".*"); CLAN_NAME_TEMPLATE = serverConfig.getString("ClanNameTemplate", ".*"); ALLY_NAME_TEMPLATE = serverConfig.getString("AllyNameTemplate", ".*"); + SERVER_RESTART_SCHEDULE_ENABLED = serverConfig.getBoolean("ServerRestartScheduleEnabled", false); + SERVER_RESTART_SCHEDULE_MESSAGE = serverConfig.getBoolean("ServerRestartScheduleMessage", false); + SERVER_RESTART_SCHEDULE_COUNTDOWN = serverConfig.getInt("ServerRestartScheduleCountdown", 600); + SERVER_RESTART_SCHEDULE = serverConfig.getString("ServerRestartSchedule", "08:00").split(","); + SERVER_RESTART_DAYS = new ArrayList<>(); + for (String day : serverConfig.getString("ServerRestartDays", "").trim().split(",")) + { + if (Util.isDigit(day)) + { + SERVER_RESTART_DAYS.add(Integer.parseInt(day)); + } + } } public static void loadTelnetConfig() diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/GameServer.java index a6e7f19824..357db12c44 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/GameServer.java @@ -101,6 +101,7 @@ import org.l2jmobius.gameserver.instancemanager.PetitionManager; import org.l2jmobius.gameserver.instancemanager.QuestManager; import org.l2jmobius.gameserver.instancemanager.RaidBossPointsManager; import org.l2jmobius.gameserver.instancemanager.RaidBossSpawnManager; +import org.l2jmobius.gameserver.instancemanager.ServerRestartManager; import org.l2jmobius.gameserver.instancemanager.SiegeManager; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.entity.Announcements; @@ -459,6 +460,11 @@ public class GameServer LOGGER.info("L2Walker protection actived."); } + if (Config.SERVER_RESTART_SCHEDULE_ENABLED) + { + ServerRestartManager.getInstance(); + } + System.gc(); Util.printSection("Info"); diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/instancemanager/ServerRestartManager.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/instancemanager/ServerRestartManager.java new file mode 100644 index 0000000000..e96d04ddaa --- /dev/null +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/instancemanager/ServerRestartManager.java @@ -0,0 +1,150 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 3 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 . + */ +package org.l2jmobius.gameserver.instancemanager; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; +import java.util.logging.Logger; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.concurrent.ThreadPool; +import org.l2jmobius.gameserver.Shutdown; + +/** + * @author Gigi, Mobius + */ +public class ServerRestartManager +{ + static final Logger LOGGER = Logger.getLogger(ServerRestartManager.class.getName()); + + private String nextRestartTime = "unknown"; + + protected ServerRestartManager() + { + try + { + final Calendar currentTime = Calendar.getInstance(); + final Calendar restartTime = Calendar.getInstance(); + Calendar lastRestart = null; + long delay = 0; + long lastDelay = 0; + + for (String scheduledTime : Config.SERVER_RESTART_SCHEDULE) + { + final String[] splitTime = scheduledTime.trim().split(":"); + restartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTime[0])); + restartTime.set(Calendar.MINUTE, Integer.parseInt(splitTime[1])); + restartTime.set(Calendar.SECOND, 00); + + if (restartTime.getTimeInMillis() < currentTime.getTimeInMillis()) + { + restartTime.add(Calendar.DAY_OF_WEEK, 1); + } + + if (!Config.SERVER_RESTART_DAYS.isEmpty()) + { + while (!Config.SERVER_RESTART_DAYS.contains(restartTime.get(Calendar.DAY_OF_WEEK))) + { + restartTime.add(Calendar.DAY_OF_WEEK, 1); + } + } + + delay = restartTime.getTimeInMillis() - currentTime.getTimeInMillis(); + if (lastDelay == 0) + { + lastDelay = delay; + lastRestart = restartTime; + } + if (delay < lastDelay) + { + lastDelay = delay; + lastRestart = restartTime; + } + } + + if (lastRestart != null) + { + if (Config.SERVER_RESTART_DAYS.isEmpty() || (Config.SERVER_RESTART_DAYS.size() == 7)) + { + nextRestartTime = new SimpleDateFormat("HH:mm").format(lastRestart.getTime()); + } + else + { + nextRestartTime = new SimpleDateFormat("MMMM d'" + getDayNumberSuffix(lastRestart.get(Calendar.DAY_OF_MONTH)) + "' HH:mm", Locale.UK).format(lastRestart.getTime()); + } + ThreadPool.schedule(new ServerRestartTask(), lastDelay - (Config.SERVER_RESTART_SCHEDULE_COUNTDOWN * 1000)); + LOGGER.info("Scheduled server restart at " + lastRestart.getTime() + "."); + } + } + catch (Exception e) + { + LOGGER.info("The scheduled server restart config is not set properly, please correct it!"); + } + } + + private String getDayNumberSuffix(int day) + { + switch (day) + { + case 1: + case 21: + case 31: + { + return "st"; + } + case 2: + case 22: + { + return "nd"; + } + case 3: + case 23: + { + return "rd"; + } + default: + { + return "th"; + } + } + } + + public String getNextRestartTime() + { + return nextRestartTime; + } + + class ServerRestartTask implements Runnable + { + @Override + public void run() + { + Shutdown.getInstance().startShutdown(null, Config.SERVER_RESTART_SCHEDULE_COUNTDOWN, true); + } + } + + public static ServerRestartManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final ServerRestartManager INSTANCE = new ServerRestartManager(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java index d63996e5fa..3ad79deeef 100644 --- a/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java +++ b/L2J_Mobius_C4_ScionsOfDestiny/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java @@ -39,6 +39,7 @@ import org.l2jmobius.gameserver.instancemanager.CrownManager; import org.l2jmobius.gameserver.instancemanager.DimensionalRiftManager; import org.l2jmobius.gameserver.instancemanager.FortSiegeManager; import org.l2jmobius.gameserver.instancemanager.PetitionManager; +import org.l2jmobius.gameserver.instancemanager.ServerRestartManager; import org.l2jmobius.gameserver.instancemanager.SiegeManager; import org.l2jmobius.gameserver.model.Effect; import org.l2jmobius.gameserver.model.Skill; @@ -267,6 +268,11 @@ public class EnterWorld extends GameClientPacket SevenSigns.getInstance().sendCurrentPeriodMsg(player); Announcements.getInstance().showAnnouncements(player); + if ((Config.SERVER_RESTART_SCHEDULE_ENABLED) && (Config.SERVER_RESTART_SCHEDULE_MESSAGE)) + { + player.sendPacket(new CreatureSay(0, ChatType.WHISPER, "[SERVER]", "Next restart is scheduled at " + ServerRestartManager.getInstance().getNextRestartTime() + ".")); + } + loadTutorial(player); // Check for crowns diff --git a/L2J_Mobius_C6_Interlude/dist/game/config/main/Server.ini b/L2J_Mobius_C6_Interlude/dist/game/config/main/Server.ini index befac7c16d..6d540cfb8b 100644 --- a/L2J_Mobius_C6_Interlude/dist/game/config/main/Server.ini +++ b/L2J_Mobius_C6_Interlude/dist/game/config/main/Server.ini @@ -61,7 +61,6 @@ MaximumDbConnections = 100 # --------------------------------------------------------------------------- # Automatic Database Backup Settings # --------------------------------------------------------------------------- - # Generate database backups when server restarts or shuts down. BackupDatabase = False @@ -157,3 +156,30 @@ ClanNameTemplate = .* # This setting restricts ally names players can set. # See CnameTemplate for details AllyNameTemplate = .* + + +# --------------------------------------------------------------------------- +# Scheduled Server Restart +# --------------------------------------------------------------------------- + +# Enable scheduled server restart. +# Default: False +ServerRestartScheduleEnabled = False + +# Send a message when player enters the game. +# Default: False +ServerRestartScheduleMessage = False + +# Restart time countdown (in seconds). +# Default: 600 (10 minutes) +ServerRestartScheduleCountdown = 600 + +# Scheduled restart schedule. +# You can put more than one value separated by commas (,). +# Example: 12:00, 00:00 +ServerRestartSchedule = 08:00 + +# Specify days that the restart will occur. Values separated by commas (,). +# Example: 1,2,3,4,5,6,7 (SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY) +# Default: 4 (WEDNESDAY) +ServerRestartDays = 4 diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java index 904357542b..5bddc5818b 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java @@ -42,6 +42,7 @@ import org.l2jmobius.commons.util.PropertiesParser; import org.l2jmobius.commons.util.StringUtil; import org.l2jmobius.gameserver.model.entity.olympiad.OlympiadPeriod; import org.l2jmobius.gameserver.util.FloodProtectorConfig; +import org.l2jmobius.gameserver.util.Util; import org.l2jmobius.loginserver.LoginController; public class Config @@ -1135,6 +1136,11 @@ public class Config public static String PET_NAME_TEMPLATE; public static String CLAN_NAME_TEMPLATE; public static String ALLY_NAME_TEMPLATE; + public static boolean SERVER_RESTART_SCHEDULE_ENABLED; + public static boolean SERVER_RESTART_SCHEDULE_MESSAGE; + public static int SERVER_RESTART_SCHEDULE_COUNTDOWN; + public static String[] SERVER_RESTART_SCHEDULE; + public static List SERVER_RESTART_DAYS; public static int IP_UPDATE_TIME; public static boolean SHOW_LICENCE; @@ -1224,6 +1230,18 @@ public class Config PET_NAME_TEMPLATE = serverConfig.getString("PetNameTemplate", ".*"); CLAN_NAME_TEMPLATE = serverConfig.getString("ClanNameTemplate", ".*"); ALLY_NAME_TEMPLATE = serverConfig.getString("AllyNameTemplate", ".*"); + SERVER_RESTART_SCHEDULE_ENABLED = serverConfig.getBoolean("ServerRestartScheduleEnabled", false); + SERVER_RESTART_SCHEDULE_MESSAGE = serverConfig.getBoolean("ServerRestartScheduleMessage", false); + SERVER_RESTART_SCHEDULE_COUNTDOWN = serverConfig.getInt("ServerRestartScheduleCountdown", 600); + SERVER_RESTART_SCHEDULE = serverConfig.getString("ServerRestartSchedule", "08:00").split(","); + SERVER_RESTART_DAYS = new ArrayList<>(); + for (String day : serverConfig.getString("ServerRestartDays", "").trim().split(",")) + { + if (Util.isDigit(day)) + { + SERVER_RESTART_DAYS.add(Integer.parseInt(day)); + } + } } public static void loadTelnetConfig() diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/GameServer.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/GameServer.java index 120665ea2b..7b620245f3 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/GameServer.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/GameServer.java @@ -105,6 +105,7 @@ import org.l2jmobius.gameserver.instancemanager.PetitionManager; import org.l2jmobius.gameserver.instancemanager.QuestManager; import org.l2jmobius.gameserver.instancemanager.RaidBossPointsManager; import org.l2jmobius.gameserver.instancemanager.RaidBossSpawnManager; +import org.l2jmobius.gameserver.instancemanager.ServerRestartManager; import org.l2jmobius.gameserver.instancemanager.SiegeManager; import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.entity.Announcements; @@ -471,6 +472,11 @@ public class GameServer LOGGER.info("L2Walker protection actived."); } + if (Config.SERVER_RESTART_SCHEDULE_ENABLED) + { + ServerRestartManager.getInstance(); + } + System.gc(); Util.printSection("Info"); diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/instancemanager/ServerRestartManager.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/instancemanager/ServerRestartManager.java new file mode 100644 index 0000000000..e96d04ddaa --- /dev/null +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/instancemanager/ServerRestartManager.java @@ -0,0 +1,150 @@ +/* + * This file is part of the L2J Mobius project. + * + * 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 3 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 . + */ +package org.l2jmobius.gameserver.instancemanager; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; +import java.util.logging.Logger; + +import org.l2jmobius.Config; +import org.l2jmobius.commons.concurrent.ThreadPool; +import org.l2jmobius.gameserver.Shutdown; + +/** + * @author Gigi, Mobius + */ +public class ServerRestartManager +{ + static final Logger LOGGER = Logger.getLogger(ServerRestartManager.class.getName()); + + private String nextRestartTime = "unknown"; + + protected ServerRestartManager() + { + try + { + final Calendar currentTime = Calendar.getInstance(); + final Calendar restartTime = Calendar.getInstance(); + Calendar lastRestart = null; + long delay = 0; + long lastDelay = 0; + + for (String scheduledTime : Config.SERVER_RESTART_SCHEDULE) + { + final String[] splitTime = scheduledTime.trim().split(":"); + restartTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splitTime[0])); + restartTime.set(Calendar.MINUTE, Integer.parseInt(splitTime[1])); + restartTime.set(Calendar.SECOND, 00); + + if (restartTime.getTimeInMillis() < currentTime.getTimeInMillis()) + { + restartTime.add(Calendar.DAY_OF_WEEK, 1); + } + + if (!Config.SERVER_RESTART_DAYS.isEmpty()) + { + while (!Config.SERVER_RESTART_DAYS.contains(restartTime.get(Calendar.DAY_OF_WEEK))) + { + restartTime.add(Calendar.DAY_OF_WEEK, 1); + } + } + + delay = restartTime.getTimeInMillis() - currentTime.getTimeInMillis(); + if (lastDelay == 0) + { + lastDelay = delay; + lastRestart = restartTime; + } + if (delay < lastDelay) + { + lastDelay = delay; + lastRestart = restartTime; + } + } + + if (lastRestart != null) + { + if (Config.SERVER_RESTART_DAYS.isEmpty() || (Config.SERVER_RESTART_DAYS.size() == 7)) + { + nextRestartTime = new SimpleDateFormat("HH:mm").format(lastRestart.getTime()); + } + else + { + nextRestartTime = new SimpleDateFormat("MMMM d'" + getDayNumberSuffix(lastRestart.get(Calendar.DAY_OF_MONTH)) + "' HH:mm", Locale.UK).format(lastRestart.getTime()); + } + ThreadPool.schedule(new ServerRestartTask(), lastDelay - (Config.SERVER_RESTART_SCHEDULE_COUNTDOWN * 1000)); + LOGGER.info("Scheduled server restart at " + lastRestart.getTime() + "."); + } + } + catch (Exception e) + { + LOGGER.info("The scheduled server restart config is not set properly, please correct it!"); + } + } + + private String getDayNumberSuffix(int day) + { + switch (day) + { + case 1: + case 21: + case 31: + { + return "st"; + } + case 2: + case 22: + { + return "nd"; + } + case 3: + case 23: + { + return "rd"; + } + default: + { + return "th"; + } + } + } + + public String getNextRestartTime() + { + return nextRestartTime; + } + + class ServerRestartTask implements Runnable + { + @Override + public void run() + { + Shutdown.getInstance().startShutdown(null, Config.SERVER_RESTART_SCHEDULE_COUNTDOWN, true); + } + } + + public static ServerRestartManager getInstance() + { + return SingletonHolder.INSTANCE; + } + + private static class SingletonHolder + { + protected static final ServerRestartManager INSTANCE = new ServerRestartManager(); + } +} \ No newline at end of file diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java index ee2f3d397f..ee85913b3a 100644 --- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java +++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java @@ -39,6 +39,7 @@ import org.l2jmobius.gameserver.instancemanager.CrownManager; import org.l2jmobius.gameserver.instancemanager.DimensionalRiftManager; import org.l2jmobius.gameserver.instancemanager.FortSiegeManager; import org.l2jmobius.gameserver.instancemanager.PetitionManager; +import org.l2jmobius.gameserver.instancemanager.ServerRestartManager; import org.l2jmobius.gameserver.instancemanager.SiegeManager; import org.l2jmobius.gameserver.model.Effect; import org.l2jmobius.gameserver.model.Skill; @@ -291,6 +292,11 @@ public class EnterWorld extends GameClientPacket SevenSigns.getInstance().sendCurrentPeriodMsg(player); Announcements.getInstance().showAnnouncements(player); + if ((Config.SERVER_RESTART_SCHEDULE_ENABLED) && (Config.SERVER_RESTART_SCHEDULE_MESSAGE)) + { + player.sendPacket(new CreatureSay(0, ChatType.WHISPER, "[SERVER]", "Next restart is scheduled at " + ServerRestartManager.getInstance().getNextRestartTime() + ".")); + } + loadTutorial(player); // Check for crowns