mirror of
https://github.com/tribufu/ServerManagers
synced 2026-06-01 09:42:39 +00:00
Finished the remaing bot commands
This commit is contained in:
parent
0f3c6e6be9
commit
aa62646f0f
23 changed files with 1041 additions and 287 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
|
@ -5555,11 +5555,15 @@
|
||||||
|
|
||||||
<sys:String x:Key="DiscordBot_ProfileMissing">The '{0}' command requires a profile id.</sys:String>
|
<sys:String x:Key="DiscordBot_ProfileMissing">The '{0}' command requires a profile id.</sys:String>
|
||||||
<sys:String x:Key="DiscordBot_ProfileNotFound">Profile '{0}' was not found or is not associated with the channel.</sys:String>
|
<sys:String x:Key="DiscordBot_ProfileNotFound">Profile '{0}' was not found or is not associated with the channel.</sys:String>
|
||||||
<sys:String x:Key="DiscordBot_ProfileBadStatus">Profile '{0}' must be '{1}' to perform the command.</sys:String>
|
<sys:String x:Key="DiscordBot_ProfileBadStatus">Profile '{0}' is in a state '{1}' that cannot run this command.</sys:String>
|
||||||
<sys:String x:Key="DiscordBot_ProfileUpdating">Profile '{0}' is currently being updated.</sys:String>
|
<sys:String x:Key="DiscordBot_ProfileUpdating">Profile '{0}' is currently being updated.</sys:String>
|
||||||
|
|
||||||
<sys:String x:Key="DiscordBot_InfoFailed">Call to server '{0}' failed.</sys:String>
|
<sys:String x:Key="DiscordBot_InfoFailed">Call to server '{0}' failed.</sys:String>
|
||||||
<sys:String x:Key="DiscordBot_BackupRequested">A backup request for server '{0}' has been sent.</sys:String>
|
<sys:String x:Key="DiscordBot_BackupRequested">A backup request for server '{0}' has been sent.</sys:String>
|
||||||
|
<sys:String x:Key="DiscordBot_RestartRequested">A restart request for server '{0}' has been sent.</sys:String>
|
||||||
|
<sys:String x:Key="DiscordBot_ShutdownRequested">A shutdown request for server '{0}' has been sent.</sys:String>
|
||||||
|
<sys:String x:Key="DiscordBot_StartRequested">A start request for server '{0}' has been sent.</sys:String>
|
||||||
|
<sys:String x:Key="DiscordBot_StopRequested">A stop request for server '{0}' has been sent.</sys:String>
|
||||||
<sys:String x:Key="DiscordBot_UpdateRequested">An update request for server '{0}' has been sent.</sys:String>
|
<sys:String x:Key="DiscordBot_UpdateRequested">An update request for server '{0}' has been sent.</sys:String>
|
||||||
|
|
||||||
<sys:String x:Key="DiscordBot_CountLabel">Count:</sys:String>
|
<sys:String x:Key="DiscordBot_CountLabel">Count:</sys:String>
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ namespace ServerManagerTool.Lib
|
||||||
_startTime = DateTime.Now;
|
_startTime = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BackupServer()
|
private void BackupServer(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (_profile == null || _profile.SotFEnabled)
|
if (_profile == null || _profile.SotFEnabled)
|
||||||
{
|
{
|
||||||
|
|
@ -142,65 +142,65 @@ namespace ServerManagerTool.Lib
|
||||||
|
|
||||||
if (_serverRunning)
|
if (_serverRunning)
|
||||||
{
|
{
|
||||||
// check if RCON is enabled
|
try
|
||||||
if (_profile.RCONEnabled)
|
|
||||||
{
|
{
|
||||||
try
|
emailMessage.AppendLine();
|
||||||
|
|
||||||
|
var sent = false;
|
||||||
|
|
||||||
|
// perform a world save
|
||||||
|
if (!string.IsNullOrWhiteSpace(Config.Default.ServerBackup_WorldSaveMessage))
|
||||||
{
|
{
|
||||||
try
|
ProcessAlert(AlertType.Backup, Config.Default.ServerBackup_WorldSaveMessage);
|
||||||
|
sent = SendMessageAsync(Config.Default.ServerBackup_WorldSaveMessage, cancellationToken).Result;
|
||||||
|
if (sent)
|
||||||
{
|
{
|
||||||
emailMessage.AppendLine();
|
emailMessage.AppendLine("sent server save message.");
|
||||||
|
|
||||||
var sent = false;
|
|
||||||
|
|
||||||
// perform a world save
|
|
||||||
if (!string.IsNullOrWhiteSpace(Config.Default.ServerBackup_WorldSaveMessage))
|
|
||||||
{
|
|
||||||
ProcessAlert(AlertType.Backup, Config.Default.ServerBackup_WorldSaveMessage);
|
|
||||||
sent = SendMessageAsync(Config.Default.ServerBackup_WorldSaveMessage, CancellationToken.None).Result;
|
|
||||||
if (sent)
|
|
||||||
{
|
|
||||||
emailMessage.AppendLine("sent server save message.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sent = SendCommandAsync(Config.Default.ServerSaveCommand, false).Result;
|
|
||||||
if (sent)
|
|
||||||
{
|
|
||||||
emailMessage.AppendLine("sent server save command.");
|
|
||||||
Task.Delay(Config.Default.ServerShutdown_WorldSaveDelay * 1000).Wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.WriteLine($"RCON> {Config.Default.ServerSaveCommand} command.\r\n{ex.Message}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
|
sent = SendCommandAsync(Config.Default.ServerSaveCommand, false).Result;
|
||||||
|
if (sent)
|
||||||
{
|
{
|
||||||
CloseRconConsole();
|
emailMessage.AppendLine("sent server save command.");
|
||||||
|
Task.Delay(Config.Default.ServerShutdown_WorldSaveDelay * 1000).Wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogProfileMessage("RCON not enabled.");
|
Debug.WriteLine($"RCON> {Config.Default.ServerSaveCommand} command.\r\n{ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExitCode != EXITCODE_NORMALEXIT)
|
if (ExitCode != EXITCODE_NORMALEXIT)
|
||||||
return;
|
return;
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
ExitCode = EXITCODE_CANCELLED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// make a backup of the current profile and config files.
|
// make a backup of the current profile and config files.
|
||||||
CreateProfileBackupArchiveFile(_profile);
|
CreateProfileBackupArchiveFile(_profile);
|
||||||
|
|
||||||
if (ExitCode != EXITCODE_NORMALEXIT)
|
if (ExitCode != EXITCODE_NORMALEXIT)
|
||||||
return;
|
return;
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
ExitCode = EXITCODE_CANCELLED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// make a backup of the current world file.
|
// make a backup of the current world file.
|
||||||
CreateServerBackupArchiveFile(emailMessage, _profile);
|
CreateServerBackupArchiveFile(emailMessage, _profile);
|
||||||
|
|
||||||
if (ExitCode != EXITCODE_NORMALEXIT)
|
if (ExitCode != EXITCODE_NORMALEXIT)
|
||||||
return;
|
return;
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
ExitCode = EXITCODE_CANCELLED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Config.Default.EmailNotify_AutoBackup)
|
if (Config.Default.EmailNotify_AutoBackup)
|
||||||
{
|
{
|
||||||
|
|
@ -269,7 +269,7 @@ namespace ServerManagerTool.Lib
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ServerStatusChangeCallback?.Invoke(ServerStatus.Updating);
|
ServerStatusChangeCallback?.Invoke(ServerStatus.Updating);
|
||||||
UpgradeLocal(true, cancellationToken, true);
|
UpgradeLocal(true, true, cancellationToken);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
@ -310,17 +310,20 @@ namespace ServerManagerTool.Lib
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the server was previously running before the update.
|
// check if the server was previously running.
|
||||||
if (!_serverRunning && !_profile.AutoRestartIfShutdown)
|
if (!_serverRunning)
|
||||||
{
|
{
|
||||||
LogProfileMessage("Server was not running, server will not be started.");
|
if (_profile.AutoRestartIfShutdown)
|
||||||
|
{
|
||||||
|
LogProfileMessage("Server was not running, server will be started as the setting to restart if shutdown is TRUE.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogProfileMessage("Server was not running, server will not be started.");
|
||||||
|
|
||||||
ExitCode = EXITCODE_NORMALEXIT;
|
ExitCode = EXITCODE_NORMALEXIT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!_serverRunning && _profile.AutoRestartIfShutdown)
|
|
||||||
{
|
|
||||||
LogProfileMessage("Server was not running, server will be started as the setting to restart if shutdown is TRUE.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the server process.
|
// Find the server process.
|
||||||
|
|
@ -404,7 +407,7 @@ namespace ServerManagerTool.Lib
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// create a connection to the server
|
// create a connection to the server
|
||||||
var endPoint = new IPEndPoint(IPAddress.Parse(_profile.ServerIP), _profile.QueryPort);
|
var endPoint = new IPEndPoint(_profile.ServerIPAddress, _profile.QueryPort);
|
||||||
gameServer = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint);
|
gameServer = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint);
|
||||||
|
|
||||||
// check if there is a shutdown reason
|
// check if there is a shutdown reason
|
||||||
|
|
@ -417,10 +420,6 @@ namespace ServerManagerTool.Lib
|
||||||
}
|
}
|
||||||
|
|
||||||
LogProfileMessage("Starting shutdown timer...");
|
LogProfileMessage("Starting shutdown timer...");
|
||||||
if (!CheckForOnlinePlayers)
|
|
||||||
{
|
|
||||||
LogProfileMessage("CheckForOnlinePlayers disabled, shutdown timer will not perform online player check.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var minutesLeft = ShutdownInterval;
|
var minutesLeft = ShutdownInterval;
|
||||||
while (minutesLeft > 0)
|
while (minutesLeft > 0)
|
||||||
|
|
@ -432,7 +431,7 @@ namespace ServerManagerTool.Lib
|
||||||
if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage))
|
if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage))
|
||||||
{
|
{
|
||||||
ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage);
|
ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage);
|
||||||
SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, CancellationToken.None).Wait();
|
SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, cancellationToken).Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
ExitCode = EXITCODE_CANCELLED;
|
ExitCode = EXITCODE_CANCELLED;
|
||||||
|
|
@ -462,7 +461,8 @@ namespace ServerManagerTool.Lib
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"CheckForOnlinePlayers disabled");
|
Debug.WriteLine($"CheckForOnlinePlayers disabled, shutdown timer cancelled.");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var message = string.Empty;
|
var message = string.Empty;
|
||||||
|
|
@ -536,7 +536,7 @@ namespace ServerManagerTool.Lib
|
||||||
{
|
{
|
||||||
LogProfileMessage(Config.Default.ServerShutdown_WorldSaveMessage);
|
LogProfileMessage(Config.Default.ServerShutdown_WorldSaveMessage);
|
||||||
ProcessAlert(AlertType.ShutdownMessage, Config.Default.ServerShutdown_WorldSaveMessage);
|
ProcessAlert(AlertType.ShutdownMessage, Config.Default.ServerShutdown_WorldSaveMessage);
|
||||||
SendMessageAsync(Config.Default.ServerShutdown_WorldSaveMessage, cancellationToken).Wait();
|
SendMessageAsync(Config.Default.ServerShutdown_WorldSaveMessage, cancellationToken).Wait(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SendCommandAsync(Config.Default.ServerSaveCommand, false).Result)
|
if (SendCommandAsync(Config.Default.ServerSaveCommand, false).Result)
|
||||||
|
|
@ -561,7 +561,7 @@ namespace ServerManagerTool.Lib
|
||||||
if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage))
|
if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage))
|
||||||
{
|
{
|
||||||
ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage);
|
ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage);
|
||||||
SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, CancellationToken.None).Wait();
|
SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, cancellationToken).Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
ExitCode = EXITCODE_CANCELLED;
|
ExitCode = EXITCODE_CANCELLED;
|
||||||
|
|
@ -587,8 +587,6 @@ namespace ServerManagerTool.Lib
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
CloseRconConsole();
|
|
||||||
|
|
||||||
gameServer?.Dispose();
|
gameServer?.Dispose();
|
||||||
gameServer = null;
|
gameServer = null;
|
||||||
}
|
}
|
||||||
|
|
@ -600,11 +598,9 @@ namespace ServerManagerTool.Lib
|
||||||
if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage))
|
if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage))
|
||||||
{
|
{
|
||||||
ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage);
|
ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage);
|
||||||
SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, CancellationToken.None).Wait();
|
SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, cancellationToken).Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseRconConsole();
|
|
||||||
|
|
||||||
ExitCode = EXITCODE_CANCELLED;
|
ExitCode = EXITCODE_CANCELLED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -653,8 +649,6 @@ namespace ServerManagerTool.Lib
|
||||||
LogProfileMessage("Exiting server timed out, attempting to close the server.");
|
LogProfileMessage("Exiting server timed out, attempting to close the server.");
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseRconConsole();
|
|
||||||
|
|
||||||
// Method 2 - Close the process
|
// Method 2 - Close the process
|
||||||
sent = process.CloseMainWindow();
|
sent = process.CloseMainWindow();
|
||||||
|
|
||||||
|
|
@ -721,7 +715,7 @@ namespace ServerManagerTool.Lib
|
||||||
ExitCode = EXITCODE_SHUTDOWN_TIMEOUT;
|
ExitCode = EXITCODE_SHUTDOWN_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpgradeLocal(bool validate, CancellationToken cancellationToken, bool updateMods)
|
private void UpgradeLocal(bool validate, bool updateMods, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (_profile == null)
|
if (_profile == null)
|
||||||
{
|
{
|
||||||
|
|
@ -1250,7 +1244,7 @@ namespace ServerManagerTool.Lib
|
||||||
{
|
{
|
||||||
// perform a steamcmd validate to confirm all the files
|
// perform a steamcmd validate to confirm all the files
|
||||||
LogProfileMessage("Validating server files (*new*).");
|
LogProfileMessage("Validating server files (*new*).");
|
||||||
UpgradeLocal(true, CancellationToken.None, false);
|
UpgradeLocal(true, false, CancellationToken.None);
|
||||||
LogProfileMessage("Validated server files (*new*).");
|
LogProfileMessage("Validated server files (*new*).");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1776,17 +1770,6 @@ namespace ServerManagerTool.Lib
|
||||||
ExitCode = EXITCODE_NORMALEXIT;
|
ExitCode = EXITCODE_NORMALEXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseRconConsole()
|
|
||||||
{
|
|
||||||
if (_rconConsole != null)
|
|
||||||
{
|
|
||||||
_rconConsole.Dispose();
|
|
||||||
_rconConsole = null;
|
|
||||||
|
|
||||||
Task.Delay(1000).Wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CheckServerWorldFileExists(ServerProfileSnapshot profile = null)
|
public void CheckServerWorldFileExists(ServerProfileSnapshot profile = null)
|
||||||
{
|
{
|
||||||
// do nothing if profile is null or SotF
|
// do nothing if profile is null or SotF
|
||||||
|
|
@ -2578,39 +2561,42 @@ namespace ServerManagerTool.Lib
|
||||||
int rconRetries = 0;
|
int rconRetries = 0;
|
||||||
int maxRetries = retryIfFailed ? RCON_MAXRETRIES : 1;
|
int maxRetries = retryIfFailed ? RCON_MAXRETRIES : 1;
|
||||||
|
|
||||||
while (retries < maxRetries && rconRetries < RCON_MAXRETRIES)
|
try
|
||||||
{
|
{
|
||||||
SetupRconConsole();
|
while (retries < maxRetries && rconRetries < RCON_MAXRETRIES)
|
||||||
|
|
||||||
if (_rconConsole == null)
|
|
||||||
{
|
{
|
||||||
LogProfileMessage($"RCON> {command} - attempt {rconRetries + 1} (a).", false);
|
SetupRconConsole();
|
||||||
#if DEBUG
|
|
||||||
LogProfileMessage("RCON connection not created.", false);
|
|
||||||
#endif
|
|
||||||
rconRetries++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rconRetries = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_rconConsole.SendCommand(command);
|
|
||||||
LogProfileMessage($"RCON> {command}");
|
|
||||||
|
|
||||||
return true;
|
if (_rconConsole == null)
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
{
|
||||||
LogProfileMessage($"RCON> {command} - attempt {retries + 1} (b).", false);
|
LogProfileMessage($"RCON> {command} - attempt {rconRetries + 1} (a).", false);
|
||||||
#if DEBUG
|
LogProfileMessage("RCON connection not created.", false);
|
||||||
LogProfileMessage($"{ex.Message}", false);
|
rconRetries++;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rconRetries = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_rconConsole.SendCommand(command);
|
||||||
|
LogProfileMessage($"RCON> {command}");
|
||||||
|
|
||||||
retries++;
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogProfileMessage($"RCON> {command} - attempt {retries + 1} (b).", false);
|
||||||
|
LogProfileMessage($"{ex.Message}", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
retries++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
CloseRconConsole();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2672,6 +2658,17 @@ namespace ServerManagerTool.Lib
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CloseRconConsole()
|
||||||
|
{
|
||||||
|
if (_rconConsole != null)
|
||||||
|
{
|
||||||
|
_rconConsole.Dispose();
|
||||||
|
_rconConsole = null;
|
||||||
|
|
||||||
|
Task.Delay(1000).Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void SetupRconConsole()
|
private void SetupRconConsole()
|
||||||
{
|
{
|
||||||
CloseRconConsole();
|
CloseRconConsole();
|
||||||
|
|
@ -2681,7 +2678,7 @@ namespace ServerManagerTool.Lib
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var endPoint = new IPEndPoint(IPAddress.Parse(_profile.ServerIP), _profile.RCONPort);
|
var endPoint = new IPEndPoint(_profile.ServerIPAddress, _profile.RCONPort);
|
||||||
var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000);
|
var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000);
|
||||||
if (server == null)
|
if (server == null)
|
||||||
{
|
{
|
||||||
|
|
@ -2718,7 +2715,7 @@ namespace ServerManagerTool.Lib
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int PerformProfileBackup(ServerProfileSnapshot profile)
|
public int PerformProfileBackup(ServerProfileSnapshot profile, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_profile = profile;
|
_profile = profile;
|
||||||
|
|
||||||
|
|
@ -2743,7 +2740,7 @@ namespace ServerManagerTool.Lib
|
||||||
// check if the mutex was established
|
// check if the mutex was established
|
||||||
if (createdNew)
|
if (createdNew)
|
||||||
{
|
{
|
||||||
BackupServer();
|
BackupServer(cancellationToken);
|
||||||
|
|
||||||
if (ExitCode != EXITCODE_NORMALEXIT)
|
if (ExitCode != EXITCODE_NORMALEXIT)
|
||||||
{
|
{
|
||||||
|
|
@ -3099,7 +3096,7 @@ namespace ServerManagerTool.Lib
|
||||||
SendEmails = true,
|
SendEmails = true,
|
||||||
ServerProcess = ServerProcessType.AutoBackup
|
ServerProcess = ServerProcessType.AutoBackup
|
||||||
};
|
};
|
||||||
exitCodes.TryAdd(profile, app.PerformProfileBackup(profile));
|
exitCodes.TryAdd(profile, app.PerformProfileBackup(profile, CancellationToken.None));
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (var profile in _profiles.Keys)
|
foreach (var profile in _profiles.Keys)
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace ServerManagerTool.Lib
|
||||||
public string AdminPassword;
|
public string AdminPassword;
|
||||||
public string ServerName;
|
public string ServerName;
|
||||||
public string ServerArgs;
|
public string ServerArgs;
|
||||||
public string ServerIP;
|
public IPAddress ServerIPAddress;
|
||||||
public int ServerPort;
|
public int ServerPort;
|
||||||
public int ServerPeerPort;
|
public int ServerPeerPort;
|
||||||
public int QueryPort;
|
public int QueryPort;
|
||||||
|
|
@ -71,7 +71,7 @@ namespace ServerManagerTool.Lib
|
||||||
AdminPassword = profile.AdminPassword,
|
AdminPassword = profile.AdminPassword,
|
||||||
ServerName = profile.ServerName,
|
ServerName = profile.ServerName,
|
||||||
ServerArgs = profile.GetServerArgs(),
|
ServerArgs = profile.GetServerArgs(),
|
||||||
ServerIP = string.IsNullOrWhiteSpace(profile.ServerIP) ? IPAddress.Loopback.ToString() : profile.ServerIP.Trim(),
|
ServerIPAddress = string.IsNullOrWhiteSpace(profile.ServerIP) ? IPAddress.Loopback : IPAddress.TryParse(profile.ServerIP.Trim(), out IPAddress ipAddress) ? ipAddress : IPAddress.Loopback,
|
||||||
ServerPort = profile.ServerPort,
|
ServerPort = profile.ServerPort,
|
||||||
ServerPeerPort = profile.ServerPeerPort,
|
ServerPeerPort = profile.ServerPeerPort,
|
||||||
QueryPort = profile.QueryPort,
|
QueryPort = profile.QueryPort,
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,9 @@ namespace ServerManagerTool.Lib
|
||||||
ServerProfile.ServerIPProperty,
|
ServerProfile.ServerIPProperty,
|
||||||
ServerProfile.MaxPlayersProperty,
|
ServerProfile.MaxPlayersProperty,
|
||||||
|
|
||||||
|
ServerProfile.ServerPasswordProperty,
|
||||||
|
ServerProfile.AdminPasswordProperty,
|
||||||
|
|
||||||
ServerProfile.ServerMapProperty,
|
ServerProfile.ServerMapProperty,
|
||||||
ServerProfile.ServerModIdsProperty,
|
ServerProfile.ServerModIdsProperty,
|
||||||
ServerProfile.TotalConversionModIdProperty,
|
ServerProfile.TotalConversionModIdProperty,
|
||||||
|
|
@ -177,7 +180,7 @@ namespace ServerManagerTool.Lib
|
||||||
},
|
},
|
||||||
(s, p) =>
|
(s, p) =>
|
||||||
{
|
{
|
||||||
if (Status == ServerStatus.Stopped || Status == ServerStatus.Uninstalled || Status == ServerStatus.Unknown)
|
if (Status == ServerStatus.Stopped || Status == ServerStatus.Uninstalled || Status == ServerStatus.Unknown || Status == ServerStatus.Updating)
|
||||||
{
|
{
|
||||||
AttachToProfileCore(profile);
|
AttachToProfileCore(profile);
|
||||||
}
|
}
|
||||||
|
|
@ -198,16 +201,7 @@ namespace ServerManagerTool.Lib
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!String.IsNullOrWhiteSpace(this.ProfileSnapshot.ServerIP) && IPAddress.TryParse(this.ProfileSnapshot.ServerIP, out IPAddress localServerIpAddress))
|
localServerQueryEndPoint = new IPEndPoint(this.ProfileSnapshot.ServerIPAddress, Convert.ToUInt16(this.ProfileSnapshot.QueryPort));
|
||||||
{
|
|
||||||
// Use the explicit Server IP
|
|
||||||
localServerQueryEndPoint = new IPEndPoint(localServerIpAddress, Convert.ToUInt16(this.ProfileSnapshot.QueryPort));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// No Server IP specified, use Loopback
|
|
||||||
localServerQueryEndPoint = new IPEndPoint(IPAddress.Loopback, Convert.ToUInt16(this.ProfileSnapshot.QueryPort));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the public endpoint for querying Steam
|
// Get the public endpoint for querying Steam
|
||||||
|
|
@ -1093,7 +1087,7 @@ namespace ServerManagerTool.Lib
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var endPoint = new IPEndPoint(IPAddress.Parse(this.ProfileSnapshot.ServerIP), this.ProfileSnapshot.RCONPort);
|
var endPoint = new IPEndPoint(this.ProfileSnapshot.ServerIPAddress, this.ProfileSnapshot.RCONPort);
|
||||||
var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000);
|
var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000);
|
||||||
|
|
||||||
if (server == null)
|
if (server == null)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace ServerManagerTool.Utils
|
||||||
|
|
||||||
public static bool HasRunningCommands => _currentProfileCommands.Count > 0;
|
public static bool HasRunningCommands => _currentProfileCommands.Count > 0;
|
||||||
|
|
||||||
public static IList<string> HandleDiscordCommand(CommandType commandType, string serverId, string channelId, string profileId)
|
public static IList<string> HandleDiscordCommand(CommandType commandType, string serverId, string channelId, string profileId, CancellationToken token)
|
||||||
{
|
{
|
||||||
// check if incoming values are valid
|
// check if incoming values are valid
|
||||||
if (string.IsNullOrWhiteSpace(serverId) || string.IsNullOrWhiteSpace(channelId))
|
if (string.IsNullOrWhiteSpace(serverId) || string.IsNullOrWhiteSpace(channelId))
|
||||||
|
|
@ -49,15 +49,17 @@ namespace ServerManagerTool.Utils
|
||||||
return GetServerStatus(channelId, profileId);
|
return GetServerStatus(channelId, profileId);
|
||||||
|
|
||||||
case CommandType.Backup:
|
case CommandType.Backup:
|
||||||
return BackupServer(channelId, profileId);
|
return BackupServer(channelId, profileId, token);
|
||||||
|
case CommandType.Restart:
|
||||||
|
return RestartServer(channelId, profileId, token);
|
||||||
case CommandType.Shutdown:
|
case CommandType.Shutdown:
|
||||||
return ShutdownServer(channelId, profileId);
|
return ShutdownServer(channelId, profileId, token);
|
||||||
case CommandType.Stop:
|
case CommandType.Stop:
|
||||||
return StopServer(channelId, profileId);
|
return StopServer(channelId, profileId, token);
|
||||||
case CommandType.Start:
|
case CommandType.Start:
|
||||||
return StartServer(channelId, profileId);
|
return StartServer(channelId, profileId, token);
|
||||||
case CommandType.Update:
|
case CommandType.Update:
|
||||||
return UpdateServer(channelId, profileId);
|
return UpdateServer(channelId, profileId, token);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), commandType) };
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), commandType) };
|
||||||
|
|
@ -108,6 +110,17 @@ namespace ServerManagerTool.Utils
|
||||||
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (server.Runtime.Status)
|
||||||
|
{
|
||||||
|
case ServerStatus.Initializing:
|
||||||
|
case ServerStatus.Stopping:
|
||||||
|
case ServerStatus.Stopped:
|
||||||
|
case ServerStatus.Uninstalled:
|
||||||
|
case ServerStatus.Unknown:
|
||||||
|
case ServerStatus.Updating:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
}
|
||||||
|
|
||||||
serverName = server.Profile.ServerName;
|
serverName = server.Profile.ServerName;
|
||||||
if (!string.IsNullOrWhiteSpace(server.Profile.ServerIP))
|
if (!string.IsNullOrWhiteSpace(server.Profile.ServerIP))
|
||||||
{
|
{
|
||||||
|
|
@ -183,7 +196,7 @@ namespace ServerManagerTool.Utils
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IList<string> BackupServer(string channelId, string profileId)
|
private static IList<string> BackupServer(string channelId, string profileId, CancellationToken token)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(profileId))
|
if (string.IsNullOrWhiteSpace(profileId))
|
||||||
{
|
{
|
||||||
|
|
@ -211,6 +224,16 @@ namespace ServerManagerTool.Utils
|
||||||
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (server.Runtime.Status)
|
||||||
|
{
|
||||||
|
case ServerStatus.Initializing:
|
||||||
|
case ServerStatus.Stopping:
|
||||||
|
case ServerStatus.Uninstalled:
|
||||||
|
case ServerStatus.Unknown:
|
||||||
|
case ServerStatus.Updating:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
}
|
||||||
|
|
||||||
profile = ServerProfileSnapshot.Create(server.Profile);
|
profile = ServerProfileSnapshot.Create(server.Profile);
|
||||||
}).Wait();
|
}).Wait();
|
||||||
|
|
||||||
|
|
@ -223,11 +246,19 @@ namespace ServerManagerTool.Utils
|
||||||
SendAlerts = true,
|
SendAlerts = true,
|
||||||
SendEmails = false,
|
SendEmails = false,
|
||||||
ServerProcess = ServerProcessType.Backup,
|
ServerProcess = ServerProcessType.Backup,
|
||||||
|
ServerStatusChangeCallback = (ServerStatus serverStatus) =>
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
server.Runtime.UpdateServerStatus(serverStatus, true);
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
task = Task.Run(() =>
|
task = Task.Run(() =>
|
||||||
{
|
{
|
||||||
app.PerformProfileBackup(profile);
|
app.PerformProfileBackup(profile, token);
|
||||||
_currentProfileCommands.Remove(profileId);
|
_currentProfileCommands.Remove(profileId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -244,22 +275,337 @@ namespace ServerManagerTool.Utils
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IList<string> ShutdownServer(string channelId, string profileId)
|
private static IList<string> RestartServer(string channelId, string profileId, CancellationToken token)
|
||||||
{
|
{
|
||||||
return new List<string>() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Shutdown) };
|
if (string.IsNullOrWhiteSpace(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Restart) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if another command is being run against the profile
|
||||||
|
if (_currentProfileCommands.ContainsKey(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
|
||||||
|
}
|
||||||
|
_currentProfileCommands.Add(profileId, CommandType.Restart);
|
||||||
|
|
||||||
|
ServerProfileSnapshot profile = null;
|
||||||
|
Task task = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
|
||||||
|
if (server is null)
|
||||||
|
{
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (server.Runtime.Status)
|
||||||
|
{
|
||||||
|
case ServerStatus.Initializing:
|
||||||
|
case ServerStatus.Stopping:
|
||||||
|
case ServerStatus.Uninstalled:
|
||||||
|
case ServerStatus.Unknown:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
|
||||||
|
case ServerStatus.Updating:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
profile = ServerProfileSnapshot.Create(server.Profile);
|
||||||
|
profile.AutoRestartIfShutdown = true;
|
||||||
|
}).Wait();
|
||||||
|
|
||||||
|
List<string> response = new List<string>();
|
||||||
|
|
||||||
|
var app = new ServerApp(true)
|
||||||
|
{
|
||||||
|
DeleteOldServerBackupFiles = !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 => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
server.Runtime.UpdateServerStatus(serverStatus, true);
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
task = Task.Run(() =>
|
||||||
|
{
|
||||||
|
app.PerformProfileShutdown(profile, true, false, false, token);
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
});
|
||||||
|
|
||||||
|
response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_RestartRequested"), profile.ServerName));
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (task is null)
|
||||||
|
{
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IList<string> StopServer(string channelId, string profileId)
|
private static IList<string> ShutdownServer(string channelId, string profileId, CancellationToken token)
|
||||||
{
|
{
|
||||||
return new List<string>() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Stop) };
|
if (string.IsNullOrWhiteSpace(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Shutdown) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if another command is being run against the profile
|
||||||
|
if (_currentProfileCommands.ContainsKey(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
|
||||||
|
}
|
||||||
|
_currentProfileCommands.Add(profileId, CommandType.Shutdown);
|
||||||
|
|
||||||
|
ServerProfileSnapshot profile = null;
|
||||||
|
Task task = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
|
||||||
|
if (server is null)
|
||||||
|
{
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (server.Runtime.Status)
|
||||||
|
{
|
||||||
|
case ServerStatus.Initializing:
|
||||||
|
case ServerStatus.Stopping:
|
||||||
|
case ServerStatus.Stopped:
|
||||||
|
case ServerStatus.Uninstalled:
|
||||||
|
case ServerStatus.Unknown:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
|
||||||
|
case ServerStatus.Updating:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
profile = ServerProfileSnapshot.Create(server.Profile);
|
||||||
|
}).Wait();
|
||||||
|
|
||||||
|
List<string> response = new List<string>();
|
||||||
|
|
||||||
|
var app = new ServerApp(true)
|
||||||
|
{
|
||||||
|
DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
|
||||||
|
OutputLogs = false,
|
||||||
|
SendAlerts = true,
|
||||||
|
SendEmails = false,
|
||||||
|
ServerProcess = ServerProcessType.Shutdown,
|
||||||
|
ServerStatusChangeCallback = (ServerStatus serverStatus) =>
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
server.Runtime.UpdateServerStatus(serverStatus, true);
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
task = Task.Run(() =>
|
||||||
|
{
|
||||||
|
app.PerformProfileShutdown(profile, false, false, false, token);
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
});
|
||||||
|
|
||||||
|
response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_ShutdownRequested"), profile.ServerName));
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (task is null)
|
||||||
|
{
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IList<string> StartServer(string channelId, string profileId)
|
private static IList<string> StopServer(string channelId, string profileId, CancellationToken token)
|
||||||
{
|
{
|
||||||
return new List<string>() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Start) };
|
if (string.IsNullOrWhiteSpace(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Shutdown) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if another command is being run against the profile
|
||||||
|
if (_currentProfileCommands.ContainsKey(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
|
||||||
|
}
|
||||||
|
_currentProfileCommands.Add(profileId, CommandType.Shutdown);
|
||||||
|
|
||||||
|
ServerProfileSnapshot profile = null;
|
||||||
|
Task task = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
|
||||||
|
if (server is null)
|
||||||
|
{
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (server.Runtime.Status)
|
||||||
|
{
|
||||||
|
case ServerStatus.Initializing:
|
||||||
|
case ServerStatus.Stopping:
|
||||||
|
case ServerStatus.Stopped:
|
||||||
|
case ServerStatus.Uninstalled:
|
||||||
|
case ServerStatus.Unknown:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
|
||||||
|
case ServerStatus.Updating:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
profile = ServerProfileSnapshot.Create(server.Profile);
|
||||||
|
}).Wait();
|
||||||
|
|
||||||
|
List<string> response = new List<string>();
|
||||||
|
|
||||||
|
var app = new ServerApp(true)
|
||||||
|
{
|
||||||
|
DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
|
||||||
|
OutputLogs = false,
|
||||||
|
SendAlerts = true,
|
||||||
|
SendEmails = false,
|
||||||
|
ServerProcess = ServerProcessType.Shutdown,
|
||||||
|
ShutdownInterval = 0,
|
||||||
|
ServerStatusChangeCallback = (ServerStatus serverStatus) =>
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
server.Runtime.UpdateServerStatus(serverStatus, true);
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
task = Task.Run(() =>
|
||||||
|
{
|
||||||
|
app.PerformProfileShutdown(profile, false, false, false, token);
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
});
|
||||||
|
|
||||||
|
response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_StopRequested"), profile.ServerName));
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (task is null)
|
||||||
|
{
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IList<string> UpdateServer(string channelId, string profileId)
|
private static IList<string> StartServer(string channelId, string profileId, CancellationToken token)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Start) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if another command is being run against the profile
|
||||||
|
if (_currentProfileCommands.ContainsKey(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
|
||||||
|
}
|
||||||
|
_currentProfileCommands.Add(profileId, CommandType.Start);
|
||||||
|
|
||||||
|
ServerProfileSnapshot profile = null;
|
||||||
|
Task task = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
|
||||||
|
if (server is null)
|
||||||
|
{
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (server.Runtime.Status)
|
||||||
|
{
|
||||||
|
case ServerStatus.Initializing:
|
||||||
|
case ServerStatus.Stopping:
|
||||||
|
case ServerStatus.Running:
|
||||||
|
case ServerStatus.Uninstalled:
|
||||||
|
case ServerStatus.Unknown:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
|
||||||
|
case ServerStatus.Updating:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
profile = ServerProfileSnapshot.Create(server.Profile);
|
||||||
|
profile.AutoRestartIfShutdown = true;
|
||||||
|
}).Wait();
|
||||||
|
|
||||||
|
List<string> response = new List<string>();
|
||||||
|
|
||||||
|
var app = new ServerApp(true)
|
||||||
|
{
|
||||||
|
DeleteOldServerBackupFiles = !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 => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
server.Runtime.UpdateServerStatus(serverStatus, true);
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
task = Task.Run(() =>
|
||||||
|
{
|
||||||
|
app.PerformProfileShutdown(profile, true, false, false, token);
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
});
|
||||||
|
|
||||||
|
response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_StartRequested"), profile.ServerName));
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (task is null)
|
||||||
|
{
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IList<string> UpdateServer(string channelId, string profileId, CancellationToken token)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(profileId))
|
if (string.IsNullOrWhiteSpace(profileId))
|
||||||
{
|
{
|
||||||
|
|
@ -293,7 +639,7 @@ namespace ServerManagerTool.Utils
|
||||||
case ServerStatus.Initializing:
|
case ServerStatus.Initializing:
|
||||||
case ServerStatus.Stopping:
|
case ServerStatus.Stopping:
|
||||||
case ServerStatus.Unknown:
|
case ServerStatus.Unknown:
|
||||||
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, ServerRuntime.GetServerStatusString(ServerStatus.Stopped)));
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
|
||||||
case ServerStatus.Running:
|
case ServerStatus.Running:
|
||||||
performRestart = true;
|
performRestart = true;
|
||||||
|
|
@ -327,7 +673,7 @@ namespace ServerManagerTool.Utils
|
||||||
|
|
||||||
task = Task.Run(() =>
|
task = Task.Run(() =>
|
||||||
{
|
{
|
||||||
app.PerformProfileShutdown(profile, performRestart, true, false, CancellationToken.None);
|
app.PerformProfileShutdown(profile, performRestart, true, false, token);
|
||||||
_currentProfileCommands.Remove(profileId);
|
_currentProfileCommands.Remove(profileId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -664,7 +664,7 @@ namespace ServerManagerTool
|
||||||
ProfileId = server.Runtime.ProfileSnapshot.ProfileId,
|
ProfileId = server.Runtime.ProfileSnapshot.ProfileId,
|
||||||
ProfileName = server.Runtime.ProfileSnapshot.ProfileName,
|
ProfileName = server.Runtime.ProfileSnapshot.ProfileName,
|
||||||
MaxPlayers = server.Runtime.MaxPlayers,
|
MaxPlayers = server.Runtime.MaxPlayers,
|
||||||
RCONHost = server.Runtime.ProfileSnapshot.ServerIP,
|
RCONHost = server.Runtime.ProfileSnapshot.ServerIPAddress.ToString(),
|
||||||
RCONPort = server.Runtime.ProfileSnapshot.RCONPort,
|
RCONPort = server.Runtime.ProfileSnapshot.RCONPort,
|
||||||
|
|
||||||
PGM_Enabled = server.Profile.PGM_Enabled,
|
PGM_Enabled = server.Profile.PGM_Enabled,
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ namespace ServerManagerTool.Windows
|
||||||
|
|
||||||
var profile = ServerProfileSnapshot.Create(server.Profile);
|
var profile = ServerProfileSnapshot.Create(server.Profile);
|
||||||
|
|
||||||
var exitCode = await Task.Run(() => app.PerformProfileBackup(profile));
|
var exitCode = await Task.Run(() => app.PerformProfileBackup(profile, CancellationToken.None));
|
||||||
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
|
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
|
||||||
{
|
{
|
||||||
throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}");
|
throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}");
|
||||||
|
|
|
||||||
|
|
@ -1099,7 +1099,7 @@ namespace ServerManagerTool
|
||||||
|
|
||||||
var profile = ServerProfileSnapshot.Create(Server.Profile);
|
var profile = ServerProfileSnapshot.Create(Server.Profile);
|
||||||
|
|
||||||
var exitCode = await Task.Run(() => app.PerformProfileBackup(profile));
|
var exitCode = await Task.Run(() => app.PerformProfileBackup(profile, CancellationToken.None));
|
||||||
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
|
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
|
||||||
throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}");
|
throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1225,11 +1225,15 @@
|
||||||
|
|
||||||
<sys:String x:Key="DiscordBot_ProfileMissing">The '{0}' command requires a profile id.</sys:String>
|
<sys:String x:Key="DiscordBot_ProfileMissing">The '{0}' command requires a profile id.</sys:String>
|
||||||
<sys:String x:Key="DiscordBot_ProfileNotFound">Profile '{0}' was not found or is not associated with the channel.</sys:String>
|
<sys:String x:Key="DiscordBot_ProfileNotFound">Profile '{0}' was not found or is not associated with the channel.</sys:String>
|
||||||
<sys:String x:Key="DiscordBot_ProfileBadStatus">Profile '{0}' must be '{1}' to perform the command.</sys:String>
|
<sys:String x:Key="DiscordBot_ProfileBadStatus">Profile '{0}' is in a state '{1}' that cannot run this command.</sys:String>
|
||||||
<sys:String x:Key="DiscordBot_ProfileUpdating">Profile '{0}' is currently being updated.</sys:String>
|
<sys:String x:Key="DiscordBot_ProfileUpdating">Profile '{0}' is currently being updated.</sys:String>
|
||||||
|
|
||||||
<sys:String x:Key="DiscordBot_InfoFailed">Call to server '{0}' failed.</sys:String>
|
<sys:String x:Key="DiscordBot_InfoFailed">Call to server '{0}' failed.</sys:String>
|
||||||
<sys:String x:Key="DiscordBot_BackupRequested">A backup request for server '{0}' has been sent.</sys:String>
|
<sys:String x:Key="DiscordBot_BackupRequested">A backup request for server '{0}' has been sent.</sys:String>
|
||||||
|
<sys:String x:Key="DiscordBot_RestartRequested">A restart request for server '{0}' has been sent.</sys:String>
|
||||||
|
<sys:String x:Key="DiscordBot_ShutdownRequested">A shutdown request for server '{0}' has been sent.</sys:String>
|
||||||
|
<sys:String x:Key="DiscordBot_StartRequested">A start request for server '{0}' has been sent.</sys:String>
|
||||||
|
<sys:String x:Key="DiscordBot_StopRequested">A stop request for server '{0}' has been sent.</sys:String>
|
||||||
<sys:String x:Key="DiscordBot_UpdateRequested">An update request for server '{0}' has been sent.</sys:String>
|
<sys:String x:Key="DiscordBot_UpdateRequested">An update request for server '{0}' has been sent.</sys:String>
|
||||||
|
|
||||||
<sys:String x:Key="DiscordBot_CountLabel">Count:</sys:String>
|
<sys:String x:Key="DiscordBot_CountLabel">Count:</sys:String>
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ namespace ServerManagerTool.Lib
|
||||||
_startTime = DateTime.Now;
|
_startTime = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BackupServer()
|
private void BackupServer(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (_profile == null)
|
if (_profile == null)
|
||||||
{
|
{
|
||||||
|
|
@ -146,58 +146,67 @@ namespace ServerManagerTool.Lib
|
||||||
|
|
||||||
if (_serverRunning)
|
if (_serverRunning)
|
||||||
{
|
{
|
||||||
// check if RCON is enabled
|
try
|
||||||
//if (_profile.RconEnabled)
|
{
|
||||||
//{
|
emailMessage.AppendLine();
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// emailMessage.AppendLine();
|
|
||||||
|
|
||||||
// // perform a world save
|
var sent = false;
|
||||||
// if (!string.IsNullOrWhiteSpace(Config.Default.ServerBackup_WorldSaveMessage))
|
|
||||||
// {
|
|
||||||
// ProcessAlert(AlertType.Backup, Config.Default.ServerBackup_WorldSaveMessage);
|
|
||||||
// sent = SendMessage(Config.Default.ServerBackup_WorldSaveMessage, CancellationToken.None);
|
|
||||||
// if (sent)
|
|
||||||
// {
|
|
||||||
// emailMessage.AppendLine("sent server save message.");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// sent = SendCommand(Config.Default.ServerSaveCommand, false);
|
// perform a world save
|
||||||
// if (sent)
|
if (!string.IsNullOrWhiteSpace(Config.Default.ServerBackup_WorldSaveMessage))
|
||||||
// {
|
{
|
||||||
// emailMessage.AppendLine("sent server save command.");
|
ProcessAlert(AlertType.Backup, Config.Default.ServerBackup_WorldSaveMessage);
|
||||||
// Task.Delay(Config.Default.ServerShutdown_WorldSaveDelay * 1000).Wait();
|
sent = SendMessageAsync(Config.Default.ServerBackup_WorldSaveMessage, CancellationToken.None).Result;
|
||||||
// }
|
if (sent)
|
||||||
// }
|
{
|
||||||
// catch (Exception ex)
|
emailMessage.AppendLine("sent server save message.");
|
||||||
// {
|
}
|
||||||
// CloseRconConsole();
|
}
|
||||||
|
|
||||||
// Debug.WriteLine($"RCON> {Config.Default.ServerSaveCommand} command.\r\n{ex.Message}");
|
sent = SendCommandAsync(Config.Default.ServerSaveCommand, false).Result;
|
||||||
// }
|
if (sent)
|
||||||
//}
|
{
|
||||||
//else
|
emailMessage.AppendLine("sent server save command.");
|
||||||
//{
|
Task.Delay(Config.Default.ServerShutdown_WorldSaveDelay * 1000).Wait();
|
||||||
// LogProfileMessage("RCON not enabled.");
|
}
|
||||||
//}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
CloseRconConsole();
|
||||||
|
|
||||||
|
Debug.WriteLine($"RCON> {Config.Default.ServerSaveCommand} command.\r\n{ex.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExitCode != EXITCODE_NORMALEXIT)
|
if (ExitCode != EXITCODE_NORMALEXIT)
|
||||||
return;
|
return;
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
ExitCode = EXITCODE_CANCELLED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// make a backup of the current profile and config files.
|
// make a backup of the current profile and config files.
|
||||||
CreateProfileBackupArchiveFile();
|
CreateProfileBackupArchiveFile();
|
||||||
|
|
||||||
if (ExitCode != EXITCODE_NORMALEXIT)
|
if (ExitCode != EXITCODE_NORMALEXIT)
|
||||||
return;
|
return;
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
ExitCode = EXITCODE_CANCELLED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// make a backup of the current world file.
|
// make a backup of the current world file.
|
||||||
CreateServerBackupArchiveFile(emailMessage);
|
CreateServerBackupArchiveFile(emailMessage);
|
||||||
|
|
||||||
if (ExitCode != EXITCODE_NORMALEXIT)
|
if (ExitCode != EXITCODE_NORMALEXIT)
|
||||||
return;
|
return;
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
ExitCode = EXITCODE_CANCELLED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Config.Default.EmailNotify_AutoBackup)
|
if (Config.Default.EmailNotify_AutoBackup)
|
||||||
{
|
{
|
||||||
|
|
@ -266,7 +275,7 @@ namespace ServerManagerTool.Lib
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ServerStatusChangeCallback?.Invoke(ServerStatus.Updating);
|
ServerStatusChangeCallback?.Invoke(ServerStatus.Updating);
|
||||||
UpgradeLocal(true, steamCmdRemoveQuit, cancellationToken, true);
|
UpgradeLocal(true, true, steamCmdRemoveQuit, cancellationToken);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
@ -307,17 +316,20 @@ namespace ServerManagerTool.Lib
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the server was previously running before the update.
|
// check if the server was previously running.
|
||||||
if (!_serverRunning && !_profile.AutoRestartIfShutdown)
|
if (!_serverRunning)
|
||||||
{
|
{
|
||||||
LogProfileMessage("Server was not running, server will not be started.");
|
if (_profile.AutoRestartIfShutdown)
|
||||||
|
{
|
||||||
|
LogProfileMessage("Server was not running, server will be started as the setting to restart if shutdown is TRUE.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogProfileMessage("Server was not running, server will not be started.");
|
||||||
|
|
||||||
ExitCode = EXITCODE_NORMALEXIT;
|
ExitCode = EXITCODE_NORMALEXIT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!_serverRunning && _profile.AutoRestartIfShutdown)
|
|
||||||
{
|
|
||||||
LogProfileMessage("Server was not running, server will be started as the setting to restart if shutdown is TRUE.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the server process.
|
// Find the server process.
|
||||||
|
|
@ -390,10 +402,15 @@ namespace ServerManagerTool.Lib
|
||||||
_serverRunning = true;
|
_serverRunning = true;
|
||||||
LogProfileMessage($"Server process found PID {process.Id}.");
|
LogProfileMessage($"Server process found PID {process.Id}.");
|
||||||
|
|
||||||
|
QueryMaster.Server gameServer = null;
|
||||||
bool sent = false;
|
bool sent = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// create a connection to the server
|
||||||
|
var endPoint = new IPEndPoint(_profile.ServerIPAddress, _profile.QueryPort);
|
||||||
|
gameServer = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint);
|
||||||
|
|
||||||
// check if there is a shutdown reason
|
// check if there is a shutdown reason
|
||||||
if (!string.IsNullOrWhiteSpace(ShutdownReason) && !Config.Default.ServerShutdown_AllMessagesShowReason)
|
if (!string.IsNullOrWhiteSpace(ShutdownReason) && !Config.Default.ServerShutdown_AllMessagesShowReason)
|
||||||
{
|
{
|
||||||
|
|
@ -404,10 +421,6 @@ namespace ServerManagerTool.Lib
|
||||||
}
|
}
|
||||||
|
|
||||||
LogProfileMessage("Starting shutdown timer...");
|
LogProfileMessage("Starting shutdown timer...");
|
||||||
if (!CheckForOnlinePlayers)
|
|
||||||
{
|
|
||||||
LogProfileMessage("CheckForOnlinePlayers disabled, shutdown timer will not perform online player check.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var minutesLeft = ShutdownInterval;
|
var minutesLeft = ShutdownInterval;
|
||||||
while (minutesLeft > 0)
|
while (minutesLeft > 0)
|
||||||
|
|
@ -430,8 +443,11 @@ namespace ServerManagerTool.Lib
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var gameFile = GetServerWorldFile();
|
// BH - commented out until Funcom fix the Online player status column in the world save database
|
||||||
var playerCount = DataContainer.GetOnlinePlayerCount(gameFile);
|
//var gameFile = GetServerWorldFile();
|
||||||
|
//var playerCount = DataContainer.GetOnlinePlayerCount(gameFile);
|
||||||
|
var playerInfo = gameServer?.GetPlayers()?.Where(p => !string.IsNullOrWhiteSpace(p.Name?.Trim())).ToList();
|
||||||
|
var playerCount = playerInfo?.Count ?? -1;
|
||||||
|
|
||||||
// check if anyone is logged into the server
|
// check if anyone is logged into the server
|
||||||
if (playerCount <= 0)
|
if (playerCount <= 0)
|
||||||
|
|
@ -449,7 +465,8 @@ namespace ServerManagerTool.Lib
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"CheckForOnlinePlayers disabled");
|
Debug.WriteLine($"CheckForOnlinePlayers disabled, shutdown timer cancelled.");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var message = string.Empty;
|
var message = string.Empty;
|
||||||
|
|
@ -516,7 +533,7 @@ namespace ServerManagerTool.Lib
|
||||||
|
|
||||||
// BH - commented out until funcom provide a way to send a save command
|
// BH - commented out until funcom provide a way to send a save command
|
||||||
// check if we need to perform a world save
|
// check if we need to perform a world save
|
||||||
//if (_profile.RconEnabled && Config.Default.ServerShutdown_EnableWorldSave)
|
//if (Config.Default.ServerShutdown_EnableWorldSave)
|
||||||
//{
|
//{
|
||||||
// try
|
// try
|
||||||
// {
|
// {
|
||||||
|
|
@ -525,10 +542,10 @@ namespace ServerManagerTool.Lib
|
||||||
// {
|
// {
|
||||||
// LogProfileMessage(Config.Default.ServerShutdown_WorldSaveMessage);
|
// LogProfileMessage(Config.Default.ServerShutdown_WorldSaveMessage);
|
||||||
// ProcessAlert(AlertType.ShutdownMessage, Config.Default.ServerShutdown_WorldSaveMessage);
|
// ProcessAlert(AlertType.ShutdownMessage, Config.Default.ServerShutdown_WorldSaveMessage);
|
||||||
// SendMessage(Config.Default.ServerShutdown_WorldSaveMessage, cancellationToken);
|
// SendMessageAsync(Config.Default.ServerShutdown_WorldSaveMessage, cancellationToken).Wait(cancellationToken);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if (SendCommand(Config.Default.ServerSaveCommand, false))
|
// if (SendCommandAsync(Config.Default.ServerSaveCommand, false).Result)
|
||||||
// {
|
// {
|
||||||
// try
|
// try
|
||||||
// {
|
// {
|
||||||
|
|
@ -576,7 +593,8 @@ namespace ServerManagerTool.Lib
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
CloseRconConsole();
|
gameServer?.Dispose();
|
||||||
|
gameServer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cancellationToken.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
|
@ -589,8 +607,6 @@ namespace ServerManagerTool.Lib
|
||||||
SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, CancellationToken.None).Wait();
|
SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, CancellationToken.None).Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseRconConsole();
|
|
||||||
|
|
||||||
ExitCode = EXITCODE_CANCELLED;
|
ExitCode = EXITCODE_CANCELLED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -664,7 +680,7 @@ namespace ServerManagerTool.Lib
|
||||||
ExitCode = EXITCODE_SHUTDOWN_TIMEOUT;
|
ExitCode = EXITCODE_SHUTDOWN_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpgradeLocal(bool validate, bool steamCmdRemoveQuit, CancellationToken cancellationToken, bool updateMods)
|
private void UpgradeLocal(bool validate, bool updateMods, bool steamCmdRemoveQuit, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (_profile == null)
|
if (_profile == null)
|
||||||
{
|
{
|
||||||
|
|
@ -1182,7 +1198,7 @@ namespace ServerManagerTool.Lib
|
||||||
{
|
{
|
||||||
// perform a steamcmd validate to confirm all the files
|
// perform a steamcmd validate to confirm all the files
|
||||||
LogProfileMessage("Validating server files (*new*).");
|
LogProfileMessage("Validating server files (*new*).");
|
||||||
UpgradeLocal(true, false, CancellationToken.None, false);
|
UpgradeLocal(true, false, false, CancellationToken.None);
|
||||||
LogProfileMessage("Validated server files (*new*).");
|
LogProfileMessage("Validated server files (*new*).");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1703,17 +1719,6 @@ namespace ServerManagerTool.Lib
|
||||||
ExitCode = EXITCODE_NORMALEXIT;
|
ExitCode = EXITCODE_NORMALEXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseRconConsole()
|
|
||||||
{
|
|
||||||
if (_rconConsole != null)
|
|
||||||
{
|
|
||||||
_rconConsole.Dispose();
|
|
||||||
_rconConsole = null;
|
|
||||||
|
|
||||||
Task.Delay(1000).Wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CreateProfileBackupArchiveFile(ServerProfileSnapshot profile = null)
|
public void CreateProfileBackupArchiveFile(ServerProfileSnapshot profile = null)
|
||||||
{
|
{
|
||||||
var oldProfile = _profile;
|
var oldProfile = _profile;
|
||||||
|
|
@ -2413,36 +2418,43 @@ namespace ServerManagerTool.Lib
|
||||||
int rconRetries = 0;
|
int rconRetries = 0;
|
||||||
int maxRetries = retryIfFailed ? RCON_MAXRETRIES : 1;
|
int maxRetries = retryIfFailed ? RCON_MAXRETRIES : 1;
|
||||||
|
|
||||||
while (retries < maxRetries && rconRetries < RCON_MAXRETRIES)
|
try
|
||||||
{
|
{
|
||||||
SetupRconConsole();
|
while (retries < maxRetries && rconRetries < RCON_MAXRETRIES)
|
||||||
|
|
||||||
if (_rconConsole == null)
|
|
||||||
{
|
{
|
||||||
LogProfileMessage($"RCON> {command} - attempt {rconRetries + 1} (a).", false);
|
SetupRconConsole();
|
||||||
LogProfileMessage("RCON connection could not be created.", false);
|
|
||||||
rconRetries++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rconRetries = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_rconConsole.SendCommand(command);
|
|
||||||
LogProfileMessage($"RCON> {command}");
|
|
||||||
|
|
||||||
return true;
|
if (_rconConsole == null)
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
{
|
||||||
LogProfileMessage($"RCON> {command} - attempt {retries + 1} (b).", false);
|
LogProfileMessage($"RCON> {command} - attempt {rconRetries + 1} (a).", false);
|
||||||
LogProfileMessage($"{ex.Message}", false);
|
LogProfileMessage("RCON connection could not be created.", false);
|
||||||
LogProfileMessage($"{ex.StackTrace}", false);
|
rconRetries++;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rconRetries = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_rconConsole.SendCommand(command);
|
||||||
|
LogProfileMessage($"RCON> {command}");
|
||||||
|
|
||||||
retries++;
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogProfileMessage($"RCON> {command} - attempt {retries + 1} (b).", false);
|
||||||
|
LogProfileMessage($"{ex.Message}", false);
|
||||||
|
LogProfileMessage($"{ex.StackTrace}", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
retries++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
CloseRconConsole();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2504,6 +2516,17 @@ namespace ServerManagerTool.Lib
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CloseRconConsole()
|
||||||
|
{
|
||||||
|
if (_rconConsole != null)
|
||||||
|
{
|
||||||
|
_rconConsole.Dispose();
|
||||||
|
_rconConsole = null;
|
||||||
|
|
||||||
|
Task.Delay(1000).Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void SetupRconConsole()
|
private void SetupRconConsole()
|
||||||
{
|
{
|
||||||
CloseRconConsole();
|
CloseRconConsole();
|
||||||
|
|
@ -2513,7 +2536,7 @@ namespace ServerManagerTool.Lib
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var endPoint = new IPEndPoint(IPAddress.Parse(_profile.ServerIP), _profile.RconPort);
|
var endPoint = new IPEndPoint(_profile.ServerIPAddress, _profile.RconPort);
|
||||||
var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000);
|
var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000);
|
||||||
if (server == null)
|
if (server == null)
|
||||||
{
|
{
|
||||||
|
|
@ -2551,7 +2574,7 @@ namespace ServerManagerTool.Lib
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int PerformProfileBackup(ServerProfileSnapshot profile)
|
public int PerformProfileBackup(ServerProfileSnapshot profile, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_profile = profile;
|
_profile = profile;
|
||||||
|
|
||||||
|
|
@ -2573,7 +2596,7 @@ namespace ServerManagerTool.Lib
|
||||||
// check if the mutex was established
|
// check if the mutex was established
|
||||||
if (createdNew)
|
if (createdNew)
|
||||||
{
|
{
|
||||||
BackupServer();
|
BackupServer(cancellationToken);
|
||||||
|
|
||||||
if (ExitCode != EXITCODE_NORMALEXIT)
|
if (ExitCode != EXITCODE_NORMALEXIT)
|
||||||
{
|
{
|
||||||
|
|
@ -2926,7 +2949,7 @@ namespace ServerManagerTool.Lib
|
||||||
SendEmails = true,
|
SendEmails = true,
|
||||||
ServerProcess = ServerProcessType.AutoBackup
|
ServerProcess = ServerProcessType.AutoBackup
|
||||||
};
|
};
|
||||||
exitCodes.TryAdd(profile, app.PerformProfileBackup(profile));
|
exitCodes.TryAdd(profile, app.PerformProfileBackup(profile, CancellationToken.None));
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (var profile in _profiles.Keys)
|
foreach (var profile in _profiles.Keys)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ namespace ServerManagerTool.Lib
|
||||||
public string InstallDirectory;
|
public string InstallDirectory;
|
||||||
public string GameFile;
|
public string GameFile;
|
||||||
public string AdminPassword;
|
public string AdminPassword;
|
||||||
public string ServerIP;
|
public IPAddress ServerIPAddress;
|
||||||
public int ServerPort;
|
public int ServerPort;
|
||||||
public int ServerPeerPort;
|
public int ServerPeerPort;
|
||||||
public int QueryPort;
|
public int QueryPort;
|
||||||
|
|
@ -60,7 +60,7 @@ namespace ServerManagerTool.Lib
|
||||||
InstallDirectory = profile.InstallDirectory,
|
InstallDirectory = profile.InstallDirectory,
|
||||||
GameFile = profile.GetServerWorldFile(),
|
GameFile = profile.GetServerWorldFile(),
|
||||||
AdminPassword = profile.AdminPassword,
|
AdminPassword = profile.AdminPassword,
|
||||||
ServerIP = string.IsNullOrWhiteSpace(profile.ServerIP) ? IPAddress.Loopback.ToString() : profile.ServerIP.Trim(),
|
ServerIPAddress = string.IsNullOrWhiteSpace(profile.ServerIP) || !IPAddress.TryParse(profile.ServerIP.Trim(), out IPAddress ipAddress) ? IPAddress.Loopback : ipAddress,
|
||||||
ServerPort = profile.ServerPort,
|
ServerPort = profile.ServerPort,
|
||||||
ServerPeerPort = profile.ServerPeerPort,
|
ServerPeerPort = profile.ServerPeerPort,
|
||||||
QueryPort = profile.QueryPort,
|
QueryPort = profile.QueryPort,
|
||||||
|
|
|
||||||
|
|
@ -167,13 +167,19 @@ namespace ServerManagerTool.Lib
|
||||||
ServerProfile.QueryPortProperty,
|
ServerProfile.QueryPortProperty,
|
||||||
ServerProfile.ServerIPProperty,
|
ServerProfile.ServerIPProperty,
|
||||||
ServerProfile.MaxPlayersProperty,
|
ServerProfile.MaxPlayersProperty,
|
||||||
|
|
||||||
|
ServerProfile.ServerPasswordProperty,
|
||||||
|
ServerProfile.AdminPasswordProperty,
|
||||||
|
|
||||||
ServerProfile.ServerMapProperty,
|
ServerProfile.ServerMapProperty,
|
||||||
ServerProfile.ServerMapSaveFileNameProperty,
|
ServerProfile.ServerMapSaveFileNameProperty,
|
||||||
ServerProfile.ServerModIdsProperty,
|
ServerProfile.ServerModIdsProperty,
|
||||||
|
|
||||||
|
ServerProfile.MOTDIntervalProperty,
|
||||||
},
|
},
|
||||||
(s, p) =>
|
(s, p) =>
|
||||||
{
|
{
|
||||||
if (Status == ServerStatus.Stopped || Status == ServerStatus.Uninstalled || Status == ServerStatus.Unknown)
|
if (Status == ServerStatus.Stopped || Status == ServerStatus.Uninstalled || Status == ServerStatus.Unknown || Status == ServerStatus.Updating)
|
||||||
{
|
{
|
||||||
AttachToProfileCore(profile);
|
AttachToProfileCore(profile);
|
||||||
}
|
}
|
||||||
|
|
@ -194,16 +200,7 @@ namespace ServerManagerTool.Lib
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!String.IsNullOrWhiteSpace(this.ProfileSnapshot.ServerIP) && IPAddress.TryParse(this.ProfileSnapshot.ServerIP, out IPAddress localServerIpAddress))
|
localServerQueryEndPoint = new IPEndPoint(this.ProfileSnapshot.ServerIPAddress, Convert.ToUInt16(this.ProfileSnapshot.QueryPort));
|
||||||
{
|
|
||||||
// Use the explicit Server IP
|
|
||||||
localServerQueryEndPoint = new IPEndPoint(localServerIpAddress, Convert.ToUInt16(this.ProfileSnapshot.QueryPort));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// No Server IP specified, use Loopback
|
|
||||||
localServerQueryEndPoint = new IPEndPoint(IPAddress.Loopback, Convert.ToUInt16(this.ProfileSnapshot.QueryPort));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the public endpoint for querying Steam
|
// Get the public endpoint for querying Steam
|
||||||
|
|
@ -1061,7 +1058,7 @@ namespace ServerManagerTool.Lib
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var endPoint = new IPEndPoint(IPAddress.Parse(this.ProfileSnapshot.ServerIP), this.ProfileSnapshot.RconPort);
|
var endPoint = new IPEndPoint(this.ProfileSnapshot.ServerIPAddress, this.ProfileSnapshot.RconPort);
|
||||||
var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000);
|
var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000);
|
||||||
|
|
||||||
if (server == null)
|
if (server == null)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace ServerManagerTool.Utils
|
||||||
|
|
||||||
public static bool HasRunningCommands => _currentProfileCommands.Count > 0;
|
public static bool HasRunningCommands => _currentProfileCommands.Count > 0;
|
||||||
|
|
||||||
public static IList<string> HandleDiscordCommand(CommandType commandType, string serverId, string channelId, string profileId)
|
public static IList<string> HandleDiscordCommand(CommandType commandType, string serverId, string channelId, string profileId, CancellationToken token)
|
||||||
{
|
{
|
||||||
// check if incoming values are valid
|
// check if incoming values are valid
|
||||||
if (string.IsNullOrWhiteSpace(serverId) || string.IsNullOrWhiteSpace(channelId))
|
if (string.IsNullOrWhiteSpace(serverId) || string.IsNullOrWhiteSpace(channelId))
|
||||||
|
|
@ -49,15 +49,17 @@ namespace ServerManagerTool.Utils
|
||||||
return GetServerStatus(channelId, profileId);
|
return GetServerStatus(channelId, profileId);
|
||||||
|
|
||||||
case CommandType.Backup:
|
case CommandType.Backup:
|
||||||
return BackupServer(channelId, profileId);
|
return BackupServer(channelId, profileId, token);
|
||||||
|
case CommandType.Restart:
|
||||||
|
return RestartServer(channelId, profileId, token);
|
||||||
case CommandType.Shutdown:
|
case CommandType.Shutdown:
|
||||||
return ShutdownServer(channelId, profileId);
|
return ShutdownServer(channelId, profileId, token);
|
||||||
case CommandType.Stop:
|
case CommandType.Stop:
|
||||||
return StopServer(channelId, profileId);
|
return StopServer(channelId, profileId, token);
|
||||||
case CommandType.Start:
|
case CommandType.Start:
|
||||||
return StartServer(channelId, profileId);
|
return StartServer(channelId, profileId, token);
|
||||||
case CommandType.Update:
|
case CommandType.Update:
|
||||||
return UpdateServer(channelId, profileId);
|
return UpdateServer(channelId, profileId, token);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), commandType) };
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), commandType) };
|
||||||
|
|
@ -108,6 +110,17 @@ namespace ServerManagerTool.Utils
|
||||||
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (server.Runtime.Status)
|
||||||
|
{
|
||||||
|
case ServerStatus.Initializing:
|
||||||
|
case ServerStatus.Stopping:
|
||||||
|
case ServerStatus.Stopped:
|
||||||
|
case ServerStatus.Uninstalled:
|
||||||
|
case ServerStatus.Unknown:
|
||||||
|
case ServerStatus.Updating:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
}
|
||||||
|
|
||||||
serverName = server.Profile.ServerName;
|
serverName = server.Profile.ServerName;
|
||||||
if (!string.IsNullOrWhiteSpace(server.Profile.ServerIP))
|
if (!string.IsNullOrWhiteSpace(server.Profile.ServerIP))
|
||||||
{
|
{
|
||||||
|
|
@ -183,7 +196,7 @@ namespace ServerManagerTool.Utils
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IList<string> BackupServer(string channelId, string profileId)
|
private static IList<string> BackupServer(string channelId, string profileId, CancellationToken token)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(profileId))
|
if (string.IsNullOrWhiteSpace(profileId))
|
||||||
{
|
{
|
||||||
|
|
@ -211,6 +224,16 @@ namespace ServerManagerTool.Utils
|
||||||
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (server.Runtime.Status)
|
||||||
|
{
|
||||||
|
case ServerStatus.Initializing:
|
||||||
|
case ServerStatus.Stopping:
|
||||||
|
case ServerStatus.Uninstalled:
|
||||||
|
case ServerStatus.Unknown:
|
||||||
|
case ServerStatus.Updating:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
}
|
||||||
|
|
||||||
profile = ServerProfileSnapshot.Create(server.Profile);
|
profile = ServerProfileSnapshot.Create(server.Profile);
|
||||||
}).Wait();
|
}).Wait();
|
||||||
|
|
||||||
|
|
@ -223,11 +246,19 @@ namespace ServerManagerTool.Utils
|
||||||
SendAlerts = true,
|
SendAlerts = true,
|
||||||
SendEmails = false,
|
SendEmails = false,
|
||||||
ServerProcess = ServerProcessType.Backup,
|
ServerProcess = ServerProcessType.Backup,
|
||||||
|
ServerStatusChangeCallback = (ServerStatus serverStatus) =>
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
server.Runtime.UpdateServerStatus(serverStatus, true);
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
task = Task.Run(() =>
|
task = Task.Run(() =>
|
||||||
{
|
{
|
||||||
app.PerformProfileBackup(profile);
|
app.PerformProfileBackup(profile, token);
|
||||||
_currentProfileCommands.Remove(profileId);
|
_currentProfileCommands.Remove(profileId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -244,22 +275,337 @@ namespace ServerManagerTool.Utils
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IList<string> ShutdownServer(string channelId, string profileId)
|
private static IList<string> RestartServer(string channelId, string profileId, CancellationToken token)
|
||||||
{
|
{
|
||||||
return new List<string>() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Shutdown) };
|
if (string.IsNullOrWhiteSpace(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Restart) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if another command is being run against the profile
|
||||||
|
if (_currentProfileCommands.ContainsKey(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
|
||||||
|
}
|
||||||
|
_currentProfileCommands.Add(profileId, CommandType.Restart);
|
||||||
|
|
||||||
|
ServerProfileSnapshot profile = null;
|
||||||
|
Task task = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
|
||||||
|
if (server is null)
|
||||||
|
{
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (server.Runtime.Status)
|
||||||
|
{
|
||||||
|
case ServerStatus.Initializing:
|
||||||
|
case ServerStatus.Stopping:
|
||||||
|
case ServerStatus.Uninstalled:
|
||||||
|
case ServerStatus.Unknown:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
|
||||||
|
case ServerStatus.Updating:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
profile = ServerProfileSnapshot.Create(server.Profile);
|
||||||
|
profile.AutoRestartIfShutdown = true;
|
||||||
|
}).Wait();
|
||||||
|
|
||||||
|
List<string> response = new List<string>();
|
||||||
|
|
||||||
|
var app = new ServerApp(true)
|
||||||
|
{
|
||||||
|
DeleteOldServerBackupFiles = !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 => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
server.Runtime.UpdateServerStatus(serverStatus, true);
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
task = Task.Run(() =>
|
||||||
|
{
|
||||||
|
app.PerformProfileShutdown(profile, true, false, false, false, token);
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
});
|
||||||
|
|
||||||
|
response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_RestartRequested"), profile.ServerName));
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (task is null)
|
||||||
|
{
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IList<string> StopServer(string channelId, string profileId)
|
private static IList<string> ShutdownServer(string channelId, string profileId, CancellationToken token)
|
||||||
{
|
{
|
||||||
return new List<string>() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Stop) };
|
if (string.IsNullOrWhiteSpace(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Shutdown) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if another command is being run against the profile
|
||||||
|
if (_currentProfileCommands.ContainsKey(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
|
||||||
|
}
|
||||||
|
_currentProfileCommands.Add(profileId, CommandType.Shutdown);
|
||||||
|
|
||||||
|
ServerProfileSnapshot profile = null;
|
||||||
|
Task task = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
|
||||||
|
if (server is null)
|
||||||
|
{
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (server.Runtime.Status)
|
||||||
|
{
|
||||||
|
case ServerStatus.Initializing:
|
||||||
|
case ServerStatus.Stopping:
|
||||||
|
case ServerStatus.Stopped:
|
||||||
|
case ServerStatus.Uninstalled:
|
||||||
|
case ServerStatus.Unknown:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
|
||||||
|
case ServerStatus.Updating:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
profile = ServerProfileSnapshot.Create(server.Profile);
|
||||||
|
}).Wait();
|
||||||
|
|
||||||
|
List<string> response = new List<string>();
|
||||||
|
|
||||||
|
var app = new ServerApp(true)
|
||||||
|
{
|
||||||
|
DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
|
||||||
|
OutputLogs = false,
|
||||||
|
SendAlerts = true,
|
||||||
|
SendEmails = false,
|
||||||
|
ServerProcess = ServerProcessType.Shutdown,
|
||||||
|
ServerStatusChangeCallback = (ServerStatus serverStatus) =>
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
server.Runtime.UpdateServerStatus(serverStatus, true);
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
task = Task.Run(() =>
|
||||||
|
{
|
||||||
|
app.PerformProfileShutdown(profile, false, false, false, false, token);
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
});
|
||||||
|
|
||||||
|
response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_ShutdownRequested"), profile.ServerName));
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (task is null)
|
||||||
|
{
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IList<string> StartServer(string channelId, string profileId)
|
private static IList<string> StopServer(string channelId, string profileId, CancellationToken token)
|
||||||
{
|
{
|
||||||
return new List<string>() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Start) };
|
if (string.IsNullOrWhiteSpace(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Shutdown) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if another command is being run against the profile
|
||||||
|
if (_currentProfileCommands.ContainsKey(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
|
||||||
|
}
|
||||||
|
_currentProfileCommands.Add(profileId, CommandType.Shutdown);
|
||||||
|
|
||||||
|
ServerProfileSnapshot profile = null;
|
||||||
|
Task task = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
|
||||||
|
if (server is null)
|
||||||
|
{
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (server.Runtime.Status)
|
||||||
|
{
|
||||||
|
case ServerStatus.Initializing:
|
||||||
|
case ServerStatus.Stopping:
|
||||||
|
case ServerStatus.Stopped:
|
||||||
|
case ServerStatus.Uninstalled:
|
||||||
|
case ServerStatus.Unknown:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
|
||||||
|
case ServerStatus.Updating:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
profile = ServerProfileSnapshot.Create(server.Profile);
|
||||||
|
}).Wait();
|
||||||
|
|
||||||
|
List<string> response = new List<string>();
|
||||||
|
|
||||||
|
var app = new ServerApp(true)
|
||||||
|
{
|
||||||
|
DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
|
||||||
|
OutputLogs = false,
|
||||||
|
SendAlerts = true,
|
||||||
|
SendEmails = false,
|
||||||
|
ServerProcess = ServerProcessType.Shutdown,
|
||||||
|
ShutdownInterval = 0,
|
||||||
|
ServerStatusChangeCallback = (ServerStatus serverStatus) =>
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
server.Runtime.UpdateServerStatus(serverStatus, true);
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
task = Task.Run(() =>
|
||||||
|
{
|
||||||
|
app.PerformProfileShutdown(profile, false, false, false, false, token);
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
});
|
||||||
|
|
||||||
|
response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_StopRequested"), profile.ServerName));
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (task is null)
|
||||||
|
{
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IList<string> UpdateServer(string channelId, string profileId)
|
private static IList<string> StartServer(string channelId, string profileId, CancellationToken token)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Start) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if another command is being run against the profile
|
||||||
|
if (_currentProfileCommands.ContainsKey(profileId))
|
||||||
|
{
|
||||||
|
return new List<string> { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
|
||||||
|
}
|
||||||
|
_currentProfileCommands.Add(profileId, CommandType.Start);
|
||||||
|
|
||||||
|
ServerProfileSnapshot profile = null;
|
||||||
|
Task task = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TaskUtils.RunOnUIThreadAsync(() =>
|
||||||
|
{
|
||||||
|
var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
|
||||||
|
if (server is null)
|
||||||
|
{
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (server.Runtime.Status)
|
||||||
|
{
|
||||||
|
case ServerStatus.Initializing:
|
||||||
|
case ServerStatus.Stopping:
|
||||||
|
case ServerStatus.Running:
|
||||||
|
case ServerStatus.Uninstalled:
|
||||||
|
case ServerStatus.Unknown:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
|
||||||
|
case ServerStatus.Updating:
|
||||||
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
profile = ServerProfileSnapshot.Create(server.Profile);
|
||||||
|
profile.AutoRestartIfShutdown = true;
|
||||||
|
}).Wait();
|
||||||
|
|
||||||
|
List<string> response = new List<string>();
|
||||||
|
|
||||||
|
var app = new ServerApp(true)
|
||||||
|
{
|
||||||
|
DeleteOldServerBackupFiles = !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 => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
|
||||||
|
server.Runtime.UpdateServerStatus(serverStatus, true);
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
task = Task.Run(() =>
|
||||||
|
{
|
||||||
|
app.PerformProfileShutdown(profile, true, false, false, false, token);
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
});
|
||||||
|
|
||||||
|
response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_StartRequested"), profile.ServerName));
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (task is null)
|
||||||
|
{
|
||||||
|
_currentProfileCommands.Remove(profileId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IList<string> UpdateServer(string channelId, string profileId, CancellationToken token)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(profileId))
|
if (string.IsNullOrWhiteSpace(profileId))
|
||||||
{
|
{
|
||||||
|
|
@ -293,7 +639,7 @@ namespace ServerManagerTool.Utils
|
||||||
case ServerStatus.Initializing:
|
case ServerStatus.Initializing:
|
||||||
case ServerStatus.Stopping:
|
case ServerStatus.Stopping:
|
||||||
case ServerStatus.Unknown:
|
case ServerStatus.Unknown:
|
||||||
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, ServerRuntime.GetServerStatusString(ServerStatus.Stopped)));
|
throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
|
||||||
|
|
||||||
case ServerStatus.Running:
|
case ServerStatus.Running:
|
||||||
performRestart = true;
|
performRestart = true;
|
||||||
|
|
@ -327,7 +673,7 @@ namespace ServerManagerTool.Utils
|
||||||
|
|
||||||
task = Task.Run(() =>
|
task = Task.Run(() =>
|
||||||
{
|
{
|
||||||
app.PerformProfileShutdown(profile, performRestart, true, false, false, CancellationToken.None);
|
app.PerformProfileShutdown(profile, performRestart, true, false, false, token);
|
||||||
_currentProfileCommands.Remove(profileId);
|
_currentProfileCommands.Remove(profileId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -542,7 +542,7 @@ namespace ServerManagerTool
|
||||||
ProfileId = server.Runtime.ProfileSnapshot.ProfileId,
|
ProfileId = server.Runtime.ProfileSnapshot.ProfileId,
|
||||||
ProfileName = server.Runtime.ProfileSnapshot.ProfileName,
|
ProfileName = server.Runtime.ProfileSnapshot.ProfileName,
|
||||||
MaxPlayers = server.Runtime.MaxPlayers,
|
MaxPlayers = server.Runtime.MaxPlayers,
|
||||||
RconHost = server.Runtime.ProfileSnapshot.ServerIP,
|
RconHost = server.Runtime.ProfileSnapshot.ServerIPAddress.ToString(),
|
||||||
RconPort = server.Runtime.ProfileSnapshot.RconPort,
|
RconPort = server.Runtime.ProfileSnapshot.RconPort,
|
||||||
RconPassword = server.Runtime.ProfileSnapshot.RconPassword,
|
RconPassword = server.Runtime.ProfileSnapshot.RconPassword,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ namespace ServerManagerTool.Windows
|
||||||
|
|
||||||
var profile = ServerProfileSnapshot.Create(server.Profile);
|
var profile = ServerProfileSnapshot.Create(server.Profile);
|
||||||
|
|
||||||
var exitCode = await Task.Run(() => app.PerformProfileBackup(profile));
|
var exitCode = await Task.Run(() => app.PerformProfileBackup(profile, CancellationToken.None));
|
||||||
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
|
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
|
||||||
{
|
{
|
||||||
throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}");
|
throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}");
|
||||||
|
|
|
||||||
|
|
@ -834,7 +834,7 @@ namespace ServerManagerTool
|
||||||
|
|
||||||
var profile = ServerProfileSnapshot.Create(Server.Profile);
|
var profile = ServerProfileSnapshot.Create(Server.Profile);
|
||||||
|
|
||||||
var exitCode = await Task.Run(() => app.PerformProfileBackup(profile));
|
var exitCode = await Task.Run(() => app.PerformProfileBackup(profile, CancellationToken.None));
|
||||||
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
|
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
|
||||||
throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}");
|
throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
using ServerManagerTool.DiscordBot.Enums;
|
using ServerManagerTool.DiscordBot.Enums;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace ServerManagerTool.DiscordBot.Delegates
|
namespace ServerManagerTool.DiscordBot.Delegates
|
||||||
{
|
{
|
||||||
public delegate IList<string> HandleCommandDelegate(CommandType commandType, string serverId, string channelId, string profileId);
|
public delegate IList<string> HandleCommandDelegate(CommandType commandType, string serverId, string channelId, string profileId, CancellationToken token);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
Status,
|
Status,
|
||||||
|
|
||||||
Backup,
|
Backup,
|
||||||
|
Restart,
|
||||||
Shutdown,
|
Shutdown,
|
||||||
Start,
|
Start,
|
||||||
Stop,
|
Stop,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ namespace ServerManagerTool.DiscordBot.Interfaces
|
||||||
{
|
{
|
||||||
public interface IServerManagerBot
|
public interface IServerManagerBot
|
||||||
{
|
{
|
||||||
|
CancellationToken Token { get; }
|
||||||
|
|
||||||
Task StartAsync(string discordToken, string commandPrefix, string dataDirectory, HandleCommandDelegate handleCommandCallback, HandleTranslationDelegate handleTranslationCallback, CancellationToken token);
|
Task StartAsync(string discordToken, string commandPrefix, string dataDirectory, HandleCommandDelegate handleCommandCallback, HandleTranslationDelegate handleTranslationCallback, CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ using Discord.Commands;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using ServerManagerTool.DiscordBot.Delegates;
|
using ServerManagerTool.DiscordBot.Delegates;
|
||||||
using ServerManagerTool.DiscordBot.Enums;
|
using ServerManagerTool.DiscordBot.Enums;
|
||||||
|
using ServerManagerTool.DiscordBot.Interfaces;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ServerManagerTool.DiscordBot.Modules
|
namespace ServerManagerTool.DiscordBot.Modules
|
||||||
|
|
@ -12,19 +14,21 @@ namespace ServerManagerTool.DiscordBot.Modules
|
||||||
[Name("Server Commands")]
|
[Name("Server Commands")]
|
||||||
public sealed class ServerCommandModule : InteractiveBase
|
public sealed class ServerCommandModule : InteractiveBase
|
||||||
{
|
{
|
||||||
|
private readonly IServerManagerBot _serverManagerBot;
|
||||||
private readonly CommandService _service;
|
private readonly CommandService _service;
|
||||||
private readonly HandleCommandDelegate _handleCommandCallback;
|
private readonly HandleCommandDelegate _handleCommandCallback;
|
||||||
private readonly IConfigurationRoot _config;
|
private readonly IConfigurationRoot _config;
|
||||||
|
|
||||||
public ServerCommandModule(CommandService service, HandleCommandDelegate handleCommandCallback, IConfigurationRoot config)
|
public ServerCommandModule(IServerManagerBot serverManagerBot, CommandService service, HandleCommandDelegate handleCommandCallback, IConfigurationRoot config)
|
||||||
{
|
{
|
||||||
|
_serverManagerBot = serverManagerBot;
|
||||||
_service = service;
|
_service = service;
|
||||||
_handleCommandCallback = handleCommandCallback;
|
_handleCommandCallback = handleCommandCallback;
|
||||||
_config = config;
|
_config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Command("backup", RunMode = RunMode.Async)]
|
[Command("backup", RunMode = RunMode.Async)]
|
||||||
[Summary("Perform a backup of the server")]
|
[Summary("Backup the server")]
|
||||||
[Remarks("backup profileId")]
|
[Remarks("backup profileId")]
|
||||||
[RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)]
|
[RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)]
|
||||||
public async Task BackupServerAsync(string profileId)
|
public async Task BackupServerAsync(string profileId)
|
||||||
|
|
@ -34,7 +38,38 @@ namespace ServerManagerTool.DiscordBot.Modules
|
||||||
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
||||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||||
|
|
||||||
var response = _handleCommandCallback?.Invoke(CommandType.Backup, serverId, channelId, profileId);
|
var response = _handleCommandCallback?.Invoke(CommandType.Backup, serverId, channelId, profileId, _serverManagerBot.Token);
|
||||||
|
if (response is null)
|
||||||
|
{
|
||||||
|
await ReplyAsync("No servers associated with this channel.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var output in response)
|
||||||
|
{
|
||||||
|
await ReplyAsync(output.Replace("&", "_"));
|
||||||
|
await Task.Delay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await ReplyAsync($"'{Context.Message}' command sent and failed with exception ({ex.Message})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("restart", RunMode = RunMode.Async)]
|
||||||
|
[Summary("Restart the server")]
|
||||||
|
[Remarks("restart profileId")]
|
||||||
|
[RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)]
|
||||||
|
public async Task RestartServerAsync(string profileId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
||||||
|
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||||
|
|
||||||
|
var response = _handleCommandCallback?.Invoke(CommandType.Restart, serverId, channelId, profileId, _serverManagerBot.Token);
|
||||||
if (response is null)
|
if (response is null)
|
||||||
{
|
{
|
||||||
await ReplyAsync("No servers associated with this channel.");
|
await ReplyAsync("No servers associated with this channel.");
|
||||||
|
|
@ -65,7 +100,7 @@ namespace ServerManagerTool.DiscordBot.Modules
|
||||||
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
||||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||||
|
|
||||||
var response = _handleCommandCallback?.Invoke(CommandType.Shutdown, serverId, channelId, profileId);
|
var response = _handleCommandCallback?.Invoke(CommandType.Shutdown, serverId, channelId, profileId, _serverManagerBot.Token);
|
||||||
if (response is null)
|
if (response is null)
|
||||||
{
|
{
|
||||||
await ReplyAsync("No servers associated with this channel.");
|
await ReplyAsync("No servers associated with this channel.");
|
||||||
|
|
@ -96,7 +131,7 @@ namespace ServerManagerTool.DiscordBot.Modules
|
||||||
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
||||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||||
|
|
||||||
var response = _handleCommandCallback?.Invoke(CommandType.Start, serverId, channelId, profileId);
|
var response = _handleCommandCallback?.Invoke(CommandType.Start, serverId, channelId, profileId, _serverManagerBot.Token);
|
||||||
if (response is null)
|
if (response is null)
|
||||||
{
|
{
|
||||||
await ReplyAsync("No servers associated with this channel.");
|
await ReplyAsync("No servers associated with this channel.");
|
||||||
|
|
@ -127,7 +162,7 @@ namespace ServerManagerTool.DiscordBot.Modules
|
||||||
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
||||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||||
|
|
||||||
var response = _handleCommandCallback?.Invoke(CommandType.Stop, serverId, channelId, profileId);
|
var response = _handleCommandCallback?.Invoke(CommandType.Stop, serverId, channelId, profileId, _serverManagerBot.Token);
|
||||||
if (response is null)
|
if (response is null)
|
||||||
{
|
{
|
||||||
await ReplyAsync("No servers associated with this channel.");
|
await ReplyAsync("No servers associated with this channel.");
|
||||||
|
|
@ -158,7 +193,7 @@ namespace ServerManagerTool.DiscordBot.Modules
|
||||||
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
||||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||||
|
|
||||||
var response = _handleCommandCallback?.Invoke(CommandType.Update, serverId, channelId, profileId);
|
var response = _handleCommandCallback?.Invoke(CommandType.Update, serverId, channelId, profileId, _serverManagerBot.Token);
|
||||||
if (response is null)
|
if (response is null)
|
||||||
{
|
{
|
||||||
await ReplyAsync("No servers associated with this channel.");
|
await ReplyAsync("No servers associated with this channel.");
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ using Discord.Commands;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using ServerManagerTool.DiscordBot.Delegates;
|
using ServerManagerTool.DiscordBot.Delegates;
|
||||||
using ServerManagerTool.DiscordBot.Enums;
|
using ServerManagerTool.DiscordBot.Enums;
|
||||||
|
using ServerManagerTool.DiscordBot.Interfaces;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ServerManagerTool.DiscordBot.Modules
|
namespace ServerManagerTool.DiscordBot.Modules
|
||||||
|
|
@ -12,12 +14,14 @@ namespace ServerManagerTool.DiscordBot.Modules
|
||||||
[Name("Server Query")]
|
[Name("Server Query")]
|
||||||
public sealed class ServerQueryModule : InteractiveBase
|
public sealed class ServerQueryModule : InteractiveBase
|
||||||
{
|
{
|
||||||
|
private readonly IServerManagerBot _serverManagerBot;
|
||||||
private readonly CommandService _service;
|
private readonly CommandService _service;
|
||||||
private readonly HandleCommandDelegate _handleCommandCallback;
|
private readonly HandleCommandDelegate _handleCommandCallback;
|
||||||
private readonly IConfigurationRoot _config;
|
private readonly IConfigurationRoot _config;
|
||||||
|
|
||||||
public ServerQueryModule(CommandService service, HandleCommandDelegate handleCommandCallback, IConfigurationRoot config)
|
public ServerQueryModule(IServerManagerBot serverManagerBot, CommandService service, HandleCommandDelegate handleCommandCallback, IConfigurationRoot config)
|
||||||
{
|
{
|
||||||
|
_serverManagerBot = serverManagerBot;
|
||||||
_service = service;
|
_service = service;
|
||||||
_handleCommandCallback = handleCommandCallback;
|
_handleCommandCallback = handleCommandCallback;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
@ -43,7 +47,7 @@ namespace ServerManagerTool.DiscordBot.Modules
|
||||||
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
||||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||||
|
|
||||||
var response = _handleCommandCallback?.Invoke(CommandType.Info, serverId, channelId, profileId);
|
var response = _handleCommandCallback?.Invoke(CommandType.Info, serverId, channelId, profileId, _serverManagerBot.Token);
|
||||||
if (response is null)
|
if (response is null)
|
||||||
{
|
{
|
||||||
await ReplyAsync("No servers associated with this channel.");
|
await ReplyAsync("No servers associated with this channel.");
|
||||||
|
|
@ -74,7 +78,7 @@ namespace ServerManagerTool.DiscordBot.Modules
|
||||||
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
||||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||||
|
|
||||||
var response = _handleCommandCallback?.Invoke(CommandType.List, serverId, channelId, null);
|
var response = _handleCommandCallback?.Invoke(CommandType.List, serverId, channelId, null, _serverManagerBot.Token);
|
||||||
if (response is null)
|
if (response is null)
|
||||||
{
|
{
|
||||||
await ReplyAsync("No servers associated with this channel.");
|
await ReplyAsync("No servers associated with this channel.");
|
||||||
|
|
@ -114,7 +118,7 @@ namespace ServerManagerTool.DiscordBot.Modules
|
||||||
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
var serverId = Context?.Guild?.Id.ToString() ?? string.Empty;
|
||||||
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
var channelId = Context?.Channel?.Id.ToString() ?? string.Empty;
|
||||||
|
|
||||||
var response = _handleCommandCallback?.Invoke(CommandType.Status, serverId, channelId, profileId);
|
var response = _handleCommandCallback?.Invoke(CommandType.Status, serverId, channelId, profileId, _serverManagerBot.Token);
|
||||||
if (response is null)
|
if (response is null)
|
||||||
{
|
{
|
||||||
await ReplyAsync("No servers associated with this channel.");
|
await ReplyAsync("No servers associated with this channel.");
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,8 @@ namespace ServerManagerTool.DiscordBot
|
||||||
Started = false;
|
Started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool Started
|
public CancellationToken Token { get; private set; }
|
||||||
{
|
public bool Started { get; private set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task StartAsync(string discordToken, string commandPrefix, string dataDirectory, HandleCommandDelegate handleCommandCallback, HandleTranslationDelegate handleTranslationCallback, CancellationToken token)
|
public async Task StartAsync(string discordToken, string commandPrefix, string dataDirectory, HandleCommandDelegate handleCommandCallback, HandleTranslationDelegate handleTranslationCallback, CancellationToken token)
|
||||||
{
|
{
|
||||||
|
|
@ -43,6 +40,8 @@ namespace ServerManagerTool.DiscordBot
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Token = token;
|
||||||
|
|
||||||
if (commandPrefix.Any(c => !char.IsLetterOrDigit(c)))
|
if (commandPrefix.Any(c => !char.IsLetterOrDigit(c)))
|
||||||
{
|
{
|
||||||
throw new Exception("#DiscordBot_InvalidPrefixError");
|
throw new Exception("#DiscordBot_InvalidPrefixError");
|
||||||
|
|
@ -57,7 +56,7 @@ namespace ServerManagerTool.DiscordBot
|
||||||
{
|
{
|
||||||
{ "DiscordSettings:Token", discordToken },
|
{ "DiscordSettings:Token", discordToken },
|
||||||
{ "DiscordSettings:Prefix", commandPrefix },
|
{ "DiscordSettings:Prefix", commandPrefix },
|
||||||
{ "ServerManager:DataDirectory", dataDirectory }
|
{ "ServerManager:DataDirectory", dataDirectory },
|
||||||
};
|
};
|
||||||
|
|
||||||
// Begin building the configuration file
|
// Begin building the configuration file
|
||||||
|
|
@ -107,7 +106,8 @@ namespace ServerManagerTool.DiscordBot
|
||||||
.AddSingleton<Random>()
|
.AddSingleton<Random>()
|
||||||
.AddSingleton(config)
|
.AddSingleton(config)
|
||||||
.AddSingleton(handleCommandCallback)
|
.AddSingleton(handleCommandCallback)
|
||||||
.AddSingleton(handleTranslationCallback);
|
.AddSingleton(handleTranslationCallback)
|
||||||
|
.AddSingleton<IServerManagerBot>(this);
|
||||||
|
|
||||||
// Create the service provider
|
// Create the service provider
|
||||||
using (var provider = services.BuildServiceProvider())
|
using (var provider = services.BuildServiceProvider())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue