diff --git a/ParadoxSaveParser.CLI/Modes.cs b/ParadoxSaveParser.CLI/Modes.cs index 54f3a35..1fe345a 100644 --- a/ParadoxSaveParser.CLI/Modes.cs +++ b/ParadoxSaveParser.CLI/Modes.cs @@ -1,5 +1,9 @@ -using System.Text.Json; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text.Json; using ParadoxSaveParser.Lib; +using Path = DTLib.Filesystem.Path; namespace ParadoxSaveParser.CLI; @@ -12,18 +16,41 @@ internal static class Modes { internal static void Search(string searchQuery, IOPath inputPath, IOPath? outputPath) { - using var inputStream = File.OpenRead(inputPath); - - using var outputStream = outputPath is null - ? Console.OpenStandardOutput() - : File.OpenWrite(outputPath.Value); - - var searchExpression = SearchExpressionCompiler.Compile(searchQuery); - - var parser = new SaveParserEU4(inputStream, searchExpression); - var parsedValue = parser.Parse(); - JsonSerializer.Serialize(outputStream, parsedValue, ParsedValueJsonContext.Default.DictionaryStringListObject); - outputStream.WriteByte((byte)'\n'); + Stream inputStream = File.OpenRead(inputPath); + try + { + byte[] head4 = new byte[4]; + inputStream.ReadExactly(head4); + inputStream.Seek(0, SeekOrigin.Begin); + if (head4.SequenceEqual([(byte)'P', (byte)'K', 3, 4])) + { + var zipArchive = new ZipArchive(inputStream, ZipArchiveMode.Read); + var zipEntry = zipArchive.Entries.FirstOrDefault(e => e.Name == "gamestate"); + if (zipEntry is null) + throw new Exception("'gamestate' file not found in zip archive"); + var unzipped = new MemoryStream((int)zipEntry.Length); + zipEntry.Open().CopyTo(unzipped); + zipArchive.Dispose(); // closes inputStream + unzipped.Seek(0, SeekOrigin.Begin); + inputStream = unzipped; + } + + using var outputStream = outputPath is null + ? Console.OpenStandardOutput() + : File.OpenWrite(outputPath.Value); + + var searchExpression = SearchExpressionCompiler.Compile(searchQuery); + + var parser = new SaveParserEU4(inputStream, searchExpression); + var parsedValue = parser.Parse(); + JsonSerializer.Serialize(outputStream, parsedValue, + ParsedValueJsonContext.Default.DictionaryStringListObject); + outputStream.WriteByte((byte)'\n'); + } + finally + { + inputStream.Dispose(); + } } internal static void Interactive() diff --git a/TODO.txt b/TODO.txt index 8ff0070..9589764 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,6 +1,3 @@ -Parser.CLI: - Temp files management system - Main: Temp files management system Database??? @@ -11,4 +8,3 @@ ParseSaveHandler: Add debug log Save parsed data in protobuf Re-parse if saved data was parsed with another query -