public bool TryReadRed4FileHeaders(BinaryReader br, [NotNullWhen(true)] out CR2WFileInfo?info) { // TODO: Shouldn't be done here... br.BaseStream.Seek(0, SeekOrigin.Begin); using var reader = new CR2WReader(br); return(reader.ReadFileInfo(out info) == EFileReadErrorCodes.NoError); }
public bool TryReadRed4FileHeaders(Stream stream, [NotNullWhen(true)] out CR2WFileInfo?info) { // TODO: Shouldn't be done here... stream.Seek(0, SeekOrigin.Begin); using var reader = new CR2WReader(stream, Encoding.Default, true); return(reader.ReadFileInfo(out info) == EFileReadErrorCodes.NoError); }
/// <summary> /// Rebuild a list of buffer bytearrays into a redfile /// </summary> /// <param name="redfileStream"></param> /// <param name="buffersenumerable"></param> /// <returns></returns> private bool Rebuild(Stream redfileStream, IEnumerable <byte[]> buffersenumerable) { var isResource = _wolvenkitFileService.IsCR2WFile(redfileStream); if (!isResource) { return(false); } using var reader = new CR2WReader(redfileStream); _ = reader.ReadFile(out var cr2w, false); var existingBuffers = cr2w.GetBuffers(); var buffers = buffersenumerable.ToList(); if (buffers.Count != existingBuffers.Count) { throw new NotSupportedException("Rebuild: Adding/Removing buffers is not supported"); } for (var i = 0; i < buffers.Count; i++) { existingBuffers[i].SetBytes(buffers[i]); } // write cr2w redfileStream.Seek(0, SeekOrigin.Begin); using var writer = new CR2WWriter(redfileStream); writer.WriteFile(cr2w); return(true); }
static void OpenFile(string path) { Console.WriteLine(path); using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) using (var br = new CR2WReader(fs, false)) { } }
//[TestMethod] //public void Test_All_Extensions() //{ // Test_Extension(); //} //[TestMethod] public void Debug() { var files = s_groupedFiles[".smartobjects"].ToList(); foreach (var file in files) { if (!file.Name.Contains("so_-008_0005_-001.smartobjects")) { continue; } var ar = s_bm.Archives.Lookup(file.Archive.ArchiveAbsolutePath).Value as Archive; using var ms = new MemoryStream(); ar?.CopyFileToStream(ms, file.NameHash64, false); ms.Seek(0, SeekOrigin.Begin); var reader = new CR2WReader(ms); var readResult = reader.ReadFile(out var c); } }
private void GetMateriaEntries(CR2WFile cr2w, Stream meshStream, ref List <string> primaryDependencies, ref List <string> materialEntryNames, ref List <CMaterialInstance> materialEntries, List <Archive> archives) { var cmesh = cr2w.RootChunk as CMesh; var ExternalMaterial = new List <CMaterialInstance>(); for (var i = 0; i < cmesh.ExternalMaterials.Count; i++) { string path = cmesh.ExternalMaterials[i].DepotPath; var hash = FNV1A64HashAlgorithm.HashString(path); 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 mi, false); ExternalMaterial.Add(mi.RootChunk as CMaterialInstance); foreach (var import in reader.ImportsList) { if (!primaryDependencies.Contains(import.DepotPath)) { primaryDependencies.Add(import.DepotPath); } } break; } } } for (var i = 0; i < cmesh.PreloadExternalMaterials.Count; i++) { string path = cmesh.PreloadExternalMaterials[i].DepotPath; var hash = FNV1A64HashAlgorithm.HashString(path); 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 mi, false); ExternalMaterial.Add(mi.RootChunk as CMaterialInstance); foreach (var import in reader.ImportsList) { if (!primaryDependencies.Contains(import.DepotPath)) { primaryDependencies.Add(import.DepotPath); } } break; } } } var LocalMaterial = new List <CMaterialInstance>(); if (cmesh.LocalMaterialBuffer.RawDataHeaders.Count != 0) { var materialStream = GetMaterialStream(meshStream, cr2w); var bytes = materialStream.ToArray(); for (var i = 0; i < cmesh.LocalMaterialBuffer.RawDataHeaders.Count; i++) { uint offset = cmesh.LocalMaterialBuffer.RawDataHeaders[i].Offset; uint size = cmesh.LocalMaterialBuffer.RawDataHeaders[i].Size; var ms = new MemoryStream(bytes, (int)offset, (int)size); var isResource = _wolvenkitFileService.IsCR2WFile(ms); if (!isResource) { throw new InvalidParsingException("not a cr2w file"); } using var reader = new CR2WReader(ms); _ = reader.ReadFile(out var mi, false); //MemoryStream ms = new MemoryStream(bytes, (int)offset, (int)size); //var mi = _wolvenkitFileService.ReadRed4File(ms); foreach (var import in reader.ImportsList) { if (!primaryDependencies.Contains(import.DepotPath)) { primaryDependencies.Add(import.DepotPath); } } LocalMaterial.Add(mi.RootChunk as CMaterialInstance); } } else { foreach (var handle in cmesh.PreloadLocalMaterialInstances) { if (handle.Chunk is CMaterialInstance mi1) { LocalMaterial.Add(mi1); } } //throw new TodoException("get import info from cr2w file?"); /*foreach (var import in cr2w.Debug.ImportInfos) * { * * if (!primaryDependencies.Contains(import.DepotPath)) * { * primaryDependencies.Add(import.DepotPath); * } * }*/ } var Count = cmesh.MaterialEntries.Count; for (var i = 0; i < Count; i++) { var Entry = cmesh.MaterialEntries[i]; materialEntryNames.Add(Entry.Name); if (Entry.IsLocalInstance) { materialEntries.Add(LocalMaterial[Entry.Index]); } else { materialEntries.Add(ExternalMaterial[Entry.Index]); } } foreach (var m in materialEntries) { string path = m.BaseMaterial.DepotPath; while (!Path.GetExtension(path).Contains("mt")) { var hash = FNV1A64HashAlgorithm.HashString(path); 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 mi, false); path = (mi.RootChunk as CMaterialInstance).BaseMaterial.DepotPath; foreach (var import in reader.ImportsList) { if (!primaryDependencies.Contains(import.DepotPath)) { primaryDependencies.Add(import.DepotPath); } } break; } } } var mt = FNV1A64HashAlgorithm.HashString(path); foreach (var ar in archives) { if (ar.Files.ContainsKey(mt)) { var ms = new MemoryStream(); ExtractSingleToStream(ar, mt, 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 mi, false); foreach (var import in reader.ImportsList) { if (!primaryDependencies.Contains(import.DepotPath)) { primaryDependencies.Add(import.DepotPath); } } break; } } } }
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); }
private static IEnumerable <ReadTestResult> Read_Archive_Items(IEnumerable <FileEntry> files) { ArgumentNullException.ThrowIfNull(s_bm); var results = new ConcurrentBag <ReadTestResult>(); var filesGroups = files.Select((f, i) => new { Value = f, Index = i }) .GroupBy(item => item.Value.Archive.ArchiveAbsolutePath); foreach (var fileGroup in filesGroups) { var fileList = fileGroup.ToList(); var ar = s_bm.Archives.Lookup(fileGroup.Key).Value as Archive; using var fs = new FileStream(fileGroup.Key, FileMode.Open, FileAccess.Read, FileShare.Read); using var mmf = MemoryMappedFile.CreateFromFile(fs, null, 0, MemoryMappedFileAccess.Read, HandleInheritability.None, false); #if IS_PARALLEL Parallel.ForEach(fileList, tmpFile => #else foreach (var tmpFile in fileList) #endif { var file = tmpFile.Value; try { using var ms = new MemoryStream(); ar?.CopyFileToStream(ms, file.NameHash64, false, mmf); ms.Seek(0, SeekOrigin.Begin); using var reader = new CR2WReader(ms); var readResult = reader.ReadFile(out var c, DECOMPRESS_BUFFERS); switch (readResult) { case EFileReadErrorCodes.NoCr2w: results.Add(new ReadTestResult { FileEntry = file, Success = true, ReadResult = ReadTestResult.ReadResultType.NoCr2W }); break; case EFileReadErrorCodes.UnsupportedVersion: results.Add(new ReadTestResult { FileEntry = file, Success = false, ReadResult = ReadTestResult.ReadResultType.UnsupportedVersion, Message = $"Unsupported Version ({c.MetaData.Version})" }); break; case EFileReadErrorCodes.NoError: c.MetaData.FileName = file.NameOrHash; var res = ReadTestResult.ReadResultType.NoError; var msg = ""; var additionalCr2WFileBytes = (int)(reader.BaseStream.Length - reader.BaseStream.Position); if (additionalCr2WFileBytes > 0) { res |= ReadTestResult.ReadResultType.HasAdditionalBytes; msg += $"Additional Bytes: {additionalCr2WFileBytes}"; } results.Add(new ReadTestResult { FileEntry = file, Success = true /*!hasAdditionalBytes && !hasUnknownBytes*/, ReadResult = res, Message = msg, AdditionalBytes = additionalCr2WFileBytes }); break; default: throw new Exception(); } } catch (Exception e) { results.Add(new ReadTestResult { FileEntry = file, Success = false, ReadResult = ReadTestResult.ReadResultType.RuntimeException, ExceptionType = e.GetType(), Message = $"{e.Message}" }); } #if IS_PARALLEL });