diff --git a/LANCommander/LANCommander.csproj b/LANCommander/LANCommander.csproj
index 5e95cfd..82d2187 100644
--- a/LANCommander/LANCommander.csproj
+++ b/LANCommander/LANCommander.csproj
@@ -26,6 +26,7 @@
+
diff --git a/LANCommander/Pages/Servers/Components/Console.razor b/LANCommander/Pages/Servers/Components/Console.razor
index c8689df..989df76 100644
--- a/LANCommander/Pages/Servers/Components/Console.razor
+++ b/LANCommander/Pages/Servers/Components/Console.razor
@@ -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
+@if (ServerConsole.Type == ServerConsoleType.RCON)
+{
+
+}
+
@code {
[Parameter] public Guid ServerId { get; set; }
[Parameter] public Guid ServerConsoleId { get; set; }
@@ -17,6 +24,11 @@
HubConnection? HubConnection;
ServerConsole ServerConsole;
+ Input 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("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("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)
diff --git a/LANCommander/Services/ServerLogService.cs b/LANCommander/Services/ServerLogService.cs
index 0e92272..668c1f4 100644
--- a/LANCommander/Services/ServerLogService.cs
+++ b/LANCommander/Services/ServerLogService.cs
@@ -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);
diff --git a/LANCommander/Services/ServerProcessService.cs b/LANCommander/Services/ServerProcessService.cs
index a75ab72..1267f9d 100644
--- a/LANCommander/Services/ServerProcessService.cs
+++ b/LANCommander/Services/ServerProcessService.cs
@@ -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 Processes = new Dictionary();
public Dictionary Threads { get; set; } = new Dictionary();
public Dictionary LogFileMonitors { get; set; } = new Dictionary();
+ private Dictionary RconConnections { get; set; } = new Dictionary();
+
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 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;