diff --git a/LANCommander.Launcher/LANCommander.Launcher.csproj b/LANCommander.Launcher/LANCommander.Launcher.csproj index 3a552aca..360068ba 100644 --- a/LANCommander.Launcher/LANCommander.Launcher.csproj +++ b/LANCommander.Launcher/LANCommander.Launcher.csproj @@ -27,6 +27,7 @@ + diff --git a/LANCommander.Launcher/UI/Components/PowerShellConsole.razor b/LANCommander.Launcher/UI/Components/PowerShellConsole.razor new file mode 100644 index 00000000..0177fa5f --- /dev/null +++ b/LANCommander.Launcher/UI/Components/PowerShellConsole.razor @@ -0,0 +1,158 @@ +@using XtermBlazor +@inject SDK.Client Client + + + + +@code { + private Xterm Terminal; + private TaskCompletionSource InputTaskCompletionSource; + + private string Command { get; set; } = ""; + private int Position { get; set; } = 0; + private int Columns { get; set; } = 0; + private int Rows { get; set; } = 0; + + private TerminalOptions _options = new TerminalOptions + { + CursorBlink = true, + CursorStyle = CursorStyle.Bar, + Theme = + { + Background = "#17615e", + }, + + }; + + protected override async Task OnInitializedAsync() + { + Client.Scripts.OnDebug = async (ps) => + { + while (true) + { + InputTaskCompletionSource = new TaskCompletionSource(); + + await InputTaskCompletionSource.Task; + + await ps.InvokeAsync(); + } + }; + } + + private async Task OnFirstRender() + { + Columns = await Terminal.GetColumns(); + Rows = await Terminal.GetRows(); + } + + private async Task OnResize(ResizeEventArgs args) + { + Columns = args.Columns; + Rows = args.Rows; + } + + private async Task OnData(string data) + { + var code = System.Text.Encoding.UTF8.GetBytes(data)[0]; + + switch (code) + { + case 13: + await Terminal.Write("\r\n"); + await Terminal.WriteLine($"Output: {Command}"); + Position = 0; + Command = ""; + break; + + case 8: + case 127: + await Backspace(); + break; + + case 27: + switch (data.Substring(1)) + { + case "[C": + await CursorRight(); + break; + + case "[D": + await CursorLeft(); + break; + } + break; + + case < 32: + case > 127: + return; + + default: + Command += data; + await Key(data); + break; + } + } + + private async Task Key(string key) + { + Position++; + await Terminal.Write(key); + } + + private async Task Backspace() + { + var originalPosition = Position; + + if (originalPosition > 0) + { + // If at end of command + if (originalPosition == Command.Length) + { + await Terminal.Write("\x1b[D \x1b[D"); + + Command = Command.Substring(0, Command.Length - 1); + Position--; + } + else + { + var tail = Command.Substring(Position); + + await Terminal.Write("\x1b[D"); + await Terminal.Write(tail + " "); + + for (int i = 0; i < tail.Length + 1; i++) + { + await Terminal.Write("\x1b[D"); + } + + Position--; + + Command = Command.Substring(0, Position) + tail; + } + } + } + + private async Task CursorLeft(int count = 1) + { + for (var i = 0; i < count; i++) + { + if (Position > 0) + { + Position--; + await Terminal.Write("\x1b[D"); + } + } + } + + private async Task CursorRight(int count = 1) + { + for (var i = 0; i < count; i++) + { + if (Position < Columns && Position < Command.Length) + { + Position++; + await Terminal.Write("\x1b[C"); + } + } + } +} \ No newline at end of file diff --git a/LANCommander.Launcher/UI/MainLayout.razor b/LANCommander.Launcher/UI/MainLayout.razor index e66a7691..471c4a29 100644 --- a/LANCommander.Launcher/UI/MainLayout.razor +++ b/LANCommander.Launcher/UI/MainLayout.razor @@ -66,6 +66,11 @@ @Body + @if (Settings.Debug.EnableScriptDebugging) + { + + } + diff --git a/LANCommander.Launcher/wwwroot/index.html b/LANCommander.Launcher/wwwroot/index.html index 0be77d07..d05e26e4 100644 --- a/LANCommander.Launcher/wwwroot/index.html +++ b/LANCommander.Launcher/wwwroot/index.html @@ -5,6 +5,7 @@ LANCommander + @@ -26,6 +27,7 @@ + diff --git a/LANCommander.SDK/PowerShell/PowerShellScript.cs b/LANCommander.SDK/PowerShell/PowerShellScript.cs index 8fd42485..1ad3efb9 100644 --- a/LANCommander.SDK/PowerShell/PowerShellScript.cs +++ b/LANCommander.SDK/PowerShell/PowerShellScript.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Management.Automation; using System.Management.Automation.Runspaces; using System.Reflection; using System.Runtime.InteropServices; @@ -30,6 +31,10 @@ namespace LANCommander.SDK.PowerShell private InitialSessionState InitialSessionState { get; set; } + private TaskCompletionSource Input { get; set; } + + public Func OnDebug; + public PowerShellScript(ScriptType type) { Type = type; @@ -179,6 +184,9 @@ namespace LANCommander.SDK.PowerShell ps.AddScript(scriptBuilder.ToString()); var results = await ps.InvokeAsync(); + + if (Debug) + await OnDebug?.Invoke(ps); } } diff --git a/LANCommander.SDK/ScriptService.cs b/LANCommander.SDK/ScriptService.cs index 4a813d59..dbb0bcc7 100644 --- a/LANCommander.SDK/ScriptService.cs +++ b/LANCommander.SDK/ScriptService.cs @@ -22,6 +22,8 @@ namespace LANCommander.SDK public delegate Task ExternalScriptRunnerHandler(PowerShellScript script); public event ExternalScriptRunnerHandler ExternalScriptRunner; + public Func OnDebug; + public ScriptService(Client client) { Client = client; @@ -54,7 +56,10 @@ namespace LANCommander.SDK script.UseFile(ScriptHelper.GetScriptFilePath(installDirectory, gameId, Enums.ScriptType.Install)); if (debug) + { script.EnableDebug(); + script.OnDebug = OnDebug; + } bool handled = false; @@ -95,7 +100,10 @@ namespace LANCommander.SDK script.UseFile(path); if (debug) + { script.EnableDebug(); + script.OnDebug = OnDebug; + } bool handled = false; @@ -136,7 +144,10 @@ namespace LANCommander.SDK script.UseFile(path); if (debug) + { script.EnableDebug(); + script.OnDebug = OnDebug; + } bool handled = false; @@ -174,7 +185,10 @@ namespace LANCommander.SDK script.UseFile(path); if (debug) + { script.EnableDebug(); + script.OnDebug = OnDebug; + } bool handled = false; @@ -223,7 +237,10 @@ namespace LANCommander.SDK SDK.GameService.UpdatePlayerAlias(installDirectory, gameId, newName); if (debug) + { script.EnableDebug(); + script.OnDebug = OnDebug; + } bool handled = false; @@ -266,7 +283,10 @@ namespace LANCommander.SDK GameService.UpdateCurrentKey(installDirectory, gameId, key); if (debug) + { script.EnableDebug(); + script.OnDebug = OnDebug; + } bool handled = false;