2023-12-20 20:25:25 -06:00
|
|
|
|
using AutoMapper;
|
|
|
|
|
|
using CoreRCON;
|
2024-08-04 18:44:33 -05:00
|
|
|
|
using LANCommander.Server.Data.Models;
|
2024-07-04 16:34:30 -05:00
|
|
|
|
using LANCommander.SDK.Enums;
|
2023-12-20 20:25:25 -06:00
|
|
|
|
using LANCommander.SDK.PowerShell;
|
2023-08-16 20:27:07 -05:00
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
2023-03-18 00:44:31 -05:00
|
|
|
|
using System.Diagnostics;
|
2023-08-17 23:39:07 -05:00
|
|
|
|
using System.Net;
|
2024-08-16 18:36:17 -05:00
|
|
|
|
using LANCommander.SDK;
|
2025-01-29 20:35:42 -06:00
|
|
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
2024-10-07 18:04:26 -05:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
2023-03-18 00:44:31 -05:00
|
|
|
|
|
2024-08-04 18:44:33 -05:00
|
|
|
|
namespace LANCommander.Server.Services
|
2023-03-18 00:44:31 -05:00
|
|
|
|
{
|
2023-04-15 16:44:26 -05:00
|
|
|
|
public enum ServerProcessStatus
|
|
|
|
|
|
{
|
2023-08-16 20:27:07 -05:00
|
|
|
|
Retrieving,
|
2023-04-15 16:44:26 -05:00
|
|
|
|
Stopped,
|
|
|
|
|
|
Starting,
|
2023-08-17 01:32:27 -05:00
|
|
|
|
Stopping,
|
2023-04-15 16:44:26 -05:00
|
|
|
|
Running,
|
|
|
|
|
|
Error
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-15 20:15:53 -05:00
|
|
|
|
public class ServerLogEventArgs : EventArgs
|
|
|
|
|
|
{
|
|
|
|
|
|
public string Line { get; private set; }
|
2023-08-17 19:55:46 -05:00
|
|
|
|
public ServerConsole Log { get; private set; }
|
2023-08-15 20:15:53 -05:00
|
|
|
|
|
2023-08-17 19:55:46 -05:00
|
|
|
|
public ServerLogEventArgs(string line, ServerConsole console)
|
2023-08-15 20:15:53 -05:00
|
|
|
|
{
|
|
|
|
|
|
Line = line;
|
2023-08-17 19:55:46 -05:00
|
|
|
|
Log = console;
|
2023-08-15 20:15:53 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-31 21:00:47 -05:00
|
|
|
|
public class ServerStatusUpdateEventArgs : EventArgs
|
|
|
|
|
|
{
|
2024-08-04 18:44:33 -05:00
|
|
|
|
public Data.Models.Server Server { get; private set; }
|
2023-08-31 21:00:47 -05:00
|
|
|
|
public ServerProcessStatus Status { get; private set; }
|
2023-09-01 00:57:20 -05:00
|
|
|
|
public Exception Exception { get; private set; }
|
2023-08-31 21:00:47 -05:00
|
|
|
|
|
2024-08-04 18:44:33 -05:00
|
|
|
|
public ServerStatusUpdateEventArgs(Data.Models.Server server, ServerProcessStatus status)
|
2023-08-31 21:00:47 -05:00
|
|
|
|
{
|
|
|
|
|
|
Server = server;
|
|
|
|
|
|
Status = status;
|
|
|
|
|
|
}
|
2023-09-01 00:57:20 -05:00
|
|
|
|
|
2024-08-04 18:44:33 -05:00
|
|
|
|
public ServerStatusUpdateEventArgs(Data.Models.Server server, ServerProcessStatus status, Exception exception) : this(server, status)
|
2023-09-01 00:57:20 -05:00
|
|
|
|
{
|
|
|
|
|
|
Exception = exception;
|
|
|
|
|
|
}
|
2023-08-31 21:00:47 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-17 19:55:46 -05:00
|
|
|
|
public class LogFileMonitor : IDisposable
|
2023-08-16 20:27:07 -05:00
|
|
|
|
{
|
|
|
|
|
|
private ManualResetEvent Latch;
|
|
|
|
|
|
private FileStream FileStream;
|
|
|
|
|
|
private FileSystemWatcher FileSystemWatcher;
|
|
|
|
|
|
|
2024-10-07 18:04:26 -05:00
|
|
|
|
public LogFileMonitor(Data.Models.Server server, ServerConsole serverConsole)
|
2023-08-16 20:27:07 -05:00
|
|
|
|
{
|
2023-08-17 19:55:46 -05:00
|
|
|
|
var logPath = Path.Combine(server.WorkingDirectory, serverConsole.Path);
|
2023-08-16 20:27:07 -05:00
|
|
|
|
|
2023-08-17 19:55:46 -05:00
|
|
|
|
if (File.Exists(serverConsole.Path))
|
2023-08-16 20:27:07 -05:00
|
|
|
|
{
|
|
|
|
|
|
var lockMe = new object();
|
|
|
|
|
|
|
|
|
|
|
|
Latch = new ManualResetEvent(true);
|
|
|
|
|
|
FileStream = new FileStream(logPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
|
|
|
|
|
FileSystemWatcher = new FileSystemWatcher(Path.GetDirectoryName(logPath));
|
|
|
|
|
|
|
|
|
|
|
|
FileSystemWatcher.Changed += (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
lock (lockMe)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (e.FullPath != logPath)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
Latch.Set();
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
using (var sr = new StreamReader(FileStream))
|
|
|
|
|
|
{
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
|
|
|
|
|
|
|
Latch.WaitOne();
|
|
|
|
|
|
|
|
|
|
|
|
lock (lockMe)
|
|
|
|
|
|
{
|
|
|
|
|
|
String line;
|
|
|
|
|
|
|
|
|
|
|
|
while ((line = sr.ReadLine()) != null)
|
|
|
|
|
|
{
|
2024-10-07 18:04:26 -05:00
|
|
|
|
// hubContext.Clients.All.SendAsync("Log", serverConsole.ServerId, line);
|
2023-08-16 20:27:07 -05:00
|
|
|
|
//OnLog?.Invoke(this, new ServerLogEventArgs(line, log));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Latch.Set();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Latch != null)
|
|
|
|
|
|
Latch.Dispose();
|
|
|
|
|
|
|
|
|
|
|
|
if (FileStream != null)
|
|
|
|
|
|
FileStream.Dispose();
|
|
|
|
|
|
|
|
|
|
|
|
if (FileSystemWatcher != null)
|
|
|
|
|
|
FileSystemWatcher.Dispose();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-17 23:39:07 -05:00
|
|
|
|
public class RconConnection
|
|
|
|
|
|
{
|
|
|
|
|
|
public RCON RCON { get; set; }
|
|
|
|
|
|
public LogReceiver LogReceiver { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public RconConnection(string host, int port, string password)
|
|
|
|
|
|
{
|
|
|
|
|
|
RCON = new RCON(new IPEndPoint(IPAddress.Parse(host), port), password);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-04-20 00:24:46 -05:00
|
|
|
|
public class ServerProcessService : BaseService
|
2023-03-18 00:44:31 -05:00
|
|
|
|
{
|
2025-01-29 20:35:42 -06:00
|
|
|
|
public Dictionary<Guid, CancellationTokenSource> Running { get; set; } = new();
|
|
|
|
|
|
public Dictionary<Guid, LogFileMonitor> LogFileMonitors { get; set; } = new();
|
2023-03-18 00:44:31 -05:00
|
|
|
|
|
2025-01-29 20:35:42 -06:00
|
|
|
|
private Dictionary<Guid, RCON> RconConnections { get; set; } = new();
|
2025-03-16 14:01:33 -05:00
|
|
|
|
private Dictionary<Guid, ServerProcessStatus> Status { get; set; } = new();
|
2023-08-17 23:39:07 -05:00
|
|
|
|
|
2023-08-15 20:15:53 -05:00
|
|
|
|
public delegate void OnLogHandler(object sender, ServerLogEventArgs e);
|
|
|
|
|
|
public event OnLogHandler OnLog;
|
2025-03-16 14:01:33 -05:00
|
|
|
|
public event EventHandler<ServerStatusUpdateEventArgs> OnStatusUpdate;
|
2025-01-29 20:35:42 -06:00
|
|
|
|
|
2023-12-22 13:47:39 -06:00
|
|
|
|
private readonly IServiceProvider ServiceProvider;
|
2024-08-16 18:36:17 -05:00
|
|
|
|
private readonly SDK.Client Client;
|
2025-01-29 20:35:42 -06:00
|
|
|
|
private readonly IMapper Mapper;
|
2023-08-15 20:15:53 -05:00
|
|
|
|
|
2024-08-28 20:33:59 -05:00
|
|
|
|
public ServerProcessService(
|
|
|
|
|
|
ILogger<ServerProcessService> logger,
|
|
|
|
|
|
IServiceProvider serviceProvider,
|
2025-01-29 20:35:42 -06:00
|
|
|
|
SDK.Client client,
|
|
|
|
|
|
IMapper mapper) : base(logger)
|
2023-08-15 20:15:53 -05:00
|
|
|
|
{
|
2023-12-22 13:47:39 -06:00
|
|
|
|
ServiceProvider = serviceProvider;
|
2024-08-16 18:36:17 -05:00
|
|
|
|
Client = client;
|
2025-01-29 20:35:42 -06:00
|
|
|
|
Mapper = mapper;
|
2023-08-15 20:15:53 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-22 13:47:39 -06:00
|
|
|
|
public async Task StartServerAsync(Guid serverId)
|
2023-03-18 00:44:31 -05:00
|
|
|
|
{
|
2024-08-04 18:44:33 -05:00
|
|
|
|
Data.Models.Server server;
|
2023-12-20 20:25:25 -06:00
|
|
|
|
|
2023-12-22 13:47:39 -06:00
|
|
|
|
using (var scope = ServiceProvider.CreateScope())
|
2023-12-20 20:25:25 -06:00
|
|
|
|
{
|
2023-12-22 13:47:39 -06:00
|
|
|
|
var serverService = scope.ServiceProvider.GetRequiredService<ServerService>();
|
|
|
|
|
|
|
2025-01-25 02:04:27 -06:00
|
|
|
|
server = await serverService
|
|
|
|
|
|
.Query(q =>
|
|
|
|
|
|
{
|
|
|
|
|
|
return q
|
|
|
|
|
|
.Include(s => s.Scripts)
|
|
|
|
|
|
.Include(s => s.Game)
|
|
|
|
|
|
.Include(s => s.ServerConsoles);
|
|
|
|
|
|
}).GetAsync(serverId);
|
2023-12-22 13:47:39 -06:00
|
|
|
|
|
2024-01-27 11:14:07 -08:00
|
|
|
|
// Don't start the server if it's already started
|
|
|
|
|
|
if (GetStatus(server) != ServerProcessStatus.Stopped)
|
|
|
|
|
|
return;
|
2025-03-16 14:01:33 -05:00
|
|
|
|
|
|
|
|
|
|
UpdateStatus(server, ServerProcessStatus.Starting);
|
2023-12-22 13:47:39 -06:00
|
|
|
|
|
2025-02-01 02:21:34 -06:00
|
|
|
|
_logger?.LogInformation("Starting server \"{ServerName}\" for game {GameName}", server.Name, server.Game?.Title);
|
2023-12-22 13:47:39 -06:00
|
|
|
|
|
2024-08-12 00:15:16 -05:00
|
|
|
|
foreach (var serverScript in server.Scripts.Where(s => s.Type == ScriptType.BeforeStart))
|
2023-12-20 20:25:25 -06:00
|
|
|
|
{
|
2024-08-11 14:48:24 -05:00
|
|
|
|
try
|
2023-12-20 20:25:25 -06:00
|
|
|
|
{
|
2024-08-11 14:48:24 -05:00
|
|
|
|
var script = new PowerShellScript(SDK.Enums.ScriptType.BeforeStart);
|
2023-12-20 20:25:25 -06:00
|
|
|
|
|
2025-02-04 18:54:31 -06:00
|
|
|
|
script.AddVariable("Server", Mapper.Map<SDK.Models.Server>(server));
|
2023-12-20 20:25:25 -06:00
|
|
|
|
|
2024-08-11 14:48:24 -05:00
|
|
|
|
script.UseWorkingDirectory(server.WorkingDirectory);
|
|
|
|
|
|
script.UseInline(serverScript.Contents);
|
|
|
|
|
|
script.UseShellExecute();
|
2023-12-20 20:25:25 -06:00
|
|
|
|
|
2025-02-01 02:21:34 -06:00
|
|
|
|
_logger?.LogInformation("Executing script \"{ScriptName}\"", serverScript.Name);
|
2023-12-20 20:25:25 -06:00
|
|
|
|
|
2024-08-16 18:36:17 -05:00
|
|
|
|
if (Client.Scripts.Debug)
|
|
|
|
|
|
script.EnableDebug();
|
|
|
|
|
|
|
2024-09-20 00:50:45 -05:00
|
|
|
|
await script.ExecuteAsync<int>();
|
2023-12-20 20:25:25 -06:00
|
|
|
|
}
|
2024-08-11 14:48:24 -05:00
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
2025-02-01 02:21:34 -06:00
|
|
|
|
_logger?.LogError(ex, "Error running script \"{ScriptName}\" for server \"{ServerName}\"", serverScript.Name, server.Name);
|
2024-08-11 14:48:24 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-03-18 00:44:31 -05:00
|
|
|
|
|
2025-02-01 02:21:34 -06:00
|
|
|
|
using (var executionContext = new ProcessExecutionContext(Client, _logger))
|
2023-08-11 15:03:30 -05:00
|
|
|
|
{
|
2025-01-29 20:35:42 -06:00
|
|
|
|
try
|
2023-12-27 20:13:25 -06:00
|
|
|
|
{
|
2025-01-29 20:35:42 -06:00
|
|
|
|
executionContext.AddVariable("ServerId", server.Id.ToString());
|
|
|
|
|
|
executionContext.AddVariable("ServerName", server.Name);
|
|
|
|
|
|
executionContext.AddVariable("ServerHost", server.Host);
|
|
|
|
|
|
executionContext.AddVariable("ServerPort", server.Port.ToString());
|
2023-08-31 21:00:47 -05:00
|
|
|
|
|
2025-01-29 20:35:42 -06:00
|
|
|
|
if (server.Game != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
executionContext.AddVariable("GameTitle", server.Game?.Title);
|
|
|
|
|
|
executionContext.AddVariable("GameId", server.Game?.Id.ToString());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var logFile in server.ServerConsoles.Where(sc => sc.Type == ServerConsoleType.LogFile))
|
|
|
|
|
|
{
|
|
|
|
|
|
StartMonitoringLog(logFile, server);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-16 14:01:33 -05:00
|
|
|
|
UpdateStatus(server, ServerProcessStatus.Running);
|
2025-01-29 20:35:42 -06:00
|
|
|
|
|
|
|
|
|
|
var cancellationTokenSource = new CancellationTokenSource();
|
|
|
|
|
|
|
|
|
|
|
|
Running[server.Id] = cancellationTokenSource;
|
|
|
|
|
|
|
2025-02-25 22:05:23 -06:00
|
|
|
|
await executionContext.ExecuteServerAsync(Mapper.Map<SDK.Models.Server>(server), cancellationTokenSource);
|
|
|
|
|
|
|
|
|
|
|
|
if (Running.ContainsKey(server.Id))
|
|
|
|
|
|
Running.Remove(server.Id);
|
2025-01-29 20:35:42 -06:00
|
|
|
|
|
2025-03-16 14:01:33 -05:00
|
|
|
|
UpdateStatus(server, ServerProcessStatus.Stopped);
|
2023-12-27 20:13:25 -06:00
|
|
|
|
}
|
2025-01-29 20:35:42 -06:00
|
|
|
|
catch (Exception ex)
|
2023-12-27 20:13:25 -06:00
|
|
|
|
{
|
2025-03-16 14:01:33 -05:00
|
|
|
|
UpdateStatus(server, ServerProcessStatus.Error, ex);
|
2023-08-31 21:00:47 -05:00
|
|
|
|
|
2025-02-01 02:21:34 -06:00
|
|
|
|
_logger?.LogError(ex, "Could not start server {ServerName} ({ServerId})", server.Name, server.Id);
|
2025-01-29 20:35:42 -06:00
|
|
|
|
}
|
2023-08-15 20:15:53 -05:00
|
|
|
|
|
2023-12-27 20:13:25 -06:00
|
|
|
|
}
|
2023-08-31 21:00:47 -05:00
|
|
|
|
}
|
2023-03-18 00:44:31 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-04-13 17:43:26 -05:00
|
|
|
|
|
2024-11-12 18:32:46 -06:00
|
|
|
|
public async void StopServerAsync(Guid serverId)
|
2023-03-18 00:44:31 -05:00
|
|
|
|
{
|
2023-12-22 13:47:39 -06:00
|
|
|
|
using (var scope = ServiceProvider.CreateScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
var serverService = scope.ServiceProvider.GetRequiredService<ServerService>();
|
2023-12-20 20:25:25 -06:00
|
|
|
|
|
2025-01-25 02:04:27 -06:00
|
|
|
|
var server = await serverService
|
|
|
|
|
|
.Query(q =>
|
|
|
|
|
|
{
|
|
|
|
|
|
return q
|
|
|
|
|
|
.Include(s => s.Scripts)
|
|
|
|
|
|
.Include(s => s.Game)
|
|
|
|
|
|
.Include(s => s.ServerConsoles);
|
|
|
|
|
|
}).GetAsync(serverId);
|
2023-08-31 21:00:47 -05:00
|
|
|
|
|
2025-02-01 02:21:34 -06:00
|
|
|
|
_logger?.LogInformation("Stopping server \"{ServerName}\" for game {GameName}", server.Name, server.Game?.Title);
|
2023-04-13 17:43:26 -05:00
|
|
|
|
|
2025-03-16 14:01:33 -05:00
|
|
|
|
UpdateStatus(server, ServerProcessStatus.Stopping);
|
2023-08-16 20:27:07 -05:00
|
|
|
|
|
2025-01-29 20:35:42 -06:00
|
|
|
|
if (Running.ContainsKey(server.Id))
|
2023-12-22 13:47:39 -06:00
|
|
|
|
{
|
2025-01-29 20:35:42 -06:00
|
|
|
|
await Running[server.Id].CancelAsync();
|
2024-06-19 18:18:51 -05:00
|
|
|
|
|
2025-01-29 20:35:42 -06:00
|
|
|
|
Running.Remove(server.Id);
|
2023-12-22 13:47:39 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (LogFileMonitors.ContainsKey(server.Id))
|
2023-12-20 20:25:25 -06:00
|
|
|
|
{
|
2023-12-22 13:47:39 -06:00
|
|
|
|
LogFileMonitors[server.Id].Dispose();
|
|
|
|
|
|
LogFileMonitors.Remove(server.Id);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-12 00:15:16 -05:00
|
|
|
|
foreach (var serverScript in server.Scripts.Where(s => s.Type == ScriptType.AfterStop))
|
2023-12-22 13:47:39 -06:00
|
|
|
|
{
|
2024-08-11 14:48:24 -05:00
|
|
|
|
try
|
2023-12-20 20:25:25 -06:00
|
|
|
|
{
|
2024-08-11 14:48:24 -05:00
|
|
|
|
var script = new PowerShellScript(SDK.Enums.ScriptType.AfterStop);
|
2023-12-20 20:25:25 -06:00
|
|
|
|
|
2025-02-04 18:54:31 -06:00
|
|
|
|
script.AddVariable("Server", Mapper.Map<SDK.Models.Server>(server));
|
2023-12-20 20:25:25 -06:00
|
|
|
|
|
2024-08-11 14:48:24 -05:00
|
|
|
|
script.UseWorkingDirectory(server.WorkingDirectory);
|
|
|
|
|
|
script.UseInline(serverScript.Contents);
|
|
|
|
|
|
script.UseShellExecute();
|
2023-12-20 20:25:25 -06:00
|
|
|
|
|
2025-02-01 02:21:34 -06:00
|
|
|
|
_logger?.LogInformation("Executing script \"{ScriptName}\"", serverScript.Name);
|
2023-12-20 20:25:25 -06:00
|
|
|
|
|
2024-08-16 18:36:17 -05:00
|
|
|
|
if (Client.Scripts.Debug)
|
|
|
|
|
|
script.EnableDebug();
|
|
|
|
|
|
|
2024-09-20 00:50:45 -05:00
|
|
|
|
await script.ExecuteAsync<int>();
|
2023-12-20 20:25:25 -06:00
|
|
|
|
}
|
2024-08-11 14:48:24 -05:00
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
2025-02-01 02:21:34 -06:00
|
|
|
|
_logger?.LogError(ex, "Error running script \"{ScriptName}\" for server \"{ServerName}\"", serverScript.Name, server.Name);
|
2024-08-11 14:48:24 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-12-20 20:25:25 -06:00
|
|
|
|
|
2025-03-16 14:01:33 -05:00
|
|
|
|
UpdateStatus(server, ServerProcessStatus.Stopped);
|
2023-12-22 13:47:39 -06:00
|
|
|
|
}
|
2023-03-18 00:44:31 -05:00
|
|
|
|
}
|
2023-04-15 16:44:26 -05:00
|
|
|
|
|
2024-08-04 18:44:33 -05:00
|
|
|
|
private void StartMonitoringLog(ServerConsole log, Data.Models.Server server)
|
2023-08-15 20:15:53 -05:00
|
|
|
|
{
|
2023-08-17 19:55:46 -05:00
|
|
|
|
if (!LogFileMonitors.ContainsKey(server.Id))
|
2023-08-15 20:15:53 -05:00
|
|
|
|
{
|
2024-10-07 18:04:26 -05:00
|
|
|
|
LogFileMonitors[server.Id] = new LogFileMonitor(server, log);
|
2023-08-15 20:15:53 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-17 23:39:07 -05:00
|
|
|
|
public RCON RconConnect(ServerConsole console)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!RconConnections.ContainsKey(console.Id))
|
|
|
|
|
|
{
|
2023-08-18 00:50:12 -05:00
|
|
|
|
var rcon = new RCON(new IPEndPoint(IPAddress.Parse(console.Host), console.Port.GetValueOrDefault()), console.Password);
|
2023-08-17 23:39:07 -05:00
|
|
|
|
|
|
|
|
|
|
RconConnections[console.Id] = rcon;
|
|
|
|
|
|
|
|
|
|
|
|
return rcon;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
return RconConnections[console.Id];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async Task<string> RconSendCommandAsync(string command, ServerConsole console)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (RconConnections.ContainsKey(console.Id))
|
|
|
|
|
|
{
|
|
|
|
|
|
return await RconConnections[console.Id].SendCommandAsync(command);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-16 14:01:33 -05:00
|
|
|
|
private void UpdateStatus(Data.Models.Server server, ServerProcessStatus status, Exception ex = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (ex != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Status[server.Id] = ServerProcessStatus.Error;
|
|
|
|
|
|
OnStatusUpdate?.Invoke(this, new ServerStatusUpdateEventArgs(server, ServerProcessStatus.Error, ex));
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (!Status.ContainsKey(server.Id))
|
|
|
|
|
|
{
|
|
|
|
|
|
Status[server.Id] = status;
|
|
|
|
|
|
OnStatusUpdate?.Invoke(this, new ServerStatusUpdateEventArgs(server, status));
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (Status[server.Id] != status)
|
|
|
|
|
|
{
|
|
|
|
|
|
Status[server.Id] = status;
|
|
|
|
|
|
OnStatusUpdate?.Invoke(this, new ServerStatusUpdateEventArgs(server, status));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-04 18:44:33 -05:00
|
|
|
|
public ServerProcessStatus GetStatus(Data.Models.Server server)
|
2023-04-15 16:44:26 -05:00
|
|
|
|
{
|
2023-08-30 19:45:42 -05:00
|
|
|
|
if (server == null)
|
|
|
|
|
|
return ServerProcessStatus.Stopped;
|
2025-01-29 20:35:42 -06:00
|
|
|
|
|
|
|
|
|
|
if (Running.ContainsKey(server.Id) && Running[server.Id].IsCancellationRequested)
|
|
|
|
|
|
return ServerProcessStatus.Stopping;
|
|
|
|
|
|
|
|
|
|
|
|
if (Running.ContainsKey(server.Id) && !Running[server.Id].IsCancellationRequested)
|
2023-04-15 16:44:26 -05:00
|
|
|
|
return ServerProcessStatus.Running;
|
|
|
|
|
|
|
|
|
|
|
|
return ServerProcessStatus.Stopped;
|
|
|
|
|
|
}
|
2023-03-18 00:44:31 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|