Added backend and console support for RCON
This commit is contained in:
parent
da017acab4
commit
1281ebff15
4 changed files with 132 additions and 14 deletions
|
@ -26,6 +26,7 @@
|
|||
<PackageReference Include="Blazor-ApexCharts" Version="0.9.18-beta" />
|
||||
<PackageReference Include="BlazorMonaco" Version="3.0.0" />
|
||||
<PackageReference Include="ByteSize" Version="2.1.1" />
|
||||
<PackageReference Include="CoreRCON" Version="5.0.5" />
|
||||
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.4" />
|
||||
<PackageReference Include="Hangfire.Core" Version="1.8.4" />
|
||||
<PackageReference Include="Hangfire.InMemory" Version="0.5.1" />
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
@using Microsoft.AspNetCore.SignalR.Client
|
||||
@using LANCommander.Data.Enums;
|
||||
@using Microsoft.AspNetCore.SignalR.Client
|
||||
@using NLog;
|
||||
@using XtermBlazor
|
||||
@inject ServerService ServerService
|
||||
@inject ServerConsoleService ServerConsoleService
|
||||
@inject ServerProcessService ServerProcessService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IMessageService MessageService
|
||||
@implements IAsyncDisposable
|
||||
|
||||
<Xterm @ref="Terminal" Options="TerminalOptions" AddonIds="TerminalAddons" />
|
||||
|
||||
@if (ServerConsole.Type == ServerConsoleType.RCON)
|
||||
{
|
||||
<Input @ref="CommandInput" @bind-Value="Command" BindOnInput OnPressEnter="OnPressEnter" @onkeyup="OnCommandKeyDown" />
|
||||
}
|
||||
|
||||
@code {
|
||||
[Parameter] public Guid ServerId { get; set; }
|
||||
[Parameter] public Guid ServerConsoleId { get; set; }
|
||||
|
@ -17,6 +24,11 @@
|
|||
HubConnection? HubConnection;
|
||||
ServerConsole ServerConsole;
|
||||
|
||||
Input<string> CommandInput;
|
||||
string Command;
|
||||
string[] History;
|
||||
int HistoryPosition;
|
||||
|
||||
TerminalOptions TerminalOptions = new TerminalOptions
|
||||
{
|
||||
CursorBlink = true,
|
||||
|
@ -31,18 +43,34 @@
|
|||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
ServerConsole = await ServerConsoleService.Get(ServerConsoleId);
|
||||
|
||||
HubConnection = new HubConnectionBuilder()
|
||||
.WithUrl(NavigationManager.ToAbsoluteUri("/hubs/gameserver"))
|
||||
.Build();
|
||||
|
||||
HubConnection.On<Guid, Guid, string>("Log", (serverId, logId, message) =>
|
||||
History = new string[50];
|
||||
HistoryPosition = 0;
|
||||
|
||||
if (ServerConsole.Type == ServerConsoleType.LogFile)
|
||||
{
|
||||
if (serverId == ServerId && logId == ServerConsoleId)
|
||||
Terminal.WriteLine(message);
|
||||
});
|
||||
HubConnection = new HubConnectionBuilder()
|
||||
.WithUrl(NavigationManager.ToAbsoluteUri("/hubs/gameserver"))
|
||||
.Build();
|
||||
|
||||
await HubConnection.StartAsync();
|
||||
HubConnection.On<Guid, Guid, string>("Log", (serverId, logId, message) =>
|
||||
{
|
||||
if (serverId == ServerId && logId == ServerConsoleId)
|
||||
Terminal.WriteLine(message);
|
||||
});
|
||||
|
||||
await HubConnection.StartAsync();
|
||||
}
|
||||
else if (ServerConsole.Type == ServerConsoleType.RCON)
|
||||
{
|
||||
try {
|
||||
ServerProcessService.RconConnect(ServerConsole);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await MessageService.Error($"Could not connect to RCON server: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
|
@ -63,6 +91,52 @@
|
|||
}
|
||||
}
|
||||
|
||||
public async Task OnPressEnter() {
|
||||
await ServerProcessService.RconSendCommandAsync(Command, ServerConsole);
|
||||
|
||||
Array.Copy(History, 0, History, 1, History.Length - 1);
|
||||
History[0] = Command;
|
||||
HistoryPosition = -1;
|
||||
Command = "";
|
||||
CommandInput.Value = "";
|
||||
await Task.Yield();
|
||||
await CommandInput.ValueChanged.InvokeAsync();
|
||||
await CommandInput.Focus(FocusBehavior.FocusAndClear);
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
public async Task OnCommandKeyDown(KeyboardEventArgs args)
|
||||
{
|
||||
switch (args.Key)
|
||||
{
|
||||
case "ArrowUp":
|
||||
if (HistoryPosition < History.Length && History[HistoryPosition + 1] != null)
|
||||
HistoryPosition++;
|
||||
|
||||
Command = History[HistoryPosition];
|
||||
|
||||
StateHasChanged();
|
||||
break;
|
||||
|
||||
case "ArrowDown":
|
||||
if (HistoryPosition >= 0)
|
||||
{
|
||||
HistoryPosition--;
|
||||
|
||||
if (HistoryPosition >= 0)
|
||||
Command = History[HistoryPosition];
|
||||
else
|
||||
{
|
||||
Command = "";
|
||||
}
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (HubConnection is not null)
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
using LANCommander.Data;
|
||||
using CoreRCON;
|
||||
using LANCommander.Data;
|
||||
using LANCommander.Data.Enums;
|
||||
using LANCommander.Data.Models;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
|
||||
namespace LANCommander.Services
|
||||
{
|
||||
|
@ -12,6 +15,9 @@ namespace LANCommander.Services
|
|||
{
|
||||
var log = await Get(logId);
|
||||
|
||||
if (log.Type != ServerConsoleType.LogFile)
|
||||
throw new Exception("Invalid console type");
|
||||
|
||||
var logPath = Path.Combine(log.Server.WorkingDirectory, log.Path);
|
||||
|
||||
return await File.ReadAllLinesAsync(logPath);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using LANCommander.Data.Enums;
|
||||
using CoreRCON;
|
||||
using LANCommander.Data.Enums;
|
||||
using LANCommander.Data.Models;
|
||||
using LANCommander.Hubs;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
@ -6,6 +7,7 @@ using Microsoft.EntityFrameworkCore;
|
|||
using NLog;
|
||||
using NLog.Fluent;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
|
||||
namespace LANCommander.Services
|
||||
{
|
||||
|
@ -98,12 +100,25 @@ namespace LANCommander.Services
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public class ServerProcessService : BaseService
|
||||
{
|
||||
public Dictionary<Guid, Process> Processes = new Dictionary<Guid, Process>();
|
||||
public Dictionary<Guid, int> Threads { get; set; } = new Dictionary<Guid, int>();
|
||||
public Dictionary<Guid, LogFileMonitor> LogFileMonitors { get; set; } = new Dictionary<Guid, LogFileMonitor>();
|
||||
|
||||
private Dictionary<Guid, RCON> RconConnections { get; set; } = new Dictionary<Guid, RCON>();
|
||||
|
||||
public delegate void OnLogHandler(object sender, ServerLogEventArgs e);
|
||||
public event OnLogHandler OnLog;
|
||||
|
||||
|
@ -177,14 +192,36 @@ namespace LANCommander.Services
|
|||
|
||||
private void StartMonitoringLog(ServerConsole log, Server server)
|
||||
{
|
||||
var logPath = Path.Combine(server.WorkingDirectory, log.Path);
|
||||
|
||||
if (!LogFileMonitors.ContainsKey(server.Id))
|
||||
{
|
||||
LogFileMonitors[server.Id] = new LogFileMonitor(server, log, HubContext);
|
||||
}
|
||||
}
|
||||
|
||||
public RCON RconConnect(ServerConsole console)
|
||||
{
|
||||
if (!RconConnections.ContainsKey(console.Id))
|
||||
{
|
||||
var rcon = new RCON(new IPEndPoint(IPAddress.Parse(console.Host), console.Port), console.Password);
|
||||
|
||||
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 "";
|
||||
}
|
||||
|
||||
public ServerProcessStatus GetStatus(Server server)
|
||||
{
|
||||
Process process = null;
|
||||
|
|
Loading…
Add table
Reference in a new issue