Skip to content

Commit

Permalink
add CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
diogotr7 committed Jun 13, 2024
1 parent 88962d0 commit 57e77cb
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 66 deletions.
16 changes: 10 additions & 6 deletions StarBreaker.Forge/DataForge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public DataForge(byte[] allBytes, string outputFolder)
// }
}

public void Export(Regex? fileNameFilter = null, IProgress<float>? progress = null)
public void Export(Regex? fileNameFilter = null, IProgress<double>? progress = null)
{
_progress = 0;
var structsPerFileName = new Dictionary<string, List<DataForgeRecord>>();
Expand All @@ -57,7 +57,7 @@ public void Export(Regex? fileNameFilter = null, IProgress<float>? progress = nu
}

var total = structsPerFileName.Count;

Parallel.ForEach(structsPerFileName, data =>
{
var structs = _database.StructDefinitions.Span;
Expand Down Expand Up @@ -108,13 +108,14 @@ public void Export(Regex? fileNameFilter = null, IProgress<float>? progress = nu
writer.Write("__root");
writer.Write('>');
}
var currentProgress = Interlocked.Increment(ref _progress);
progress?.Report(currentProgress * 100f / total);
//only report progress every 250 records and when we are done
if (currentProgress == total || currentProgress % 250 == 0)
progress?.Report(currentProgress / (double)total);
});
}

