Files
gregExtractor/Commands/ExtractCommand.cs
T

87 lines
3.4 KiB
C#

using gregExtractor.Models;
using gregExtractor.Services;
using gregExtractor.Utils;
namespace gregExtractor.Commands;
public sealed class ExtractCommand : AsyncCommand<ExtractCommand.Settings>
{
public sealed class Settings : CommandSettings
{
[CommandOption("--path <IL2CPP_PATH>")]
public string? Path { get; init; }
}
public override async Task<int> ExecuteAsync(CommandContext context, Settings settings)
{
AnsiConsole.Write(new FigletText("gregExtractor").Color(Color.Cyan1));
string workingDirectory = Directory.GetCurrentDirectory();
string groupsPath = Path.Combine(workingDirectory, "hook_groups.json");
var logMessages = new List<string>();
var progress = new Progress<string>(message => logMessages.Add(message));
HookClassifier classifier = HookClassifier.LoadFromFile(groupsPath, progress);
string? il2CppPath = settings.Path;
if (string.IsNullOrWhiteSpace(il2CppPath))
il2CppPath = SteamLocator.FindIl2CppAssembliesPath();
if (string.IsNullOrWhiteSpace(il2CppPath))
{
AnsiConsole.MarkupLine("[yellow]Could not auto-detect Il2CppAssemblies path.[/]");
il2CppPath = AnsiConsole.Ask<string>("Enter IL2CPP directory path:");
}
if (string.IsNullOrWhiteSpace(il2CppPath) || !Directory.Exists(il2CppPath))
{
AnsiConsole.MarkupLine("[red]Invalid IL2CPP path.[/]");
return -1;
}
IReadOnlyList<HookDefinition> hooks = Array.Empty<HookDefinition>();
var extractor = new ExtractorService();
await AnsiConsole.Status()
.Spinner(Spinner.Known.Dots)
.StartAsync("Extracting IL2CPP hooks...", async _ =>
{
hooks = await extractor.ExtractAsync(il2CppPath!, classifier, progress, CancellationToken.None).ConfigureAwait(false);
})
.ConfigureAwait(false);
string gameHooksPath = Path.Combine(workingDirectory, "game_hooks.json");
await File.WriteAllTextAsync(
gameHooksPath,
JsonSerializer.Serialize(hooks, new JsonSerializerOptions { WriteIndented = true }),
CancellationToken.None)
.ConfigureAwait(false);
HookDefinition[] uncategorized = hooks
.Where(hook => string.Equals(hook.Group, "Uncategorized", StringComparison.OrdinalIgnoreCase))
.ToArray();
string unknownHooksPath = Path.Combine(workingDirectory, "unknown_hooks.json");
await File.WriteAllTextAsync(
unknownHooksPath,
JsonSerializer.Serialize(uncategorized, new JsonSerializerOptions { WriteIndented = true }),
CancellationToken.None)
.ConfigureAwait(false);
var table = new Table().RoundedBorder();
table.AddColumn("Group");
table.AddColumn("Count");
foreach (IGrouping<string, HookDefinition> group in hooks.GroupBy(hook => hook.Group).OrderBy(group => group.Key, StringComparer.OrdinalIgnoreCase))
table.AddRow(group.Key, group.Count().ToString());
AnsiConsole.Write(table);
foreach (string line in logMessages)
AnsiConsole.MarkupLine($"[grey]{Markup.Escape(line)}[/]");
AnsiConsole.MarkupLine($"[green]✓ {hooks.Count} hooks saved[/] -> {Markup.Escape(gameHooksPath)}");
return 0;
}
}