Compare commits
4 commits
main
...
feature/se
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3094b03746 | ||
|
|
1f7db5c5df | ||
|
|
45f1b7b267 | ||
|
|
c28f47b632 |
22 changed files with 480 additions and 336 deletions
|
|
@ -7,6 +7,7 @@ using System.Data.Common;
|
|||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using LANCommander.SDK;
|
||||
using LANCommander.SDK.PowerShell;
|
||||
|
||||
namespace LANCommander.Launcher.Services.Extensions
|
||||
{
|
||||
|
|
@ -24,6 +25,10 @@ namespace LANCommander.Launcher.Services.Extensions
|
|||
var logger = scope.ServiceProvider.GetService<ILogger>();
|
||||
var authenticationService = scope.ServiceProvider.GetService<AuthenticationService>();
|
||||
var keepAliveService = scope.ServiceProvider.GetService<KeepAliveService>();
|
||||
var client = scope.ServiceProvider.GetService<SDK.Client>();
|
||||
var debugHandler = scope.ServiceProvider.GetService<PowerShellDebugHandler>();
|
||||
|
||||
client.Scripts.RegisterDebugHandler(debugHandler);
|
||||
|
||||
#region Scaffold Required Directories
|
||||
try
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ using System.Runtime.InteropServices;
|
|||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using LANCommander.SDK.PowerShell;
|
||||
|
||||
namespace LANCommander.Launcher.Services.Extensions
|
||||
{
|
||||
|
|
@ -81,6 +82,13 @@ namespace LANCommander.Launcher.Services.Extensions
|
|||
services.AddScoped<TagService>();
|
||||
services.AddScoped<UpdateService>();
|
||||
|
||||
var debugHandler = new PowerShellDebugHandler
|
||||
{
|
||||
SessionId = Guid.Empty,
|
||||
};
|
||||
|
||||
services.AddSingleton(debugHandler);
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
@using System.Diagnostics
|
||||
@using LANCommander.SDK
|
||||
@using LANCommander.SDK.Helpers
|
||||
@using LANCommander.SDK.PowerShell
|
||||
@inject GameService GameService
|
||||
@inject UserService UserService
|
||||
@inject LibraryService LibraryService
|
||||
|
|
@ -10,6 +11,7 @@
|
|||
@inject ModalService ModalService
|
||||
@inject MessageBusService MessageBusService
|
||||
@inject SDK.Client Client
|
||||
@inject PowerShellDebugHandler DebugHandler
|
||||
@inject LocalizationService LocalizationService
|
||||
|
||||
@if (GameActions != null && GameActions.Count() > 0)
|
||||
|
|
@ -278,7 +280,7 @@ else
|
|||
|
||||
foreach (var manifest in manifests)
|
||||
{
|
||||
await Client.Scripts.RunInstallScriptAsync(Game.InstallDirectory, manifest.Id);
|
||||
await Client.Scripts.RunInstallScriptAsync(Game.InstallDirectory, manifest.Id, DebugHandler);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -288,7 +290,7 @@ else
|
|||
|
||||
foreach (var manifest in manifests)
|
||||
{
|
||||
await Client.Scripts.RunUninstallScriptAsync(Game.InstallDirectory, manifest.Id);
|
||||
await Client.Scripts.RunUninstallScriptAsync(Game.InstallDirectory, manifest.Id, DebugHandler);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -299,7 +301,7 @@ else
|
|||
|
||||
foreach (var manifest in manifests)
|
||||
{
|
||||
await Client.Scripts.RunNameChangeScriptAsync(Game.InstallDirectory, Game.Id, user.GetUserNameSafe ?? Settings.DEFAULT_GAME_USERNAME);
|
||||
await Client.Scripts.RunNameChangeScriptAsync(Game.InstallDirectory, Game.Id, user.GetUserNameSafe ?? Settings.DEFAULT_GAME_USERNAME, DebugHandler);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -311,7 +313,7 @@ else
|
|||
{
|
||||
var key = Client.Games.GetAllocatedKey(manifest.Id);
|
||||
|
||||
await Client.Scripts.RunKeyChangeScriptAsync(Game.InstallDirectory, Game.Id, key);
|
||||
await Client.Scripts.RunKeyChangeScriptAsync(Game.InstallDirectory, Game.Id, key, DebugHandler);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,95 +0,0 @@
|
|||
@using XtermBlazor
|
||||
@using LogLevel = Microsoft.Extensions.Logging.LogLevel
|
||||
@inject SDK.Client Client
|
||||
|
||||
<div class="terminal @(Visible ? "" : "hidden")">
|
||||
<Xterm @ref="Terminal" Options="_options" OnFirstRender="@OnFirstRender" Addons="@Addons" />
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private bool Visible { get; set; } = false;
|
||||
private Xterm Terminal;
|
||||
private TaskCompletionSource<string> InputTaskCompletionSource;
|
||||
|
||||
private TerminalOptions _options = new TerminalOptions
|
||||
{
|
||||
CursorBlink = true,
|
||||
CursorStyle = CursorStyle.Bar,
|
||||
};
|
||||
|
||||
private HashSet<string> Addons = new HashSet<string>()
|
||||
{
|
||||
"readline",
|
||||
"addon-fit"
|
||||
};
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Client.Scripts.OnDebugStart = async (ps) =>
|
||||
{
|
||||
Terminal?.Clear();
|
||||
Visible = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
await Terminal.Addon("addon-fit").InvokeVoidAsync("fit");
|
||||
};
|
||||
|
||||
Client.Scripts.OnOutput = async (level, message) =>
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case LogLevel.Error:
|
||||
await Terminal.WriteLine($"\x1b[0;31m{message}");
|
||||
break;
|
||||
|
||||
case LogLevel.Warning:
|
||||
await Terminal.WriteLine($"\x1b[0;33m{message}");
|
||||
break;
|
||||
|
||||
case LogLevel.Debug:
|
||||
await Terminal.WriteLine($"\x1b[0;37m{message}");
|
||||
break;
|
||||
|
||||
case LogLevel.Trace:
|
||||
await Terminal.WriteLine($"\x1b[0;36m{message}");
|
||||
break;
|
||||
|
||||
case LogLevel.Information:
|
||||
await Terminal.WriteLine($"\x1b[0;37m{message}");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
Client.Scripts.OnDebugBreak = async (ps) =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var input = await ReadLine();
|
||||
|
||||
if (input.Trim().Equals("exit", StringComparison.OrdinalIgnoreCase))
|
||||
break;
|
||||
|
||||
if (input.StartsWith('$'))
|
||||
input = "Write-Host " + input;
|
||||
|
||||
ps.Commands.Clear();
|
||||
ps.AddScript(input);
|
||||
|
||||
await ps.InvokeAsync();
|
||||
}
|
||||
|
||||
Visible = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
};
|
||||
}
|
||||
|
||||
private async Task OnFirstRender()
|
||||
{
|
||||
await Terminal.Addon("addon-fit").InvokeVoidAsync("fit");
|
||||
}
|
||||
|
||||
private async Task<string> ReadLine()
|
||||
{
|
||||
return await Terminal.Addon("readline").InvokeAsync<string>("read", "> ");
|
||||
}
|
||||
}
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
@if (Settings.Debug.EnableScriptDebugging)
|
||||
{
|
||||
<PowerShellConsole/>
|
||||
<DebugConsole SessionId="Guid.Empty" />
|
||||
}
|
||||
|
||||
<KeepAliveContainer/>
|
||||
|
|
|
|||
13
LANCommander.SDK/Factories/ScriptFactory.cs
Normal file
13
LANCommander.SDK/Factories/ScriptFactory.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using LANCommander.SDK.Enums;
|
||||
using LANCommander.SDK.PowerShell;
|
||||
using LANCommander.SDK.Services;
|
||||
|
||||
namespace LANCommander.SDK.Factories;
|
||||
|
||||
public class ScriptFactory(ScriptService scriptService)
|
||||
{
|
||||
public PowerShellScript Create(ScriptType type)
|
||||
{
|
||||
return new PowerShellScript(type, scriptService);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,86 @@ namespace LANCommander.SDK.PowerShell;
|
|||
|
||||
public class PowerShellDebugHandler
|
||||
{
|
||||
public Func<System.Management.Automation.PowerShell, Task> OnDebugStart;
|
||||
public Func<System.Management.Automation.PowerShell, Task> OnDebugBreak;
|
||||
public Func<LogLevel, string, Task> OnOutput;
|
||||
public Guid SessionId { get; set; } = Guid.NewGuid();
|
||||
|
||||
public event EventHandler<OnDebugStartEventArgs> OnDebugStart;
|
||||
public event EventHandler<OnDebugBreakEventArgs> OnDebugBreak;
|
||||
public event EventHandler<OnDebugOutputEventArgs> OnDebugOutput;
|
||||
public event EventHandler<OnDebugStopEventArgs> OnDebugStop;
|
||||
|
||||
private System.Management.Automation.PowerShell _powerShell;
|
||||
|
||||
internal void Start(System.Management.Automation.PowerShell ps = null)
|
||||
{
|
||||
if (_powerShell == null)
|
||||
_powerShell = ps;
|
||||
|
||||
OnDebugStart?.Invoke(this, new OnDebugStartEventArgs
|
||||
{
|
||||
PowerShell = _powerShell,
|
||||
});
|
||||
}
|
||||
|
||||
internal void Break(System.Management.Automation.PowerShell ps = null)
|
||||
{
|
||||
if (_powerShell == null)
|
||||
_powerShell = ps;
|
||||
|
||||
OnDebugStart?.Invoke(this, new OnDebugStartEventArgs
|
||||
{
|
||||
PowerShell = _powerShell,
|
||||
});
|
||||
}
|
||||
|
||||
internal void Output(LogLevel level, string message)
|
||||
{
|
||||
OnDebugOutput?.Invoke(this, new OnDebugOutputEventArgs
|
||||
{
|
||||
LogLevel = level,
|
||||
Message = message
|
||||
});
|
||||
}
|
||||
|
||||
internal void Stop(System.Management.Automation.PowerShell ps = null)
|
||||
{
|
||||
if (_powerShell == null)
|
||||
_powerShell = ps;
|
||||
|
||||
OnDebugStop?.Invoke(this, new OnDebugStopEventArgs
|
||||
{
|
||||
PowerShell = _powerShell,
|
||||
});
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(string input)
|
||||
{
|
||||
if (input.StartsWith('$'))
|
||||
input = $"Write-Host {input}";
|
||||
|
||||
_powerShell.Commands.Clear();
|
||||
_powerShell.AddScript(input);
|
||||
|
||||
await _powerShell.InvokeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public class OnDebugStartEventArgs : EventArgs
|
||||
{
|
||||
public System.Management.Automation.PowerShell PowerShell { get; set; }
|
||||
}
|
||||
|
||||
public class OnDebugBreakEventArgs : EventArgs
|
||||
{
|
||||
public System.Management.Automation.PowerShell PowerShell { get; set; }
|
||||
}
|
||||
|
||||
public class OnDebugOutputEventArgs : EventArgs
|
||||
{
|
||||
public LogLevel LogLevel { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
|
||||
public class OnDebugStopEventArgs : EventArgs
|
||||
{
|
||||
public System.Management.Automation.PowerShell PowerShell { get; set; }
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ using System.Reflection;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using LANCommander.SDK.Services;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
|
||||
|
|
@ -35,6 +36,8 @@ namespace LANCommander.SDK.PowerShell
|
|||
private TaskCompletionSource<string> Input { get; set; }
|
||||
|
||||
public PowerShellDebugHandler DebugHandler { get; private set; }
|
||||
|
||||
private ScriptService ScriptService { get; set; }
|
||||
|
||||
private const string Logo = @"
|
||||
__ ___ _ _______ __
|
||||
|
|
@ -44,9 +47,11 @@ namespace LANCommander.SDK.PowerShell
|
|||
|
||||
";
|
||||
|
||||
public PowerShellScript(ScriptType type)
|
||||
public PowerShellScript(ScriptType type, ScriptService scriptService)
|
||||
{
|
||||
Type = type;
|
||||
ScriptService = scriptService;
|
||||
|
||||
Variables = new PowerShellVariableList();
|
||||
Arguments = new Dictionary<string, string>();
|
||||
DebugHandler = new PowerShellDebugHandler();
|
||||
|
|
@ -144,9 +149,13 @@ namespace LANCommander.SDK.PowerShell
|
|||
public PowerShellScript EnableDebug(PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
Debug = true;
|
||||
|
||||
|
||||
if (debugHandler != null)
|
||||
{
|
||||
DebugHandler = debugHandler;
|
||||
|
||||
ScriptService.RegisterDebugHandler(debugHandler);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
|
@ -184,9 +193,9 @@ namespace LANCommander.SDK.PowerShell
|
|||
using (var ps = System.Management.Automation.PowerShell.Create())
|
||||
{
|
||||
ps.Runspace = runspace;
|
||||
|
||||
|
||||
if (Debug)
|
||||
await (DebugHandler.OnDebugStart?.Invoke(ps) ?? Task.CompletedTask);
|
||||
DebugHandler.Start(ps);
|
||||
|
||||
ps.AddScript("Write-Host $Logo");
|
||||
|
||||
|
|
@ -206,21 +215,18 @@ namespace LANCommander.SDK.PowerShell
|
|||
|
||||
ps.AddScript("Write-Host ''");
|
||||
ps.AddScript("Write-Host 'Enter \"exit\" to continue'");
|
||||
|
||||
if (DebugHandler.OnOutput != null)
|
||||
{
|
||||
ps.Streams.Information.DataAdded += Information_DataAdded;
|
||||
ps.Streams.Verbose.DataAdded += Verbose_DataAdded;
|
||||
ps.Streams.Debug.DataAdded += Debug_DataAdded;
|
||||
ps.Streams.Warning.DataAdded += Warning_DataAdded;
|
||||
ps.Streams.Error.DataAdded += Error_DataAdded;
|
||||
}
|
||||
|
||||
ps.Streams.Information.DataAdded += Information_DataAdded;
|
||||
ps.Streams.Verbose.DataAdded += Verbose_DataAdded;
|
||||
ps.Streams.Debug.DataAdded += Debug_DataAdded;
|
||||
ps.Streams.Warning.DataAdded += Warning_DataAdded;
|
||||
ps.Streams.Error.DataAdded += Error_DataAdded;
|
||||
}
|
||||
|
||||
var results = await ps.InvokeAsync();
|
||||
|
||||
if (Debug)
|
||||
await (DebugHandler.OnDebugBreak?.Invoke(ps) ?? Task.CompletedTask);
|
||||
DebugHandler.Break(ps);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -239,6 +245,9 @@ namespace LANCommander.SDK.PowerShell
|
|||
if (IgnoreWow64)
|
||||
Wow64RevertWow64FsRedirection(ref wow64Value);
|
||||
|
||||
if (DebugHandler != null)
|
||||
ScriptService.DeregisterDebugHandler(DebugHandler);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -246,29 +255,29 @@ namespace LANCommander.SDK.PowerShell
|
|||
{
|
||||
var record = ((PSDataCollection<ErrorRecord>)sender)[e.Index];
|
||||
|
||||
DebugHandler.OnOutput?.Invoke(LogLevel.Error, $"{record.InvocationInfo.InvocationName} : {record.Exception.Message}");
|
||||
DebugHandler.OnOutput?.Invoke(LogLevel.Error, record.InvocationInfo.PositionMessage);
|
||||
DebugHandler.Output(LogLevel.Error, $"{record.InvocationInfo.InvocationName} : {record.Exception.Message}");
|
||||
DebugHandler.Output(LogLevel.Error, record.InvocationInfo.PositionMessage);
|
||||
}
|
||||
|
||||
private void Warning_DataAdded(object sender, DataAddedEventArgs e)
|
||||
{
|
||||
var record = ((PSDataCollection<WarningRecord>)sender)[e.Index];
|
||||
|
||||
DebugHandler.OnOutput?.Invoke(LogLevel.Warning, record.Message);
|
||||
DebugHandler.Output(LogLevel.Warning, record.Message);
|
||||
}
|
||||
|
||||
private void Debug_DataAdded(object sender, DataAddedEventArgs e)
|
||||
{
|
||||
var record = ((PSDataCollection<DebugRecord>)sender)[e.Index];
|
||||
|
||||
DebugHandler.OnOutput?.Invoke(LogLevel.Debug, record.Message);
|
||||
DebugHandler.Output(LogLevel.Debug, record.Message);
|
||||
}
|
||||
|
||||
private void Verbose_DataAdded(object sender, DataAddedEventArgs e)
|
||||
{
|
||||
var record = ((PSDataCollection<VerboseRecord>)sender)[e.Index];
|
||||
|
||||
DebugHandler.OnOutput?.Invoke(LogLevel.Trace, record.Message);
|
||||
DebugHandler.Output(LogLevel.Trace, record.Message);
|
||||
}
|
||||
|
||||
private void Information_DataAdded(object sender, DataAddedEventArgs e)
|
||||
|
|
@ -276,7 +285,7 @@ namespace LANCommander.SDK.PowerShell
|
|||
var record = ((PSDataCollection<InformationRecord>)sender)[e.Index];
|
||||
|
||||
if (record.MessageData != null && record.MessageData is HostInformationMessage)
|
||||
DebugHandler.OnOutput?.Invoke(LogLevel.Information, (record.MessageData as HostInformationMessage).Message);
|
||||
DebugHandler.Output(LogLevel.Information, (record.MessageData as HostInformationMessage).Message);
|
||||
}
|
||||
|
||||
public static string Serialize<T>(T input)
|
||||
|
|
|
|||
9
LANCommander.SDK/Rpc/Interfaces/Client/Log.cs
Normal file
9
LANCommander.SDK/Rpc/Interfaces/Client/Log.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LANCommander.SDK.Rpc.Client;
|
||||
|
||||
public partial interface IRpcClient
|
||||
{
|
||||
Task Log_ConsoleOutputAsync(Guid sessionId, string content);
|
||||
}
|
||||
12
LANCommander.SDK/Rpc/Interfaces/Client/Script.cs
Normal file
12
LANCommander.SDK/Rpc/Interfaces/Client/Script.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace LANCommander.SDK.Rpc.Client;
|
||||
|
||||
public partial interface IRpcClient
|
||||
{
|
||||
Task Script_DebugOutputAsync(Guid sessionId, LogLevel level, string message);
|
||||
Task Script_DebugStartAsync(Guid sessionId);
|
||||
Task Script_DebugBreakAsync(Guid sessionId);
|
||||
}
|
||||
10
LANCommander.SDK/Rpc/Interfaces/Server/Script.cs
Normal file
10
LANCommander.SDK/Rpc/Interfaces/Server/Script.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LANCommander.SDK.Rpc.Server;
|
||||
|
||||
public partial interface IRpcHub
|
||||
{
|
||||
Task Script_ExecuteAsync(Guid scriptId);
|
||||
Task Script_ConsoleInputAsync(Guid sessionId, string input);
|
||||
}
|
||||
12
LANCommander.SDK/Rpc/Log.cs
Normal file
12
LANCommander.SDK/Rpc/Log.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LANCommander.SDK.Rpc;
|
||||
|
||||
public partial class RpcClient
|
||||
{
|
||||
public async Task Log_ConsoleOutputAsync(Guid sessionId, string content)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
35
LANCommander.SDK/Rpc/Script.cs
Normal file
35
LANCommander.SDK/Rpc/Script.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using LANCommander.SDK.PowerShell;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace LANCommander.SDK.Rpc;
|
||||
|
||||
public partial class RpcClient
|
||||
{
|
||||
private Dictionary<Guid, PowerShellDebugHandler> _debugHandlers = new();
|
||||
|
||||
public void AddDebugHandler(Guid sessionId, PowerShellDebugHandler handler)
|
||||
{
|
||||
_debugHandlers[sessionId] = handler;
|
||||
}
|
||||
|
||||
public async Task Script_DebugOutputAsync(Guid sessionId, LogLevel level, string message)
|
||||
{
|
||||
if (_debugHandlers.ContainsKey(sessionId))
|
||||
_debugHandlers[sessionId].Output(level, message);
|
||||
}
|
||||
|
||||
public async Task Script_DebugStartAsync(Guid sessionId)
|
||||
{
|
||||
if (_debugHandlers.ContainsKey(sessionId))
|
||||
_debugHandlers[sessionId].Start();
|
||||
}
|
||||
|
||||
public async Task Script_DebugBreakAsync(Guid sessionId)
|
||||
{
|
||||
if (_debugHandlers.ContainsKey(sessionId))
|
||||
_debugHandlers[sessionId].Break();
|
||||
}
|
||||
}
|
||||
|
|
@ -198,7 +198,7 @@ namespace LANCommander.SDK.Services
|
|||
{
|
||||
var registryImportFileContents = File.ReadAllText(registryImportFilePath);
|
||||
|
||||
var script = new PowerShellScript(Enums.ScriptType.SaveDownload);
|
||||
var script = new PowerShellScript(Enums.ScriptType.SaveDownload, _client.Scripts);
|
||||
|
||||
string adminArgument = string.Empty;
|
||||
if (registryImportFileContents.Contains("HKEY_LOCAL_MACHINE"))
|
||||
|
|
@ -208,14 +208,9 @@ namespace LANCommander.SDK.Services
|
|||
}
|
||||
|
||||
script.UseInline($"Start-Process regedit.exe {adminArgument} -ArgumentList \"/s\", \"{registryImportFilePath}\"");
|
||||
|
||||
|
||||
if (_client.Scripts.Debug)
|
||||
{
|
||||
script.EnableDebug();
|
||||
script.DebugHandler.OnDebugStart = _client.Scripts.OnDebugStart;
|
||||
script.DebugHandler.OnDebugBreak = _client.Scripts.OnDebugBreak;
|
||||
script.DebugHandler.OnOutput = _client.Scripts.OnOutput;
|
||||
}
|
||||
|
||||
await script.ExecuteAsync<int>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using LANCommander.SDK.Models;
|
|||
using LANCommander.SDK.PowerShell;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
|
@ -17,15 +18,13 @@ namespace LANCommander.SDK.Services
|
|||
|
||||
private readonly Client _client;
|
||||
|
||||
private List<PowerShellDebugHandler> _debugHandlers = new();
|
||||
|
||||
public delegate Task<bool> ExternalScriptRunnerHandler(PowerShellScript script);
|
||||
public event ExternalScriptRunnerHandler ExternalScriptRunner;
|
||||
|
||||
public bool Debug { get; set; } = false;
|
||||
|
||||
public Func<System.Management.Automation.PowerShell, Task> OnDebugStart;
|
||||
public Func<System.Management.Automation.PowerShell, Task> OnDebugBreak;
|
||||
public Func<LogLevel, string, Task> OnOutput;
|
||||
|
||||
public ScriptService(Client client)
|
||||
{
|
||||
_client = client;
|
||||
|
|
@ -36,18 +35,36 @@ namespace LANCommander.SDK.Services
|
|||
_client = client;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void RegisterDebugHandler(PowerShellDebugHandler debugHandler)
|
||||
{
|
||||
_debugHandlers.Add(debugHandler);
|
||||
}
|
||||
|
||||
public void DeregisterDebugHandler(PowerShellDebugHandler debugHandler)
|
||||
{
|
||||
_debugHandlers.Remove(debugHandler);
|
||||
}
|
||||
|
||||
public PowerShellDebugHandler GetDebugHandler(Guid sessionId)
|
||||
{
|
||||
return _debugHandlers.FirstOrDefault(h => h.SessionId == sessionId);
|
||||
}
|
||||
|
||||
#region Authentication Scripts
|
||||
public async Task RunUserLoginScript(Script loginScript, User user)
|
||||
public async Task RunUserLoginScript(Script loginScript, User user, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var op = _logger.BeginOperation("Executing user login script"))
|
||||
{
|
||||
var script = new PowerShellScript(Enums.ScriptType.UserLogin);
|
||||
var script = new PowerShellScript(Enums.ScriptType.UserLogin, _client.Scripts);
|
||||
|
||||
script.AddVariable("User", user);
|
||||
|
||||
if (Debug)
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
script.UseInline(loginScript.Contents);
|
||||
|
||||
try
|
||||
|
|
@ -72,15 +89,18 @@ namespace LANCommander.SDK.Services
|
|||
}
|
||||
}
|
||||
|
||||
public async Task RunUserRegistrationScript(Script registrationScript, User user)
|
||||
public async Task RunUserRegistrationScript(Script registrationScript, User user, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var op = _logger.BeginOperation("Executing user registration script"))
|
||||
{
|
||||
var script = new PowerShellScript(Enums.ScriptType.UserRegistration);
|
||||
var script = new PowerShellScript(Enums.ScriptType.UserRegistration, _client.Scripts);
|
||||
|
||||
script.AddVariable("User", user);
|
||||
|
||||
if (Debug)
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
script.UseInline(registrationScript.Contents);
|
||||
|
||||
|
|
@ -108,7 +128,7 @@ namespace LANCommander.SDK.Services
|
|||
#endregion
|
||||
|
||||
#region Redistributables
|
||||
public async Task<bool> RunDetectInstallScriptAsync(string installDirectory, Guid gameId, Guid redistributableId)
|
||||
public async Task<bool> RunDetectInstallScriptAsync(string installDirectory, Guid gameId, Guid redistributableId, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
bool result = default;
|
||||
|
||||
|
|
@ -123,10 +143,10 @@ namespace LANCommander.SDK.Services
|
|||
{
|
||||
using (var op = _logger.BeginOperation("Executing install detection script"))
|
||||
{
|
||||
var script = new PowerShellScript(Enums.ScriptType.DetectInstall);
|
||||
var script = new PowerShellScript(Enums.ScriptType.DetectInstall, _client.Scripts);
|
||||
|
||||
if (Debug)
|
||||
script.DebugHandler.OnDebugStart = OnDebugStart;
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
script.AddVariable("InstallDirectory", installDirectory);
|
||||
script.AddVariable("GameManifest", gameManifest);
|
||||
|
|
@ -161,20 +181,6 @@ namespace LANCommander.SDK.Services
|
|||
script.UseWorkingDirectory(Path.Combine(GameService.GetMetadataDirectoryPath(installDirectory, redistributableId)));
|
||||
script.UseFile(path);
|
||||
|
||||
try
|
||||
{
|
||||
if (Debug)
|
||||
{
|
||||
script.EnableDebug();
|
||||
script.DebugHandler.OnDebugBreak = OnDebugBreak;
|
||||
script.DebugHandler.OnOutput = OnOutput;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "Could not debug script");
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (ExternalScriptRunner != null)
|
||||
|
|
@ -194,7 +200,8 @@ namespace LANCommander.SDK.Services
|
|||
}
|
||||
}
|
||||
}
|
||||
result = await script.ExecuteAsync<bool>();
|
||||
|
||||
result = await script.ExecuteAsync<bool>();
|
||||
|
||||
op.Complete();
|
||||
}
|
||||
|
|
@ -208,7 +215,7 @@ namespace LANCommander.SDK.Services
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> RunInstallScriptAsync(string installDirectory, Guid gameId, Guid redistributableId)
|
||||
public async Task<int> RunInstallScriptAsync(string installDirectory, Guid gameId, Guid redistributableId, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
int result = default;
|
||||
|
||||
|
|
@ -223,10 +230,10 @@ namespace LANCommander.SDK.Services
|
|||
{
|
||||
using (var op = _logger.BeginOperation("Executing install detection script"))
|
||||
{
|
||||
var script = new PowerShellScript(Enums.ScriptType.Install);
|
||||
var script = new PowerShellScript(Enums.ScriptType.Install, _client.Scripts);
|
||||
|
||||
if (Debug)
|
||||
script.DebugHandler.OnDebugStart = OnDebugStart;
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
script.AddVariable("InstallDirectory", installDirectory);
|
||||
script.AddVariable("GameManifest", gameManifest);
|
||||
|
|
@ -264,20 +271,6 @@ namespace LANCommander.SDK.Services
|
|||
script.UseWorkingDirectory(extractionPath);
|
||||
script.UseFile(path);
|
||||
|
||||
try
|
||||
{
|
||||
if (Debug)
|
||||
{
|
||||
script.EnableDebug();
|
||||
script.DebugHandler.OnDebugBreak = OnDebugBreak;
|
||||
script.DebugHandler.OnOutput = OnOutput;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "Could not debug script");
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (ExternalScriptRunner != null)
|
||||
|
|
@ -298,7 +291,7 @@ namespace LANCommander.SDK.Services
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> RunBeforeStartScriptAsync(string installDirectory, Guid gameId, Guid redistributableId)
|
||||
public async Task<int> RunBeforeStartScriptAsync(string installDirectory, Guid gameId, Guid redistributableId, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
int result = default;
|
||||
|
||||
|
|
@ -313,11 +306,11 @@ namespace LANCommander.SDK.Services
|
|||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var script = new PowerShellScript(Enums.ScriptType.BeforeStart);
|
||||
var script = new PowerShellScript(Enums.ScriptType.BeforeStart, _client.Scripts);
|
||||
var playerAlias = await GameService.GetPlayerAliasAsync(installDirectory, gameId);
|
||||
|
||||
if (Debug)
|
||||
script.DebugHandler.OnDebugStart = OnDebugStart;
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
script.AddVariable("InstallDirectory", installDirectory);
|
||||
script.AddVariable("GameManifest", gameManifest);
|
||||
|
|
@ -357,20 +350,6 @@ namespace LANCommander.SDK.Services
|
|||
script.UseWorkingDirectory(extractionPath);
|
||||
script.UseFile(path);
|
||||
|
||||
try
|
||||
{
|
||||
if (Debug)
|
||||
{
|
||||
script.EnableDebug();
|
||||
script.DebugHandler.OnDebugBreak = OnDebugBreak;
|
||||
script.DebugHandler.OnOutput = OnOutput;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "Could not debug script");
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (ExternalScriptRunner != null)
|
||||
|
|
@ -395,7 +374,7 @@ namespace LANCommander.SDK.Services
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> RunAfterStopScriptAsync(string installDirectory, Guid gameId, Guid redistributableId)
|
||||
public async Task<int> RunAfterStopScriptAsync(string installDirectory, Guid gameId, Guid redistributableId, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
int result = default;
|
||||
|
||||
|
|
@ -410,10 +389,10 @@ namespace LANCommander.SDK.Services
|
|||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var script = new PowerShellScript(Enums.ScriptType.AfterStop);
|
||||
var script = new PowerShellScript(Enums.ScriptType.AfterStop, _client.Scripts);
|
||||
|
||||
if (Debug)
|
||||
script.DebugHandler.OnDebugStart = OnDebugStart;
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
script.AddVariable("InstallDirectory", installDirectory);
|
||||
script.AddVariable("GameManifest", gameManifest);
|
||||
|
|
@ -453,20 +432,6 @@ namespace LANCommander.SDK.Services
|
|||
script.UseWorkingDirectory(extractionPath);
|
||||
script.UseFile(path);
|
||||
|
||||
try
|
||||
{
|
||||
if (Debug)
|
||||
{
|
||||
script.EnableDebug();
|
||||
script.DebugHandler.OnDebugBreak = OnDebugBreak;
|
||||
script.DebugHandler.OnOutput = OnOutput;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "Could not debug script");
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (ExternalScriptRunner != null)
|
||||
|
|
@ -492,7 +457,7 @@ namespace LANCommander.SDK.Services
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> RunNameChangeScriptAsync(string installDirectory, Guid gameId, Guid redistributableId, string newName)
|
||||
public async Task<int> RunNameChangeScriptAsync(string installDirectory, Guid gameId, Guid redistributableId, string newName, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
int result = default;
|
||||
|
||||
|
|
@ -517,10 +482,10 @@ namespace LANCommander.SDK.Services
|
|||
|
||||
_logger?.LogTrace("New Name: {NewName}", newName);
|
||||
|
||||
var script = new PowerShellScript(Enums.ScriptType.NameChange);
|
||||
var script = new PowerShellScript(Enums.ScriptType.NameChange, _client.Scripts);
|
||||
|
||||
if (Debug)
|
||||
script.DebugHandler.OnDebugStart = OnDebugStart;
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
script.AddVariable("InstallDirectory", installDirectory);
|
||||
script.AddVariable("GameManifest", gameManifest);
|
||||
|
|
@ -561,20 +526,6 @@ namespace LANCommander.SDK.Services
|
|||
script.UseWorkingDirectory(extractionPath);
|
||||
script.UseFile(path);
|
||||
|
||||
try
|
||||
{
|
||||
if (Debug)
|
||||
{
|
||||
script.EnableDebug();
|
||||
script.DebugHandler.OnDebugBreak = OnDebugBreak;
|
||||
script.DebugHandler.OnOutput = OnOutput;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "Could not debug script");
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (ExternalScriptRunner != null)
|
||||
|
|
@ -602,7 +553,7 @@ namespace LANCommander.SDK.Services
|
|||
#endregion
|
||||
|
||||
#region Games
|
||||
public async Task<int> RunInstallScriptAsync(string installDirectory, Guid gameId)
|
||||
public async Task<int> RunInstallScriptAsync(string installDirectory, Guid gameId, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
int result = default;
|
||||
|
||||
|
|
@ -615,10 +566,10 @@ namespace LANCommander.SDK.Services
|
|||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var script = new PowerShellScript(Enums.ScriptType.Install);
|
||||
var script = new PowerShellScript(Enums.ScriptType.Install, _client.Scripts);
|
||||
|
||||
if (Debug)
|
||||
script.DebugHandler.OnDebugStart = OnDebugStart;
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
script.AddVariable("InstallDirectory", installDirectory);
|
||||
script.AddVariable("GameManifest", manifest);
|
||||
|
|
@ -648,20 +599,6 @@ namespace LANCommander.SDK.Services
|
|||
_logger?.LogError(ex, "Could not enrich logs");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Debug)
|
||||
{
|
||||
script.EnableDebug();
|
||||
script.DebugHandler.OnDebugBreak = OnDebugBreak;
|
||||
script.DebugHandler.OnOutput = OnOutput;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "Could not debug script");
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (ExternalScriptRunner != null)
|
||||
|
|
@ -686,7 +623,7 @@ namespace LANCommander.SDK.Services
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> RunUninstallScriptAsync(string installDirectory, Guid gameId)
|
||||
public async Task<int> RunUninstallScriptAsync(string installDirectory, Guid gameId, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
int result = default;
|
||||
|
||||
|
|
@ -699,10 +636,10 @@ namespace LANCommander.SDK.Services
|
|||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var script = new PowerShellScript(Enums.ScriptType.Uninstall);
|
||||
var script = new PowerShellScript(Enums.ScriptType.Uninstall, _client.Scripts);
|
||||
|
||||
if (Debug)
|
||||
script.DebugHandler.OnDebugStart = OnDebugStart;
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
script.AddVariable("InstallDirectory", installDirectory);
|
||||
script.AddVariable("GameManifest", manifest);
|
||||
|
|
@ -732,20 +669,6 @@ namespace LANCommander.SDK.Services
|
|||
_logger?.LogError(ex, "Could not enrich logs");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Debug)
|
||||
{
|
||||
script.EnableDebug();
|
||||
script.DebugHandler.OnDebugBreak = OnDebugBreak;
|
||||
script.DebugHandler.OnOutput = OnOutput;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "Could not debug script");
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (ExternalScriptRunner != null)
|
||||
|
|
@ -770,7 +693,7 @@ namespace LANCommander.SDK.Services
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> RunBeforeStartScriptAsync(string installDirectory, Guid gameId)
|
||||
public async Task<int> RunBeforeStartScriptAsync(string installDirectory, Guid gameId, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
int result = default;
|
||||
|
||||
|
|
@ -783,11 +706,11 @@ namespace LANCommander.SDK.Services
|
|||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var script = new PowerShellScript(Enums.ScriptType.BeforeStart);
|
||||
var script = new PowerShellScript(Enums.ScriptType.BeforeStart, _client.Scripts);
|
||||
var playerAlias = GameService.GetPlayerAlias(installDirectory, gameId);
|
||||
|
||||
if (Debug)
|
||||
script.DebugHandler.OnDebugStart = OnDebugStart;
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
script.AddVariable("InstallDirectory", installDirectory);
|
||||
script.AddVariable("GameManifest", manifest);
|
||||
|
|
@ -819,20 +742,6 @@ namespace LANCommander.SDK.Services
|
|||
_logger?.LogError(ex, "Could not enrich logs");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Debug)
|
||||
{
|
||||
script.EnableDebug();
|
||||
script.DebugHandler.OnDebugBreak = OnDebugBreak;
|
||||
script.DebugHandler.OnOutput = OnOutput;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "Could not debug script");
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (ExternalScriptRunner != null)
|
||||
|
|
@ -857,7 +766,7 @@ namespace LANCommander.SDK.Services
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> RunAfterStopScriptAsync(string installDirectory, Guid gameId)
|
||||
public async Task<int> RunAfterStopScriptAsync(string installDirectory, Guid gameId, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
int result = default;
|
||||
|
||||
|
|
@ -870,10 +779,10 @@ namespace LANCommander.SDK.Services
|
|||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var script = new PowerShellScript(Enums.ScriptType.AfterStop);
|
||||
var script = new PowerShellScript(Enums.ScriptType.AfterStop, _client.Scripts);
|
||||
|
||||
if (Debug)
|
||||
script.DebugHandler.OnDebugStart = OnDebugStart;
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
script.AddVariable("InstallDirectory", installDirectory);
|
||||
script.AddVariable("GameManifest", manifest);
|
||||
|
|
@ -904,20 +813,6 @@ namespace LANCommander.SDK.Services
|
|||
_logger?.LogError(ex, "Could not enrich logs");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Debug)
|
||||
{
|
||||
script.EnableDebug();
|
||||
script.DebugHandler.OnDebugBreak = OnDebugBreak;
|
||||
script.DebugHandler.OnOutput = OnOutput;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "Could not debug script");
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (ExternalScriptRunner != null)
|
||||
|
|
@ -943,7 +838,7 @@ namespace LANCommander.SDK.Services
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> RunNameChangeScriptAsync(string installDirectory, Guid gameId, string newName)
|
||||
public async Task<int> RunNameChangeScriptAsync(string installDirectory, Guid gameId, string newName, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
int result = default;
|
||||
|
||||
|
|
@ -966,10 +861,10 @@ namespace LANCommander.SDK.Services
|
|||
|
||||
_logger?.LogTrace("New Name: {NewName}", newName);
|
||||
|
||||
var script = new PowerShellScript(Enums.ScriptType.NameChange);
|
||||
var script = new PowerShellScript(Enums.ScriptType.NameChange, _client.Scripts);
|
||||
|
||||
if (Debug)
|
||||
script.DebugHandler.OnDebugStart = OnDebugStart;
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
script.AddVariable("InstallDirectory", installDirectory);
|
||||
script.AddVariable("GameManifest", manifest);
|
||||
|
|
@ -1005,20 +900,6 @@ namespace LANCommander.SDK.Services
|
|||
|
||||
GameService.UpdatePlayerAlias(installDirectory, gameId, newName);
|
||||
|
||||
try
|
||||
{
|
||||
if (Debug)
|
||||
{
|
||||
script.EnableDebug();
|
||||
script.DebugHandler.OnDebugBreak = OnDebugBreak;
|
||||
script.DebugHandler.OnOutput = OnOutput;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "Could not debug script");
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (ExternalScriptRunner != null)
|
||||
|
|
@ -1043,7 +924,7 @@ namespace LANCommander.SDK.Services
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> RunKeyChangeScriptAsync(string installDirectory, Guid gameId, string key)
|
||||
public async Task<int> RunKeyChangeScriptAsync(string installDirectory, Guid gameId, string key, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
int result = default;
|
||||
|
||||
|
|
@ -1056,10 +937,10 @@ namespace LANCommander.SDK.Services
|
|||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var script = new PowerShellScript(Enums.ScriptType.KeyChange);
|
||||
var script = new PowerShellScript(Enums.ScriptType.KeyChange, _client.Scripts);
|
||||
|
||||
if (Debug)
|
||||
script.DebugHandler.OnDebugStart = OnDebugStart;
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
_logger?.LogTrace("New key is {Key}", key);
|
||||
|
||||
|
|
@ -1095,20 +976,6 @@ namespace LANCommander.SDK.Services
|
|||
|
||||
GameService.UpdateCurrentKey(installDirectory, gameId, key);
|
||||
|
||||
try
|
||||
{
|
||||
if (Debug)
|
||||
{
|
||||
script.EnableDebug();
|
||||
script.DebugHandler.OnDebugBreak = OnDebugBreak;
|
||||
script.DebugHandler.OnOutput = OnOutput;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "Could not debug script");
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
if (ExternalScriptRunner != null)
|
||||
|
|
@ -1133,17 +1000,20 @@ namespace LANCommander.SDK.Services
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task<Package> RunPackageScriptAsync(Script packageScript, Game game)
|
||||
public async Task<Package> RunPackageScriptAsync(Script packageScript, Game game, PowerShellDebugHandler debugHandler = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var op = _logger.BeginOperation("Executing game package script"))
|
||||
{
|
||||
var script = new PowerShellScript(Enums.ScriptType.Package);
|
||||
var script = new PowerShellScript(Enums.ScriptType.Package, _client.Scripts);
|
||||
|
||||
script.AddVariable("Game", game);
|
||||
|
||||
|
||||
script.UseInline(packageScript.Contents);
|
||||
|
||||
if (Debug)
|
||||
script.EnableDebug(debugHandler);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ public class DockerServerEngine(
|
|||
{
|
||||
try
|
||||
{
|
||||
var script = new PowerShellScript(SDK.Enums.ScriptType.BeforeStart);
|
||||
var script = new PowerShellScript(SDK.Enums.ScriptType.BeforeStart, client.Scripts);
|
||||
|
||||
script.AddVariable("Server", mapper.Map<SDK.Models.Server>(server));
|
||||
|
||||
|
|
@ -159,7 +159,7 @@ public class DockerServerEngine(
|
|||
{
|
||||
try
|
||||
{
|
||||
var script = new PowerShellScript(SDK.Enums.ScriptType.AfterStop);
|
||||
var script = new PowerShellScript(SDK.Enums.ScriptType.AfterStop, client.Scripts);
|
||||
|
||||
script.AddVariable("Server", mapper.Map<SDK.Models.Server>(server));
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ public class LocalServerEngine(
|
|||
{
|
||||
try
|
||||
{
|
||||
var script = new PowerShellScript(SDK.Enums.ScriptType.BeforeStart);
|
||||
var script = new PowerShellScript(SDK.Enums.ScriptType.BeforeStart, client.Scripts);
|
||||
|
||||
script.AddVariable("Server", mapper.Map<SDK.Models.Server>(server));
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ public class LocalServerEngine(
|
|||
{
|
||||
try
|
||||
{
|
||||
var script = new PowerShellScript(SDK.Enums.ScriptType.AfterStop);
|
||||
var script = new PowerShellScript(SDK.Enums.ScriptType.AfterStop, client.Scripts);
|
||||
|
||||
script.AddVariable("Server", mapper.Map<SDK.Models.Server>(server));
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ namespace LANCommander.Server.Services
|
|||
IHttpContextAccessor httpContextAccessor,
|
||||
IDbContextFactory<DatabaseContext> contextFactory,
|
||||
IServiceProvider serviceProvider,
|
||||
UserService userService) : BaseDatabaseService<Data.Models.Server>(logger, cache, mapper, httpContextAccessor, contextFactory)
|
||||
UserService userService,
|
||||
SDK.Client client) : BaseDatabaseService<Data.Models.Server>(logger, cache, mapper, httpContextAccessor, contextFactory)
|
||||
{
|
||||
public override async Task<Data.Models.Server> AddAsync(Data.Models.Server entity)
|
||||
{
|
||||
|
|
@ -118,7 +119,7 @@ namespace LANCommander.Server.Services
|
|||
{
|
||||
try
|
||||
{
|
||||
var scriptContext = new PowerShellScript(ScriptType.GameStarted);
|
||||
var scriptContext = new PowerShellScript(ScriptType.GameStarted, client.Scripts);
|
||||
|
||||
scriptContext.AddVariable("Server", mapper.Map<SDK.Models.Server>(server));
|
||||
scriptContext.AddVariable("Game", mapper.Map<SDK.Models.Game>(server.Game));
|
||||
|
|
@ -151,7 +152,7 @@ namespace LANCommander.Server.Services
|
|||
{
|
||||
try
|
||||
{
|
||||
var scriptContext = new PowerShellScript(ScriptType.GameStopped);
|
||||
var scriptContext = new PowerShellScript(ScriptType.GameStopped, client.Scripts);
|
||||
|
||||
scriptContext.AddVariable("Server", mapper.Map<SDK.Models.Server>(server));
|
||||
scriptContext.AddVariable("Game", mapper.Map<SDK.Models.Game>(server.Game));
|
||||
|
|
|
|||
6
LANCommander.Server/Hubs/Log.cs
Normal file
6
LANCommander.Server/Hubs/Log.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
namespace LANCommander.Server.Hubs;
|
||||
|
||||
public partial class RpcHub
|
||||
{
|
||||
|
||||
}
|
||||
59
LANCommander.Server/Hubs/Script.cs
Normal file
59
LANCommander.Server/Hubs/Script.cs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
using System.Management.Automation;
|
||||
using LANCommander.SDK.Enums;
|
||||
using LANCommander.SDK.Models;
|
||||
using LANCommander.SDK.PowerShell;
|
||||
|
||||
namespace LANCommander.Server.Hubs;
|
||||
|
||||
public partial class RpcHub
|
||||
{
|
||||
private readonly Dictionary<Guid, Script> _scripts = new Dictionary<Guid, Script>();
|
||||
private string GetScriptSessionGroupName(Guid sessionId) => $"Script/Sessions/{sessionId}";
|
||||
|
||||
public async Task Script_ExecuteAsync(Guid scriptId)
|
||||
{
|
||||
var script = await scriptService.GetAsync(scriptId);
|
||||
var game = await gameService.GetAsync(script.GameId ?? Guid.Empty);
|
||||
|
||||
if (script.Type == ScriptType.Package)
|
||||
{
|
||||
var debugHandler = new PowerShellDebugHandler();
|
||||
|
||||
debugHandler.OnDebugOutput += DebugOutput;
|
||||
debugHandler.OnDebugBreak += DebugBreak;
|
||||
debugHandler.OnDebugStart += DebugStart;
|
||||
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, GetScriptSessionGroupName(debugHandler.SessionId));
|
||||
await Clients.Group(GetScriptSessionGroupName(debugHandler.SessionId))
|
||||
.Script_DebugStartAsync(debugHandler.SessionId);
|
||||
|
||||
await client.Scripts.RunPackageScriptAsync(mapper.Map<SDK.Models.Script>(script), mapper.Map<SDK.Models.Game>(game), debugHandler);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Script_ConsoleInputAsync(Guid sessionId, string input)
|
||||
{
|
||||
var debugHandler = client.Scripts.GetDebugHandler(sessionId);
|
||||
|
||||
if (debugHandler != null)
|
||||
await debugHandler.ExecuteAsync(input);
|
||||
}
|
||||
|
||||
private void DebugStart(object? sender, OnDebugStartEventArgs args)
|
||||
{
|
||||
if (sender is PowerShellDebugHandler debugHandler)
|
||||
Clients.Caller.Script_DebugStartAsync(debugHandler.SessionId);
|
||||
}
|
||||
|
||||
private void DebugBreak(object? sender, OnDebugBreakEventArgs args)
|
||||
{
|
||||
if (sender is PowerShellDebugHandler debugHandler)
|
||||
Clients.Caller.Script_DebugBreakAsync(debugHandler.SessionId);
|
||||
}
|
||||
|
||||
private void DebugOutput(object? sender, OnDebugOutputEventArgs args)
|
||||
{
|
||||
if (sender is PowerShellDebugHandler debugHandler)
|
||||
Clients.Caller.Script_DebugOutputAsync(debugHandler.SessionId, args.LogLevel, args.Message);
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,10 @@ namespace LANCommander.Server.Hubs;
|
|||
public partial class RpcHub(
|
||||
IFusionCache cache,
|
||||
IMapper mapper,
|
||||
SDK.Client client,
|
||||
ChatService chatService,
|
||||
GameService gameService,
|
||||
ScriptService scriptService,
|
||||
ServerService serverService) : Hub<IRpcClient>, IRpcHub
|
||||
{
|
||||
|
||||
|
|
|
|||
111
LANCommander.UI/Components/DebugConsole/DebugConsole.razor
Normal file
111
LANCommander.UI/Components/DebugConsole/DebugConsole.razor
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
@using LANCommander.SDK
|
||||
@using LANCommander.SDK.PowerShell
|
||||
@using XtermBlazor
|
||||
@using LogLevel = Microsoft.Extensions.Logging.LogLevel
|
||||
@inject Client Client
|
||||
@namespace LANCommander.UI.Components
|
||||
|
||||
<div class="terminal @(Visible ? "" : "hidden")">
|
||||
<Xterm @ref="Terminal" Options="_options" OnFirstRender="@OnFirstRender" Addons="@Addons" />
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter] public PowerShellDebugHandler DebugHandler { get; set; }
|
||||
[Parameter] public Guid? SessionId { get; set; }
|
||||
|
||||
private bool Visible { get; set; } = false;
|
||||
private Xterm Terminal;
|
||||
private TaskCompletionSource<string> InputTaskCompletionSource;
|
||||
|
||||
private TerminalOptions _options = new()
|
||||
{
|
||||
CursorBlink = true,
|
||||
CursorStyle = CursorStyle.Bar,
|
||||
};
|
||||
|
||||
private HashSet<string> Addons = new()
|
||||
{
|
||||
"readline",
|
||||
"addon-fit"
|
||||
};
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
if (SessionId != null)
|
||||
DebugHandler = Client.Scripts.GetDebugHandler(SessionId.Value);
|
||||
|
||||
DebugHandler.OnDebugStart += OnDebugStart;
|
||||
DebugHandler.OnDebugBreak += OnDebugBreak;
|
||||
DebugHandler.OnDebugOutput += OnDebugOutput;
|
||||
DebugHandler.OnDebugStop += OnDebugStop;
|
||||
}
|
||||
|
||||
private async void OnDebugStart(object? sender, OnDebugStartEventArgs e)
|
||||
{
|
||||
Visible = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
await Terminal.Addon("addon-fit").InvokeVoidAsync("fit");
|
||||
}
|
||||
|
||||
private async void OnDebugBreak(object? sender, OnDebugBreakEventArgs e)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var input = await ReadLine();
|
||||
|
||||
if (input.Trim().Equals("exit", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await Terminal.Clear();
|
||||
break;
|
||||
}
|
||||
|
||||
await DebugHandler.ExecuteAsync(input);
|
||||
}
|
||||
|
||||
Visible = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private async void OnDebugOutput(object? sender, OnDebugOutputEventArgs e)
|
||||
{
|
||||
switch (e.LogLevel)
|
||||
{
|
||||
case LogLevel.Error:
|
||||
await Terminal.WriteLine($"\x1b[0;31m{e.Message}");
|
||||
break;
|
||||
|
||||
case LogLevel.Warning:
|
||||
await Terminal.WriteLine($"\x1b[0;33m{e.Message}");
|
||||
break;
|
||||
|
||||
case LogLevel.Debug:
|
||||
await Terminal.WriteLine($"\x1b[0;37m{e.Message}");
|
||||
break;
|
||||
|
||||
case LogLevel.Trace:
|
||||
await Terminal.WriteLine($"\x1b[0;36m{e.Message}");
|
||||
break;
|
||||
|
||||
case LogLevel.Information:
|
||||
await Terminal.WriteLine($"\x1b[0;37m{e.Message}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnDebugStop(object? sender, OnDebugStopEventArgs e)
|
||||
{
|
||||
await Terminal.Clear();
|
||||
Visible = false;
|
||||
}
|
||||
|
||||
private async Task OnFirstRender()
|
||||
{
|
||||
await Terminal.Addon("addon-fit").InvokeVoidAsync("fit");
|
||||
}
|
||||
|
||||
private async Task<string> ReadLine()
|
||||
{
|
||||
return await Terminal.Addon("readline").InvokeAsync<string>("read", "> ");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue