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 @@
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
-
- 15000
+ 5000
120000
diff --git a/src/ConanServerManager/ConanServerManager.csproj b/src/ConanServerManager/ConanServerManager.csproj
index e1053835..8d038949 100644
--- a/src/ConanServerManager/ConanServerManager.csproj
+++ b/src/ConanServerManager/ConanServerManager.csproj
@@ -198,6 +198,7 @@
+
diff --git a/src/ConanServerManager/Config.Designer.cs b/src/ConanServerManager/Config.Designer.cs
index c83ed115..08b3b1f0 100644
--- a/src/ConanServerManager/Config.Designer.cs
+++ b/src/ConanServerManager/Config.Designer.cs
@@ -1833,7 +1833,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/ConanServerManager/Config.settings b/src/ConanServerManager/Config.settings
index 2eed0a9d..9cce06c8 100644
--- a/src/ConanServerManager/Config.settings
+++ b/src/ConanServerManager/Config.settings
@@ -510,7 +510,7 @@
0
- 15000
+ 5000
120000
diff --git a/src/ConanServerManager/Enums/ServerUpdateType.cs b/src/ConanServerManager/Enums/ServerUpdateType.cs
new file mode 100644
index 00000000..81004b37
--- /dev/null
+++ b/src/ConanServerManager/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/ConanServerManager/Globalization/en-US/en-US.xaml b/src/ConanServerManager/Globalization/en-US/en-US.xaml
index eac1a72c..14aa154f 100644
--- a/src/ConanServerManager/Globalization/en-US/en-US.xaml
+++ b/src/ConanServerManager/Globalization/en-US/en-US.xaml
@@ -400,8 +400,9 @@
Server Monitor
- Selected
Total Servers:
+ Selected
+ Profile
Server
Map
Mods
@@ -410,16 +411,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.
@@ -427,6 +433,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
@@ -1356,6 +1365,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/ConanServerManager/Lib/ServerApp.cs b/src/ConanServerManager/Lib/ServerApp.cs
index efe4a395..804c3148 100644
--- a/src/ConanServerManager/Lib/ServerApp.cs
+++ b/src/ConanServerManager/Lib/ServerApp.cs
@@ -37,9 +37,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;
@@ -83,8 +88,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;
@@ -96,22 +99,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 bool SendAlerts { get; set; } = false;
+ public bool SendEmails { get; set; } = false;
+ public ProgressDelegate ProgressCallback { get; set; } = null;
+ 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)
{
@@ -223,7 +226,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)
{
@@ -277,13 +280,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
{
@@ -419,7 +422,6 @@ namespace ServerManagerTool.Lib
QueryMaster.Server gameServer = null;
bool sent = false;
- var serverAccessible = true;
try
{
@@ -481,43 +483,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
// BH - commented out until funcom provide a way to send a save command
// check if we need to perform a world save
- //if (serverAccessible && PerformWorldSave)
+ //if (PerformWorldSave)
//{
// try
// {
@@ -731,7 +707,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)
{
@@ -756,67 +732,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, Config.Default.AppIdServer, string.Empty, validate ? "validate" : string.Empty);
+ var steamCmdArgs = string.Empty;
var workingDirectory = Config.Default.DataPath;
- 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, 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)
{
@@ -861,7 +863,9 @@ namespace ServerManagerTool.Lib
modTitle = $"{modId} - {modDetail?.title ?? ""}";
if (modDetail != null)
+ {
LogProfileMessage($"{modDetail.title}.\r\n");
+ }
var modCachePath = ModUtils.GetModCachePath(modId);
var cacheTimeFile = ModUtils.GetLatestModCacheTimeFile(modId);
@@ -944,9 +948,13 @@ namespace ServerManagerTool.Lib
steamCmdArgs = string.Empty;
if (Config.Default.SteamCmd_UseAnonymousCredentials)
+ {
steamCmdArgs = SteamUtils.BuildSteamCmdArguments(steamCmdRemoveQuit, Config.Default.SteamCmdInstallModArgsFormat, Config.Default.SteamCmd_AnonymousUsername, Config.Default.AppId, modId);
+ }
else
+ {
steamCmdArgs = SteamUtils.BuildSteamCmdArguments(steamCmdRemoveQuit, Config.Default.SteamCmdInstallModArgsFormat, Config.Default.SteamCmd_Username, Config.Default.AppId, modId);
+ }
modSuccess = ServerUpdater.UpgradeModsAsync(steamCmdFile, steamCmdArgs, workingDirectory, null, null, Config.Default.SteamCmdRedirectOutput ? modOutputHandler : null, cancellationToken, SteamCMDProcessWindowStyle).Result;
if (modSuccess && downloadSuccessful)
@@ -990,10 +998,14 @@ namespace ServerManagerTool.Lib
}
}
else
+ {
modSuccess = !updateError;
+ }
}
else
+ {
modSuccess = !updateError;
+ }
if (copyMod)
{
@@ -1258,7 +1270,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*).");
}
@@ -1637,7 +1649,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)
@@ -1759,7 +1771,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)
@@ -2173,7 +2185,7 @@ namespace ServerManagerTool.Lib
catch (IOException)
{
retries++;
- if (retries >= FILECOPY_MAXRETRIES) throw;
+ if (retries >= MAXRETRIES_FILECOPY) throw;
Task.Delay(5000).Wait();
}
}
@@ -2579,8 +2591,7 @@ namespace ServerManagerTool.Lib
if (string.IsNullOrWhiteSpace(command))
return false;
- var rconRetries = RCON_MAXRETRIES;
- var sent = false;
+ var rconRetries = MAXRETRIES_RCON;
try
{
@@ -2596,23 +2607,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
@@ -2620,7 +2631,7 @@ namespace ServerManagerTool.Lib
CloseRconConsole();
}
- return sent;
+ return false;
}
private bool SendMessage(string message, CancellationToken token)
@@ -2630,7 +2641,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);
@@ -2696,7 +2707,7 @@ namespace ServerManagerTool.Lib
_rconConsole.Dispose();
_rconConsole = null;
- Task.Delay(1000).Wait();
+ Task.Delay(DELAY_RCONCONNECTION).Wait();
}
}
@@ -2722,7 +2733,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);
@@ -2822,7 +2833,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;
@@ -2864,7 +2875,7 @@ namespace ServerManagerTool.Lib
{
LogProfileMessage("Server lock established.\r\n");
- ShutdownServer(performRestart, performUpdate, steamCmdRemoveQuit, cancellationToken);
+ ShutdownServer(performRestart, updateType, steamCmdRemoveQuit, cancellationToken);
if (ExitCode != EXITCODE_NORMALEXIT)
{
@@ -3274,7 +3285,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/ConanServerManager/Utils/DiscordBotHelper.cs b/src/ConanServerManager/Utils/DiscordBotHelper.cs
index 036b9ea6..d915a5b5 100644
--- a/src/ConanServerManager/Utils/DiscordBotHelper.cs
+++ b/src/ConanServerManager/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)
@@ -336,7 +336,6 @@ namespace ServerManagerTool.Utils
{
var app = new ServerApp(true)
{
- DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup,
OutputLogs = false,
SendAlerts = true,
SendEmails = false,
@@ -366,11 +365,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();
@@ -402,11 +401,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))
@@ -424,12 +428,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);
@@ -441,7 +453,6 @@ namespace ServerManagerTool.Utils
{
var app = new ServerApp(true)
{
- DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup,
OutputLogs = false,
SendAlerts = true,
SendEmails = false,
@@ -461,11 +472,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;
@@ -475,7 +489,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();
@@ -507,7 +521,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;
@@ -535,7 +554,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));
}
}
@@ -546,7 +565,6 @@ namespace ServerManagerTool.Utils
var app = new ServerApp(true)
{
BackupWorldFile = shutdown,
- DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup,
OutputLogs = false,
PerformWorldSave = shutdown,
SendAlerts = true,
@@ -570,7 +588,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);
@@ -583,112 +601,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)
- )
- );
-
- 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))
@@ -769,7 +681,6 @@ namespace ServerManagerTool.Utils
{
var app = new ServerApp(true)
{
- DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup,
OutputLogs = false,
SendAlerts = true,
SendEmails = false,
@@ -789,7 +700,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/ConanServerManager/Windows/ServerMonitorWindow.xaml b/src/ConanServerManager/Windows/ServerMonitorWindow.xaml
index 7721108b..e1afc8e5 100644
--- a/src/ConanServerManager/Windows/ServerMonitorWindow.xaml
+++ b/src/ConanServerManager/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 @@
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
-
+
+
+
+
+
@@ -602,9 +636,9 @@
-
+
-
+
diff --git a/src/ConanServerManager/Windows/ServerMonitorWindow.xaml.cs b/src/ConanServerManager/Windows/ServerMonitorWindow.xaml.cs
index 2e57dec5..85d2a342 100644
--- a/src/ConanServerManager/Windows/ServerMonitorWindow.xaml.cs
+++ b/src/ConanServerManager/Windows/ServerMonitorWindow.xaml.cs
@@ -29,6 +29,17 @@ namespace ServerManagerTool.Windows
///
public partial class ServerMonitorWindow : Window
{
+ public class ServerMonitorOutput_Critical : Run
+ {
+ public ServerMonitorOutput_Critical(string value)
+ : base(value)
+ {
+ Foreground = Brushes.Red;
+ FontWeight = FontWeights.Bold;
+ FontSize = FontSize + 2;
+ }
+ }
+
public class ServerMonitorOutput_Error : Run
{
public ServerMonitorOutput_Error(string value)
@@ -47,6 +58,16 @@ namespace ServerManagerTool.Windows
}
}
+ public class ServerMonitorOutput_Warning : Run
+ {
+ public ServerMonitorOutput_Warning(string value)
+ : base(value)
+ {
+ Foreground = Brushes.Orange;
+ FontWeight = FontWeights.Bold;
+ }
+ }
+
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static readonly List Windows = new List();
@@ -63,6 +84,8 @@ namespace ServerManagerTool.Windows
public static readonly DependencyProperty ShowUpdateButtonProperty = DependencyProperty.Register(nameof(ShowUpdateButton), typeof(bool), typeof(ServerMonitorWindow), new PropertyMetadata(false));
public static readonly DependencyProperty IsStandAloneWindowProperty = DependencyProperty.Register(nameof(IsStandAloneWindow), typeof(bool), typeof(ServerMonitorWindow), new PropertyMetadata(false));
public static readonly DependencyProperty CancellationTokenSourceProperty = DependencyProperty.Register(nameof(CancellationTokenSource), typeof(CancellationTokenSource), typeof(ServerMonitorWindow));
+ public static readonly DependencyProperty ProcessServersSequentiallyProperty = DependencyProperty.Register(nameof(ProcessServersSequentially), typeof(bool), typeof(ServerMonitorWindow), new PropertyMetadata(false));
+ public static readonly DependencyProperty SequentialProcessDelayProperty = DependencyProperty.Register(nameof(SequentialProcessDelay), typeof(int), typeof(ServerMonitorWindow), new PropertyMetadata(10));
public ServerMonitorWindow(): this(null)
{
@@ -121,6 +144,18 @@ namespace ServerManagerTool.Windows
set { SetValue(CancellationTokenSourceProperty, value); }
}
+ public bool ProcessServersSequentially
+ {
+ get { return (bool)GetValue(ProcessServersSequentiallyProperty); }
+ set { SetValue(ProcessServersSequentiallyProperty, value); }
+ }
+
+ public int SequentialProcessDelay
+ {
+ get { return (int)GetValue(SequentialProcessDelayProperty); }
+ set { SetValue(SequentialProcessDelayProperty, value); }
+ }
+
private void ServerMonitorWindow_Loaded(object sender, RoutedEventArgs e)
{
if (ServerManager == null)
@@ -454,22 +489,52 @@ namespace ServerManagerTool.Windows
}
}
+ public void AddCriticalBlockContent(string message)
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var p = new Paragraph();
+
+ p.Inlines.Add(new ServerMonitorOutput_Critical(message));
+
+ ConsoleContent.Blocks.Add(p);
+ }).DoNotWait();
+ }
+
public void AddErrorBlockContent(string message)
{
- var p = new Paragraph();
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var p = new Paragraph();
- p.Inlines.Add(new ServerMonitorOutput_Error(message));
+ p.Inlines.Add(new ServerMonitorOutput_Error(message));
- ConsoleContent.Blocks.Add(p);
+ ConsoleContent.Blocks.Add(p);
+ }).DoNotWait();
}
public void AddMessageBlockContent(string message)
{
- var p = new Paragraph();
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var p = new Paragraph();
- p.Inlines.Add(new ServerMonitorOutput_Success(message));
+ p.Inlines.Add(new ServerMonitorOutput_Success(message));
- ConsoleContent.Blocks.Add(p);
+ ConsoleContent.Blocks.Add(p);
+ }).DoNotWait();
+ }
+
+ public void AddWarningBlockContent(string message)
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var p = new Paragraph();
+
+ p.Inlines.Add(new ServerMonitorOutput_Warning(message));
+
+ ConsoleContent.Blocks.Add(p);
+ }).DoNotWait();
}
public void ClearBlockContents()
@@ -782,7 +847,10 @@ namespace ServerManagerTool.Windows
return new RelayCommand(
execute: async (_) =>
{
- await BackupSelectedServersAsync();
+ var processServersSequentially = ProcessServersSequentially;
+ var sequentialProcessDelay = SequentialProcessDelay;
+
+ await BackupSelectedServersAsync(processServersSequentially, sequentialProcessDelay);
},
canExecute: (_) =>
{
@@ -793,6 +861,25 @@ namespace ServerManagerTool.Windows
}
}
+ public ICommand CancelServersCommand
+ {
+ get
+ {
+ return new RelayCommand(
+ execute: (_) =>
+ {
+ CancellationTokenSource.Cancel();
+
+ AddWarningBlockContent(_globalizer.GetResourceString("ServerMonitor_ProcessServer_CancelRequestedLabel"));
+ },
+ canExecute: (_) =>
+ {
+ return CancellationTokenSource != null && !CancellationTokenSource.IsCancellationRequested;
+ }
+ );
+ }
+ }
+
public ICommand RestartServersCommand
{
get
@@ -800,7 +887,10 @@ namespace ServerManagerTool.Windows
return new RelayCommand(
execute: async (_) =>
{
- await RestartSelectedServersAsync();
+ var processServersSequentially = ProcessServersSequentially;
+ var sequentialProcessDelay = SequentialProcessDelay;
+
+ await StartSelectedServersAsync(restart: true, processServersSequentially, sequentialProcessDelay);
},
canExecute: (_) =>
{
@@ -818,7 +908,10 @@ namespace ServerManagerTool.Windows
return new RelayCommand(
execute: async (_) =>
{
- await StopSelectedServersAsync(true);
+ var processServersSequentially = ProcessServersSequentially;
+ var sequentialProcessDelay = SequentialProcessDelay;
+
+ await StopSelectedServersAsync(shutdown: true, processServersSequentially, sequentialProcessDelay);
},
canExecute: (_) =>
{
@@ -836,7 +929,10 @@ namespace ServerManagerTool.Windows
return new RelayCommand(
execute: async (_) =>
{
- await StartSelectedServersAsync();
+ var processServersSequentially = ProcessServersSequentially;
+ var sequentialProcessDelay = SequentialProcessDelay;
+
+ await StartSelectedServersAsync(restart: false, processServersSequentially, sequentialProcessDelay);
},
canExecute: (_) =>
{
@@ -854,7 +950,31 @@ namespace ServerManagerTool.Windows
return new RelayCommand(
execute: async (_) =>
{
- await StopSelectedServersAsync(false);
+ var processServersSequentially = ProcessServersSequentially;
+ var sequentialProcessDelay = SequentialProcessDelay;
+
+ await StopSelectedServersAsync(shutdown: false, processServersSequentially, sequentialProcessDelay);
+ },
+ canExecute: (_) =>
+ {
+ return ServerManager?.Servers != null && ServerManager.Servers.Count > 0 && ServerManager.Servers.Any(s => s.Selected) && ServerManager.Servers.All(s => s.Runtime.Status != ServerStatus.Unknown)
+ && CancellationTokenSource == null;
+ }
+ );
+ }
+ }
+
+ public ICommand UpdateModsCommand
+ {
+ get
+ {
+ return new RelayCommand(
+ execute: async (_) =>
+ {
+ var processServersSequentially = ProcessServersSequentially;
+ var sequentialProcessDelay = SequentialProcessDelay;
+
+ await UpdateSelectedServersAsync(updateModsOnly: true, processServersSequentially, sequentialProcessDelay);
},
canExecute: (_) =>
{
@@ -872,7 +992,10 @@ namespace ServerManagerTool.Windows
return new RelayCommand(
execute: async (_) =>
{
- await UpdateSelectedServersAsync();
+ var processServersSequentially = ProcessServersSequentially;
+ var sequentialProcessDelay = SequentialProcessDelay;
+
+ await UpdateSelectedServersAsync(updateModsOnly: false, processServersSequentially, sequentialProcessDelay);
},
canExecute: (_) =>
{
@@ -1014,7 +1137,7 @@ namespace ServerManagerTool.Windows
}
}
- private async Task BackupSelectedServersAsync()
+ private async Task BackupSelectedServersAsync(bool processServersSequentially, int sequentialProcessDelay)
{
if (CancellationTokenSource != null)
return;
@@ -1039,7 +1162,7 @@ namespace ServerManagerTool.Windows
// check if another command is being run against the profile
if (_currentProfileCommands.ContainsKey(server.Profile.ProfileID))
{
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[server.Profile.ProfileID], server.Profile.ProfileName));
+ AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[server.Profile.ProfileID], server.Profile.ServerName));
continue;
}
@@ -1050,7 +1173,7 @@ namespace ServerManagerTool.Windows
case ServerStatus.Uninstalled:
case ServerStatus.Unknown:
case ServerStatus.Updating:
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ProfileName, server.Runtime.StatusString));
+ AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ServerName, server.Runtime.StatusString));
continue;
}
@@ -1066,7 +1189,6 @@ namespace ServerManagerTool.Windows
{
var app = new ServerApp(true)
{
- DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup,
OutputLogs = false,
SendAlerts = true,
SendEmails = false,
@@ -1087,6 +1209,10 @@ namespace ServerManagerTool.Windows
var task = Task.Run(() =>
{
app.PerformProfileBackup(profile, token);
+
+ Task.Delay(5000).Wait();
+
+ AddMessageBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_CommandComplete"), profile.ServerName));
_currentProfileCommands.Remove(profile.ProfileId);
}, token);
@@ -1099,113 +1225,22 @@ namespace ServerManagerTool.Windows
{
await Task.WhenAll(tasks);
}
- catch { }
+ catch (OperationCanceledException)
+ {
+ AddCriticalBlockContent(_globalizer.GetResourceString("ServerMonitor_ProcessServer_CancelledLabel"));
+ }
+ catch (Exception)
+ {
+ }
finally
{
+ _currentProfileCommands.Clear();
CancellationTokenSource?.Dispose();
CancellationTokenSource = null;
}
}
- private async Task RestartSelectedServersAsync()
- {
- if (CancellationTokenSource != null)
- return;
-
- var serverList = ServerManager.Servers.Where(s => s.Selected);
- if (serverList.IsEmpty())
- {
- MessageBox.Show(_globalizer.GetResourceString("ServerMonitor_NoServersSelected_ErrorLabel"), _globalizer.GetResourceString("ServerMonitor_NoServersSelected_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error);
- return;
- }
-
- var result = MessageBox.Show(_globalizer.GetResourceString("ServerMonitor_RestartServers_ConfirmLabel"), _globalizer.GetResourceString("ServerMonitor_RestartServers_ConfirmTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question);
- if (result != MessageBoxResult.Yes)
- return;
-
- ClearBlockContents();
-
- var profileList = new List();
-
- foreach (var server in serverList)
- {
- // check if another command is being run against the profile
- if (_currentProfileCommands.ContainsKey(server.Profile.ProfileID))
- {
- AddErrorBlockContent(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.Uninstalled:
- case ServerStatus.Unknown:
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ProfileName, server.Runtime.StatusString));
- continue;
-
- case ServerStatus.Updating:
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), server.Profile.ProfileName));
- continue;
- }
-
- _currentProfileCommands.Add(server.Profile.ProfileID, CommandType.Restart);
- var profile = ServerProfileSnapshot.Create(server.Profile);
- profile.AutoRestartIfShutdown = true;
- profileList.Add(profile);
- }
-
- CancellationTokenSource = new CancellationTokenSource();
- var token = CancellationTokenSource.Token;
- var tasks = new List();
-
- 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);
- }
- };
-
- var task = Task.Run(() =>
- {
- app.PerformProfileShutdown(profile, true, false, false, false, token);
- _currentProfileCommands.Remove(profile.ProfileId);
- }, token);
-
- tasks.Add(task);
-
- AddMessageBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_RestartRequested"), profile.ServerName));
- }
-
- try
- {
- await Task.WhenAll(tasks);
- }
- catch { }
- finally
- {
- CancellationTokenSource?.Dispose();
- CancellationTokenSource = null;
- }
- }
-
- private async Task StartSelectedServersAsync()
+ private async Task StartSelectedServersAsync(bool restart, bool processServersSequentially, int sequentialProcessDelay)
{
if (CancellationTokenSource != null)
return;
@@ -1230,7 +1265,7 @@ namespace ServerManagerTool.Windows
// check if another command is being run against the profile
if (_currentProfileCommands.ContainsKey(server.Profile.ProfileID))
{
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[server.Profile.ProfileID], server.Profile.ProfileName));
+ AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[server.Profile.ProfileID], server.Profile.ServerName));
continue;
}
@@ -1238,18 +1273,25 @@ namespace ServerManagerTool.Windows
{
case ServerStatus.Initializing:
case ServerStatus.Stopping:
- case ServerStatus.Running:
case ServerStatus.Uninstalled:
case ServerStatus.Unknown:
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ProfileName, server.Runtime.StatusString));
+ AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ServerName, server.Runtime.StatusString));
continue;
+ case ServerStatus.Running:
+ if (!restart)
+ {
+ AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ServerName, server.Runtime.StatusString));
+ continue;
+ }
+ break;
+
case ServerStatus.Updating:
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), server.Profile.ProfileName));
+ AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), server.Profile.ServerName));
continue;
}
- _currentProfileCommands.Add(server.Profile.ProfileID, CommandType.Start);
+ _currentProfileCommands.Add(server.Profile.ProfileID, restart ? CommandType.Restart : CommandType.Start);
var profile = ServerProfileSnapshot.Create(server.Profile);
profile.AutoRestartIfShutdown = true;
profileList.Add(profile);
@@ -1263,7 +1305,6 @@ namespace ServerManagerTool.Windows
{
var app = new ServerApp(true)
{
- DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup,
OutputLogs = false,
SendAlerts = true,
SendEmails = false,
@@ -1283,28 +1324,42 @@ namespace ServerManagerTool.Windows
var task = Task.Run(() =>
{
- app.PerformProfileShutdown(profile, true, false, false, false, token);
+ app.PerformProfileShutdown(profile, true, ServerUpdateType.None, false, false, token);
+
+ Task.Delay(5000).Wait();
+
+ AddMessageBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_CommandComplete"), profile.ServerName));
_currentProfileCommands.Remove(profile.ProfileId);
}, token);
tasks.Add(task);
- AddMessageBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_StartRequested"), profile.ServerName));
+ if (restart)
+ AddMessageBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_RestartRequested"), profile.ServerName));
+ else
+ AddMessageBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_StartRequested"), profile.ServerName));
}
try
{
await Task.WhenAll(tasks);
}
- catch { }
+ catch (OperationCanceledException)
+ {
+ AddCriticalBlockContent(_globalizer.GetResourceString("ServerMonitor_ProcessServer_CancelledLabel"));
+ }
+ catch (Exception)
+ {
+ }
finally
{
+ _currentProfileCommands.Clear();
CancellationTokenSource?.Dispose();
CancellationTokenSource = null;
}
}
- private async Task StopSelectedServersAsync(bool shutdown)
+ private async Task StopSelectedServersAsync(bool shutdown, bool processServersSequentially, int sequentialProcessDelay)
{
if (CancellationTokenSource != null)
return;
@@ -1331,7 +1386,7 @@ namespace ServerManagerTool.Windows
// check if another command is being run against the profile
if (_currentProfileCommands.ContainsKey(server.Profile.ProfileID))
{
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[server.Profile.ProfileID], server.Profile.ProfileName));
+ AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[server.Profile.ProfileID], server.Profile.ServerName));
continue;
}
@@ -1342,11 +1397,11 @@ namespace ServerManagerTool.Windows
case ServerStatus.Stopped:
case ServerStatus.Uninstalled:
case ServerStatus.Unknown:
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ProfileName, server.Runtime.StatusString));
+ AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ServerName, server.Runtime.StatusString));
continue;
case ServerStatus.Updating:
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), server.Profile.ProfileName));
+ AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), server.Profile.ServerName));
continue;
}
@@ -1363,7 +1418,6 @@ namespace ServerManagerTool.Windows
var app = new ServerApp(true)
{
BackupWorldFile = shutdown,
- DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup,
OutputLogs = false,
PerformWorldSave = shutdown,
SendAlerts = true,
@@ -1387,7 +1441,11 @@ namespace ServerManagerTool.Windows
var task = Task.Run(() =>
{
- app.PerformProfileShutdown(profile, false, false, false, false, token);
+ app.PerformProfileShutdown(profile, false, ServerUpdateType.None, false, false, token);
+
+ Task.Delay(5000).Wait();
+
+ AddMessageBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_CommandComplete"), profile.ServerName));
_currentProfileCommands.Remove(profile.ProfileId);
}, token);
@@ -1403,15 +1461,22 @@ namespace ServerManagerTool.Windows
{
await Task.WhenAll(tasks);
}
- catch { }
+ catch (OperationCanceledException)
+ {
+ AddCriticalBlockContent(_globalizer.GetResourceString("ServerMonitor_ProcessServer_CancelledLabel"));
+ }
+ catch (Exception)
+ {
+ }
finally
{
+ _currentProfileCommands.Clear();
CancellationTokenSource?.Dispose();
CancellationTokenSource = null;
}
}
- private async Task UpdateSelectedServersAsync()
+ private async Task UpdateSelectedServersAsync(bool updateModsOnly, bool processServersSequentially, int sequentialProcessDelay)
{
if (CancellationTokenSource != null)
return;
@@ -1438,7 +1503,7 @@ namespace ServerManagerTool.Windows
// check if another command is being run against the profile
if (_currentProfileCommands.ContainsKey(server.Profile.ProfileID))
{
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[server.Profile.ProfileID], server.Profile.ProfileName));
+ AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[server.Profile.ProfileID], server.Profile.ServerName));
continue;
}
@@ -1451,11 +1516,11 @@ namespace ServerManagerTool.Windows
case ServerStatus.Initializing:
case ServerStatus.Stopping:
case ServerStatus.Unknown:
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ProfileName, server.Runtime.StatusString));
+ AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), server.Profile.ServerName, server.Runtime.StatusString));
continue;
case ServerStatus.Updating:
- AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), server.Profile.ProfileName));
+ AddErrorBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), server.Profile.ServerName));
continue;
}
@@ -1473,7 +1538,6 @@ namespace ServerManagerTool.Windows
{
var app = new ServerApp(true)
{
- DeleteOldBackupFiles = !Config.Default.AutoBackup_EnableBackup,
OutputLogs = false,
SendAlerts = true,
SendEmails = false,
@@ -1493,7 +1557,11 @@ namespace ServerManagerTool.Windows
var task = Task.Run(() =>
{
- app.PerformProfileShutdown(profile, profile.RestartAfterShutdown1, true, false, false, token);
+ app.PerformProfileShutdown(profile, profile.RestartAfterShutdown1, updateModsOnly ? ServerUpdateType.Mods : ServerUpdateType.ServerAndMods, false, false, token);
+
+ Task.Delay(5000).Wait();
+
+ AddMessageBlockContent(string.Format(_globalizer.GetResourceString("DiscordBot_CommandComplete"), profile.ServerName));
_currentProfileCommands.Remove(profile.ProfileId);
}, token);
@@ -1506,9 +1574,16 @@ namespace ServerManagerTool.Windows
{
await Task.WhenAll(tasks);
}
- catch { }
+ catch (OperationCanceledException)
+ {
+ AddCriticalBlockContent(_globalizer.GetResourceString("ServerMonitor_ProcessServer_CancelledLabel"));
+ }
+ catch (Exception)
+ {
+ }
finally
{
+ _currentProfileCommands.Clear();
CancellationTokenSource?.Dispose();
CancellationTokenSource = null;
}
diff --git a/src/ConanServerManager/Windows/ShutdownWindow.xaml.cs b/src/ConanServerManager/Windows/ShutdownWindow.xaml.cs
index a1618d27..32327b51 100644
--- a/src/ConanServerManager/Windows/ShutdownWindow.xaml.cs
+++ b/src/ConanServerManager/Windows/ShutdownWindow.xaml.cs
@@ -224,7 +224,7 @@ namespace ServerManagerTool
var app = new ServerApp(true)
{
CheckForOnlinePlayers = this.CheckForOnlinePlayers,
- SendMessages = this.SendShutdownMessages,
+ SendShutdownMessages = this.SendShutdownMessages,
BackupWorldFile = this.BackupWorldFile,
ShutdownInterval = this.ShutdownInterval,
ShutdownReason = this.ShutdownReason,
@@ -253,7 +253,7 @@ namespace ServerManagerTool
_shutdownCancellationSource = new CancellationTokenSource();
- var exitCode = await Task.Run(() => app.PerformProfileShutdown(profile, restartServer, updateServer, false, CommonConfig.Default.SteamCmdRemoveQuit, _shutdownCancellationSource.Token));
+ var exitCode = await Task.Run(() => app.PerformProfileShutdown(profile, restartServer, updateServer ? ServerUpdateType.ServerAndMods : ServerUpdateType.None, false, CommonConfig.Default.SteamCmdRemoveQuit, _shutdownCancellationSource.Token));
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
throw new ApplicationException($"An error occured during the shutdown process - ExitCode: {exitCode}");