87 lines
3.4 KiB
C#
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;
|
|
}
|
|
}
|