// [DataRow("basegame_2_mainmenu.archive")] // [DataRow("basegame_3_nightcity.archive")] // [DataRow("basegame_3_nightcity_gi.archive")] // [DataRow("basegame_3_nightcity_terrain.archive")] // [DataRow("basegame_4_animation.archive")] // [DataRow("basegame_4_appearance.archive")] // [DataRow("basegame_4_gamedata.archive")] public void Test_Cr2wSerialize(string archivename) { var parsers = ServiceLocator.Default.ResolveType <Red4ParserService>(); var resultDir = Path.Combine(Environment.CurrentDirectory, s_testResultsDirectory); Directory.CreateDirectory(resultDir); var totalCount = s_bm.Items.Count(); var results = new ConcurrentBag <ArchiveTestResult>(); var archiveFullName = Path.Combine(s_gameDirectoryPath, "archive", "pc", "content", archivename); var archive = s_bm.Archives[archiveFullName] as Archive; Parallel.ForEach(archive.Files, keyvalue => { var(hash, file) = keyvalue; try { #region serialize using var ms = new MemoryStream(); ModTools.ExtractSingleToStream(archive, hash, ms); var cr2w = parsers.TryReadCr2WFile(ms); if (cr2w == null) { return; } var dto = new Red4W2rcFileDto(cr2w); var json = JsonConvert.SerializeObject( dto, Formatting.Indented ); if (string.IsNullOrEmpty(json)) { throw new SerializationException(); } #endregion #region deserialize var newdto = JsonConvert.DeserializeObject <Red4W2rcFileDto>(json); if (newdto == null) { throw new SerializationException(); } var w2rc = newdto.ToW2rc(); using var newms = new MemoryStream(); using var bw = new BinaryWriter(newms); w2rc.Write(bw); #endregion #region compare var newbytes = newms.ToByteArray(); var oldbytes = ms.ToByteArray(); if (!oldbytes.SequenceEqual(newbytes)) { throw new SerializationException(); } else { } #endregion results.Add(new ArchiveTestResult() { ArchiveName = archivename, Hash = hash.ToString(), Success = true }); } catch (Exception e) { results.Add(new ArchiveTestResult() { ArchiveName = archivename, Hash = hash.ToString(), Success = false, ExceptionType = e.GetType(), Message = $"{e.Message}" }); } }); // Check success var successCount = results.Count(r => r.Success); var sb = new StringBuilder(); sb.AppendLine($"Successfully serialized: {successCount} / {totalCount} ({(int)(successCount / (double)totalCount * 100)}%)"); var success = results.All(r => r.Success); if (success) { return; } var msg = $"Successful serialized: {successCount} / {totalCount}. "; Assert.Fail(msg); }
private void Cr2wTaskInner(string path, string outputDirectory, bool deserialize, bool serialize, string pattern = "", string regex = "", ESerializeFormat format = ESerializeFormat.json) { #region checks if (string.IsNullOrEmpty(path)) { _loggerService.Warning("Please fill in an input path."); return; } var inFileInfo = new FileInfo(path); var inDirInfo = new DirectoryInfo(path); var isDirectory = !inFileInfo.Exists && inDirInfo.Exists; var isFile = inFileInfo.Exists && !inDirInfo.Exists; if (!isDirectory && !isFile) { _loggerService.Error("Input file does not exist."); return; } #endregion checks Stopwatch watch = new(); watch.Restart(); // get all files var fileInfos = isDirectory ? inDirInfo.GetFiles("*", SearchOption.AllDirectories).ToList() : new List <FileInfo> { inFileInfo }; IEnumerable <FileInfo> finalmatches = fileInfos; if (deserialize) { finalmatches = fileInfos.Where(_ => _.Extension == $".{format}"); } if (serialize) { finalmatches = fileInfos.Where(_ => Enum.GetNames(typeof(ERedExtension)).Contains(_.TrimmedExtension())); } // check search pattern then regex if (!string.IsNullOrEmpty(pattern)) { finalmatches = fileInfos.MatchesWildcard(item => item.FullName, pattern); } if (!string.IsNullOrEmpty(regex)) { var searchTerm = new System.Text.RegularExpressions.Regex($@"{regex}"); var queryMatchingFiles = from file in finalmatches let matches = searchTerm.Matches(file.FullName) where matches.Count > 0 select file; finalmatches = queryMatchingFiles; } var finalMatchesList = finalmatches.ToList(); _loggerService.Info($"Found {finalMatchesList.Count} files to process."); int progress = 0; //foreach (var fileInfo in finalMatchesList) Parallel.ForEach(finalMatchesList, fileInfo => { var outputDirInfo = string.IsNullOrEmpty(outputDirectory) ? fileInfo.Directory : new DirectoryInfo(outputDirectory); if (outputDirInfo == null || !outputDirInfo.Exists) { _loggerService.Error("Invalid output directory."); return; } if (serialize) { var infile = fileInfo.FullName; using var fs = new FileStream(infile, FileMode.Open, FileAccess.Read); var cr2w = _wolvenkitFileService.TryReadCr2WFile(fs); if (cr2w == null) { _loggerService.Error($"Could not parse {infile}."); return; } cr2w.FileName = infile; var json = ""; var dto = new Red4W2rcFileDto(cr2w); json = JsonConvert.SerializeObject( dto, Formatting.Indented ); if (string.IsNullOrEmpty(json)) { _loggerService.Error($"Could not process {infile}."); return; } var outpath = Path.Combine(outputDirInfo.FullName, $"{infile}.{format.ToString()}"); switch (format) { case ESerializeFormat.json: File.WriteAllText(outpath, json); break; case ESerializeFormat.xml: var doc = JsonConvert.DeserializeXmlNode(json, Red4W2rcFileDto.Magic); doc?.Save(outpath); break; default: throw new ArgumentOutOfRangeException(nameof(format), format, null); } _loggerService.Success($"Saved {infile} to {format.ToString()}."); } if (deserialize) { try { var json = File.ReadAllText(fileInfo.FullName); var newdto = JsonConvert.DeserializeObject <Red4W2rcFileDto>(json); if (newdto != null) { var w2rc = newdto.ToW2rc(); var ext = newdto.Extension; var outpath = Path.ChangeExtension(Path.Combine(outputDirInfo.FullName, fileInfo.Name), ext); using var fs2 = new FileStream(outpath, FileMode.Create, FileAccess.ReadWrite); using var bw = new BinaryWriter(fs2); w2rc.Write(bw); } else { throw new InvalidParsingException($"Could not parse {fileInfo.FullName}"); } _loggerService.Success($"Converted {fileInfo.FullName} to CR2W"); } catch (Exception e) { _loggerService.Error($"Could not convert {fileInfo.FullName} Error:"); _loggerService.Error(e.ToString()); //throw; } } Interlocked.Increment(ref progress); }); //} watch.Stop(); _loggerService.Info($"Elapsed time: {watch.ElapsedMilliseconds.ToString()}ms."); }