From 1d6907a471cd8ac3261871e005d3ff2f65175b7c Mon Sep 17 00:00:00 2001 From: Brett Hewitson Date: Thu, 19 May 2022 23:52:47 +1000 Subject: [PATCH] Server Monitor Changes - added sequential checkbox and slider (not implemented up yet) - added separate mod only update option. - added a cancel process option. - a lot of changes with the process methods - consoladated stop/shutdown and start/restart. - removed the server accessable flag, will now just keep counting down if server unable to be contacted. - added a retry to the RCON command sending - set to 3, with a 10 sec delay. --- src/ARKServerManager/ARKServerManager.csproj | 1 + src/ARKServerManager/App.config | 2 +- src/ARKServerManager/Config.Designer.cs | 2 +- src/ARKServerManager/Config.settings | 2 +- .../Enums/ServerUpdateType.cs | 13 + .../Globalization/en-US/en-US.xaml | 28 +- src/ARKServerManager/Lib/ServerApp.cs | 262 +++++++------ .../Utils/DiscordBotHelper.cs | 168 ++------- .../Windows/ServerMonitorWindow.xaml | 78 ++-- .../Windows/ServerMonitorWindow.xaml.cs | 353 +++++++++++------- .../Windows/ShutdownWindow.xaml.cs | 4 +- src/ConanServerManager/App.config | 2 +- .../ConanServerManager.csproj | 1 + src/ConanServerManager/Config.Designer.cs | 2 +- src/ConanServerManager/Config.settings | 2 +- .../Enums/ServerUpdateType.cs | 13 + .../Globalization/en-US/en-US.xaml | 28 +- src/ConanServerManager/Lib/ServerApp.cs | 251 +++++++------ .../Utils/DiscordBotHelper.cs | 167 ++------- .../Windows/ServerMonitorWindow.xaml | 78 ++-- .../Windows/ServerMonitorWindow.xaml.cs | 353 +++++++++++------- .../Windows/ShutdownWindow.xaml.cs | 4 +- 22 files changed, 966 insertions(+), 848 deletions(-) create mode 100644 src/ARKServerManager/Enums/ServerUpdateType.cs create mode 100644 src/ConanServerManager/Enums/ServerUpdateType.cs diff --git a/src/ARKServerManager/ARKServerManager.csproj b/src/ARKServerManager/ARKServerManager.csproj index b505318f..4ab59e11 100644 --- a/src/ARKServerManager/ARKServerManager.csproj +++ b/src/ARKServerManager/ARKServerManager.csproj @@ -224,6 +224,7 @@ + diff --git a/src/ARKServerManager/App.config b/src/ARKServerManager/App.config index 0780b246..035ccb30 100644 --- a/src/ARKServerManager/App.config +++ b/src/ARKServerManager/App.config @@ -327,7 +327,7 @@ http://arkservermanager.freeforums.net/board/25/game-data - 15000 + 5000 120000 diff --git a/src/ARKServerManager/Config.Designer.cs b/src/ARKServerManager/Config.Designer.cs index 76004616..ed890a30 100644 --- a/src/ARKServerManager/Config.Designer.cs +++ b/src/ARKServerManager/Config.Designer.cs @@ -2404,7 +2404,7 @@ namespace ServerManagerTool { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("15000")] + [global::System.Configuration.DefaultSettingValueAttribute("5000")] public int ServerStatusWatcher_LocalStatusQueryDelay { get { return ((int)(this["ServerStatusWatcher_LocalStatusQueryDelay"])); diff --git a/src/ARKServerManager/Config.settings b/src/ARKServerManager/Config.settings index 52077e44..eb8c5cbd 100644 --- a/src/ARKServerManager/Config.settings +++ b/src/ARKServerManager/Config.settings @@ -672,7 +672,7 @@ 0 - 15000 + 5000 120000 diff --git a/src/ARKServerManager/Enums/ServerUpdateType.cs b/src/ARKServerManager/Enums/ServerUpdateType.cs new file mode 100644 index 00000000..81004b37 --- /dev/null +++ b/src/ARKServerManager/Enums/ServerUpdateType.cs @@ -0,0 +1,13 @@ +using System; + +namespace ServerManagerTool.Enums +{ + [Flags] + public enum ServerUpdateType + { + None = 0, + Server = 1, + Mods = 2, + ServerAndMods = Server | Mods, + } +} diff --git a/src/ARKServerManager/Globalization/en-US/en-US.xaml b/src/ARKServerManager/Globalization/en-US/en-US.xaml index 597c4289..5ba3090f 100644 --- a/src/ARKServerManager/Globalization/en-US/en-US.xaml +++ b/src/ARKServerManager/Globalization/en-US/en-US.xaml @@ -440,8 +440,9 @@ Server Monitor - Selected Total Servers: + Selected + Profile Server Map Mods @@ -450,16 +451,21 @@ Status Create a desktop shortcut to open this form directly. - Start the selected servers. - Shutdown Selected Servers - Shutdown the selected servers. - Stop Selected Servers - Stop the selected servers. - Restart the selected servers. - Update the selected servers. - Backup the selected servers. Select all servers. Unselect all servers. + Start the selected servers. + Shutdown Selected Servers + Stop Selected Servers + Restart the selected servers. + Update/Verify Selected Servers + Update Mods Only on Selected Servers + Backup the selected servers. + Cancel processing the selected servers. + Process Servers Sequentially + If enabled, servers will be processed one after the other; otherwise they will all be processed at the same time. + Sequential Process Delay + The number of seconds to wait before the next server will be processed. + Open the Player List window. Open the RCON window. Start the server. @@ -467,6 +473,9 @@ Install the server. Update/Verify the server. + The process was cancelled by the user. You will need to the status of your servers. + A process cancellation request has been sent. + Server Update Error Another server is being upgraded, wait until the upgrade has finished and try again. Confirm Window Close @@ -5711,6 +5720,7 @@ A start request for server '{0}' has been sent. A stop request for server '{0}' has been sent. An update request for server '{0}' has been sent. + The request for server '{0}' has completed. Count: Map: diff --git a/src/ARKServerManager/Lib/ServerApp.cs b/src/ARKServerManager/Lib/ServerApp.cs index db318e9e..940eabfb 100644 --- a/src/ARKServerManager/Lib/ServerApp.cs +++ b/src/ARKServerManager/Lib/ServerApp.cs @@ -36,9 +36,14 @@ namespace ServerManagerTool.Lib public const int MUTEX_TIMEOUT = 5; // 5 minutes public const int MUTEX_ATTEMPTDELAY = 5000; // 5 seconds - private const int STEAM_MAXRETRIES = 10; - private const int RCON_MAXRETRIES = 3; - private const int FILECOPY_MAXRETRIES = 3; + private const int MAXRETRIES_FILECOPY = 3; + private const int MAXRETRIES_RCON = 3; + private const int MAXRETRIES_STEAM = 10; + + private const int DELAY_RCONCONNECTION = 1000; // 1 seconds + private const int DELAY_RCONRETRY = 10000; // 10 seconds + + private const int DIRECTORIES_PER_LINE = 200; public const int EXITCODE_NORMALEXIT = 0; private const int EXITCODE_EXITWITHERRORS = 98; @@ -82,8 +87,6 @@ namespace ServerManagerTool.Lib public const string LOGPREFIX_AUTOSHUTDOWN = "#AutoShutdownLogs"; public const string LOGPREFIX_AUTOUPDATE = "#AutoUpdateLogs"; - private const int DIRECTORIES_PER_LINE = 200; - private static DateTime _startTime = DateTime.Now; private static Dictionary _profiles = null; @@ -95,22 +98,22 @@ namespace ServerManagerTool.Lib private QueryMaster.Rcon _rconConsole = null; private bool _serverRunning = false; - public bool BackupWorldFile = Config.Default.BackupWorldFile; - public bool CheckForOnlinePlayers = Config.Default.ServerShutdown_CheckForOnlinePlayers; - public bool SendMessages = Config.Default.ServerShutdown_SendShutdownMessages; - public bool DeleteOldBackupFiles = Config.Default.AutoBackup_DeleteOldFiles; - public int ExitCode = EXITCODE_NORMALEXIT; - public bool OutputLogs = false; - public bool PerformWorldSave = Config.Default.ServerShutdown_EnableWorldSave; - public bool SendAlerts = false; - public bool SendEmails = false; - public string ShutdownReason = null; - public string UpdateReason = null; - public ServerProcessType ServerProcess = ServerProcessType.Unknown; - public int ShutdownInterval = Config.Default.ServerShutdown_GracePeriod; - public ProgressDelegate ProgressCallback = null; - public ProcessWindowStyle SteamCMDProcessWindowStyle = ProcessWindowStyle.Minimized; - public ServerStatusChangeDelegate ServerStatusChangeCallback = null; + public bool BackupWorldFile { get; set; } = Config.Default.BackupWorldFile; + public bool CheckForOnlinePlayers { get; set; } = Config.Default.ServerShutdown_CheckForOnlinePlayers; + public bool DeleteOldBackupFiles { get; set; } = Config.Default.AutoBackup_DeleteOldFiles; + public int ExitCode { get; set; } = EXITCODE_NORMALEXIT; + public bool OutputLogs { get; set; } = false; + public bool PerformWorldSave { get; set; } = Config.Default.ServerShutdown_EnableWorldSave; + public ProgressDelegate ProgressCallback { get; set; } = null; + public bool SendAlerts { get; set; } = false; + public bool SendEmails { get; set; } = false; + public bool SendShutdownMessages { get; set; } = Config.Default.ServerShutdown_SendShutdownMessages; + public ServerProcessType ServerProcess { get; set; } = ServerProcessType.Unknown; + public ServerStatusChangeDelegate ServerStatusChangeCallback { get; set; } = null; + public int ShutdownInterval { get; set; } = Config.Default.ServerShutdown_GracePeriod; + public string ShutdownReason { get; set; } = null; + public ProcessWindowStyle SteamCMDProcessWindowStyle { get; set; } = ProcessWindowStyle.Minimized; + public string UpdateReason { get; set; } = null; public ServerApp(bool resetStartTime = false) { @@ -222,7 +225,7 @@ namespace ServerManagerTool.Lib ExitCode = EXITCODE_NORMALEXIT; } - private void ShutdownServer(bool restartServer, bool updateServer, bool steamCmdRemoveQuit, CancellationToken cancellationToken) + private void ShutdownServer(bool restartServer, ServerUpdateType updateType, bool steamCmdRemoveQuit, CancellationToken cancellationToken) { if (_profile == null) { @@ -276,13 +279,13 @@ namespace ServerManagerTool.Lib return; } - if (updateServer) + if (updateType != ServerUpdateType.None) { try { LogProfileMessage(""); ServerStatusChangeCallback?.Invoke(ServerStatus.Updating); - UpgradeLocal(true, true, steamCmdRemoveQuit, cancellationToken); + UpgradeLocal(updateType, true, steamCmdRemoveQuit, cancellationToken); } finally { @@ -423,7 +426,6 @@ namespace ServerManagerTool.Lib QueryMaster.Server gameServer = null; var sent = false; - var serverAccessible = true; try { @@ -482,43 +484,17 @@ namespace ServerManagerTool.Lib } catch (Exception ex) { - serverAccessible = false; - LogProfileError("Error getting online players.", false); LogProfileError(ex.Message, false); LogProfileError("", false); } - if (!serverAccessible) - { - LogProfileMessage("Server not accessible, shutdown timer cancelled."); - break; - } - // check if anyone is logged into the server if (playerCount == 0) { LogProfileMessage("No online players, shutdown timer cancelled."); break; } - - if (playerCount < 0) - { - LogProfileMessage("Unknown online players, shutdown timer cancelled."); - break; - } - } - else - { - try - { - var serverInfo = gameServer?.GetInfo(); - serverAccessible = true; - } - catch - { - serverAccessible = false; - } } var message = string.Empty; @@ -583,7 +559,7 @@ namespace ServerManagerTool.Lib } // check if we need to perform a world save (not required for SotF servers) - if (serverAccessible && PerformWorldSave && !_profile.SotFEnabled) + if (PerformWorldSave && !_profile.SotFEnabled) { try { @@ -676,7 +652,7 @@ namespace ServerManagerTool.Lib // Method 1 - Shutdown Command if (ServerProcess != ServerProcessType.Stop) { - if (serverAccessible && _profile.RCONEnabled && Config.Default.ServerShutdown_UseShutdownCommand) + if (_profile.RCONEnabled && Config.Default.ServerShutdown_UseShutdownCommand) { try { @@ -774,7 +750,7 @@ namespace ServerManagerTool.Lib ExitCode = EXITCODE_SHUTDOWN_TIMEOUT; } - private void UpgradeLocal(bool validate, bool updateMods, bool steamCmdRemoveQuit, CancellationToken cancellationToken) + private void UpgradeLocal(ServerUpdateType updateType, bool validate, bool steamCmdRemoveQuit, CancellationToken cancellationToken) { if (_profile == null) { @@ -799,67 +775,93 @@ namespace ServerManagerTool.Lib var downloadSuccessful = false; var success = false; - // ********************* - // Server Update Section - // ********************* - - LogProfileMessage("\r\n"); - LogProfileMessage("Starting server update."); - LogProfileMessage("Updating server from steam.\r\n"); - - downloadSuccessful = !Config.Default.SteamCmdRedirectOutput; - void serverOutputHandler(object s, DataReceivedEventArgs e) - { - var dataValue = e.Data ?? string.Empty; - LogProfileMessage(dataValue); - if (!gotNewVersion && dataValue.Contains("downloading,")) - { - gotNewVersion = true; - } - if (dataValue.StartsWith("Success!")) - { - downloadSuccessful = true; - } - } - - var steamCmdArgs = SteamUtils.BuildSteamCmdArguments(steamCmdRemoveQuit, Config.Default.SteamCmdInstallServerArgsFormat, Config.Default.SteamCmd_AnonymousUsername, _profile.InstallDirectory, string.Empty, _profile.SotFEnabled ? Config.Default.AppIdServer_SotF : Config.Default.AppIdServer, string.Empty, validate ? "validate" : string.Empty); + var steamCmdArgs = string.Empty; var workingDirectory = Config.Default.DataDir; - if (steamCmdRemoveQuit) - SteamCMDProcessWindowStyle = ProcessWindowStyle.Normal; - - success = ServerUpdater.UpgradeServerAsync(steamCmdFile, steamCmdArgs, workingDirectory, null, null, _profile.InstallDirectory, Config.Default.SteamCmdRedirectOutput ? (DataReceivedEventHandler)serverOutputHandler : null, cancellationToken, SteamCMDProcessWindowStyle).Result; - if (success && downloadSuccessful) + if ((updateType & ServerUpdateType.Server) == ServerUpdateType.Server) { - LogProfileMessage("Finished server update."); - - if (Directory.Exists(_profile.InstallDirectory)) - { - if (!Config.Default.SteamCmdRedirectOutput) - // check if any of the server files have changed. - gotNewVersion = HasNewServerVersion(_profile.InstallDirectory, startTime); - - LogProfileMessage($"New server version - {gotNewVersion.ToString().ToUpperInvariant()}."); - } + // ********************* + // Server Update Section + // ********************* LogProfileMessage("\r\n"); + LogProfileMessage("Starting server update."); + LogProfileMessage("Updating server from steam.\r\n"); + + downloadSuccessful = !Config.Default.SteamCmdRedirectOutput; + void serverOutputHandler(object s, DataReceivedEventArgs e) + { + var dataValue = e.Data ?? string.Empty; + LogProfileMessage(dataValue); + if (!gotNewVersion && dataValue.Contains("downloading,")) + { + gotNewVersion = true; + } + if (dataValue.StartsWith("Success!")) + { + downloadSuccessful = true; + } + } + + // create the branch arguments + var steamCmdInstallServerBetaArgs = new StringBuilder(); + if (!string.IsNullOrWhiteSpace(_profile.BranchName)) + { + steamCmdInstallServerBetaArgs.AppendFormat(Config.Default.SteamCmdInstallServerBetaNameArgsFormat, _profile.BranchName); + if (!string.IsNullOrWhiteSpace(_profile.BranchPassword)) + { + steamCmdInstallServerBetaArgs.Append(" "); + steamCmdInstallServerBetaArgs.AppendFormat(Config.Default.SteamCmdInstallServerBetaPasswordArgsFormat, _profile.BranchPassword); + } + } + + steamCmdArgs = SteamUtils.BuildSteamCmdArguments(steamCmdRemoveQuit, Config.Default.SteamCmdInstallServerArgsFormat, Config.Default.SteamCmd_AnonymousUsername, _profile.InstallDirectory, _profile.SotFEnabled ? Config.Default.AppIdServer_SotF : Config.Default.AppIdServer, steamCmdInstallServerBetaArgs.ToString(), validate ? "validate" : string.Empty); + if (steamCmdRemoveQuit) + { + SteamCMDProcessWindowStyle = ProcessWindowStyle.Normal; + } + + success = ServerUpdater.UpgradeServerAsync(steamCmdFile, steamCmdArgs, workingDirectory, null, null, _profile.InstallDirectory, Config.Default.SteamCmdRedirectOutput ? (DataReceivedEventHandler)serverOutputHandler : null, cancellationToken, SteamCMDProcessWindowStyle).Result; + if (success && downloadSuccessful) + { + LogProfileMessage("Finished server update."); + + if (Directory.Exists(_profile.InstallDirectory)) + { + if (!Config.Default.SteamCmdRedirectOutput) + { + // check if any of the server files have changed. + gotNewVersion = HasNewServerVersion(_profile.InstallDirectory, startTime); + } + + LogProfileMessage($"New server version - {gotNewVersion.ToString().ToUpperInvariant()}."); + } + + LogProfileMessage("\r\n"); + } + else + { + success = false; + LogProfileMessage("****************************"); + LogProfileMessage("ERROR: Failed server update."); + LogProfileMessage("****************************"); + LogProfileMessage("Check steamcmd logs for more information why the server update failed.\r\n"); + + if (Config.Default.SteamCmdRedirectOutput) + { + LogProfileMessage($"If the server update keeps failing try disabling the '{_globalizer.GetResourceString("GlobalSettings_SteamCmdRedirectOutputLabel")}' option in the settings window.\r\n"); + } + + ExitCode = EXITCODE_SERVERUPDATEFAILED; + } } else { - success = false; - LogProfileMessage("****************************"); - LogProfileMessage("ERROR: Failed server update."); - LogProfileMessage("****************************"); - LogProfileMessage("Check steamcmd logs for more information why the server update failed.\r\n"); - - if (Config.Default.SteamCmdRedirectOutput) - LogProfileMessage($"If the server update keeps failing try disabling the '{_globalizer.GetResourceString("GlobalSettings_SteamCmdRedirectOutputLabel")}' option in the settings window.\r\n"); - - ExitCode = EXITCODE_SERVERUPDATEFAILED; + success = true; } // check if we need to update the mods - if (updateMods) + if ((updateType & ServerUpdateType.Mods) == ServerUpdateType.Mods) { if (success) { @@ -870,9 +872,13 @@ namespace ServerManagerTool.Lib // build a list of mods to be processed var modIdList = new List(); if (!string.IsNullOrWhiteSpace(_profile.ServerMapModId)) + { modIdList.Add(_profile.ServerMapModId); + } if (!string.IsNullOrWhiteSpace(_profile.TotalConversionModId)) + { modIdList.Add(_profile.TotalConversionModId); + } modIdList.AddRange(_profile.ServerModIds); modIdList = ModUtils.ValidateModList(modIdList); @@ -908,7 +914,9 @@ namespace ServerManagerTool.Lib modTitle = $"{modId} - {modDetail?.title ?? ""}"; if (modDetail != null) + { LogProfileMessage($"{modDetail.title}.\r\n"); + } var modCachePath = ModUtils.GetModCachePath(modId, _profile.SotFEnabled); var cacheTimeFile = ModUtils.GetLatestModCacheTimeFile(modId, _profile.SotFEnabled); @@ -991,9 +999,13 @@ namespace ServerManagerTool.Lib steamCmdArgs = string.Empty; if (Config.Default.SteamCmd_UseAnonymousCredentials) + { steamCmdArgs = SteamUtils.BuildSteamCmdArguments(steamCmdRemoveQuit, Config.Default.SteamCmdInstallModArgsFormat, Config.Default.SteamCmd_AnonymousUsername, _profile.SotFEnabled ? Config.Default.AppId_SotF : Config.Default.AppId, modId); + } else + { steamCmdArgs = SteamUtils.BuildSteamCmdArguments(steamCmdRemoveQuit, Config.Default.SteamCmdInstallModArgsFormat, Config.Default.SteamCmd_Username, _profile.SotFEnabled ? Config.Default.AppId_SotF : Config.Default.AppId, modId); + } modSuccess = ServerUpdater.UpgradeModsAsync(steamCmdFile, steamCmdArgs, workingDirectory, null, null, Config.Default.SteamCmdRedirectOutput ? modOutputHandler : null, cancellationToken, SteamCMDProcessWindowStyle).Result; if (modSuccess && downloadSuccessful) @@ -1030,17 +1042,24 @@ namespace ServerManagerTool.Lib LogProfileMessage("Check steamcmd logs for more information why the mod update failed.\r\n"); if (Config.Default.SteamCmdRedirectOutput) + { LogProfileMessage($"If the mod update keeps failing try disabling the '{_globalizer.GetResourceString("GlobalSettings_SteamCmdRedirectOutputLabel")}' option in the settings window.\r\n"); + } + copyMod = false; ExitCode = EXITCODE_MODUPDATEFAILED; } } else + { modSuccess = !updateError; + } } else + { modSuccess = !updateError; + } if (copyMod) { @@ -1135,7 +1154,9 @@ namespace ServerManagerTool.Lib LogProfileMessage("********************************************************************\r\n"); if (!Config.Default.ServerUpdate_ForceUpdateModsIfNoSteamInfo) + { LogProfileMessage($"If the mod update keeps failing try enabling the '{_globalizer.GetResourceString("GlobalSettings_ForceUpdateModsIfNoSteamInfoLabel")}' option in the settings window.\r\n"); + } ExitCode = EXITCODE_MODUPDATEFAILED; } @@ -1302,7 +1323,7 @@ namespace ServerManagerTool.Lib { // perform a steamcmd validate to confirm all the files LogProfileMessage("Validating server files (*new*)."); - UpgradeLocal(true, false, false, CancellationToken.None); + UpgradeLocal(ServerUpdateType.Server, true, false, CancellationToken.None); LogProfileMessage("Validated server files (*new*)."); } @@ -1677,7 +1698,7 @@ namespace ServerManagerTool.Lib LogError(logError); // check if we have reached the max failed attempt limit. - if (!Config.Default.AutoUpdate_RetryOnFail || attempt >= STEAM_MAXRETRIES) + if (!Config.Default.AutoUpdate_RetryOnFail || attempt >= MAXRETRIES_STEAM) { // failed max limit reached if (Config.Default.SteamCmdRedirectOutput) @@ -1799,7 +1820,7 @@ namespace ServerManagerTool.Lib LogBranchError(branchName, logError); // check if we have reached the max failed attempt limit. - if (!Config.Default.AutoUpdate_RetryOnFail || attempt >= STEAM_MAXRETRIES) + if (!Config.Default.AutoUpdate_RetryOnFail || attempt >= MAXRETRIES_STEAM) { // failed max limit reached if (Config.Default.SteamCmdRedirectOutput) @@ -2277,7 +2298,7 @@ namespace ServerManagerTool.Lib catch (IOException) { retries++; - if (retries >= FILECOPY_MAXRETRIES) throw; + if (retries >= MAXRETRIES_FILECOPY) throw; Task.Delay(5000).Wait(); } } @@ -2684,8 +2705,7 @@ namespace ServerManagerTool.Lib if (string.IsNullOrWhiteSpace(command)) return false; - var rconRetries = RCON_MAXRETRIES; - var sent = false; + var rconRetries = MAXRETRIES_RCON; try { @@ -2701,23 +2721,23 @@ namespace ServerManagerTool.Lib if (_rconConsole == null) { LogProfileError("RCON connection could not be created.", false); - rconRetries--; } else { try { _rconConsole.SendCommand(command); - sent = true; + return true; } catch (Exception ex) { LogProfileError(ex.Message, false); LogProfileError(ex.StackTrace, false); } - - break; } + + rconRetries--; + Task.Delay(DELAY_RCONRETRY).Wait(); } } finally @@ -2725,7 +2745,7 @@ namespace ServerManagerTool.Lib CloseRconConsole(); } - return sent; + return false; } private bool SendMessage(string message, CancellationToken token) @@ -2735,7 +2755,7 @@ namespace ServerManagerTool.Lib private bool SendMessage(string mode, string message, CancellationToken token) { - if (string.IsNullOrWhiteSpace(message) || !SendMessages) + if (string.IsNullOrWhiteSpace(message) || !SendShutdownMessages) return false; var sent = SendCommand($"{GetRconMessageCommand(mode)} {message}", token); @@ -2801,7 +2821,7 @@ namespace ServerManagerTool.Lib _rconConsole.Dispose(); _rconConsole = null; - Task.Delay(1000).Wait(); + Task.Delay(DELAY_RCONCONNECTION).Wait(); } } @@ -2827,7 +2847,7 @@ namespace ServerManagerTool.Lib LogProfileDebug($"SUCCESS: {nameof(SetupRconConsole)} - ServerQuery was created.", false); - Task.Delay(1000).Wait(); + Task.Delay(DELAY_RCONCONNECTION).Wait(); LogProfileMessage($"Opening RCON connection to server ({_profile.ServerIPAddress}:{_profile.RCONPort}).", false); @@ -2927,7 +2947,7 @@ namespace ServerManagerTool.Lib return ExitCode; } - public int PerformProfileShutdown(ServerProfileSnapshot profile, bool performRestart, bool performUpdate, bool checkGracePeriod, bool steamCmdRemoveQuit, CancellationToken cancellationToken) + public int PerformProfileShutdown(ServerProfileSnapshot profile, bool performRestart, ServerUpdateType updateType, bool checkGracePeriod, bool steamCmdRemoveQuit, CancellationToken cancellationToken) { _profile = profile; @@ -2969,7 +2989,7 @@ namespace ServerManagerTool.Lib { LogProfileMessage("Server lock established.\r\n"); - ShutdownServer(performRestart, performUpdate, steamCmdRemoveQuit, cancellationToken); + ShutdownServer(performRestart, updateType, steamCmdRemoveQuit, cancellationToken); if (ExitCode != EXITCODE_NORMALEXIT) { @@ -3379,7 +3399,7 @@ namespace ServerManagerTool.Lib ServerProcess = type, SteamCMDProcessWindowStyle = ProcessWindowStyle.Hidden }; - exitCode = app.PerformProfileShutdown(profile, performRestart, performUpdate, true, false, CancellationToken.None); + exitCode = app.PerformProfileShutdown(profile, performRestart, performUpdate ? ServerUpdateType.ServerAndMods : ServerUpdateType.None, true, false, CancellationToken.None); if (profile.ServerUpdated) { diff --git a/src/ARKServerManager/Utils/DiscordBotHelper.cs b/src/ARKServerManager/Utils/DiscordBotHelper.cs index 152c5de6..02049ce2 100644 --- a/src/ARKServerManager/Utils/DiscordBotHelper.cs +++ b/src/ARKServerManager/Utils/DiscordBotHelper.cs @@ -54,19 +54,19 @@ namespace ServerManagerTool.Utils return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) }; case CommandType.Restart: if (Config.Default.AllowDiscordRestart) - return RestartServer(channelId, profileIdOrAlias, token); + return StartServer(channelId, profileIdOrAlias, restart: true, token); return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) }; case CommandType.Shutdown: if (Config.Default.AllowDiscordShutdown) - return StopServer(channelId, profileIdOrAlias, true, token); - return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) }; - case CommandType.Stop: - if (Config.Default.AllowDiscordStop) - return StopServer(channelId, profileIdOrAlias, false, token); + return StopServer(channelId, profileIdOrAlias, shutdown: true, token); return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) }; case CommandType.Start: if (Config.Default.AllowDiscordStart) - return StartServer(channelId, profileIdOrAlias, token); + return StartServer(channelId, profileIdOrAlias, restart: false, token); + return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) }; + case CommandType.Stop: + if (Config.Default.AllowDiscordStop) + return StopServer(channelId, profileIdOrAlias, shutdown: false, token); return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) }; case CommandType.Update: if (Config.Default.AllowDiscordUpdate) @@ -339,7 +339,6 @@ namespace ServerManagerTool.Utils { var app = new ServerApp(true) { - DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup, OutputLogs = false, SendAlerts = true, SendEmails = false, @@ -369,11 +368,11 @@ namespace ServerManagerTool.Utils return responseList; } - private static IList RestartServer(string channelId, string profileIdOrAlias, CancellationToken token) + private static IList StartServer(string channelId, string profileIdOrAlias, bool restart, CancellationToken token) { if (string.IsNullOrWhiteSpace(profileIdOrAlias)) { - return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Restart) }; + return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), restart ? CommandType.Restart : CommandType.Start) }; } var profileList = new List(); @@ -406,11 +405,16 @@ namespace ServerManagerTool.Utils { foreach (var server in serverList) { - if (!server.Profile.AllowDiscordRestart) + if (restart && !server.Profile.AllowDiscordRestart) { responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Restart, server.Profile.ProfileName)); continue; } + if (!restart && !server.Profile.AllowDiscordStart) + { + responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Start, server.Profile.ProfileName)); + continue; + } // check if another command is being run against the profile if (_currentProfileCommands.ContainsKey(server.Profile.ProfileID)) @@ -428,12 +432,20 @@ namespace ServerManagerTool.Utils responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ProfileName, server.Runtime.StatusString)); continue; + case ServerStatus.Running: + if (!restart) + { + responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ProfileName, server.Runtime.StatusString)); + continue; + } + break; + case ServerStatus.Updating: responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), server.Profile.ProfileName)); continue; } - _currentProfileCommands.Add(server.Profile.ProfileID, CommandType.Restart); + _currentProfileCommands.Add(server.Profile.ProfileID, restart ? CommandType.Restart : CommandType.Start); var profile = ServerProfileSnapshot.Create(server.Profile); profile.AutoRestartIfShutdown = true; profileList.Add(profile); @@ -445,7 +457,6 @@ namespace ServerManagerTool.Utils { var app = new ServerApp(true) { - DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup, OutputLogs = false, SendAlerts = true, SendEmails = false, @@ -465,11 +476,14 @@ namespace ServerManagerTool.Utils Task.Run(() => { - app.PerformProfileShutdown(profile, true, false, false, false, token); + app.PerformProfileShutdown(profile, true, ServerUpdateType.None, false, false, token); _currentProfileCommands.Remove(profile.ProfileId); }, token); - responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_RestartRequested"), profile.ServerName)); + if (restart) + responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_RestartRequested"), profile.ServerName)); + else + responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_StartRequested"), profile.ServerName)); } return responseList; @@ -479,7 +493,7 @@ namespace ServerManagerTool.Utils { if (string.IsNullOrWhiteSpace(profileIdOrAlias)) { - return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Stop) }; + return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), shutdown ? CommandType.Shutdown : CommandType.Stop) }; } var profileList = new List(); @@ -512,7 +526,12 @@ namespace ServerManagerTool.Utils { foreach (var server in serverList) { - if (!server.Profile.AllowDiscordStop) + if (shutdown && !server.Profile.AllowDiscordShutdown) + { + responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Shutdown, server.Profile.ProfileName)); + continue; + } + if (!shutdown && !server.Profile.AllowDiscordStop) { responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Stop, server.Profile.ProfileName)); continue; @@ -540,7 +559,7 @@ namespace ServerManagerTool.Utils continue; } - _currentProfileCommands.Add(server.Profile.ProfileID, CommandType.Stop); + _currentProfileCommands.Add(server.Profile.ProfileID, shutdown ? CommandType.Shutdown : CommandType.Stop); profileList.Add(ServerProfileSnapshot.Create(server.Profile)); } } @@ -551,7 +570,6 @@ namespace ServerManagerTool.Utils var app = new ServerApp(true) { BackupWorldFile = shutdown, - DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup, OutputLogs = false, PerformWorldSave = shutdown, SendAlerts = true, @@ -575,7 +593,7 @@ namespace ServerManagerTool.Utils Task.Run(() => { - app.PerformProfileShutdown(profile, false, false, false, false, token); + app.PerformProfileShutdown(profile, false, ServerUpdateType.None, false, false, token); _currentProfileCommands.Remove(profile.ProfileId); }, token); @@ -588,113 +606,6 @@ namespace ServerManagerTool.Utils return responseList; } - private static IList StartServer(string channelId, string profileIdOrAlias, CancellationToken token) - { - if (string.IsNullOrWhiteSpace(profileIdOrAlias)) - { - return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Start) }; - } - - var profileList = new List(); - var responseList = new List(); - - TaskUtils.RunOnUIThreadAsync(() => - { - var serverList = ServerManager.Instance.Servers.Where(s => - string.Equals(channelId, s.Profile.DiscordChannelId, StringComparison.OrdinalIgnoreCase) - && ( - string.Equals(profileIdOrAlias, s.Profile.ProfileID, StringComparison.OrdinalIgnoreCase) - || !string.IsNullOrWhiteSpace(s.Profile.DiscordAlias) && string.Equals(profileIdOrAlias, s.Profile.DiscordAlias, StringComparison.OrdinalIgnoreCase) - || !string.IsNullOrWhiteSpace(Config.Default.DiscordBotAllServersKeyword) && string.Equals(profileIdOrAlias, Config.Default.DiscordBotAllServersKeyword, StringComparison.OrdinalIgnoreCase) - || s.Profile.AllowDiscordClusterAlias && string.Equals(profileIdOrAlias, s.Profile.CrossArkClusterId, StringComparison.OrdinalIgnoreCase) - ) - ); - - if (serverList.IsEmpty()) - { - if (!string.IsNullOrWhiteSpace(Config.Default.DiscordBotAllServersKeyword) && string.Equals(profileIdOrAlias, Config.Default.DiscordBotAllServersKeyword, StringComparison.OrdinalIgnoreCase)) - { - responseList.Add(_globalizer.GetResourceString("DiscordBot_NoChannelProfiles")); - } - else - { - responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileIdOrAlias)); - } - } - else - { - foreach (var server in serverList) - { - if (!server.Profile.AllowDiscordStart) - { - responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Start, server.Profile.ProfileName)); - continue; - } - - // check if another command is being run against the profile - if (_currentProfileCommands.ContainsKey(server.Profile.ProfileID)) - { - responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[server.Profile.ProfileID], server.Profile.ProfileName)); - continue; - } - - switch (server.Runtime.Status) - { - case ServerStatus.Initializing: - case ServerStatus.Stopping: - case ServerStatus.Running: - case ServerStatus.Uninstalled: - case ServerStatus.Unknown: - responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ProfileName, server.Runtime.StatusString)); - continue; - - case ServerStatus.Updating: - responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), server.Profile.ProfileName)); - continue; - } - - _currentProfileCommands.Add(server.Profile.ProfileID, CommandType.Start); - var profile = ServerProfileSnapshot.Create(server.Profile); - profile.AutoRestartIfShutdown = true; - profileList.Add(profile); - } - } - }).Wait(token); - - foreach (var profile in profileList) - { - var app = new ServerApp(true) - { - DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup, - OutputLogs = false, - SendAlerts = true, - SendEmails = false, - ServerProcess = ServerProcessType.Restart, - ServerStatusChangeCallback = (ServerStatus serverStatus) => - { - TaskUtils.RunOnUIThreadAsync(() => - { - var server = ServerManager.Instance.Servers.FirstOrDefault(s => string.Equals(profile.ProfileId, s.Profile.ProfileID, StringComparison.OrdinalIgnoreCase)); - if (server != null) - { - server.Runtime.UpdateServerStatus(serverStatus, serverStatus != ServerStatus.Unknown); - } - }).Wait(token); - } - }; - - Task.Run(() => - { - app.PerformProfileShutdown(profile, true, false, false, false, token); - _currentProfileCommands.Remove(profile.ProfileId); - }, token); - - responseList.Add(string.Format(_globalizer.GetResourceString("DiscordBot_StartRequested"), profile.ServerName)); - } - - return responseList; - } - private static IList UpdateServer(string channelId, string profileIdOrAlias, CancellationToken token) { if (string.IsNullOrWhiteSpace(profileIdOrAlias)) @@ -776,7 +687,6 @@ namespace ServerManagerTool.Utils { var app = new ServerApp(true) { - DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup, OutputLogs = false, SendAlerts = true, SendEmails = false, @@ -796,7 +706,7 @@ namespace ServerManagerTool.Utils Task.Run(() => { - app.PerformProfileShutdown(profile, profile.RestartAfterShutdown1, true, false, false, token); + app.PerformProfileShutdown(profile, profile.RestartAfterShutdown1, ServerUpdateType.ServerAndMods, false, false, token); _currentProfileCommands.Remove(profile.ProfileId); }, token); diff --git a/src/ARKServerManager/Windows/ServerMonitorWindow.xaml b/src/ARKServerManager/Windows/ServerMonitorWindow.xaml index 48bc10d1..5e8130ef 100644 --- a/src/ARKServerManager/Windows/ServerMonitorWindow.xaml +++ b/src/ARKServerManager/Windows/ServerMonitorWindow.xaml @@ -6,6 +6,7 @@ xmlns:tb="http://www.hardcodet.net/taskbar" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:sm="clr-namespace:ServerManagerTool" + xmlns:cctl="clr-namespace:ServerManagerTool.Common.Controls;assembly=ServerManager.Common" xmlns:clib="clr-namespace:ServerManagerTool.Common.Lib;assembly=ServerManager.Common" xmlns:com="clr-namespace:ServerManagerTool.Common;assembly=ServerManager.Common" xmlns:controls="clr-namespace:ServerManagerTool.Common.Controls;assembly=ServerManager.Common" @@ -31,6 +32,12 @@ + + + + + + @@ -38,6 +45,7 @@ + @@ -52,6 +60,8 @@ + + @@ -82,34 +92,39 @@ - - - - - - - - - - + + - + + + + + + + + + + - + + + + + -