diff --git a/src/ARKServerManager/Lib/ServerApp.cs b/src/ARKServerManager/Lib/ServerApp.cs index a860ac49..6720234b 100644 --- a/src/ARKServerManager/Lib/ServerApp.cs +++ b/src/ARKServerManager/Lib/ServerApp.cs @@ -158,18 +158,18 @@ namespace ServerManagerTool.Lib if (!string.IsNullOrWhiteSpace(Config.Default.ServerBackup_WorldSaveMessage)) { ProcessAlert(AlertType.Backup, Config.Default.ServerBackup_WorldSaveMessage); - sent = SendMessageAsync(Config.Default.RCON_BackupMessageCommand, Config.Default.ServerBackup_WorldSaveMessage, cancellationToken).Result; + sent = SendMessage(Config.Default.RCON_BackupMessageCommand, Config.Default.ServerBackup_WorldSaveMessage, cancellationToken); if (sent) { emailMessage.AppendLine("sent server save message."); } } - sent = SendCommandAsync(Config.Default.ServerSaveCommand, false).Result; + sent = SendCommand(Config.Default.ServerSaveCommand, cancellationToken); if (sent) { emailMessage.AppendLine("sent server save command."); - Task.Delay(Config.Default.ServerShutdown_WorldSaveDelay * 1000).Wait(); + Task.Delay(Config.Default.ServerShutdown_WorldSaveDelay * 1000, cancellationToken).Wait(cancellationToken); } } catch (Exception ex) @@ -419,7 +419,8 @@ namespace ServerManagerTool.Lib LogProfileMessage($"Server process found PID {process.Id}."); QueryMaster.Server gameServer = null; - bool sent = false; + var sent = false; + var serverAccessible = true; try { @@ -433,7 +434,7 @@ namespace ServerManagerTool.Lib LogProfileMessage("Sending shutdown reason..."); ProcessAlert(AlertType.ShutdownReason, ShutdownReason); - SendMessageAsync(ShutdownReason, cancellationToken).Wait(); + SendMessage(ShutdownReason, cancellationToken); } LogProfileMessage("Starting shutdown timer..."); @@ -458,7 +459,7 @@ namespace ServerManagerTool.Lib if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage)) { ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage); - SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, cancellationToken).Wait(); + SendMessage(Config.Default.ServerShutdown_CancelMessage, cancellationToken); } ExitCode = EXITCODE_CANCELLED; @@ -467,28 +468,54 @@ namespace ServerManagerTool.Lib if (CheckForOnlinePlayers) { + var playerCount = -1; + try { var playerInfo = gameServer?.GetPlayers()?.Where(p => !string.IsNullOrWhiteSpace(p.Name?.Trim())); - var playerCount = playerInfo?.Count() ?? -1; - - // check if anyone is logged into the server - if (playerCount <= 0) - { - LogProfileMessage("No online players, shutdown timer cancelled."); - break; - } + playerCount = playerInfo?.Count() ?? -1; LogProfileMessage($"Online players: {playerCount}."); } catch (Exception ex) { - Debug.WriteLine($"Error getting/displaying online players.\r\n{ex.Message}"); + 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 { - Debug.WriteLine($"CheckForOnlinePlayers disabled, shutdown timer cancelled."); + try + { + var serverInfo = gameServer?.GetInfo(); + serverAccessible = true; + } + catch + { + serverAccessible = false; + } } var message = string.Empty; @@ -540,7 +567,7 @@ namespace ServerManagerTool.Lib message = $"{message}\r\n{ShutdownReason}"; } - sent = SendMessageAsync(message, cancellationToken).Result; + sent = SendMessage(message, cancellationToken); } minutesLeft--; @@ -553,7 +580,7 @@ namespace ServerManagerTool.Lib } // check if we need to perform a world save (not required for SotF servers) - if (Config.Default.ServerShutdown_EnableWorldSave && !_profile.SotFEnabled) + if (serverAccessible && Config.Default.ServerShutdown_EnableWorldSave && !_profile.SotFEnabled) { try { @@ -562,10 +589,10 @@ namespace ServerManagerTool.Lib { LogProfileMessage(Config.Default.ServerShutdown_WorldSaveMessage); ProcessAlert(AlertType.ShutdownMessage, Config.Default.ServerShutdown_WorldSaveMessage); - SendMessageAsync(Config.Default.ServerShutdown_WorldSaveMessage, cancellationToken).Wait(cancellationToken); + SendMessage(Config.Default.ServerShutdown_WorldSaveMessage, cancellationToken); } - if (SendCommandAsync(Config.Default.ServerSaveCommand, false).Result) + if (SendCommand(Config.Default.ServerSaveCommand, cancellationToken)) { try { @@ -587,7 +614,7 @@ namespace ServerManagerTool.Lib if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage)) { ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage); - SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, cancellationToken).Wait(); + SendMessage(Config.Default.ServerShutdown_CancelMessage, cancellationToken); } ExitCode = EXITCODE_CANCELLED; @@ -608,7 +635,7 @@ namespace ServerManagerTool.Lib message = $"{message}\r\n{ShutdownReason}"; } - SendMessageAsync(message, cancellationToken).Wait(); + SendMessage(message, cancellationToken); } } finally @@ -624,7 +651,7 @@ namespace ServerManagerTool.Lib if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage)) { ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage); - SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, cancellationToken).Wait(); + SendMessage(Config.Default.ServerShutdown_CancelMessage, cancellationToken); } ExitCode = EXITCODE_CANCELLED; @@ -644,14 +671,14 @@ namespace ServerManagerTool.Lib process.Exited += handler; // Method 1 - Shutdown Command - if (_profile.RCONEnabled && Config.Default.ServerShutdown_UseShutdownCommand) + if (serverAccessible && _profile.RCONEnabled && Config.Default.ServerShutdown_UseShutdownCommand) { try { - sent = SendCommandAsync(Config.Default.ServerShutdownCommand, false).Result; + sent = SendCommand(Config.Default.ServerShutdownCommand, cancellationToken); if (sent) { - Task.Delay(10000).Wait(); + Task.Delay(10000, cancellationToken).Wait(cancellationToken); } } catch (Exception ex) @@ -2019,6 +2046,8 @@ namespace ServerManagerTool.Lib var backupFileName = $"{mapName}_{_startTime:yyyyMMdd_HHmmss}{Config.Default.BackupExtension}"; var backupFile = IOUtils.NormalizePath(Path.Combine(backupFolder, backupFileName)); + LogProfileMessage($"{worldFileName} last write time: {File.GetLastWriteTime(worldFile):yyyy-MM-dd HH:mm:ss}"); + if (!Directory.Exists(backupFolder)) Directory.CreateDirectory(backupFolder); @@ -2632,48 +2661,46 @@ namespace ServerManagerTool.Lib } } - private async Task SendCommandAsync(string command, bool retryIfFailed) + private bool SendCommand(string command, CancellationToken token) { if (_profile == null || !_profile.RCONEnabled) return false; if (string.IsNullOrWhiteSpace(command)) return false; - int retries = 0; - int rconRetries = 0; - int maxRetries = retryIfFailed ? RCON_MAXRETRIES : 1; + var rconRetries = RCON_MAXRETRIES; + var sent = false; try { - while (retries < maxRetries && rconRetries < RCON_MAXRETRIES) + while (rconRetries > 0) { + if (token.IsCancellationRequested) + break; + SetupRconConsole(); + LogProfileMessage($"RCON> {command}"); + if (_rconConsole == null) { - LogProfileMessage($"RCON> {command} - attempt {rconRetries + 1} (a).", false); - LogProfileMessage("RCON connection could not be created.", false); - rconRetries++; + LogProfileError("RCON connection could not be created.", false); + rconRetries--; } else { - rconRetries = 0; try { _rconConsole.SendCommand(command); - LogProfileMessage($"RCON> {command}"); - - return true; + sent = true; } catch (Exception ex) { - LogProfileMessage($"RCON> {command} - attempt {retries + 1} (b).", false); - LogProfileMessage($"{ex.Message}", false); - LogProfileMessage($"{ex.StackTrace}", false); + LogProfileError(ex.Message, false); + LogProfileError(ex.StackTrace, false); } - await Task.Delay(100); - retries++; + break; } } } @@ -2682,20 +2709,20 @@ namespace ServerManagerTool.Lib CloseRconConsole(); } - return false; + return sent; } - private async Task SendMessageAsync(string message, CancellationToken token) + private bool SendMessage(string message, CancellationToken token) { - return await SendMessageAsync(Config.Default.RCON_MessageCommand, message, token); + return SendMessage(Config.Default.RCON_MessageCommand, message, token); } - private async Task SendMessageAsync(string mode, string message, CancellationToken token) + private bool SendMessage(string mode, string message, CancellationToken token) { if (string.IsNullOrWhiteSpace(message) || !SendMessages) return false; - var sent = await SendCommandAsync($"{GetRconMessageCommand(mode)} {message}", false); + var sent = SendCommand($"{GetRconMessageCommand(mode)} {message}", token); if (sent) { @@ -2753,6 +2780,8 @@ namespace ServerManagerTool.Lib { if (_rconConsole != null) { + LogProfileMessage($"Closing RCON connection to server ({_profile.ServerIPAddress}:{_profile.RCONPort})."); + _rconConsole.Dispose(); _rconConsole = null; @@ -2769,6 +2798,9 @@ namespace ServerManagerTool.Lib try { + LogProfileMessage(""); + LogProfileMessage($"Creating RCON connection to server ({_profile.ServerIPAddress}:{_profile.RCONPort})."); + var endPoint = new IPEndPoint(_profile.ServerIPAddress, _profile.RCONPort); var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000); if (server == null) @@ -2781,6 +2813,8 @@ namespace ServerManagerTool.Lib Task.Delay(1000).Wait(); + LogProfileMessage($"Opening RCON connection to server ({_profile.ServerIPAddress}:{_profile.RCONPort})."); + _rconConsole = server.GetControl(_profile.RCONPassword); if (_rconConsole == null) { @@ -2815,13 +2849,22 @@ namespace ServerManagerTool.Lib try { // try to establish a mutex for the profile. - mutex = new Mutex(true, GetMutexName(_profile.InstallDirectory), out createdNew); + var mutexName = GetMutexName(_profile.InstallDirectory); + LogProfileMessage($"Attempting to establish a lock on the server ({mutexName})"); + + mutex = new Mutex(true, mutexName, out createdNew); if (!createdNew) - createdNew = mutex.WaitOne(new TimeSpan(0, MUTEX_TIMEOUT, 0)); + { + var timeout = new TimeSpan(0, MUTEX_TIMEOUT, 0); + LogProfileMessage($"Could not lock server, waiting for server to unlock - timeout set to {timeout}."); + createdNew = mutex.WaitOne(timeout); + } // check if the mutex was established if (createdNew) { + LogProfileMessage("Server lock established.\r\n"); + BackupServer(cancellationToken); if (ExitCode != EXITCODE_NORMALEXIT) @@ -2894,13 +2937,22 @@ namespace ServerManagerTool.Lib else { // try to establish a mutex for the profile. - mutex = new Mutex(true, GetMutexName(_profile.InstallDirectory), out createdNew); + var mutexName = GetMutexName(_profile.InstallDirectory); + LogProfileMessage($"Attempting to establish a lock on the server ({mutexName})"); + + mutex = new Mutex(true, mutexName, out createdNew); if (!createdNew) - createdNew = mutex.WaitOne(new TimeSpan(0, MUTEX_TIMEOUT, 0)); + { + var timeout = new TimeSpan(0, MUTEX_TIMEOUT, 0); + LogProfileMessage($"Could not lock server, waiting for server to unlock - timeout set to {timeout}."); + createdNew = mutex.WaitOne(timeout); + } // check if the mutex was established if (createdNew) { + LogProfileMessage("Server lock established.\r\n"); + ShutdownServer(performRestart, performUpdate, steamCmdRemoveQuit, cancellationToken); if (ExitCode != EXITCODE_NORMALEXIT) @@ -2990,13 +3042,22 @@ namespace ServerManagerTool.Lib LogBranchMessage(branch.BranchName, $"[{_profile.ProfileName}] Started server update process."); // try to establish a mutex for the profile. - mutex = new Mutex(true, GetMutexName(_profile.InstallDirectory), out createdNew); + var mutexName = GetMutexName(_profile.InstallDirectory); + LogProfileMessage($"Attempting to establish a lock on the server ({mutexName})"); + + mutex = new Mutex(true, mutexName, out createdNew); if (!createdNew) - createdNew = mutex.WaitOne(new TimeSpan(0, MUTEX_TIMEOUT, 0)); + { + var timeout = new TimeSpan(0, MUTEX_TIMEOUT, 0); + LogProfileMessage($"Could not lock server, waiting for server to unlock - timeout set to {timeout}."); + createdNew = mutex.WaitOne(timeout); + } // check if the mutex was established if (createdNew) { + LogProfileMessage("Server lock established.\r\n"); + UpdateFiles(); LogBranchMessage(branch.BranchName, $"[{_profile.ProfileName}] Finished server update process."); @@ -3011,6 +3072,7 @@ namespace ServerManagerTool.Lib else { ExitCode = EXITCODE_PROCESSALREADYRUNNING; + LogProfileMessage("Cancelled server update process, could not lock server."); LogBranchMessage(branch.BranchName, $"[{_profile.ProfileName}] Cancelled server update process, could not lock server."); } } @@ -3069,13 +3131,22 @@ namespace ServerManagerTool.Lib var cacheFolder = GetServerCacheFolder(branch.BranchName); // try to establish a mutex for the profile. - mutex = new Mutex(true, GetMutexName(cacheFolder), out createdNew); + var mutexName = GetMutexName(cacheFolder); + LogBranchMessage(branch.BranchName, $"Attempting to establish a lock on the cache ({mutexName})"); + + mutex = new Mutex(true, mutexName, out createdNew); if (!createdNew) - createdNew = mutex.WaitOne(new TimeSpan(0, MUTEX_TIMEOUT, 0)); + { + var timeout = new TimeSpan(0, MUTEX_TIMEOUT, 0); + LogBranchMessage(branch.BranchName, $"Could not lock cache, waiting for cache to unlock - timeout set to {timeout}."); + createdNew = mutex.WaitOne(timeout); + } // check if the mutex was established if (createdNew) { + LogBranchMessage(branch.BranchName, "Cache lock established.\r\n"); + // update the server cache for the branch UpdateServerCache(branch.BranchName, branch.BranchPassword); @@ -3139,7 +3210,7 @@ namespace ServerManagerTool.Lib else { ExitCode = EXITCODE_PROCESSALREADYRUNNING; - LogMessage($"[{GetBranchName(branch.BranchName)}] Cancelled branch update process, could not lock branch folder."); + LogMessage($"[{GetBranchName(branch.BranchName)}] Cancelled branch update process, could not lock cache."); } } catch (Exception ex) diff --git a/src/ARKServerManager/Lib/ServerStatusWatcher.cs b/src/ARKServerManager/Lib/ServerStatusWatcher.cs index 238034d3..b8dc73ac 100644 --- a/src/ARKServerManager/Lib/ServerStatusWatcher.cs +++ b/src/ARKServerManager/Lib/ServerStatusWatcher.cs @@ -310,7 +310,8 @@ namespace ServerManagerTool.Lib try { - onlinePlayerCount = serverInfo?.Players ?? 0; + var playerInfo = server?.GetPlayers()?.Where(p => !string.IsNullOrWhiteSpace(p.Name?.Trim())); + onlinePlayerCount = playerInfo?.Count() ?? 0; } catch (Exception) { diff --git a/src/ARKServerManager/UserControls/ServerSettingsControl.xaml.cs b/src/ARKServerManager/UserControls/ServerSettingsControl.xaml.cs index f3187e73..204ccb54 100644 --- a/src/ARKServerManager/UserControls/ServerSettingsControl.xaml.cs +++ b/src/ARKServerManager/UserControls/ServerSettingsControl.xaml.cs @@ -784,12 +784,12 @@ namespace ServerManagerTool var profileFile = ServerProfile.LoadFromProfileFile(file, null); if (profileFile != null) { - profileFile.AdminPassword = "obfuscated"; - profileFile.ServerPassword = "obfuscated"; - profileFile.SpectatorPassword = "obfuscated"; - profileFile.WebAlarmKey = "obfuscated"; - profileFile.WebAlarmUrl = "obfuscated"; - profileFile.BranchPassword = "obfuscated"; + profileFile.AdminPassword = string.IsNullOrWhiteSpace(profileFile.AdminPassword) ? "empty" : "obfuscated"; + profileFile.ServerPassword = string.IsNullOrWhiteSpace(profileFile.ServerPassword) ? "empty" : "obfuscated"; + profileFile.SpectatorPassword = string.IsNullOrWhiteSpace(profileFile.SpectatorPassword) ? "empty" : "obfuscated"; + profileFile.WebAlarmKey = string.IsNullOrWhiteSpace(profileFile.WebAlarmKey) ? "empty" : "obfuscated"; + profileFile.WebAlarmUrl = string.IsNullOrWhiteSpace(profileFile.WebAlarmUrl) ? "empty" : "obfuscated"; + profileFile.BranchPassword = string.IsNullOrWhiteSpace(profileFile.BranchPassword) ? "empty" : "obfuscated"; obfuscateFiles.Add(file, profileFile.ToOutputString()); } } @@ -859,10 +859,6 @@ namespace ServerManagerTool comment.AppendLine($"MachinePublicIP: {Config.Default.MachinePublicIP}"); comment.AppendLine($"Data Directory: {Config.Default.DataDir}"); comment.AppendLine($"Profiles Directory: {Config.Default.ConfigDirectory}"); - if (!string.IsNullOrWhiteSpace(Config.Default.BackupPath)) - comment.AppendLine($"Backup Directory: {Config.Default.BackupPath}"); - else - comment.AppendLine($"Backup Directory: *{Path.Combine(Config.Default.DataDir, Config.Default.BackupDir)}"); comment.AppendLine($"Server Directory: {this.Settings.InstallDirectory}"); comment.AppendLine($"SotF Server: {this.Settings.SOTF_Enabled}"); @@ -870,69 +866,95 @@ namespace ServerManagerTool comment.AppendLine($"IsAdministrator: {SecurityUtils.IsAdministrator()}"); comment.AppendLine($"RunAsAdministratorPrompt: {Config.Default.RunAsAdministratorPrompt}"); + comment.AppendLine($"CheckIfServerManagerRunningOnStartup: {Config.Default.CheckIfServerManagerRunningOnStartup}"); + comment.AppendLine($"ManageFirewallAutomatically: {Config.Default.ManageFirewallAutomatically}"); + comment.AppendLine($"ManagePublicIPAutomatically: {Config.Default.ManagePublicIPAutomatically}"); comment.AppendLine($"MainWindow_WindowState: {Config.Default.MainWindow_WindowState}"); comment.AppendLine($"MainWindow_MinimizeToTray: {Config.Default.MainWindow_MinimizeToTray}"); - comment.AppendLine($"ManageFirewallAutomatically: {Config.Default.ManageFirewallAutomatically}"); - comment.AppendLine($"ValidateProfileOnServerStart: {Config.Default.ValidateProfileOnServerStart}"); + comment.AppendLine($"ServerMonitorWindow_WindowState: {Config.Default.ServerMonitorWindow_WindowState}"); + comment.AppendLine($"SteamCMD File: {SteamCmdUpdater.GetSteamCmdFile(Config.Default.DataDir)}"); - comment.AppendLine($"SteamCmdRedirectOutput: {Config.Default.SteamCmdRedirectOutput}"); comment.AppendLine($"SteamCmd_UseAnonymousCredentials: {Config.Default.SteamCmd_UseAnonymousCredentials}"); comment.AppendLine($"SteamCmd_Username Set: {!string.IsNullOrWhiteSpace(Config.Default.SteamCmd_Username)}"); comment.AppendLine($"SteamCmd_Password Set: {!string.IsNullOrWhiteSpace(Config.Default.SteamCmd_Password)}"); comment.AppendLine($"SteamAPIKey: {!string.IsNullOrWhiteSpace(CommonConfig.Default.SteamAPIKey)}"); - comment.AppendLine($"SectionSOTFEnabled: {Config.Default.SectionSOTFEnabled}"); - comment.AppendLine($"SectionPGMEnabled: {Config.Default.SectionPGMEnabled}"); comment.AppendLine($"SectionCraftingOverridesEnabled: {Config.Default.SectionCraftingOverridesEnabled}"); + comment.AppendLine($"SectionStackSizeOverridesEnabled: {Config.Default.SectionStackSizeOverridesEnabled}"); + comment.AppendLine($"SectionCustomEngineSettingsEnabled: {Config.Default.SectionCustomEngineSettingsEnabled}"); comment.AppendLine($"SectionMapSpawnerOverridesEnabled: {Config.Default.SectionMapSpawnerOverridesEnabled}"); comment.AppendLine($"SectionSupplyCrateOverridesEnabled: {Config.Default.SectionSupplyCrateOverridesEnabled}"); - comment.AppendLine($"SectionStackSizeOverridesEnabled: {Config.Default.SectionStackSizeOverridesEnabled}"); comment.AppendLine($"SectionPreventTransferOverridesEnabled: {Config.Default.SectionPreventTransferOverridesEnabled}"); + comment.AppendLine($"SectionPGMEnabled: {Config.Default.SectionPGMEnabled}"); + comment.AppendLine($"SectionSOTFEnabled: {Config.Default.SectionSOTFEnabled}"); + + comment.AppendLine($"CustomLevelXPIncrease_Player: {Config.Default.CustomLevelXPIncrease_Player}"); + comment.AppendLine($"CustomLevelXPIncrease_Dino: {Config.Default.CustomLevelXPIncrease_Dino}"); + + comment.AppendLine($"ServerStatus_EnableActions: {Config.Default.ServerStatus_EnableActions}"); + comment.AppendLine($"ServerStatus_ShowActionConfirmation: {Config.Default.ServerStatus_ShowActionConfirmation}"); + + comment.AppendLine($"ValidateProfileOnServerStart: {Config.Default.ValidateProfileOnServerStart}"); + comment.AppendLine($"ServerUpdate_OnServerStart: {Config.Default.ServerUpdate_OnServerStart}"); + comment.AppendLine($"ServerStartMinimized: {Config.Default.ServerStartMinimized}"); + + comment.AppendLine($"ServerUpdate_UpdateModsWhenUpdatingServer: {Config.Default.ServerUpdate_UpdateModsWhenUpdatingServer}"); + comment.AppendLine($"ServerUpdate_ForceUpdateMods: {Config.Default.ServerUpdate_ForceUpdateMods}"); + comment.AppendLine($"ServerUpdate_ForceCopyMods: {Config.Default.ServerUpdate_ForceCopyMods}"); + comment.AppendLine($"ServerUpdate_ForceUpdateModsIfNoSteamInfo: {Config.Default.ServerUpdate_ForceUpdateModsIfNoSteamInfo}"); + comment.AppendLine($"WorkshopCache_ExpiredHours: {Config.Default.WorkshopCache_ExpiredHours}"); + + if (!string.IsNullOrWhiteSpace(Config.Default.BackupPath)) + comment.AppendLine($"Backup Directory: {Config.Default.BackupPath}"); + else + comment.AppendLine($"Backup Directory: *{Path.Combine(Config.Default.DataDir, Config.Default.BackupDir)}"); + comment.AppendLine($"AutoBackup_IncludeSaveGamesFolder: {Config.Default.AutoBackup_IncludeSaveGamesFolder}"); + comment.AppendLine($"AutoBackup_DeleteOldFiles: {Config.Default.AutoBackup_DeleteOldFiles}"); + comment.AppendLine($"AutoBackup_DeleteInterval: {Config.Default.AutoBackup_DeleteInterval}"); + comment.AppendLine($"RCON_BackupMessageCommand: {Config.Default.RCON_BackupMessageCommand}"); + comment.AppendLine($"ServerBackup_WorldSaveMessage: {Config.Default.ServerBackup_WorldSaveMessage}"); comment.AppendLine($"AutoBackup_EnableBackup: {Config.Default.AutoBackup_EnableBackup}"); comment.AppendLine($"AutoBackup_BackupPeriod: {Config.Default.AutoBackup_BackupPeriod}"); - comment.AppendLine($"AutoBackup_DeleteOldFiles: {Config.Default.AutoBackup_DeleteOldFiles}"); - comment.AppendLine($"AutoBackup_DeleteInterval: {Config.Default.AutoBackup_DeleteInterval}"); comment.AppendLine($"AutoUpdate_EnableUpdate: {Config.Default.AutoUpdate_EnableUpdate}"); comment.AppendLine($"AutoUpdate_CacheDir: {Config.Default.AutoUpdate_CacheDir}"); comment.AppendLine($"AutoUpdate_UpdatePeriod: {Config.Default.AutoUpdate_UpdatePeriod}"); comment.AppendLine($"AutoUpdate_UseSmartCopy: {Config.Default.AutoUpdate_UseSmartCopy}"); - comment.AppendLine($"AutoUpdate_RetryOnFail: {Config.Default.AutoUpdate_RetryOnFail}"); - comment.AppendLine($"AutoUpdate_ShowUpdateReason: {Config.Default.AutoUpdate_ShowUpdateReason}"); comment.AppendLine($"AutoUpdate_ValidateServerFiles: {Config.Default.AutoUpdate_ValidateServerFiles}"); + comment.AppendLine($"AutoUpdate_RetryOnFail: {Config.Default.AutoUpdate_RetryOnFail}"); + comment.AppendLine($"AutoUpdate_ParallelUpdate: {Config.Default.AutoUpdate_ParallelUpdate}"); + comment.AppendLine($"AutoUpdate_SequencialDelayPeriod: {Config.Default.AutoUpdate_SequencialDelayPeriod}"); + comment.AppendLine($"AutoUpdate_ShowUpdateReason: {Config.Default.AutoUpdate_ShowUpdateReason}"); + comment.AppendLine($"AutoUpdate_ShowUpdateReason: {Config.Default.AutoUpdate_UpdateReasonPrefix}"); comment.AppendLine($"AutoUpdate_OverrideServerStartup: {Config.Default.AutoUpdate_OverrideServerStartup}"); comment.AppendLine($"AutoRestart_EnabledGracePeriod: {Config.Default.AutoRestart_EnabledGracePeriod}"); comment.AppendLine($"AutoRestart_GracePeriod: {Config.Default.AutoRestart_GracePeriod}"); - comment.AppendLine($"ServerShutdown_EnableWorldSave: {Config.Default.ServerShutdown_EnableWorldSave}"); comment.AppendLine($"ServerShutdown_CheckForOnlinePlayers: {Config.Default.ServerShutdown_CheckForOnlinePlayers}"); comment.AppendLine($"ServerShutdown_SendShutdownMessages: {Config.Default.ServerShutdown_SendShutdownMessages}"); comment.AppendLine($"ServerShutdown_GracePeriod: {Config.Default.ServerShutdown_GracePeriod}"); - comment.AppendLine($"ServerUpdate_UpdateModsWhenUpdatingServer: {Config.Default.ServerUpdate_UpdateModsWhenUpdatingServer}"); - comment.AppendLine($"ServerUpdate_ForceCopyMods: {Config.Default.ServerUpdate_ForceCopyMods}"); - comment.AppendLine($"ServerUpdate_ForceUpdateMods: {Config.Default.ServerUpdate_ForceUpdateMods}"); - comment.AppendLine($"ServerUpdate_ForceUpdateModsIfNoSteamInfo: {Config.Default.ServerUpdate_ForceUpdateModsIfNoSteamInfo}"); - comment.AppendLine($"ServerUpdate_OnServerStart: {Config.Default.ServerUpdate_OnServerStart}"); + comment.AppendLine($"ServerShutdown_AllMessagesShowReason: {Config.Default.ServerShutdown_AllMessagesShowReason}"); comment.AppendLine($"DiscordBotEnabled: {Config.Default.DiscordBotEnabled}"); comment.AppendLine($"HasDiscordBotToken: {!string.IsNullOrWhiteSpace(Config.Default.DiscordBotToken)}"); comment.AppendLine($"DiscordBotServerId: {Config.Default.DiscordBotServerId}"); comment.AppendLine($"DiscordBotPrefix: {Config.Default.DiscordBotPrefix}"); comment.AppendLine($"DiscordBotLogLevel: {Config.Default.DiscordBotLogLevel}"); - comment.AppendLine($"DiscordBotAllowAllBots: {Config.Default.DiscordBotAllowAllBots}"); - comment.AppendLine($"DiscordBotWhitelist: {string.Join(";", Config.Default.DiscordBotWhitelist)}"); + comment.AppendLine($"DiscordBotAllServersKeyword: {Config.Default.DiscordBotAllServersKeyword}"); comment.AppendLine($"AllowDiscordBackup: {Config.Default.AllowDiscordBackup}"); comment.AppendLine($"AllowDiscordRestart: {Config.Default.AllowDiscordRestart}"); comment.AppendLine($"AllowDiscordShutdown: {Config.Default.AllowDiscordShutdown}"); comment.AppendLine($"AllowDiscordStart: {Config.Default.AllowDiscordStart}"); comment.AppendLine($"AllowDiscordStop: {Config.Default.AllowDiscordStop}"); comment.AppendLine($"AllowDiscordUpdate: {Config.Default.AllowDiscordUpdate}"); + comment.AppendLine($"DiscordBotAllowAllBots: {Config.Default.DiscordBotAllowAllBots}"); + comment.AppendLine($"DiscordBotWhitelist: {string.Join(";", Config.Default.DiscordBotWhitelist)}"); - comment.AppendLine($"EmailNotify_AutoRestart: {Config.Default.EmailNotify_AutoRestart}"); comment.AppendLine($"EmailNotify_AutoBackup: {Config.Default.EmailNotify_AutoBackup}"); comment.AppendLine($"EmailNotify_AutoUpdate: {Config.Default.EmailNotify_AutoUpdate}"); + comment.AppendLine($"EmailNotify_AutoRestart: {Config.Default.EmailNotify_AutoRestart}"); comment.AppendLine($"EmailNotify_ShutdownRestart: {Config.Default.EmailNotify_ShutdownRestart}"); comment.AppendLine($"ServerShutdown_UseShutdownCommand: {Config.Default.ServerShutdown_UseShutdownCommand}"); @@ -941,10 +963,12 @@ namespace ServerManagerTool comment.AppendLine($"AutoUpdate_VerifyServerAfterUpdate: {Config.Default.AutoUpdate_VerifyServerAfterUpdate}"); comment.AppendLine($"SteamCmdRemoveQuit: {CommonConfig.Default.SteamCmdRemoveQuit}"); comment.AppendLine($"UpdateDirectoryPermissions: {Config.Default.UpdateDirectoryPermissions}"); + comment.AppendLine($"SteamCmdRedirectOutput: {Config.Default.SteamCmdRedirectOutput}"); comment.AppendLine($"LoggingEnabled: {Config.Default.LoggingEnabled}"); comment.AppendLine($"LoggingMaxArchiveDays: {Config.Default.LoggingMaxArchiveDays}"); comment.AppendLine($"LoggingMaxArchiveFiles: {Config.Default.LoggingMaxArchiveFiles}"); comment.AppendLine($"ServerShutdown_WorldSaveDelay: {Config.Default.ServerShutdown_WorldSaveDelay}"); + comment.AppendLine($"RCON_MessageCommand: {Config.Default.RCON_MessageCommand}"); var zipFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), this.Settings.ProfileID + ".zip"); if (File.Exists(zipFile)) File.Delete(zipFile); diff --git a/src/ARKServerManager/VersionFeed.xml b/src/ARKServerManager/VersionFeed.xml index 72b793c8..fdb48cef 100644 --- a/src/ARKServerManager/VersionFeed.xml +++ b/src/ARKServerManager/VersionFeed.xml @@ -5,7 +5,30 @@ Ark Server Manager Version Feed This is the Ark Server Manager release version feed. - 2022-05-11T00:00:00Z + 2022-05-15T00:00:00Z + + + urn:uuid:2E2A14AE-EE5B-4384-8143-BF5D1C8A487D + 1.1.428 (1.1.428.1) + 1.1.428.1 + + 2022-05-15T00:00:00Z + +
+

+ BUGFIX +
+

    +
  • Server Shutdown/Restart - rewritten the code that sends the RCON commands to prevent the hangs after the RCON command fails.
  • +
+

+
+
+ + bletch + bletch1971@hotmail.com + +
urn:uuid:BB7749B7-31F1-46B8-848D-3F3B6E84EA5B diff --git a/src/ARKServerManager/VersionFeedBeta.xml b/src/ARKServerManager/VersionFeedBeta.xml index 25160bb3..d3f2fdb1 100644 --- a/src/ARKServerManager/VersionFeedBeta.xml +++ b/src/ARKServerManager/VersionFeedBeta.xml @@ -5,44 +5,21 @@ Ark Server Manager Version Feed This is the Ark Server Manager beta version feed. - 2022-05-11T00:00:00Z + 2022-05-15T00:00:00Z - urn:uuid:BB7749B7-31F1-46B8-848D-3F3B6E84EA5B - 1.1.427 (1.1.427.2) - 1.1.427.2 + urn:uuid:2E2A14AE-EE5B-4384-8143-BF5D1C8A487D + 1.1.428 (1.1.428.1) + 1.1.428.1 - 2022-05-11T00:00:00Z - -
-

- CHANGE -
-

    -
  • ru-RU Translation file updated.
  • -
-

-
-
- - bletch - bletch1971@hotmail.com - -
- - - urn:uuid:BB7749B7-31F1-46B8-848D-3F3B6E84EA5B - 1.1.427 (1.1.427.1) - 1.1.427.1 - - 2022-05-09T00:00:00Z + 2022-05-15T00:00:00Z

BUGFIX

    -
  • World Save Backups - have fixed the timestamps associated with the files inside the zip file.
  • +
  • Server Shutdown/Restart - rewritten the code that sends the RCON commands to prevent the hangs after the RCON command fails.

diff --git a/src/ConanServerManager/Lib/ServerApp.cs b/src/ConanServerManager/Lib/ServerApp.cs index ded17b4c..f4ddf5a3 100644 --- a/src/ConanServerManager/Lib/ServerApp.cs +++ b/src/ConanServerManager/Lib/ServerApp.cs @@ -159,18 +159,18 @@ namespace ServerManagerTool.Lib if (!string.IsNullOrWhiteSpace(Config.Default.ServerBackup_WorldSaveMessage)) { ProcessAlert(AlertType.Backup, Config.Default.ServerBackup_WorldSaveMessage); - sent = SendMessageAsync(Config.Default.RCON_BackupMessageCommand, Config.Default.ServerBackup_WorldSaveMessage, cancellationToken).Result; + sent = SendMessage(Config.Default.RCON_BackupMessageCommand, Config.Default.ServerBackup_WorldSaveMessage, cancellationToken); if (sent) { emailMessage.AppendLine("sent server save message."); } } - sent = SendCommandAsync(Config.Default.ServerSaveCommand, false).Result; + sent = SendCommand(Config.Default.ServerSaveCommand, cancellationToken); if (sent) { emailMessage.AppendLine("sent server save command."); - Task.Delay(Config.Default.ServerShutdown_WorldSaveDelay * 1000).Wait(); + Task.Delay(Config.Default.ServerShutdown_WorldSaveDelay * 1000, cancellationToken).Wait(cancellationToken); } } catch (Exception ex) @@ -416,6 +416,7 @@ namespace ServerManagerTool.Lib QueryMaster.Server gameServer = null; bool sent = false; + var serverAccessible = true; try { @@ -429,7 +430,7 @@ namespace ServerManagerTool.Lib LogProfileMessage("Sending shutdown reason..."); ProcessAlert(AlertType.ShutdownReason, ShutdownReason); - SendMessageAsync(ShutdownReason, cancellationToken).Wait(); + SendMessage(ShutdownReason, cancellationToken); } LogProfileMessage("Starting shutdown timer..."); @@ -454,7 +455,7 @@ namespace ServerManagerTool.Lib if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage)) { ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage); - SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, cancellationToken).Wait(); + SendMessage(Config.Default.ServerShutdown_CancelMessage, cancellationToken); } ExitCode = EXITCODE_CANCELLED; @@ -463,31 +464,57 @@ namespace ServerManagerTool.Lib if (CheckForOnlinePlayers) { + var playerCount = -1; + try { // BH - commented out until Funcom fix the Online player status column in the world save database //var gameFile = GetServerWorldFile(); //var playerCount = DataContainer.GetOnlinePlayerCount(gameFile); var playerInfo = gameServer?.GetPlayers()?.Where(p => !string.IsNullOrWhiteSpace(p.Name?.Trim())); - var playerCount = playerInfo?.Count() ?? -1; - - // check if anyone is logged into the server - if (playerCount <= 0) - { - LogProfileMessage("No online players, shutdown timer cancelled."); - break; - } + playerCount = playerInfo?.Count() ?? -1; LogProfileMessage($"Online players: {playerCount}."); } catch (Exception ex) { - Debug.WriteLine($"Error getting/displaying online players.\r\n{ex.Message}"); + 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 { - Debug.WriteLine($"CheckForOnlinePlayers disabled, shutdown timer cancelled."); + try + { + var serverInfo = gameServer?.GetInfo(); + serverAccessible = true; + } + catch + { + serverAccessible = false; + } } var message = string.Empty; @@ -539,7 +566,7 @@ namespace ServerManagerTool.Lib message = $"{message}\r\n{ShutdownReason}"; } - sent = SendMessageAsync(message, cancellationToken).Result; + sent = SendMessage(message, cancellationToken); } minutesLeft--; @@ -553,7 +580,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 (Config.Default.ServerShutdown_EnableWorldSave) + //if (serverAccessible && Config.Default.ServerShutdown_EnableWorldSave) //{ // try // { @@ -562,10 +589,10 @@ namespace ServerManagerTool.Lib // { // LogProfileMessage(Config.Default.ServerShutdown_WorldSaveMessage); // ProcessAlert(AlertType.ShutdownMessage, Config.Default.ServerShutdown_WorldSaveMessage); - // SendMessageAsync(Config.Default.ServerShutdown_WorldSaveMessage, cancellationToken).Wait(cancellationToken); + // SendMessage(Config.Default.ServerShutdown_WorldSaveMessage, cancellationToken); // } - // if (SendCommandAsync(Config.Default.ServerSaveCommand, false).Result) + // if (SendCommandAsync(Config.Default.ServerSaveCommand).Result) // { // try // { @@ -587,7 +614,7 @@ namespace ServerManagerTool.Lib if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage)) { ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage); - SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, cancellationToken).Wait(); + SendMessage(Config.Default.ServerShutdown_CancelMessage, cancellationToken); } ExitCode = EXITCODE_CANCELLED; @@ -608,7 +635,7 @@ namespace ServerManagerTool.Lib message = $"{message}\r\n{ShutdownReason}"; } - SendMessageAsync(message, cancellationToken).Wait(); + SendMessage(message, cancellationToken); } } finally @@ -624,7 +651,7 @@ namespace ServerManagerTool.Lib if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage)) { ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage); - SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, cancellationToken).Wait(); + SendMessage(Config.Default.ServerShutdown_CancelMessage, cancellationToken); } ExitCode = EXITCODE_CANCELLED; @@ -1943,6 +1970,8 @@ namespace ServerManagerTool.Lib var backupFileName = $"{mapName}_{_startTime:yyyyMMdd_HHmmss}{Config.Default.BackupExtension}"; var backupFile = IOUtils.NormalizePath(Path.Combine(backupFolder, backupFileName)); + LogProfileMessage($"{worldFileName} last write time: {File.GetLastWriteTime(worldFile):yyyy-MM-dd HH:mm:ss}"); + if (!Directory.Exists(backupFolder)) Directory.CreateDirectory(backupFolder); @@ -2529,48 +2558,46 @@ namespace ServerManagerTool.Lib } } - private async Task SendCommandAsync(string command, bool retryIfFailed) + private bool SendCommand(string command, CancellationToken token) { if (_profile == null || !_profile.RconEnabled) return false; if (string.IsNullOrWhiteSpace(command)) return false; - int retries = 0; - int rconRetries = 0; - int maxRetries = retryIfFailed ? RCON_MAXRETRIES : 1; + var rconRetries = RCON_MAXRETRIES; + var sent = false; try { - while (retries < maxRetries && rconRetries < RCON_MAXRETRIES) + while (rconRetries > 0) { + if (token.IsCancellationRequested) + break; + SetupRconConsole(); + LogProfileMessage($"RCON> {command}"); + if (_rconConsole == null) { - LogProfileMessage($"RCON> {command} - attempt {rconRetries + 1} (a).", false); - LogProfileMessage("RCON connection could not be created.", false); - rconRetries++; + LogProfileError("RCON connection could not be created.", false); + rconRetries--; } else { - rconRetries = 0; try { _rconConsole.SendCommand(command); - LogProfileMessage($"RCON> {command}"); - - return true; + sent = true; } catch (Exception ex) { - LogProfileMessage($"RCON> {command} - attempt {retries + 1} (b).", false); - LogProfileMessage($"{ex.Message}", false); - LogProfileMessage($"{ex.StackTrace}", false); + LogProfileError(ex.Message, false); + LogProfileError(ex.StackTrace, false); } - await Task.Delay(100); - retries++; + break; } } } @@ -2579,20 +2606,20 @@ namespace ServerManagerTool.Lib CloseRconConsole(); } - return false; + return sent; } - private async Task SendMessageAsync(string message, CancellationToken token) + private bool SendMessage(string message, CancellationToken token) { - return await SendMessageAsync(Config.Default.RCON_MessageCommand, message, token); + return SendMessage(Config.Default.RCON_MessageCommand, message, token); } - private async Task SendMessageAsync(string mode, string message, CancellationToken token) + private bool SendMessage(string mode, string message, CancellationToken token) { if (string.IsNullOrWhiteSpace(message) || !SendMessages) return false; - var sent = await SendCommandAsync($"{GetRconMessageCommand(mode)} {message}", false); + var sent = SendCommand($"{GetRconMessageCommand(mode)} {message}", token); if (sent) { @@ -2650,6 +2677,8 @@ namespace ServerManagerTool.Lib { if (_rconConsole != null) { + LogProfileMessage($"Closing RCON connection to server ({_profile.ServerIPAddress}:{_profile.RconPort})."); + _rconConsole.Dispose(); _rconConsole = null; @@ -2666,6 +2695,9 @@ namespace ServerManagerTool.Lib try { + LogProfileMessage(""); + LogProfileMessage($"Creating RCON connection to server ({_profile.ServerIPAddress}:{_profile.RconPort})."); + var endPoint = new IPEndPoint(_profile.ServerIPAddress, _profile.RconPort); var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000); if (server == null) @@ -2678,6 +2710,8 @@ namespace ServerManagerTool.Lib Task.Delay(1000).Wait(); + LogProfileMessage($"Opening RCON connection to server ({_profile.ServerIPAddress}:{_profile.RconPort})."); + _rconConsole = server.GetControl(_profile.RconPassword); if (_rconConsole == null) { @@ -2712,13 +2746,22 @@ namespace ServerManagerTool.Lib try { // try to establish a mutex for the profile. - mutex = new Mutex(true, GetMutexName(_profile.InstallDirectory), out createdNew); + var mutexName = GetMutexName(_profile.InstallDirectory); + LogProfileMessage($"Attempting to establish a lock on the server ({mutexName})"); + + mutex = new Mutex(true, mutexName, out createdNew); if (!createdNew) - createdNew = mutex.WaitOne(new TimeSpan(0, MUTEX_TIMEOUT, 0)); + { + var timeout = new TimeSpan(0, MUTEX_TIMEOUT, 0); + LogProfileMessage($"Could not lock server, waiting for server to unlock - timeout set to {timeout}."); + createdNew = mutex.WaitOne(timeout); + } // check if the mutex was established if (createdNew) { + LogProfileMessage("Server lock established.\r\n"); + BackupServer(cancellationToken); if (ExitCode != EXITCODE_NORMALEXIT) @@ -2791,13 +2834,22 @@ namespace ServerManagerTool.Lib else { // try to establish a mutex for the profile. - mutex = new Mutex(true, GetMutexName(_profile.InstallDirectory), out createdNew); + var mutexName = GetMutexName(_profile.InstallDirectory); + LogProfileMessage($"Attempting to establish a lock on the server ({mutexName})"); + + mutex = new Mutex(true, mutexName, out createdNew); if (!createdNew) - createdNew = mutex.WaitOne(new TimeSpan(0, MUTEX_TIMEOUT, 0)); + { + var timeout = new TimeSpan(0, MUTEX_TIMEOUT, 0); + LogProfileMessage($"Could not lock server, waiting for server to unlock - timeout set to {timeout}."); + createdNew = mutex.WaitOne(timeout); + } // check if the mutex was established if (createdNew) { + LogProfileMessage("Server lock established.\r\n"); + ShutdownServer(performRestart, performUpdate, steamCmdRemoveQuit, cancellationToken); if (ExitCode != EXITCODE_NORMALEXIT) @@ -2887,13 +2939,22 @@ namespace ServerManagerTool.Lib LogBranchMessage(branch.BranchName, $"[{_profile.ProfileName}] Started server update process."); // try to establish a mutex for the profile. - mutex = new Mutex(true, GetMutexName(_profile.InstallDirectory), out createdNew); + var mutexName = GetMutexName(_profile.InstallDirectory); + LogProfileMessage($"Attempting to establish a lock on the server ({mutexName})"); + + mutex = new Mutex(true, mutexName, out createdNew); if (!createdNew) - createdNew = mutex.WaitOne(new TimeSpan(0, MUTEX_TIMEOUT, 0)); + { + var timeout = new TimeSpan(0, MUTEX_TIMEOUT, 0); + LogProfileMessage($"Could not lock server, waiting for server to unlock - timeout set to {timeout}."); + createdNew = mutex.WaitOne(timeout); + } // check if the mutex was established if (createdNew) { + LogProfileMessage("Server lock established.\r\n"); + UpdateFiles(); LogBranchMessage(branch.BranchName, $"[{_profile.ProfileName}] Finished server update process."); @@ -2908,6 +2969,7 @@ namespace ServerManagerTool.Lib else { ExitCode = EXITCODE_PROCESSALREADYRUNNING; + LogProfileMessage("Cancelled server update process, could not lock server."); LogBranchMessage(branch.BranchName, $"[{_profile.ProfileName}] Cancelled server update process, could not lock server."); } } @@ -2966,13 +3028,22 @@ namespace ServerManagerTool.Lib var cacheFolder = GetServerCacheFolder(branch.BranchName); // try to establish a mutex for the profile. - mutex = new Mutex(true, GetMutexName(cacheFolder), out createdNew); + var mutexName = GetMutexName(cacheFolder); + LogBranchMessage(branch.BranchName, $"Attempting to establish a lock on the cache ({mutexName})"); + + mutex = new Mutex(true, mutexName, out createdNew); if (!createdNew) - createdNew = mutex.WaitOne(new TimeSpan(0, MUTEX_TIMEOUT, 0)); + { + var timeout = new TimeSpan(0, MUTEX_TIMEOUT, 0); + LogBranchMessage(branch.BranchName, $"Could not lock cache, waiting for cache to unlock - timeout set to {timeout}."); + createdNew = mutex.WaitOne(timeout); + } // check if the mutex was established if (createdNew) { + LogBranchMessage(branch.BranchName, "Cache lock established.\r\n"); + // update the server cache for the branch UpdateServerCache(branch.BranchName, branch.BranchPassword); @@ -3036,7 +3107,7 @@ namespace ServerManagerTool.Lib else { ExitCode = EXITCODE_PROCESSALREADYRUNNING; - LogMessage($"[{GetBranchName(branch.BranchName)}] Cancelled branch update process, could not lock branch folder."); + LogMessage($"[{GetBranchName(branch.BranchName)}] Cancelled branch update process, could not lock cache."); } } catch (Exception ex) diff --git a/src/ConanServerManager/Lib/ServerStatusWatcher.cs b/src/ConanServerManager/Lib/ServerStatusWatcher.cs index cb1894a3..e97de630 100644 --- a/src/ConanServerManager/Lib/ServerStatusWatcher.cs +++ b/src/ConanServerManager/Lib/ServerStatusWatcher.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Net; using System.Net.Sockets; using System.Threading.Tasks; @@ -307,15 +308,16 @@ namespace ServerManagerTool.Lib { serverInfo = null; } - } - try - { - onlinePlayerCount = serverInfo?.Players ?? 0; - } - catch (Exception) - { - onlinePlayerCount = 0; + try + { + var playerInfo = server?.GetPlayers()?.Where(p => !string.IsNullOrWhiteSpace(p.Name?.Trim())); + onlinePlayerCount = playerInfo?.Count() ?? 0; + } + catch (Exception) + { + onlinePlayerCount = 0; + } } } catch (SocketException ex) diff --git a/src/ConanServerManager/UserControls/ServerSettingsControl.xaml.cs b/src/ConanServerManager/UserControls/ServerSettingsControl.xaml.cs index 428f2dea..f3b368b8 100644 --- a/src/ConanServerManager/UserControls/ServerSettingsControl.xaml.cs +++ b/src/ConanServerManager/UserControls/ServerSettingsControl.xaml.cs @@ -572,10 +572,10 @@ namespace ServerManagerTool var profileFile = ServerProfile.LoadFromProfileFile(file, null); if (profileFile != null) { - profileFile.AdminPassword = "obfuscated"; - profileFile.ServerPassword = "obfuscated"; - profileFile.RconPassword = "obfuscated"; - profileFile.BranchPassword = "obfuscated"; + profileFile.AdminPassword = string.IsNullOrWhiteSpace(profileFile.AdminPassword) ? "empty" : "obfuscated"; + profileFile.ServerPassword = string.IsNullOrWhiteSpace(profileFile.ServerPassword) ? "empty" : "obfuscated"; + profileFile.RconPassword = string.IsNullOrWhiteSpace(profileFile.RconPassword) ? "empty" : "obfuscated"; + profileFile.BranchPassword = string.IsNullOrWhiteSpace(profileFile.BranchPassword) ? "empty" : "obfuscated"; obfuscateFiles.Add(file, profileFile.ToOutputString()); } } @@ -634,74 +634,92 @@ namespace ServerManagerTool comment.AppendLine($"Server Manager Version: {App.Instance.Version}"); comment.AppendLine($"Server Manager Code: {Config.Default.ServerManagerCode}"); comment.AppendLine($"Server Manager Key: {Config.Default.ServerManagerUniqueKey}"); - comment.AppendLine($"Server Manager Directory: {Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)}"); + comment.AppendLine($"Server Manager Directory: {Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}"); comment.AppendLine($"MachinePublicIP: {Config.Default.MachinePublicIP}"); comment.AppendLine($"Data Directory: {Config.Default.DataPath}"); comment.AppendLine($"Profiles Directory: {Config.Default.ConfigPath}"); - if (!string.IsNullOrWhiteSpace(Config.Default.BackupPath)) - comment.AppendLine($"Backup Directory: {Config.Default.BackupPath}"); - else - comment.AppendLine($"Backup Directory: *{Path.Combine(Config.Default.DataPath, Config.Default.BackupRelativePath)}"); comment.AppendLine($"Server Directory: {this.Settings.InstallDirectory}"); comment.AppendLine($"IsAdministrator: {SecurityUtils.IsAdministrator()}"); comment.AppendLine($"RunAsAdministratorPrompt: {Config.Default.RunAsAdministratorPrompt}"); + comment.AppendLine($"CheckIfServerManagerRunningOnStartup: {Config.Default.CheckIfServerManagerRunningOnStartup}"); + comment.AppendLine($"ManageFirewallAutomatically: {Config.Default.ManageFirewallAutomatically}"); + comment.AppendLine($"ManagePublicIPAutomatically: {Config.Default.ManagePublicIPAutomatically}"); comment.AppendLine($"MainWindow_WindowState: {Config.Default.MainWindow_WindowState}"); comment.AppendLine($"MainWindow_MinimizeToTray: {Config.Default.MainWindow_MinimizeToTray}"); - comment.AppendLine($"ManageFirewallAutomatically: {Config.Default.ManageFirewallAutomatically}"); - comment.AppendLine($"ValidateProfileOnServerStart: {Config.Default.ValidateProfileOnServerStart}"); + comment.AppendLine($"ServerMonitorWindow_WindowState: {Config.Default.ServerMonitorWindow_WindowState}"); + comment.AppendLine($"SteamCMD File: {SteamCmdUpdater.GetSteamCmdFile(Config.Default.DataPath)}"); - comment.AppendLine($"SteamCmdRedirectOutput: {Config.Default.SteamCmdRedirectOutput}"); comment.AppendLine($"SteamCmd_UseAnonymousCredentials: {Config.Default.SteamCmd_UseAnonymousCredentials}"); comment.AppendLine($"SteamCmd_Username Set: {!string.IsNullOrWhiteSpace(Config.Default.SteamCmd_Username)}"); comment.AppendLine($"SteamCmd_Password Set: {!string.IsNullOrWhiteSpace(Config.Default.SteamCmd_Password)}"); comment.AppendLine($"SteamAPIKey: {!string.IsNullOrWhiteSpace(CommonConfig.Default.SteamAPIKey)}"); - comment.AppendLine($"AutoBackup_EnableBackup: {Config.Default.AutoBackup_EnableBackup}"); - comment.AppendLine($"AutoBackup_BackupPeriod: {Config.Default.AutoBackup_BackupPeriod}"); + comment.AppendLine($"ServerStatus_EnableActions: {Config.Default.ServerStatus_EnableActions}"); + comment.AppendLine($"ServerStatus_ShowActionConfirmation: {Config.Default.ServerStatus_ShowActionConfirmation}"); + + comment.AppendLine($"ValidateProfileOnServerStart: {Config.Default.ValidateProfileOnServerStart}"); + comment.AppendLine($"ServerUpdate_OnServerStart: {Config.Default.ServerUpdate_OnServerStart}"); + comment.AppendLine($"ServerStartMinimized: {Config.Default.ServerStartMinimized}"); + + comment.AppendLine($"ServerUpdate_UpdateModsWhenUpdatingServer: {Config.Default.ServerUpdate_UpdateModsWhenUpdatingServer}"); + comment.AppendLine($"ServerUpdate_ForceUpdateMods: {Config.Default.ServerUpdate_ForceUpdateMods}"); + comment.AppendLine($"ServerUpdate_ForceCopyMods: {Config.Default.ServerUpdate_ForceCopyMods}"); + comment.AppendLine($"ServerUpdate_ForceUpdateModsIfNoSteamInfo: {Config.Default.ServerUpdate_ForceUpdateModsIfNoSteamInfo}"); + comment.AppendLine($"WorkshopCache_ExpiredHours: {Config.Default.WorkshopCache_ExpiredHours}"); + + if (!string.IsNullOrWhiteSpace(Config.Default.BackupPath)) + comment.AppendLine($"Backup Directory: {Config.Default.BackupPath}"); + else + comment.AppendLine($"Backup Directory: *{Path.Combine(Config.Default.DataPath, Config.Default.BackupRelativePath)}"); + comment.AppendLine($"AutoBackup_IncludeSaveGamesFolder: {Config.Default.AutoBackup_IncludeSaveGamesFolder}"); comment.AppendLine($"AutoBackup_DeleteOldFiles: {Config.Default.AutoBackup_DeleteOldFiles}"); comment.AppendLine($"AutoBackup_DeleteInterval: {Config.Default.AutoBackup_DeleteInterval}"); + comment.AppendLine($"RCON_BackupMessageCommand: {Config.Default.RCON_BackupMessageCommand}"); + comment.AppendLine($"ServerBackup_WorldSaveMessage: {Config.Default.ServerBackup_WorldSaveMessage}"); + + comment.AppendLine($"AutoBackup_EnableBackup: {Config.Default.AutoBackup_EnableBackup}"); + comment.AppendLine($"AutoBackup_BackupPeriod: {Config.Default.AutoBackup_BackupPeriod}"); comment.AppendLine($"AutoUpdate_EnableUpdate: {Config.Default.AutoUpdate_EnableUpdate}"); comment.AppendLine($"AutoUpdate_CacheDir: {Config.Default.AutoUpdate_CacheDir}"); comment.AppendLine($"AutoUpdate_UpdatePeriod: {Config.Default.AutoUpdate_UpdatePeriod}"); comment.AppendLine($"AutoUpdate_UseSmartCopy: {Config.Default.AutoUpdate_UseSmartCopy}"); - comment.AppendLine($"AutoUpdate_RetryOnFail: {Config.Default.AutoUpdate_RetryOnFail}"); - comment.AppendLine($"AutoUpdate_ShowUpdateReason: {Config.Default.AutoUpdate_ShowUpdateReason}"); comment.AppendLine($"AutoUpdate_ValidateServerFiles: {Config.Default.AutoUpdate_ValidateServerFiles}"); + comment.AppendLine($"AutoUpdate_RetryOnFail: {Config.Default.AutoUpdate_RetryOnFail}"); + comment.AppendLine($"AutoUpdate_ParallelUpdate: {Config.Default.AutoUpdate_ParallelUpdate}"); + comment.AppendLine($"AutoUpdate_SequencialDelayPeriod: {Config.Default.AutoUpdate_SequencialDelayPeriod}"); + comment.AppendLine($"AutoUpdate_ShowUpdateReason: {Config.Default.AutoUpdate_ShowUpdateReason}"); + comment.AppendLine($"AutoUpdate_ShowUpdateReason: {Config.Default.AutoUpdate_UpdateReasonPrefix}"); comment.AppendLine($"AutoUpdate_OverrideServerStartup: {Config.Default.AutoUpdate_OverrideServerStartup}"); comment.AppendLine($"AutoRestart_EnabledGracePeriod: {Config.Default.AutoRestart_EnabledGracePeriod}"); comment.AppendLine($"AutoRestart_GracePeriod: {Config.Default.AutoRestart_GracePeriod}"); - comment.AppendLine($"ServerShutdown_EnableWorldSave: {Config.Default.ServerShutdown_EnableWorldSave}"); comment.AppendLine($"ServerShutdown_CheckForOnlinePlayers: {Config.Default.ServerShutdown_CheckForOnlinePlayers}"); comment.AppendLine($"ServerShutdown_SendShutdownMessages: {Config.Default.ServerShutdown_SendShutdownMessages}"); comment.AppendLine($"ServerShutdown_GracePeriod: {Config.Default.ServerShutdown_GracePeriod}"); - comment.AppendLine($"ServerUpdate_UpdateModsWhenUpdatingServer: {Config.Default.ServerUpdate_UpdateModsWhenUpdatingServer}"); - comment.AppendLine($"ServerUpdate_ForceCopyMods: {Config.Default.ServerUpdate_ForceCopyMods}"); - comment.AppendLine($"ServerUpdate_ForceUpdateMods: {Config.Default.ServerUpdate_ForceUpdateMods}"); - comment.AppendLine($"ServerUpdate_ForceUpdateModsIfNoSteamInfo: {Config.Default.ServerUpdate_ForceUpdateModsIfNoSteamInfo}"); - comment.AppendLine($"ServerUpdate_OnServerStart: {Config.Default.ServerUpdate_OnServerStart}"); + comment.AppendLine($"ServerShutdown_AllMessagesShowReason: {Config.Default.ServerShutdown_AllMessagesShowReason}"); comment.AppendLine($"DiscordBotEnabled: {Config.Default.DiscordBotEnabled}"); comment.AppendLine($"HasDiscordBotToken: {!string.IsNullOrWhiteSpace(Config.Default.DiscordBotToken)}"); comment.AppendLine($"DiscordBotServerId: {Config.Default.DiscordBotServerId}"); comment.AppendLine($"DiscordBotPrefix: {Config.Default.DiscordBotPrefix}"); comment.AppendLine($"DiscordBotLogLevel: {Config.Default.DiscordBotLogLevel}"); - comment.AppendLine($"DiscordBotAllowAllBots: {Config.Default.DiscordBotAllowAllBots}"); - comment.AppendLine($"DiscordBotWhitelist: {string.Join(";", Config.Default.DiscordBotWhitelist)}"); + comment.AppendLine($"DiscordBotAllServersKeyword: {Config.Default.DiscordBotAllServersKeyword}"); comment.AppendLine($"AllowDiscordBackup: {Config.Default.AllowDiscordBackup}"); comment.AppendLine($"AllowDiscordRestart: {Config.Default.AllowDiscordRestart}"); comment.AppendLine($"AllowDiscordShutdown: {Config.Default.AllowDiscordShutdown}"); comment.AppendLine($"AllowDiscordStart: {Config.Default.AllowDiscordStart}"); comment.AppendLine($"AllowDiscordStop: {Config.Default.AllowDiscordStop}"); comment.AppendLine($"AllowDiscordUpdate: {Config.Default.AllowDiscordUpdate}"); + comment.AppendLine($"DiscordBotAllowAllBots: {Config.Default.DiscordBotAllowAllBots}"); + comment.AppendLine($"DiscordBotWhitelist: {string.Join(";", Config.Default.DiscordBotWhitelist)}"); - comment.AppendLine($"EmailNotify_AutoRestart: {Config.Default.EmailNotify_AutoRestart}"); comment.AppendLine($"EmailNotify_AutoBackup: {Config.Default.EmailNotify_AutoBackup}"); comment.AppendLine($"EmailNotify_AutoUpdate: {Config.Default.EmailNotify_AutoUpdate}"); + comment.AppendLine($"EmailNotify_AutoRestart: {Config.Default.EmailNotify_AutoRestart}"); comment.AppendLine($"EmailNotify_ShutdownRestart: {Config.Default.EmailNotify_ShutdownRestart}"); comment.AppendLine($"ServerShutdown_UseShutdownCommand: {Config.Default.ServerShutdown_UseShutdownCommand}"); @@ -710,10 +728,12 @@ namespace ServerManagerTool comment.AppendLine($"AutoUpdate_VerifyServerAfterUpdate: {Config.Default.AutoUpdate_VerifyServerAfterUpdate}"); comment.AppendLine($"SteamCmdRemoveQuit: {CommonConfig.Default.SteamCmdRemoveQuit}"); comment.AppendLine($"UpdateDirectoryPermissions: {Config.Default.UpdateDirectoryPermissions}"); + comment.AppendLine($"SteamCmdRedirectOutput: {Config.Default.SteamCmdRedirectOutput}"); comment.AppendLine($"LoggingEnabled: {Config.Default.LoggingEnabled}"); comment.AppendLine($"LoggingMaxArchiveDays: {Config.Default.LoggingMaxArchiveDays}"); comment.AppendLine($"LoggingMaxArchiveFiles: {Config.Default.LoggingMaxArchiveFiles}"); comment.AppendLine($"ServerShutdown_WorldSaveDelay: {Config.Default.ServerShutdown_WorldSaveDelay}"); + comment.AppendLine($"RCON_MessageCommand: {Config.Default.RCON_MessageCommand}"); var zipFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), this.Settings.ProfileID + ".zip"); if (File.Exists(zipFile)) File.Delete(zipFile); diff --git a/src/ConanServerManager/VersionFeed.xml b/src/ConanServerManager/VersionFeed.xml index 8a78ab28..aa2bf20c 100644 --- a/src/ConanServerManager/VersionFeed.xml +++ b/src/ConanServerManager/VersionFeed.xml @@ -5,7 +5,30 @@ Conan Server Manager Version Feed This is the Conan Server Manager release version feed. - 2022-05-09T00:00:00Z + 2022-05-15T00:00:00Z + + + urn:uuid:E367ACB5-E38A-4B3A-A089-E43D011A97E4 + 1.1.72 (1.1.72.1) + 1.1.72.1 + + 2022-05-15T00:00:00Z + +
+

+ BUGFIX +
+

    +
  • Server Shutdown/Restart - have rewritten the code that sends the RCON commands to prevent the hangs after the RCON command fails.
  • +
+

+
+
+ + bletch + bletch1971@hotmail.com + +
urn:uuid:CE3805D7-1CC8-4DF6-8015-8E2B9B87C1FF diff --git a/src/ConanServerManager/VersionFeedBeta.xml b/src/ConanServerManager/VersionFeedBeta.xml index d2d18cd5..733c8a20 100644 --- a/src/ConanServerManager/VersionFeedBeta.xml +++ b/src/ConanServerManager/VersionFeedBeta.xml @@ -5,21 +5,21 @@ Conan Server Manager Version Feed This is the Conan Server Manager beta version feed. - 2022-05-09T00:00:00Z + 2022-05-15T00:00:00Z - urn:uuid:CE3805D7-1CC8-4DF6-8015-8E2B9B87C1FF - 1.1.71 (1.1.71.1) - 1.1.71.1 + urn:uuid:E367ACB5-E38A-4B3A-A089-E43D011A97E4 + 1.1.72 (1.1.72.1) + 1.1.72.1 - 2022-05-09T00:00:00Z + 2022-05-15T00:00:00Z

BUGFIX

    -
  • World Save Backups - have fixed the timestamps associated with the files inside the zip file.
  • +
  • Server Shutdown/Restart - have rewritten the code that sends the RCON commands to prevent the hangs after the RCON command fails.