public void ExportSingle(Regex? fileNameFilter = null, IProgress<float>? progress = null)
public void ExportSingle(Regex? fileNameFilter = null, IProgress<double>? progress = null)
{
var progressValue = 0;
var total = _database.RecordDefinitions.Length;
Expand All @@ -141,7 +142,10 @@ public void ExportSingle(Regex? fileNameFilter = null, IProgress<float>? progres
FillNode(child, structDef, reader, 0);

child.WriteTo(writer, 1, _database, _offsets);
progress?.Report(progressValue++ * 100f / total);

++progressValue;
if (progressValue % 250 == 0 || progressValue == total)
progress?.Report(progressValue / (double)total);
}

writer.WriteLine("</__root>");
Expand Down
4 changes: 2 additions & 2 deletions StarBreaker.Forge/IDataForge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ public interface IDataForge
/// </summary>
/// <param name="fileNameFilter">Regex to filter files to export</param>
/// <param name="progress">Progress callback</param>
void Export(Regex? fileNameFilter = null, IProgress<float>? progress = null);
void Export(Regex? fileNameFilter = null, IProgress<double>? progress = null);

/// <summary>
/// Export all records in the DataCoreBinary into a single XML file.
/// </summary>
/// <param name="fileNameFilter">Regex to filter files to export</param>
/// <param name="progress">Progress callback</param>
void ExportSingle(Regex? fileNameFilter = null, IProgress<float>? progress = null);
void ExportSingle(Regex? fileNameFilter = null, IProgress<double>? progress = null);

/// <summary>
/// Export all enums in the DataForge to a dictionary.
Expand Down
39 changes: 39 additions & 0 deletions StarBreaker/ExtractCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Diagnostics;
using System.Text.RegularExpressions;
using CliFx;
using CliFx.Attributes;
using CliFx.Infrastructure;
using StarBreaker.Forge;

namespace StarBreaker;

[Command("extract", Description = "Extracts a DataForge binary file into separate xml files")]
public class ExtractCommand : ICommand
{
[CommandOption("dcb", 'd', Description = "Path to the DataForge binary file")]
public required string DataForgeBinary { get; init; }

[CommandOption("output", 'o', Description = "Path to the output directory")]
public required string OutputDirectory { get; init; }

[CommandOption("filter", 'f', Description = "Regex pattern to filter entries")]
public Regex? RegexPattern { get; init; }

public ValueTask ExecuteAsync(IConsole console)
{
var bytes = File.ReadAllBytes(DataForgeBinary);
var dataForge = new DataForge(bytes, OutputDirectory);

console.Output.WriteLine("DataForge loaded.");
console.Output.WriteLine("Exporting...");

var sw = Stopwatch.StartNew();
dataForge.Export(RegexPattern, new ProgressBar(console));
sw.Stop();

console.Output.WriteLine();
console.Output.WriteLine($"Export completed in {sw.ElapsedMilliseconds}ms.");

return default;
}
}
39 changes: 39 additions & 0 deletions StarBreaker/ExtractSingleCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Diagnostics;
using System.Text.RegularExpressions;
using CliFx;
using CliFx.Attributes;
using CliFx.Infrastructure;
using StarBreaker.Forge;

namespace StarBreaker;

[Command("extract-single", Description = "Extracts a DataForge binary file into a single xml")]
public class ExtractSingleCommand : ICommand
{
[CommandOption("dcb", 'd', Description = "Path to the DataForge binary file")]
public required string DataForgeBinary { get; init; }

[CommandOption("output", 'o', Description = "Path to the output directory")]
public required string OutputDirectory { get; init; }

[CommandOption("filter", 'f', Description = "Regex pattern to filter entries")]
public Regex? RegexPattern { get; init; }

public ValueTask ExecuteAsync(IConsole console)
{
var bytes = File.ReadAllBytes(DataForgeBinary);
var dataForge = new DataForge(bytes, OutputDirectory);

console.Output.WriteLine("DataForge loaded.");
console.Output.WriteLine("Exporting...");

var sw = Stopwatch.StartNew();
dataForge.ExportSingle(RegexPattern, new ProgressBar(console));
sw.Stop();

console.Output.WriteLine();
console.Output.WriteLine($"Export completed in {sw.ElapsedMilliseconds}ms.");

return default;
}
}
63 changes: 5 additions & 58 deletions StarBreaker/Program.cs
Original file line number Diff line number Diff line change
@@ -1,59 +1,6 @@
using System.Diagnostics;
using StarBreaker.Forge;
using CliFx;

namespace StarBreaker;

public static class Program
{
private const string dcb = @"C:\Scratch\extract\Game.dcb";
private const string destDir = @"C:\Scratch\extract\stbr\";
private static DataForge dataForge = null!;

public static void Main()
{
var bytes = File.ReadAllBytes(dcb);

var sw1 = Stopwatch.StartNew();
dataForge = new DataForge(bytes, destDir);
Console.WriteLine($"DataForge Constructor took: {sw1.ElapsedMilliseconds}ms");

var printed1 = -1;
var exportProgress = new Progress<float>(percent =>
{
if (Math.Abs(percent % 10) < 1)
{
var part = (int)percent / 10;
if (part > printed1)
{
printed1 = part;
Console.WriteLine($"Export {percent}%");
}
}
});
var sw2 = Stopwatch.StartNew();
dataForge.Export(null, exportProgress);
Console.WriteLine($"Export took: {sw2.ElapsedMilliseconds}ms");

int printed = -1;
var exportProgress1 = new Progress<float>(percent =>
{
if (Math.Abs(percent % 10) < 1)
{
var part = (int)percent / 10;
if (part > printed)
{
printed = part;
Console.WriteLine($"ExportSingle {percent}%");
}
}
});
var sw = Stopwatch.StartNew();
dataForge.ExportSingle(null, exportProgress1);
Console.WriteLine($"ExportSingle took: {sw.ElapsedMilliseconds}ms");

// foreach (var x in dataForge.ExportEnums())
// {
// File.WriteAllText(Path.Combine(destDir, Path.ChangeExtension(x.Key, ".txt")), string.Join("\n", x.Value));
// }
}
}
return await new CliApplicationBuilder()
.AddCommandsFromThisAssembly()
.Build()
.RunAsync();
43 changes: 43 additions & 0 deletions StarBreaker/ProgressBar.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using CliFx.Infrastructure;

namespace StarBreaker;

public class ProgressBar : IProgress<double>
{
private const int _totalBlocks = 20;
private readonly IConsole _console;
private int? _originalCursorLeft;
private int? _originalCursorTop;

public ProgressBar(IConsole console)
{
_console = console;
}

private void RenderProgress(double progress)
{
if (_originalCursorLeft != null && _originalCursorTop != null)
{
_console.CursorLeft = _originalCursorLeft.Value;
_console.CursorTop = _originalCursorTop.Value;
}
else
{
_originalCursorLeft = _console.CursorLeft;
_originalCursorTop = _console.CursorTop;
}

var completedBlocks = (int)(progress * _totalBlocks);
var progressBar = new string('#', completedBlocks) + new string('-', _totalBlocks - completedBlocks);

_console.Output.Write($"[{progressBar}] {progress:P0}");
}

public void Report(double progress)
{
if (!_console.IsOutputRedirected)
{
RenderProgress(progress);
}
}
}
12 changes: 12 additions & 0 deletions StarBreaker/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"profiles": {
"extract": {
"commandName": "Project",
"commandLineArgs": "extract --dcb \"C:\\Scratch\\extract\\Game.dcb\" --output \"C:\\Scratch\\extract\\stbr\" --filter \"^[0-9A-Za-z]{3}[0-9A-Za-z-]\\d{0,21}$\""
},
"extract-single": {
"commandName": "Project",
"commandLineArgs": "extract-single --dcb \"C:\\Scratch\\extract\\Game.dcb\" --output \"C:\\Scratch\\extract\\stbr\" --filter \"^[0-9A-Za-z]{3}[0-9A-Za-z-]\\d{0,21}$\""
}
}
}
4 changes: 4 additions & 0 deletions StarBreaker/StarBreaker.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@
<ItemGroup>
<ProjectReference Include="..\StarBreaker.Forge\StarBreaker.Forge.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="CliFx" Version="2.3.5" />
</ItemGroup>
</Project>

0 comments on commit 57e77cb

Please sign in to comment.