public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args) { var lastSubmission = user.GetLocalString("RESTART_SERVER_LAST_SUBMISSION"); var isFirstSubmission = true; // Check for the last submission, if any. if (!string.IsNullOrWhiteSpace(lastSubmission)) { // Found one, parse it. var dateTime = DateTime.Parse(lastSubmission); if (DateTime.UtcNow <= dateTime.AddSeconds(15)) { // Player submitted a second request within 15 seconds of the last one. // This is a confirmation they want to restart. isFirstSubmission = false; } } // Player hasn't submitted or time has elapsed if (isFirstSubmission) { user.SetLocalString("RESTART_SERVER_LAST_SUBMISSION", DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)); user.FloatingText("Please confirm server reset by entering another \"/restartserver <CD Key>\" command within 15 seconds."); } else { foreach (var player in NWModule.Get().Players) { _.BootPC(player, $"A DM has restarted the server. Please reconnect shortly."); } NWNXAdmin.ShutdownServer(); } }
private static void Run() { if (IsDisabled) { return; } using (new Profiler(nameof(ServerRestartProcessor) + "." + nameof(Run))) { var now = DateTime.UtcNow; if (now >= RestartTime) { _.ExportAllCharacters(); foreach (var player in NWModule.Get().Players) { _.BootPC(player, "Server is automatically rebooting. This is a temporary solution until we can fix performance problems. Thank you for your patience and understanding."); } NWNXAdmin.ShutdownServer(); } else if (now >= _nextNotification) { var delta = RestartTime - now; string rebootString = TimeService.GetTimeLongIntervals(delta.Days, delta.Hours, delta.Minutes, delta.Seconds, false); string message = "Server will automatically reboot in " + rebootString; foreach (var player in NWModule.Get().Players) { // Send a message about the next reboot. player.FloatingText(message); // If the player has a lease which is expiring in <= 24 hours, notify them. int leasesExpiring = DataService.Where <PCBase>(x => x.DateRentDue.AddHours(-24) <= now && x.PlayerID == player.GlobalID).Count; if (leasesExpiring > 0) { string leaseDetails = leasesExpiring == 1 ? "1 lease" : leasesExpiring + " leases"; player.FloatingText("You have " + leaseDetails + " expiring in less than 24 hours (real world time). Please extend the lease or your land will be forfeited."); } } Console.WriteLine(message); // We're in the last hour before rebooting. Schedule the next notification 45 minutes from now. if (delta.TotalHours <= 1 && delta.TotalMinutes >= 45) { _nextNotification = DateTime.UtcNow.AddMinutes(45); } // Notify every minute when it comes close to the reboot time. else if (delta.TotalMinutes <= 15) { _nextNotification = DateTime.UtcNow.AddMinutes(1); } // Otherwise notify on the standard timing. else { _nextNotification = DateTime.UtcNow.AddMinutes(NotificationIntervalMinutes); } } } }