private void MonitorServerRunning(CancellationToken token) { while (!token.IsCancellationRequested) { try { Thread.Sleep(30 * 1000); var process = Process.GetProcesses().Where(c => c.ProcessName.Contains("ConanSandboxServer")).FirstOrDefault(); if (process != null) { var startTime = process.StartTime; if (_settings.General.RestartServerAfterHours == 0) { continue; } if (startTime.AddHours(_settings.General.RestartServerAfterHours) <= DateTime.Now) { if (_settings.Update.AnnounceTwitch || _settings.Update.AnnounceDiscord) { var runningTime = DateTime.Now.Subtract(startTime); var announceMessage = $"Conan Server Automatic Restarts are set to run every {_settings.General.RestartServerAfterHours} Hours. The server has been up for {Math.Round(runningTime.TotalHours, 2)} H {runningTime.Minutes} M. The Server will restart in {_settings.Update.AnnounceMinutesBefore} {(_settings.Update.AnnounceMinutesBefore == 1 ? "Minute" : "Minutes")}."; if (_discordClient != null) { _discordClient.SendMessage(announceMessage); } if (_twitchService != null) { _twitchService.SendMessage(announceMessage); } } if (_settings.Update.AnnounceMinutesBefore > 0) { Thread.Sleep(_settings.Update.AnnounceMinutesBefore * 60 * 1000); } bool exited = false; process.Exited += (sender, e) => { exited = true; }; Utils.TerminateServer(); process.WaitForExit(30 * 1000); if (!exited) { process.CloseMainWindow(); } Thread.Sleep(30 * 1000); if (!exited) { process.Kill(); } Thread.Sleep(30 * 1000); Log.Information("Server exceeded maximum specified running time, and a restart request was successfully made."); } } else { Log.Information("Conan Server Not Detected - Launching Now"); var processStartInfo = new ProcessStartInfo { FileName = $"{_settings.Conan.FolderPath}{_settings.Conan.Executable}", Arguments = $"{_settings.Conan.StartupParameters} -log", RedirectStandardOutput = false, UseShellExecute = false }; Process.Start(processStartInfo); if (_settings.Update.AnnounceTwitch || _settings.Update.AnnounceDiscord) { var announceMessage = $"Conan Server was not detected as running. Restarting now. The server should show as being online in 2-3 Minutes."; if (_discordClient != null) { _discordClient.SendMessage(announceMessage); } if (_twitchService != null) { _twitchService.SendMessage(announceMessage); } } } } catch (Exception e) { Log.Error("Error in Application Monitor: {exception}", e.Message); } } }
private bool DetectUpdate() { try { if (_settings.Update.InstalledBuild == 0) { if (string.IsNullOrWhiteSpace(_settings.Conan.FolderPath)) { Log.Error("You must set your Installation Folder path in the config.json file"); return(false); } Log.Information("Current Conan Dedicated Server Build Version not stored in Settings, Trying to get it now from your Application Manifest file"); var installedBuild = File.ReadAllLines(Path.Combine(_settings.Conan.FolderPath, "steamapps", "appmanifest_443030.acf")) ?.FirstOrDefault(c => c.Contains("buildid")) ?.Split(new char[] { '\t', '\t' }) ?.LastOrDefault() ?.Trim() ?.Replace("\"", ""); if (installedBuild == null) { Log.Error("Couldn't get installed Conan Dedicated Server Build Version from your appmanifest_443030.acf file. Please set this manually in config.json"); } else { _settings.Update.InstalledBuild = Convert.ToInt32(installedBuild); Utils.SaveSettings(Program.StartupPath, _settings); Log.Information("Conan Dedicated Server Build Version has been detected and set as {buildversion}", installedBuild); return(false); } } // Clear SteamCMD App Cache so correct Live build is Pulled! // App needs to be admin, or have write permissions on the steamcmd directory. var cache = Path.Combine(_settings.Update.SteamCmdPath, "appcache"); if (Directory.Exists(cache)) { Directory.Delete(cache, true); } var processStartInfo = new ProcessStartInfo { FileName = $"{_settings.Update.SteamCmdPath}steamcmd.exe", Arguments = "+login anonymous +app_info_update 1 +app_info_print 443030 +app_info_print 443030 +quit", RedirectStandardOutput = true, UseShellExecute = false }; var process = Process.Start(processStartInfo); var output = process.StandardOutput.ReadToEnd().Split(new char[] { '\r', '\n' }); process.WaitForExit(); var steamVersionString = output.FirstOrDefault(c => c.Contains("buildid")); if (steamVersionString == null) { Log.Error("Steam Version was Not Detected"); return(false); } var steamVersion = Convert.ToInt32(steamVersionString.Split(new char[] { '\t', '\t' }) ?.LastOrDefault() ?.Trim() ?.Replace("\"", "")); if (steamVersion <= _settings.Update.InstalledBuild) { Log.Information("Installed Version is the same or greater than the steam version. No Update Needed!"); return(false); } Log.Information("Detected SteamVersion as: {steamversion}. Your version is: {localVersion} An Update is required.", steamVersion, _settings.Update.InstalledBuild.ToString()); if (_settings.Update.AnnounceTwitch) { if (_twitchClient != null) { _twitchClient.SendMessage(_messages.Twitch.TwitchUpdateMessage.Replace("@version", $"{steamVersion}").Replace("@announcebefore", $"{_settings.Update.AnnounceMinutesBefore}{(_settings.Update.AnnounceMinutesBefore == 1 ? "Minute" : "Minutes")}")); } } if (_settings.Update.AnnounceDiscord) { if (_discordClient != null) { _discordClient.SendMessage(_messages.Discord.DiscordUpdateMessage.Replace("@version", $"{steamVersion}").Replace("@announcebefore", $"{_settings.Update.AnnounceMinutesBefore}{(_settings.Update.AnnounceMinutesBefore == 1 ? "Minute" : "Minutes")}")); } } _settings.Update.InstalledBuild = Convert.ToInt32(steamVersion); Utils.SaveSettings(Program.StartupPath, _settings); return(true); } catch (Exception e) { Log.Error("Exception occured in Detecting Update: {exception}", e.Message); return(false); } }
private void MonitorServerRunning(CancellationToken token) { var _nextAnnounce = DateTime.Now.AddMinutes(_messages.AnnounceIntervalInMinutes); while (!token.IsCancellationRequested) { try { Thread.Sleep(30 * 1000); var process = Process.GetProcesses().Where(c => c.ProcessName.Contains("ConanSandboxServer")).FirstOrDefault(); if (process != null) { var startTime = process.StartTime; if (_settings.Update.AnnounceTwitch || _settings.Update.AnnounceDiscord || _settings.Update.AnnounceRCON) { if (_messages.AnnounceIntervalInMinutes != 0) { if (_nextAnnounce <= DateTime.Now) { if (_discordClient != null) { _discordClient.SendMessage(_messages.Discord.DiscordServerUptimeMessage.Replace("@countdownminutes", $"{_settings.Update.AnnounceMinutesBefore} {(_settings.Update.AnnounceMinutesBefore == 1 ? "Minute" : "Minutes")}").Replace("@uptime", $"{Math.Round(DateTime.Now.Subtract(process.StartTime).TotalHours, 2)} H {DateTime.Now.Subtract(process.StartTime).Minutes} M.").Replace("@restartinterval", $"{_messages.AnnounceIntervalInMinutes} {(_messages.AnnounceIntervalInMinutes == 1 ? "Minute" : "Minutes")}")); } if (_twitchService != null) { _twitchService.SendMessage(_messages.Twitch.TwitchServerUptimeMessage.Replace("@countdownminutes", $"{_settings.Update.AnnounceMinutesBefore} {(_settings.Update.AnnounceMinutesBefore == 1 ? "Minute" : "Minutes")}").Replace("@uptime", $"{Math.Round(DateTime.Now.Subtract(process.StartTime).TotalHours, 2)} H {DateTime.Now.Subtract(process.StartTime).Minutes} M.").Replace("@restartinterval", $"{_messages.AnnounceIntervalInMinutes} {(_messages.AnnounceIntervalInMinutes == 1 ? "Minute" : "Minutes")}")); } if (_rconClient != null) { _rconClient.SendMessage(_messages.RCON.RCONServerUptimeMessage.Replace("@countdownminutes", $"{_settings.Update.AnnounceMinutesBefore} {(_settings.Update.AnnounceMinutesBefore == 1 ? "Minute" : "Minutes")}").Replace("@uptime", $"{Math.Round(DateTime.Now.Subtract(process.StartTime).TotalHours, 2)} H {DateTime.Now.Subtract(process.StartTime).Minutes} M.").Replace("@restartinterval", $"{_messages.AnnounceIntervalInMinutes} {(_messages.AnnounceIntervalInMinutes == 1 ? "Minute" : "Minutes")}")); } _nextAnnounce = DateTime.Now.AddMinutes(_messages.AnnounceIntervalInMinutes); } } } if (_settings.General.RestartServerAfterHours == 0) { continue; } if (startTime.AddHours(_settings.General.RestartServerAfterHours) <= DateTime.Now) { if (_settings.Update.AnnounceTwitch || _settings.Update.AnnounceDiscord || _settings.Update.AnnounceRCON) { if (_discordClient != null) { _discordClient.SendMessage(_messages.Discord.DiscordServerRestartingMessage.Replace("@countdownminutes", $"{_settings.Update.AnnounceMinutesBefore} {(_settings.Update.AnnounceMinutesBefore == 1 ? "Minute" : "Minutes")}")); } if (_twitchService != null) { _twitchService.SendMessage(_messages.Twitch.TwitchServerRestartingMessage.Replace("@countdownminutes", $"{_settings.Update.AnnounceMinutesBefore} {(_settings.Update.AnnounceMinutesBefore == 1 ? "Minute" : "Minutes")}")); } if (_rconClient != null) { _rconClient.SendMessage(_messages.RCON.RCONServerRestartingMessage.Replace("@countdownminutes", $"{_settings.Update.AnnounceMinutesBefore} {(_settings.Update.AnnounceMinutesBefore == 1 ? "Minute" : "Minutes")}")); } } if (_settings.Update.AnnounceMinutesBefore > 0) { Thread.Sleep(_settings.Update.AnnounceMinutesBefore * 60 * 1000); } // Until we have RCON - Use AutoHotKey.Interop to send ^C to the server for a clean shutdown. Utils.TerminateServer(); Thread.Sleep(30 * 1000); process = Process.GetProcesses().Where(c => c.ProcessName.Contains("ConanSandboxServer")).FirstOrDefault(); if (process != null) { process.Kill(); } // Wait 30 seconds for a clean shutdown Thread.Sleep(30 * 1000); Log.Information("Server exceeded maximum specified running time, and a restart request was successfully made."); } } else { Log.Information("Conan Server Not Detected - Launching Now"); var processStartInfo = new ProcessStartInfo { FileName = $"{_settings.Conan.FolderPath}{_settings.Conan.Executable}", Arguments = $"{_settings.Conan.StartupParameters} -log", RedirectStandardOutput = false, UseShellExecute = false }; var conanProcess = Process.Start(processStartInfo); if (_settings.Update.AnnounceTwitch || _settings.Update.AnnounceDiscord) { var announceMessage = $"Conan Server was not detected as running. Restarting now. The server should show as being online in 2-3 Minutes."; if (_discordClient != null) { _discordClient.SendMessage(announceMessage); } if (_twitchService != null) { _twitchService.SendMessage(announceMessage); } } try { //Higher priority Thread.Sleep(5000); Process.GetProcesses().Where(c => c.ProcessName.Contains("ConanSandboxServer")).ToList().ForEach(p => p.PriorityClass = ProcessPriorityClass.High); } catch (Exception e) { Log.Error(e, "Failed to higher priority of ConanSandboxServer"); } } } catch (Exception e) { Log.Error("Error in Application Monitor: {exception}", e.Message); } } }