add redux CLI based on redux GUI output formats
This commit is contained in:
136
Il2CppInspector.Redux.CLI/CliClient.cs
Normal file
136
Il2CppInspector.Redux.CLI/CliClient.cs
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
using System.Threading.Channels;
|
||||||
|
using Il2CppInspector.Redux.FrontendCore;
|
||||||
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
|
using Spectre.Console;
|
||||||
|
|
||||||
|
namespace Il2CppInspector.Redux.CLI;
|
||||||
|
|
||||||
|
public class CliClient : IDisposable
|
||||||
|
{
|
||||||
|
public bool ImportCompleted { get; private set; }
|
||||||
|
|
||||||
|
private volatile int _finishedLoadingCount = 0;
|
||||||
|
|
||||||
|
private readonly HubConnection _connection;
|
||||||
|
private readonly List<IDisposable> _commandListeners = [];
|
||||||
|
|
||||||
|
private Channel<string>? _logMessageChannel;
|
||||||
|
|
||||||
|
public CliClient(HubConnection connection)
|
||||||
|
{
|
||||||
|
_connection = connection;
|
||||||
|
|
||||||
|
_commandListeners.Add(_connection.On<string>(nameof(UiClient.ShowLogMessage), ShowLogMessage));
|
||||||
|
_commandListeners.Add(_connection.On(nameof(UiClient.BeginLoading), BeginLoading));
|
||||||
|
_commandListeners.Add(_connection.On(nameof(UiClient.FinishLoading), FinishLoading));
|
||||||
|
_commandListeners.Add(_connection.On<string>(nameof(UiClient.ShowInfoToast), ShowInfoToast));
|
||||||
|
_commandListeners.Add(_connection.On<string>(nameof(UiClient.ShowSuccessToast), ShowSuccessToast));
|
||||||
|
_commandListeners.Add(_connection.On<string>(nameof(UiClient.ShowErrorToast), ShowErrorToast));
|
||||||
|
_commandListeners.Add(_connection.On(nameof(UiClient.OnImportCompleted), OnImportCompleted));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask OnUiLaunched(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
await _connection.InvokeAsync(nameof(Il2CppHub.OnUiLaunched), cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask SubmitInputFiles(List<string> inputFiles, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
await _connection.InvokeAsync(nameof(Il2CppHub.SubmitInputFiles), inputFiles, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask QueueExport(string exportTypeId, string outputDirectory, Dictionary<string, string> settings,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
await _connection.InvokeAsync(nameof(Il2CppHub.QueueExport), exportTypeId, outputDirectory, settings, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask StartExport(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
await _connection.InvokeAsync(nameof(Il2CppHub.StartExport), cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask<List<string>> GetPotentialUnityVersions(CancellationToken cancellationToken = default)
|
||||||
|
=> await _connection.InvokeAsync<List<string>>(nameof(Il2CppHub.GetPotentialUnityVersions), cancellationToken);
|
||||||
|
|
||||||
|
public async ValueTask ExportIl2CppFiles(string outputDirectory, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
await _connection.InvokeAsync(nameof(Il2CppHub.ExportIl2CppFiles), outputDirectory, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask<string> GetInspectorVersion(CancellationToken cancellationToken = default)
|
||||||
|
=> await _connection.InvokeAsync<string>(nameof(Il2CppHub.GetInspectorVersion), cancellationToken);
|
||||||
|
|
||||||
|
public async ValueTask WaitForLoadingToFinishAsync(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var currentLoadingCount = _finishedLoadingCount;
|
||||||
|
while (_finishedLoadingCount == currentLoadingCount)
|
||||||
|
await Task.Delay(10, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ShowLogMessage(string message)
|
||||||
|
{
|
||||||
|
if (_logMessageChannel == null)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine($"[white bold]{message}[/]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _logMessageChannel.Writer.WriteAsync(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BeginLoading()
|
||||||
|
{
|
||||||
|
_logMessageChannel = Channel.CreateUnbounded<string>(new UnboundedChannelOptions
|
||||||
|
{
|
||||||
|
SingleReader = true,
|
||||||
|
SingleWriter = true,
|
||||||
|
AllowSynchronousContinuations = true
|
||||||
|
});
|
||||||
|
|
||||||
|
AnsiConsole.Status()
|
||||||
|
.Spinner(Spinner.Known.Triangle)
|
||||||
|
.StartAsync("Loading", async ctx =>
|
||||||
|
{
|
||||||
|
await foreach (var newLogMessage in _logMessageChannel.Reader.ReadAllAsync())
|
||||||
|
{
|
||||||
|
ctx.Status(newLogMessage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FinishLoading()
|
||||||
|
{
|
||||||
|
_logMessageChannel?.Writer.Complete();
|
||||||
|
Interlocked.Increment(ref _finishedLoadingCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ShowInfoToast(string message)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLineInterpolated($"[bold white]INFO: {message}[/]");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ShowSuccessToast(string message)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLineInterpolated($"[bold][green]SUCCESS: [/] [white]{message}[/][/]");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ShowErrorToast(string message)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLineInterpolated($"[bold][red]ERROR: [/] [white]{message}[/][/]");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnImportCompleted()
|
||||||
|
{
|
||||||
|
ImportCompleted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
|
||||||
|
foreach (var listener in _commandListeners)
|
||||||
|
listener.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
38
Il2CppInspector.Redux.CLI/Commands/BaseCommand.cs
Normal file
38
Il2CppInspector.Redux.CLI/Commands/BaseCommand.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using Il2CppInspector.Redux.FrontendCore;
|
||||||
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Il2CppInspector.Redux.CLI.Commands;
|
||||||
|
|
||||||
|
internal abstract class BaseCommand<T>(PortProvider portProvider) : AsyncCommand<T> where T : CommandSettings
|
||||||
|
{
|
||||||
|
private const string HubPath = "/il2cpp"; // TODO: Make this into a shared constant
|
||||||
|
|
||||||
|
private readonly int _serverPort = portProvider.Port;
|
||||||
|
|
||||||
|
protected abstract Task<int> ExecuteAsync(CliClient client, T settings);
|
||||||
|
|
||||||
|
public override async Task<int> ExecuteAsync(CommandContext context, T settings)
|
||||||
|
{
|
||||||
|
var connection = new HubConnectionBuilder().WithUrl($"http://localhost:{_serverPort}{HubPath}")
|
||||||
|
.AddJsonProtocol(options =>
|
||||||
|
{
|
||||||
|
options.PayloadSerializerOptions.TypeInfoResolverChain.Insert(0,
|
||||||
|
FrontendCoreJsonSerializerContext.Default);
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
await connection.StartAsync();
|
||||||
|
|
||||||
|
int result;
|
||||||
|
using (var client = new CliClient(connection))
|
||||||
|
{
|
||||||
|
await client.OnUiLaunched();
|
||||||
|
result = await ExecuteAsync(client, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
await connection.StopAsync();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
Il2CppInspector.Redux.CLI/Commands/InteractiveCommand.cs
Normal file
17
Il2CppInspector.Redux.CLI/Commands/InteractiveCommand.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
|
using Spectre.Console;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Il2CppInspector.Redux.CLI.Commands;
|
||||||
|
|
||||||
|
internal class InteractiveCommand(PortProvider portProvider) : BaseCommand<InteractiveCommand.Options>(portProvider)
|
||||||
|
{
|
||||||
|
public class Options : CommandSettings;
|
||||||
|
|
||||||
|
protected override async Task<int> ExecuteAsync(CliClient client, Options settings)
|
||||||
|
{
|
||||||
|
await Task.Delay(1000);
|
||||||
|
await AnsiConsole.AskAsync<string>("meow?");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
Il2CppInspector.Redux.CLI/Commands/ManualCommand.cs
Normal file
21
Il2CppInspector.Redux.CLI/Commands/ManualCommand.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using Spectre.Console;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Il2CppInspector.Redux.CLI.Commands;
|
||||||
|
|
||||||
|
internal abstract class ManualCommand<T>(PortProvider portProvider) : BaseCommand<T>(portProvider) where T : ManualCommandOptions
|
||||||
|
{
|
||||||
|
public override ValidationResult Validate(CommandContext context, T settings)
|
||||||
|
{
|
||||||
|
foreach (var inputPath in settings.InputPaths)
|
||||||
|
{
|
||||||
|
if (!Path.Exists(inputPath))
|
||||||
|
return ValidationResult.Error($"Provided input path {inputPath} does not exit.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists(settings.OutputPath))
|
||||||
|
return ValidationResult.Error("Provided output path already exists as a file.");
|
||||||
|
|
||||||
|
return ValidationResult.Success();
|
||||||
|
}
|
||||||
|
}
|
||||||
15
Il2CppInspector.Redux.CLI/Commands/ManualCommandOptions.cs
Normal file
15
Il2CppInspector.Redux.CLI/Commands/ManualCommandOptions.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Il2CppInspector.Redux.CLI.Commands;
|
||||||
|
|
||||||
|
internal class ManualCommandOptions : CommandSettings
|
||||||
|
{
|
||||||
|
[CommandArgument(0, "<InputPath>")]
|
||||||
|
[Description("Paths to the input files. Will be subsequently loaded until binary and metadata were found.")]
|
||||||
|
public string[] InputPaths { get; init; } = [];
|
||||||
|
|
||||||
|
[CommandOption("-o|--output")]
|
||||||
|
[Description("Path to the output folder")]
|
||||||
|
public string OutputPath { get; init; } = "";
|
||||||
|
}
|
||||||
172
Il2CppInspector.Redux.CLI/Commands/ProcessCommand.cs
Normal file
172
Il2CppInspector.Redux.CLI/Commands/ProcessCommand.cs
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
using Il2CppInspector.Cpp;
|
||||||
|
using Il2CppInspector.Redux.FrontendCore.Outputs;
|
||||||
|
using Spectre.Console;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Il2CppInspector.Redux.CLI.Commands;
|
||||||
|
|
||||||
|
internal class ProcessCommand(PortProvider portProvider) : ManualCommand<ProcessCommand.Option>(portProvider)
|
||||||
|
{
|
||||||
|
// NOTE: There might be a better option than replicating all available flags here (and in the TS UI).
|
||||||
|
// Investigate this in the future.
|
||||||
|
|
||||||
|
public class Option : ManualCommandOptions
|
||||||
|
{
|
||||||
|
// C++ Scaffolding
|
||||||
|
[CommandOption("--output-cpp-scaffolding")]
|
||||||
|
public bool CppScaffolding { get; init; } = false;
|
||||||
|
|
||||||
|
[CommandOption("--unity-version")]
|
||||||
|
public string? UnityVersion { get; init; }
|
||||||
|
|
||||||
|
[CommandOption("--compiler-type")]
|
||||||
|
public CppCompilerType CompilerType { get; init; } = CppCompilerType.GCC;
|
||||||
|
|
||||||
|
// C# stub
|
||||||
|
[CommandOption("-s|--output-csharp-stub")]
|
||||||
|
public bool CSharpStubs { get; init; } = false;
|
||||||
|
|
||||||
|
[CommandOption("--layout")]
|
||||||
|
public CSharpLayout Layout { get; init; } = CSharpLayout.SingleFile;
|
||||||
|
|
||||||
|
[CommandOption("--flatten-hierarchy")]
|
||||||
|
public bool FlattenHierarchy { get; init; } = false;
|
||||||
|
|
||||||
|
[CommandOption("--sorting-mode")]
|
||||||
|
public TypeSortingMode SortingMode { get; init; } = TypeSortingMode.Alphabetical;
|
||||||
|
|
||||||
|
[CommandOption("--suppress-metadata")]
|
||||||
|
public bool SuppressMetadata { get; init; } = false;
|
||||||
|
|
||||||
|
[CommandOption("--compilable")]
|
||||||
|
public bool MustCompile { get; init; } = false;
|
||||||
|
|
||||||
|
[CommandOption("--separate-assembly-attributes")]
|
||||||
|
public bool SeparateAssemblyAttributes { get; init; } = true;
|
||||||
|
|
||||||
|
// Disassembler metadata
|
||||||
|
[CommandOption("-m|--output-disassembler-metadata")]
|
||||||
|
public bool DisassemblerMetadata { get; init; } = false;
|
||||||
|
|
||||||
|
[CommandOption("--disassembler")]
|
||||||
|
public DisassemblerType Disassembler { get; init; } = DisassemblerType.IDA;
|
||||||
|
|
||||||
|
// Dummy DLL output
|
||||||
|
[CommandOption("-d|--output-dummy-dlls")]
|
||||||
|
public bool DummyDlls { get; init; } = false;
|
||||||
|
|
||||||
|
// Visual Studio solution
|
||||||
|
[CommandOption("--output-vs-solution")]
|
||||||
|
public bool VsSolution { get; init; } = false;
|
||||||
|
|
||||||
|
[CommandOption("--unity-path")]
|
||||||
|
public string? UnityPath { get; init; }
|
||||||
|
|
||||||
|
[CommandOption("--unity-assemblies-path")]
|
||||||
|
public string? UnityAssembliesPath { get; init; }
|
||||||
|
|
||||||
|
[CommandOption("--extract-il2cpp-files")]
|
||||||
|
public string? ExtractIl2CppFilesPath { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task<int> ExecuteAsync(CliClient client, Option settings)
|
||||||
|
{
|
||||||
|
var inspectorVersion = await client.GetInspectorVersion();
|
||||||
|
AnsiConsole.MarkupLineInterpolated($"Using inspector [gray]{inspectorVersion}[/]");
|
||||||
|
|
||||||
|
await client.SubmitInputFiles(settings.InputPaths.ToList());
|
||||||
|
await client.WaitForLoadingToFinishAsync();
|
||||||
|
if (!client.ImportCompleted)
|
||||||
|
{
|
||||||
|
AnsiConsole.MarkupLine("[bold][red]FAILED[/] to load IL2CPP data from the given inputs.[/]");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.ExtractIl2CppFilesPath != null)
|
||||||
|
{
|
||||||
|
await client.ExportIl2CppFiles(settings.ExtractIl2CppFilesPath);
|
||||||
|
await client.WaitForLoadingToFinishAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
var unityVersions = await client.GetPotentialUnityVersions();
|
||||||
|
|
||||||
|
if (settings.CppScaffolding)
|
||||||
|
{
|
||||||
|
var directory = Path.Join(settings.OutputPath, "cpp");
|
||||||
|
await client.QueueExport(CppScaffoldingOutput.Id, directory, new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["unityversion"] = settings.UnityVersion ?? unityVersions.First(),
|
||||||
|
["compilertype"] = settings.CompilerType.ToString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.CSharpStubs)
|
||||||
|
{
|
||||||
|
var directory = Path.Join(settings.OutputPath, "cs");
|
||||||
|
await client.QueueExport(CSharpStubOutput.Id, directory, new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["layout"] = settings.Layout.ToString(),
|
||||||
|
["flattenhierarchy"] = settings.FlattenHierarchy.ToString(),
|
||||||
|
["sortingmode"] = settings.SortingMode.ToString(),
|
||||||
|
["suppressmetadata"] = settings.SuppressMetadata.ToString(),
|
||||||
|
["mustcompile"] = settings.MustCompile.ToString(),
|
||||||
|
["separateassemblyattributes"] = settings.SeparateAssemblyAttributes.ToString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.DisassemblerMetadata)
|
||||||
|
{
|
||||||
|
await client.QueueExport(DisassemblerMetadataOutput.Id, settings.OutputPath,
|
||||||
|
new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["disassembler"] = settings.Disassembler.ToString(),
|
||||||
|
["unityversion"] = settings.UnityVersion ?? unityVersions.First()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.DummyDlls)
|
||||||
|
{
|
||||||
|
var directory = Path.Join(settings.OutputPath, "dll");
|
||||||
|
await client.QueueExport(DummyDllOutput.Id, directory, new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["suppressmetadata"] = settings.SuppressMetadata.ToString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.VsSolution)
|
||||||
|
{
|
||||||
|
var directory = Path.Join(settings.OutputPath, "vs");
|
||||||
|
await client.QueueExport(VsSolutionOutput.Id, directory, new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["unitypath"] = settings.UnityPath ?? "",
|
||||||
|
["unityassembliespath"] = settings.UnityAssembliesPath ?? ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await client.StartExport();
|
||||||
|
await client.WaitForLoadingToFinishAsync();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ValidationResult Validate(CommandContext context, Option settings)
|
||||||
|
{
|
||||||
|
if (settings.UnityPath != null && !Path.Exists(settings.UnityPath))
|
||||||
|
return ValidationResult.Error($"Provided Unity path {settings.UnityPath} does not exist.");
|
||||||
|
|
||||||
|
if (settings.UnityAssembliesPath != null && !Path.Exists(settings.UnityAssembliesPath))
|
||||||
|
return ValidationResult.Error($"Provided Unity assemblies path {settings.UnityAssembliesPath} does not exist.");
|
||||||
|
|
||||||
|
if (settings.ExtractIl2CppFilesPath != null && File.Exists(settings.ExtractIl2CppFilesPath))
|
||||||
|
return ValidationResult.Error(
|
||||||
|
$"Provided extracted IL2CPP files path {settings.ExtractIl2CppFilesPath} already exists as a file.");
|
||||||
|
|
||||||
|
if (settings is
|
||||||
|
{
|
||||||
|
CppScaffolding: false, CSharpStubs: false, DisassemblerMetadata: false, DummyDlls: false,
|
||||||
|
VsSolution: false
|
||||||
|
})
|
||||||
|
return ValidationResult.Error("At least one output format must be specified.");
|
||||||
|
|
||||||
|
return base.Validate(context, settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
20
Il2CppInspector.Redux.CLI/Il2CppInspector.Redux.CLI.csproj
Normal file
20
Il2CppInspector.Redux.CLI/Il2CppInspector.Redux.CLI.csproj
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<InvariantGlobalization>true</InvariantGlobalization>
|
||||||
|
<PublishAot>true</PublishAot>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.7" />
|
||||||
|
<PackageReference Include="Spectre.Console.Cli" Version="0.50.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Il2CppInspector.Redux.FrontendCore\Il2CppInspector.Redux.FrontendCore.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
6
Il2CppInspector.Redux.CLI/PortProvider.cs
Normal file
6
Il2CppInspector.Redux.CLI/PortProvider.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Il2CppInspector.Redux.CLI;
|
||||||
|
|
||||||
|
internal sealed class PortProvider(int port)
|
||||||
|
{
|
||||||
|
public int Port => port;
|
||||||
|
}
|
||||||
46
Il2CppInspector.Redux.CLI/Program.cs
Normal file
46
Il2CppInspector.Redux.CLI/Program.cs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
using Il2CppInspector.Redux.CLI;
|
||||||
|
using Il2CppInspector.Redux.CLI.Commands;
|
||||||
|
using Il2CppInspector.Redux.FrontendCore;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateSlimBuilder();
|
||||||
|
|
||||||
|
builder.Services.ConfigureHttpJsonOptions(options =>
|
||||||
|
{
|
||||||
|
options.SerializerOptions.TypeInfoResolverChain.Insert(0, FrontendCoreJsonSerializerContext.Default);
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Services.Configure<JsonHubProtocolOptions>(options =>
|
||||||
|
{
|
||||||
|
options.PayloadSerializerOptions.TypeInfoResolverChain.Insert(0, FrontendCoreJsonSerializerContext.Default);
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Services.AddFrontendCore();
|
||||||
|
builder.Logging.ClearProviders();
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
app.UseCors();
|
||||||
|
|
||||||
|
app.MapFrontendCore();
|
||||||
|
|
||||||
|
await app.StartAsync();
|
||||||
|
|
||||||
|
var serverUrl = app.Urls.First();
|
||||||
|
var port = new Uri(serverUrl).Port;
|
||||||
|
|
||||||
|
var commandServiceProvider = new ServiceCollection();
|
||||||
|
commandServiceProvider.AddSingleton(new PortProvider(port));
|
||||||
|
|
||||||
|
var commandTypeRegistrar = new ServiceTypeRegistrar(commandServiceProvider);
|
||||||
|
var consoleApp = new CommandApp<InteractiveCommand>(commandTypeRegistrar);
|
||||||
|
|
||||||
|
consoleApp.Configure(config =>
|
||||||
|
{
|
||||||
|
config.AddCommand<ProcessCommand>("process")
|
||||||
|
.WithDescription("Processes the provided input data into one or more output formats.");
|
||||||
|
});
|
||||||
|
|
||||||
|
await consoleApp.RunAsync(args);
|
||||||
|
await app.StopAsync();
|
||||||
23
Il2CppInspector.Redux.CLI/Properties/launchSettings.json
Normal file
23
Il2CppInspector.Redux.CLI/Properties/launchSettings.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"WSL": {
|
||||||
|
"commandName": "WSL2",
|
||||||
|
"launchUrl": "http://localhost:5118/",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
|
"ASPNETCORE_URLS": "http://localhost:5118"
|
||||||
|
},
|
||||||
|
"distributionName": ""
|
||||||
|
},
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"commandLineArgs": "process -d --disassembler ghidra M:\\Downloads\\Reversing\\NotYetAnalyzedAPKs\\pokemon_friends\\libil2cpp.so M:\\Downloads\\Reversing\\NotYetAnalyzedAPKs\\pokemon_friends\\global-metadata.dat",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"applicationUrl": "http://localhost:5118"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"$schema": "https://json.schemastore.org/launchsettings.json"
|
||||||
|
}
|
||||||
30
Il2CppInspector.Redux.CLI/ServiceTypeRegistrar.cs
Normal file
30
Il2CppInspector.Redux.CLI/ServiceTypeRegistrar.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Il2CppInspector.Redux.CLI;
|
||||||
|
|
||||||
|
public class ServiceTypeRegistrar(IServiceCollection serviceCollection) : ITypeRegistrar
|
||||||
|
{
|
||||||
|
private readonly IServiceCollection _serviceCollection = serviceCollection;
|
||||||
|
private ServiceTypeResolver? _resolver;
|
||||||
|
|
||||||
|
public void Register(Type service, Type implementation)
|
||||||
|
{
|
||||||
|
_serviceCollection.AddSingleton(service, implementation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterInstance(Type service, object implementation)
|
||||||
|
{
|
||||||
|
_serviceCollection.AddSingleton(service, implementation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterLazy(Type service, Func<object> factory)
|
||||||
|
{
|
||||||
|
_serviceCollection.AddSingleton(service, _ => factory());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITypeResolver Build()
|
||||||
|
{
|
||||||
|
_resolver ??= new ServiceTypeResolver(_serviceCollection.BuildServiceProvider());
|
||||||
|
return _resolver;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
Il2CppInspector.Redux.CLI/ServiceTypeResolver.cs
Normal file
13
Il2CppInspector.Redux.CLI/ServiceTypeResolver.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using Spectre.Console.Cli;
|
||||||
|
|
||||||
|
namespace Il2CppInspector.Redux.CLI;
|
||||||
|
|
||||||
|
public class ServiceTypeResolver(IServiceProvider serviceProvider) : ITypeResolver
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider _serviceProvider = serviceProvider;
|
||||||
|
|
||||||
|
public object? Resolve(Type? type)
|
||||||
|
=> type == null
|
||||||
|
? null
|
||||||
|
: _serviceProvider.GetService(type);
|
||||||
|
}
|
||||||
8
Il2CppInspector.Redux.CLI/appsettings.Development.json
Normal file
8
Il2CppInspector.Redux.CLI/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
Il2CppInspector.Redux.CLI/appsettings.json
Normal file
9
Il2CppInspector.Redux.CLI/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
@@ -48,6 +48,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Il2CppInspector.Redux.GUI",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Il2CppInspector.Redux.FrontendCore", "Il2CppInspector.Redux.FrontendCore\Il2CppInspector.Redux.FrontendCore.csproj", "{D80D0FCE-4C9C-4BF1-8936-71DFB0B2D86A}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Il2CppInspector.Redux.FrontendCore", "Il2CppInspector.Redux.FrontendCore\Il2CppInspector.Redux.FrontendCore.csproj", "{D80D0FCE-4C9C-4BF1-8936-71DFB0B2D86A}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Il2CppInspector.Redux.CLI", "Il2CppInspector.Redux.CLI\Il2CppInspector.Redux.CLI.csproj", "{8FA27979-23F4-4A4E-8B69-503A20BF1344}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -88,6 +90,10 @@ Global
|
|||||||
{D80D0FCE-4C9C-4BF1-8936-71DFB0B2D86A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D80D0FCE-4C9C-4BF1-8936-71DFB0B2D86A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{D80D0FCE-4C9C-4BF1-8936-71DFB0B2D86A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D80D0FCE-4C9C-4BF1-8936-71DFB0B2D86A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D80D0FCE-4C9C-4BF1-8936-71DFB0B2D86A}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D80D0FCE-4C9C-4BF1-8936-71DFB0B2D86A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{8FA27979-23F4-4A4E-8B69-503A20BF1344}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{8FA27979-23F4-4A4E-8B69-503A20BF1344}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{8FA27979-23F4-4A4E-8B69-503A20BF1344}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{8FA27979-23F4-4A4E-8B69-503A20BF1344}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
Reference in New Issue
Block a user