using System.Globalization; namespace AcDream.Bake; internal sealed record BakeCommandLineOptions( string DatDirectory, string OutputPath, HashSet? IdFilter, HashSet? LandblockFilter, int Threads, bool ProgressJson); internal static class BakeCommandLine { internal const string Usage = "usage: acdream-bake --dat-dir [--out ] " + "[--ids 0xId,0xId,...] [--landblocks 0xId,...] " + "[--threads ] [--progress-json]\n" + " acdream-bake --help"; public static bool IsHelpRequest(IReadOnlyList args) { ArgumentNullException.ThrowIfNull(args); return args.Count == 1 && args[0] is "--help" or "-h"; } public static bool TryParse( IReadOnlyList args, TextWriter error, out BakeCommandLineOptions? options) { ArgumentNullException.ThrowIfNull(args); ArgumentNullException.ThrowIfNull(error); string? datDirectory = null; string? outputPath = null; HashSet? idFilter = null; HashSet? landblockFilter = null; int threads = Environment.ProcessorCount; bool progressJson = false; for (int i = 0; i < args.Count; i++) { switch (args[i]) { case "--dat-dir": datDirectory = Value(args, ref i); break; case "--out": outputPath = Value(args, ref i); break; case "--ids": idFilter = ParseHexList(Value(args, ref i), error); break; case "--landblocks": landblockFilter = ParseHexList(Value(args, ref i), error); break; case "--threads": if (int.TryParse( Value(args, ref i), NumberStyles.Integer, CultureInfo.InvariantCulture, out int parsedThreads) && parsedThreads > 0) { threads = parsedThreads; } break; case "--progress-json": progressJson = true; break; default: error.WriteLine($"unrecognized argument: {args[i]}"); options = null; return false; } } if (string.IsNullOrWhiteSpace(datDirectory)) { error.WriteLine(Usage); options = null; return false; } outputPath ??= Path.Combine(datDirectory, "acdream.pak"); options = new BakeCommandLineOptions( datDirectory, outputPath, idFilter, landblockFilter, threads, progressJson); return true; } private static string? Value(IReadOnlyList args, ref int index) => index + 1 < args.Count ? args[++index] : null; private static HashSet ParseHexList(string? raw, TextWriter error) { var result = new HashSet(); if (string.IsNullOrWhiteSpace(raw)) { return result; } foreach (string token in raw.Split( ',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)) { string hex = token.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? token[2..] : token; if (uint.TryParse( hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out uint value)) { result.Add(value); } else { error.WriteLine($"warning: could not parse id '{token}' - skipped"); } } return result; } }