private bool DumpAppPackage(CR2WFile cr2w, Stream appStream, string outfile) { var blob = cr2w.RootChunk as appearanceAppearanceResource; var datas = new List <RedFileDto>(); foreach (var appearance in blob.Appearances) { if (appearance.Chunk.CompiledData.Buffer.MemSize > 0) { var packageStream = new MemoryStream(); packageStream.Write(appearance.Chunk.CompiledData.Buffer.GetBytes()); var package = new CompiledPackage(_hashService); packageStream.Seek(0, SeekOrigin.Begin); package.Read(new BinaryReader(packageStream)); datas.Add(new RedFileDto(cr2w)); } } if (datas.Count > 1) { var data = RedJsonSerializer.Serialize(datas); File.WriteAllText(outfile, data); return(true); } return(false); }
/// <summary> /// Converts a W2RC stream to text /// </summary> /// <param name="format"></param> /// <param name="instream"></param> /// <returns></returns> /// <exception cref="InvalidParsingException"></exception> /// <exception cref="SerializationException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> public string ConvertToText(ETextConvertFormat format, string infile) { using var instream = new FileStream(infile, FileMode.Open, FileAccess.Read); if (!_wolvenkitFileService.TryReadRed4File(instream, out var cr2w)) { throw new InvalidParsingException("ConvertToText"); } cr2w.MetaData.FileName = infile; var dto = new RedFileDto(cr2w); var json = RedJsonSerializer.Serialize(dto); if (string.IsNullOrEmpty(json)) { throw new SerializationException(); } switch (format) { case ETextConvertFormat.json: return(json); case ETextConvertFormat.xml: throw new NotSupportedException(nameof(format)); default: throw new ArgumentOutOfRangeException(nameof(format), format, null); } }
private bool DumpEntPackage(CR2WFile cr2w, Stream entStream, string outfile) { var blob = cr2w.RootChunk as entEntityTemplate; if (blob.CompiledData.Buffer.MemSize > 0) { var packageStream = new MemoryStream(); packageStream.Write(blob.CompiledData.Buffer.GetBytes()); var package = new CompiledPackage(_hashService); packageStream.Seek(0, SeekOrigin.Begin); package.Read(new BinaryReader(packageStream)); var data = RedJsonSerializer.Serialize(new RedFileDto(cr2w)); File.WriteAllText(outfile, data); return(true); } return(false); }
private static void Test_Extension(string extension) { var parsers = _host.Services.GetRequiredService <Red4ParserService>(); var resultDir = Path.Combine(Environment.CurrentDirectory, s_testResultsDirectory); Directory.CreateDirectory(resultDir); foreach (var file in Directory.GetFiles(resultDir)) { File.Delete(file); } var results = new ConcurrentBag <ArchiveTestResult>(); var files = s_groupedFiles[extension].ToList(); #if IS_PARALLEL Parallel.ForEach(files, file => #else foreach (var file in files) #endif { var hash = file.Key; var archive = file.Archive as Archive; ArgumentNullException.ThrowIfNull(archive); try { #region convert to json using var originalMemoryStream = new MemoryStream(); ModTools.ExtractSingleToStream(archive, hash, originalMemoryStream); if (!parsers.TryReadRed4File(originalMemoryStream, out var originalFile)) { #if IS_PARALLEL return; #else continue; #endif } var dto = new RedFileDto(originalFile); var json = RedJsonSerializer.Serialize(dto); if (string.IsNullOrEmpty(json)) { throw new SerializationException(); } #endregion #region convert back from json var newdto = RedJsonSerializer.Deserialize <RedFileDto>(json); if (newdto == null) { throw new SerializationException(); } var newFile = newdto.Data; #endregion #region compare // old file var header = originalFile.MetaData; var objectsend = (int)header.ObjectsEnd; var originalBytes = originalMemoryStream.ToByteArray().Take(objectsend); // write the new file using var newMemoryStream = new MemoryStream(); using var writer = new CR2WWriter(newMemoryStream); writer.WriteFile(newFile); // hack to compare buffers var newBytes = newMemoryStream.ToByteArray(); newMemoryStream.Seek(0, SeekOrigin.Begin); var dbg = parsers.ReadRed4File(newMemoryStream); //var newExportStartOffset = (int)dbg.Chunks.FirstOrDefault().GetOffset(); // var originalExportStartOffset = (int)originalFile.Chunks.FirstOrDefault().GetOffset(); // if (!originalBytes.Skip(160).SequenceEqual(newBytes.Skip(160))) // { // // check again skipping the tables // if (originalExportStartOffset == newExportStartOffset) // { // if (!originalBytes.Skip(originalExportStartOffset).SequenceEqual(newBytes.Skip(newExportStartOffset))) // { //#if WRITE // File.WriteAllBytes(Path.Combine(resultDir, $"{file.Key}.o.bin"), originalBytes.ToArray()); // File.WriteAllBytes(Path.Combine(resultDir, $"{file.Key}.bin"), newBytes.ToArray()); //#endif // throw new SerializationException("Exports not equal"); // } // else // { // } // } // else // { //#if WRITE // File.WriteAllBytes(Path.Combine(resultDir, $"{file.Key}.o.bin"), originalBytes.ToArray()); // File.WriteAllBytes(Path.Combine(resultDir, $"{file.Key}.bin"), newBytes.ToArray()); //#endif // throw new SerializationException("Header not equal"); // } // } // else // { // } #endregion results.Add(new ArchiveTestResult() { ArchiveName = archive.Name, Hash = hash.ToString(), Success = true }); } catch (Exception e) { Console.WriteLine($"{hash} - {e.Message} - {e.StackTrace}"); results.Add(new ArchiveTestResult() { ArchiveName = archive.Name, Hash = hash.ToString(), Success = false, ExceptionType = e.GetType(), Message = $"{e.Message}" }); } #if IS_PARALLEL });
private void ParseMaterials(CR2WFile cr2w, Stream meshStream, FileInfo outfile, List <Archive> archives, string matRepo, EUncookExtension eUncookExtension = EUncookExtension.dds) { var primaryDependencies = new List <string>(); var materialEntryNames = new List <string>(); var materialEntries = new List <CMaterialInstance>(); GetMateriaEntries(cr2w, meshStream, ref primaryDependencies, ref materialEntryNames, ref materialEntries, archives); var mlSetupNames = new List <string>(); var mlTemplateNames = new List <string>(); var HairProfileNames = new List <string>(); var TexturesList = new List <string>(); var exportArgs = new GlobalExportArgs().Register( new XbmExportArgs() { UncookExtension = eUncookExtension }, new MlmaskExportArgs() { UncookExtension = eUncookExtension.ToMlmaskUncookExtension() } ); for (var i = 0; i < primaryDependencies.Count; i++) { if (Path.GetExtension(primaryDependencies[i]) == ".xbm") { if (!TexturesList.Contains(primaryDependencies[i])) { TexturesList.Add(primaryDependencies[i]); } var hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]); foreach (var ar in archives) { if (ar.Files.ContainsKey(hash)) { if (!File.Exists(Path.Combine(matRepo, Path.ChangeExtension(primaryDependencies[i], "." + exportArgs.Get <XbmExportArgs>().UncookExtension.ToString())))) { if (Directory.Exists(matRepo)) { UncookSingle(ar, hash, new DirectoryInfo(matRepo), exportArgs); } } break; } } } if (Path.GetExtension(primaryDependencies[i]) == ".mlmask") { if (!TexturesList.Contains(primaryDependencies[i])) { TexturesList.Add(primaryDependencies[i]); } var hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]); foreach (var ar in archives) { if (ar.Files.ContainsKey(hash)) { if (!File.Exists(Path.Combine(matRepo, primaryDependencies[i].Replace(".mlmask", $"_0.{exportArgs.Get<XbmExportArgs>().UncookExtension.ToString()}")))) { if (Directory.Exists(matRepo)) { UncookSingle(ar, hash, new DirectoryInfo(matRepo), exportArgs); } } break; } } } if (Path.GetExtension(primaryDependencies[i]) == ".hp") { if (!HairProfileNames.Contains(primaryDependencies[i])) { var hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]); foreach (var ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ExtractSingleToStream(ar, hash, ms); ms.Seek(0, SeekOrigin.Begin); HairProfileNames.Add(primaryDependencies[i]); var path = Path.Combine(matRepo, Path.ChangeExtension(primaryDependencies[i], ".hp.json")); if (!File.Exists(path)) { if (!new FileInfo(path).Directory.Exists) { Directory.CreateDirectory(new FileInfo(path).Directory.FullName); } var hp = _wolvenkitFileService.ReadRed4File(ms); //hp.FileName = primaryDependencies[i]; var dto = new RedFileDto(hp); var doc = RedJsonSerializer.Serialize(dto); File.WriteAllText(path, doc); } break; } } } } if (Path.GetExtension(primaryDependencies[i]) == ".mlsetup") { if (!mlSetupNames.Contains(primaryDependencies[i])) { var hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]); foreach (var ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ExtractSingleToStream(ar, hash, ms); ms.Seek(0, SeekOrigin.Begin); var isResource = _wolvenkitFileService.IsCR2WFile(ms); if (!isResource) { throw new InvalidParsingException("not a cr2w file"); } using var reader = new CR2WReader(ms); _ = reader.ReadFile(out var mls, false); mlSetupNames.Add(primaryDependencies[i]); var path = Path.Combine(matRepo, Path.ChangeExtension(primaryDependencies[i], ".mlsetup.json")); if (!File.Exists(path)) { if (!new FileInfo(path).Directory.Exists) { Directory.CreateDirectory(new FileInfo(path).Directory.FullName); } //mls.FileName = primaryDependencies[i]; var dto = new RedFileDto(mls); var doc = RedJsonSerializer.Serialize(dto); File.WriteAllText(path, doc); } for (var e = 0; e < reader.ImportsList.Count; e++) { if (Path.GetExtension(reader.ImportsList[e].DepotPath) == ".xbm") { if (!TexturesList.Contains(reader.ImportsList[e].DepotPath)) { TexturesList.Add(reader.ImportsList[e].DepotPath); } var hash1 = FNV1A64HashAlgorithm.HashString(reader.ImportsList[e].DepotPath); foreach (var arr in archives) { if (arr.Files.ContainsKey(hash1)) { if (!File.Exists(Path.Combine(matRepo, Path.ChangeExtension(reader.ImportsList[e].DepotPath, "." + exportArgs.Get <XbmExportArgs>().UncookExtension.ToString())))) { if (Directory.Exists(matRepo)) { UncookSingle(arr, hash1, new DirectoryInfo(matRepo), exportArgs); } } break; } } } if (Path.GetExtension(reader.ImportsList[e].DepotPath) == ".mltemplate") { if (!mlTemplateNames.Contains(reader.ImportsList[e].DepotPath)) { var hash2 = FNV1A64HashAlgorithm.HashString(reader.ImportsList[e].DepotPath); foreach (var arr in archives) { if (arr.Files.ContainsKey(hash2)) { var mss = new MemoryStream(); ExtractSingleToStream(arr, hash2, mss); mss.Seek(0, SeekOrigin.Begin); var mlt = _wolvenkitFileService.ReadRed4File(mss); mlTemplateNames.Add(reader.ImportsList[e].DepotPath); var path1 = Path.Combine(matRepo, Path.ChangeExtension(reader.ImportsList[e].DepotPath, ".mltemplate.json")); if (!File.Exists(path1)) { if (!new FileInfo(path1).Directory.Exists) { Directory.CreateDirectory(new FileInfo(path1).Directory.FullName); } //mlt.FileName = mls.Imports[e].DepotPath; var dto1 = new RedFileDto(mlt); var doc1 = RedJsonSerializer.Serialize(dto1); File.WriteAllText(path1, doc1); } for (var eye = 0; eye < reader.ImportsList.Count; eye++) { if (!TexturesList.Contains(reader.ImportsList[eye].DepotPath)) { TexturesList.Add(reader.ImportsList[eye].DepotPath); } var hash3 = FNV1A64HashAlgorithm.HashString(reader.ImportsList[eye].DepotPath); foreach (var arrr in archives) { if (arrr.Files.ContainsKey(hash3)) { if (!File.Exists(Path.Combine(matRepo, Path.ChangeExtension(reader.ImportsList[eye].DepotPath, "." + exportArgs.Get <XbmExportArgs>().UncookExtension.ToString())))) { if (Directory.Exists(matRepo)) { UncookSingle(arrr, hash3, new DirectoryInfo(matRepo), exportArgs); } } break; } } } break; } } } } } break; } } } } } var RawMaterials = new List <RawMaterial>(); var usedMts = new Dictionary <string, CMaterialTemplate>(); for (var i = 0; i < materialEntries.Count; i++) { RawMaterials.Add(ContainRawMaterial(materialEntries[i], materialEntryNames[i], archives, ref usedMts)); } var matTemplates = new List <RawMaterial>(); { var keys = usedMts.Keys.ToList(); for (var i = 0; i < keys.Count; i++) { var rawMat = new RawMaterial { Name = keys[i], Data = new Dictionary <string, object>() }; foreach (var item in usedMts[keys[i]].Parameters[2]) { rawMat.Data.Add(item.Chunk.ParameterName, GetSerializableValue(item.Chunk)); } matTemplates.Add(rawMat); } } var matData = new MatData { MaterialRepo = matRepo, Materials = RawMaterials, TexturesList = TexturesList, MaterialTemplates = matTemplates }; var str = RedJsonSerializer.Serialize(matData); File.WriteAllText(Path.ChangeExtension(outfile.FullName, ".Material.json"), str); }