private static async Task Loadhashes(string path) { var _maincontroller = ServiceLocator.Default.ResolveType <IMainController>(); Stopwatch watch = new Stopwatch(); watch.Restart(); var hashDictionary = new ConcurrentDictionary <ulong, string>(); Parallel.ForEach(File.ReadLines(path), line => { // check line line = line.Split(',', StringSplitOptions.RemoveEmptyEntries).First(); if (!string.IsNullOrEmpty(line)) { ulong hash = FNV1A64HashAlgorithm.HashString(line); hashDictionary.AddOrUpdate(hash, line, (key, val) => val); } }); _maincontroller.Hashdict = hashDictionary.ToDictionary( entry => entry.Key, entry => entry.Value); watch.Stop(); Console.WriteLine($"Loaded {hashDictionary.Count} hashes in {watch.ElapsedMilliseconds}ms."); }
private UInt16 AddProperty(FieldInfo info) { var propertyName = info == null ? string.Empty : info.Name; var className = info == null ? string.Empty : info.DeclaringType.Name; var fnv1a = new FNV1A64HashAlgorithm(); fnv1a.AppendString(className, true); fnv1a.AppendString(propertyName, true); var index = m_properties.FindIndex(i => i.hash == fnv1a.HashUInt64); if (index >= 0) { return(Convert.ToUInt16(index)); } m_properties.Add(new CR2WProperty() { className = AddName(className), classFlags = 0, propertyName = AddName(propertyName), propertyFlags = 0, hash = fnv1a.HashUInt64, }); fnv1a.Dispose(); return(Convert.ToUInt16(m_properties.Count)); }
private PackageImport ReadImport(Package04ImportHeader r, bool readAsHash) { // needs header offset //Debug.Assert(BaseStream.Position == r.offset); var import = new PackageImport() { Flags = (InternalEnums.EImportFlags)(r.sync ? 0b1 : 0b0) }; if (readAsHash) { import.Hash = _reader.ReadUInt64(); import.DepotPath = _hashService.Get(import.Hash); } else { var bytes = _reader.ReadBytes(r.size); import.DepotPath = Encoding.UTF8.GetString(bytes.ToArray()); import.Hash = FNV1A64HashAlgorithm.HashString(import.DepotPath); if (CollectData) { DataCollection.RawImportList.Add(import.DepotPath); } } return(import); }
public ulong RegisterVanillaPath(string path) { var hashint = FNV1A64HashAlgorithm.HashString(path); if (!HashdumpDict.ContainsKey(path)) { HashdumpDict.Add(path, hashint); } return(hashint); }
public OpusTools(Archive soundbanks, string modFolder, string rawFolder, bool useMod = false) //audio_2_soundbanks.archive { _soundBanks = soundbanks; _modFolder = new DirectoryInfo(modFolder); _rawFolder = new DirectoryInfo(rawFolder); _isModded = useMod; if (!Directory.Exists(Path.Combine(_modFolder.FullName, "base\\sound\\soundbanks"))) { Directory.CreateDirectory(Path.Combine(_modFolder.FullName, "base\\sound\\soundbanks")); } if (!Directory.Exists(_rawFolder.FullName)) { Directory.CreateDirectory(_rawFolder.FullName); } if (_isModded) { var infoFile = Path.Combine(_modFolder.FullName, "base\\sound\\soundbanks\\sfx_container.opusinfo"); if (File.Exists(infoFile)) { var ms = new MemoryStream(File.ReadAllBytes(infoFile)); var br = new BinaryReader(ms); ms.Position = 0; if (BitConverter.ToString(br.ReadBytes(3)) != "53-4E-44") { _isModded = false; } else { Info = new OpusInfo(ms); } } else { _isModded = false; } } if (!_isModded) { var hash = FNV1A64HashAlgorithm.HashString("base\\sound\\soundbanks\\sfx_container.opusinfo"); var ms = new MemoryStream(); if (_soundBanks.Files.ContainsKey(hash)) { ModTools.ExtractSingleToStream(_soundBanks, hash, ms); Info = new OpusInfo(ms); } else { Info = new OpusInfo(); } } }
private ulong CalculateHash() { if (string.IsNullOrEmpty(_value)) { return(0); } var buffer = Encoding.UTF8.GetBytes(_value); var sBuffer = Array.ConvertAll(buffer, b => b != 0x80 ? (byte)Math.Abs((sbyte)b) : (byte)0x80); return(FNV1A64HashAlgorithm.HashReadOnlySpan(sBuffer)); }
public static ulong ComputeFieldInfoHash(FieldInfo info) { var fieldName = GetREDNameString(info); var declaringName = info.DeclaringType.Name; var fnv = new FNV1A64HashAlgorithm(); fnv.AppendString(declaringName, true); fnv.AppendString(fieldName, true); return(fnv.HashUInt64); }
public static ArchiveFileInfo SearchFile(String path) { UInt64 nameHash = FNV1A64HashAlgorithm.HashString(path); try { return(ArchiveManager.SearchFile(nameHash)); } catch (FileNotFoundException e) { throw new FileNotFoundException("File not found", path, e); } }
public static int HashTask(string[] input, bool missing) { #region checks foreach (var s in input) { if (!string.IsNullOrEmpty(s)) { logger.LogString(FNV1A64HashAlgorithm.HashString(s).ToString(), Logtype.Normal); } } #endregion if (missing) { var missingh = File.ReadAllLines(@"C:\Gog\Cyberpunk 2077\archive\pc\content\missinghashes.txt"); var lines = File.ReadAllLines(@"X:\cp77\langs-work.txt"); var Hashdict = new Dictionary <ulong, string>(); var bad = new Dictionary <ulong, string>(); foreach (var line in lines) { var hash = FNV1A64HashAlgorithm.HashString(line); if (missingh.Contains(hash.ToString())) { if (!Hashdict.ContainsKey(hash)) { Hashdict.Add(hash, line); } } else { if (!bad.ContainsKey(hash)) { bad.Add(hash, line); } } } } return(1); }
public bool ExportOpusUsingHash(uint opusHash) { if (!_isModded) { for (uint i = 0; i < Info.OpusCount; i++) { if (Info.OpusHashes[i] == opusHash) { var containerHash = FNV1A64HashAlgorithm.HashString("base\\sound\\soundbanks\\sfx_container_" + Info.PackIndices[i] + ".opuspak"); var ms = new MemoryStream(); ModTools.ExtractSingleToStream(_soundBanks, containerHash, ms); Info.WriteOpusFromPak(ms, _rawFolder, i); return(true); } if (Info.OpusCount == i + 1) { return(false); } } } else { for (uint i = 0; i < Info.OpusCount; i++) { if (Info.OpusHashes[i] == opusHash) { var pakFile = Path.Combine(_modFolder.FullName, "base\\sound\\soundbanks\\sfx_container_" + Info.PackIndices[i] + ".opuspak"); if (File.Exists(pakFile)) { var ms = new MemoryStream(File.ReadAllBytes(pakFile)); Info.WriteOpusFromPak(ms, _rawFolder, i); return(true); } else { return(false); } } if (Info.OpusCount == i + 1) { return(false); } } } return(false); }
/// <summary> /// Creates and archive from a folder and packs all files inside into it /// </summary> /// <param name="infolder"></param> /// <param name="outpath"></param> /// <returns></returns> public static Archive.Archive Pack(DirectoryInfo infolder, DirectoryInfo outpath) { if (!infolder.Exists) { return(null); } if (!outpath.Exists) { return(null); } var outfile = Path.Combine(outpath.FullName, $"basegame_{infolder.Name}.archive"); var ar = new Archive.Archive { Filepath = outfile, Table = new ArTable() }; using var fs = new FileStream(outfile, FileMode.Create); using var bw = new BinaryWriter(fs); #region write header ar.Header.Write(bw); bw.Write(new byte[132]); // some weird padding #endregion #region write files var exludedExtensions = new[] { ".buffer", ".dds", ".DS_Store", //Hooray for OSX }; var allfiles = infolder.GetFiles("*", SearchOption.AllDirectories); var parentfiles = allfiles .Where(_ => exludedExtensions.All(x => _.Extension != x)); var fileInfos = parentfiles .OrderBy(_ => FNV1A64HashAlgorithm.HashString(GetRelpath(_))) .ToList(); string GetRelpath(FileInfo infi) => infi.FullName[(infolder.FullName.Length + 1)..];
private void ExecuteOpenImport(ICR2WImport input) { var depotpath = input.DepotPathStr; var key = FNV1A64HashAlgorithm.HashString(depotpath); var foundItems = new List <IGameFile>(); foreach (var manager in _gameControllerFactory.GetController().GetArchiveManagers(false) .Where(manager => manager.Items.ContainsKey(key))) { foundItems.AddRange(manager.Items[key]); } var itemToImport = foundItems.FirstOrDefault(); if (itemToImport != null) { _gameControllerFactory.GetController().AddToMod(itemToImport); } }
private RawMaterial ContainRawMaterial(CMaterialInstance cMaterialInstance, string Name, List <Archive> archives) { RawMaterial rawMaterial = new RawMaterial(); rawMaterial.Name = Name; rawMaterial.BaseMaterial = cMaterialInstance.BaseMaterial.DepotPath; List <CMaterialInstance> BaseMaterials = new List <CMaterialInstance>(); string path = cMaterialInstance.BaseMaterial.DepotPath; while (!Path.GetExtension(path).Contains("mt")) { ulong hash = FNV1A64HashAlgorithm.HashString(path); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); var mi = _wolvenkitFileService.TryReadCr2WFile(ms); BaseMaterials.Add(mi.Chunks[0].Data as CMaterialInstance); path = (mi.Chunks[0].Data as CMaterialInstance).BaseMaterial.DepotPath; break; } } } string type = Path.GetFileName(path); BaseMaterials.Reverse(); for (int i = 0; i < BaseMaterials.Count; i++) { MATERIAL.ContainRawMaterialEnum(ref rawMaterial, BaseMaterials[i], type); } MATERIAL.ContainRawMaterialEnum(ref rawMaterial, cMaterialInstance, type); return(rawMaterial); }
private CR2WFile LoadFile(string path, List <Archive> archives) { 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); if (!_wolvenkitFileService.TryReadRed4File(ms, out var file)) { throw new Exception("Invalid CR2W file"); } return(file); } } throw new FileNotFoundException(path); }
public void CompareMemorySAsciiStringChunked() { List <string> originals = new(); Dictionary <ulong, uint[]> hashDictionary = new(); Dictionary <SAsciiString, uint> helperDict = new(new MyComparer()); hashDictionary.EnsureCapacity(500_000); var runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll"); var paths = new List <string>(runtimeAssemblies); var resolver = new PathAssemblyResolver(paths); var mlc = new MetadataLoadContext(resolver); var before = GC.GetTotalMemory(true); Assembly assembly; using (mlc) { assembly = mlc.LoadFromAssemblyPath("WolvenKit.Common.dll"); using var stream = assembly.GetManifestResourceStream(s_used); // read KARK header var oodleCompression = stream.ReadStruct <uint>(); if (oodleCompression != OodleHelper.KARK) { throw new DecompressionException($"Incorrect hash file."); } var outputsize = stream.ReadStruct <uint>(); // read the rest of the stream var outputbuffer = new byte[outputsize]; var inbuffer = stream.ToByteArray(true); OozNative.Kraken_Decompress(inbuffer, inbuffer.Length, outputbuffer, outputbuffer.Length); using (var ms = new MemoryStream(outputbuffer)) using (var sr = new StreamReader(ms)) { string line; while ((line = sr.ReadLine()) != null) { originals.Add(line); var hash = FNV1A64HashAlgorithm.HashString(line); var pathParts = line.Split('\\'); hashDictionary.Add(hash, new uint[pathParts.Length]); for (var i = 0; i < pathParts.Length; i++) { var s = pathParts[i]; var a = new SAsciiString(s); uint idx; if (helperDict.ContainsKey(a)) { idx = helperDict[a]; } else { //chunks.Add(a); var count = helperDict.Count; helperDict.Add(a, (uint)count); idx = (uint)count; } hashDictionary[hash][i] = idx; } } } } var after = GC.GetTotalMemory(true); double diff = after - before; Console.WriteLine($"Memory: {diff.ToString()}"); // compare var failed = 0; var keys = helperDict.Keys.ToList(); foreach (var s in originals) { var hash = FNV1A64HashAlgorithm.HashString(s); var gottenString = ""; for (var i = 0; i < hashDictionary[hash].Length; i++) { var idx = hashDictionary[hash][i]; gottenString += keys[(int)idx].ToString(); if (i < hashDictionary[hash].Length - 1) { gottenString += Path.DirectorySeparatorChar; } } if (!gottenString.Equals(s)) { failed++; } } Assert.AreEqual(0, failed); }
public void TestFNV1a64_ByteSpan(byte[] test, ulong result) { Assert.AreEqual(FNV1A64HashAlgorithm.HashReadOnlySpan(test), result); }
public void TestFNV1a64_NullEnded(string test, ulong result) { Assert.AreEqual(FNV1A64HashAlgorithm.HashString(test, Encoding.ASCII, true), result); }
public void TestFNV1a64(string test, ulong result) { // Assert.AreEqual(FNV1A64HashAlgorithm.HashString(test), result); Assert.AreEqual(FNV1A64HashAlgorithm.HashString(test), result); }
public void TestFNV1a64_CharSpan(string test, ulong result) { Assert.AreEqual(FNV1A64HashAlgorithm.HashReadOnlySpan(test.AsSpan()), result); }
public ulong GetRedHash(EditorProject project) => FNV1A64HashAlgorithm.HashString(GetRelativeName(project));
public bool ExportMorphTargets(Stream targetStream, FileInfo outfile, List <Archive> archives, string modFolder, bool isGLBinary = true) { var cr2w = _wolvenkitFileService.ReadRed4File(targetStream); if (cr2w == null || cr2w.RootChunk is not MorphTargetMesh morphBlob || morphBlob.Blob.Chunk is not rendRenderMorphTargetMeshBlob blob || blob.BaseBlob.Chunk is not rendRenderMeshBlob rendblob) { return(false); } RawArmature Rig = null; { var hash = FNV1A64HashAlgorithm.HashString(morphBlob.BaseMesh.DepotPath); var meshStream = new MemoryStream(); foreach (var ar in archives) { if (ar.Files.ContainsKey(hash)) { ExtractSingleToStream(ar, hash, meshStream); break; } } var meshCr2w = _wolvenkitFileService.ReadRed4File(meshStream); if (meshCr2w != null && meshCr2w.RootChunk is MorphTargetMesh tBlob1 && tBlob1.Blob.Chunk is rendRenderMorphTargetMeshBlob tBlob2 && tBlob2.BaseBlob.Chunk is rendRenderMeshBlob tBlob3) { Rig = MeshTools.GetOrphanRig(tBlob3, meshCr2w); } } using var meshbuffer = new MemoryStream(rendblob.RenderBuffer.Buffer.GetBytes()); var meshesinfo = MeshTools.GetMeshesinfo(rendblob, cr2w); var expMeshes = MeshTools.ContainRawMesh(meshbuffer, meshesinfo, true); var diffsbuffer = new MemoryStream(); var mappingbuffer = new MemoryStream(); var texbuffer = new MemoryStream(); if (blob.DiffsBuffer is not null) { diffsbuffer = new MemoryStream(blob.DiffsBuffer.Buffer.GetBytes()); //targetStream.Seek(cr2w.Buffers[blob.DiffsBuffer.Buffer - 1].Offset, SeekOrigin.Begin); //targetStream.DecompressAndCopySegment(diffsbuffer, cr2w.Buffers[blob.DiffsBuffer.Buffer - 1].DiskSize, cr2w.Buffers[blob.DiffsBuffer.Buffer - 1].MemSize); } if (blob.MappingBuffer is not null) { mappingbuffer = new MemoryStream(blob.MappingBuffer.Buffer.GetBytes()); //targetStream.Seek(cr2w.Buffers[blob.MappingBuffer.Buffer - 1].Offset, SeekOrigin.Begin); //targetStream.DecompressAndCopySegment(mappingbuffer, cr2w.Buffers[blob.MappingBuffer.Buffer - 1].DiskSize, cr2w.Buffers[blob.MappingBuffer.Buffer - 1].MemSize); } if (blob.TextureDiffsBuffer is not null) { texbuffer = new MemoryStream(blob.TextureDiffsBuffer.Buffer.GetBytes()); //targetStream.Seek(cr2w.Buffers[blob.TextureDiffsBuffer.Buffer - 1].Offset, SeekOrigin.Begin); //targetStream.DecompressAndCopySegment(texbuffer, cr2w.Buffers[blob.TextureDiffsBuffer.Buffer - 1].DiskSize, cr2w.Buffers[blob.TextureDiffsBuffer.Buffer - 1].MemSize); } var targetsInfo = GetTargetInfos(cr2w, expMeshes.Count); var expTargets = new List <RawTargetContainer[]>(); for (var i = 0; i < targetsInfo.NumTargets; i++) { var temp_NumVertexDiffsInEachChunk = new uint[expMeshes.Count]; var temp_NumVertexDiffsMappingInEachChunk = new uint[expMeshes.Count]; for (var e = 0; e < expMeshes.Count; e++) { temp_NumVertexDiffsInEachChunk[e] = targetsInfo.NumVertexDiffsInEachChunk[i, e]; temp_NumVertexDiffsMappingInEachChunk[e] = targetsInfo.NumVertexDiffsMappingInEachChunk[i, e]; } expTargets.Add(ContainRawTargets(diffsbuffer, mappingbuffer, temp_NumVertexDiffsInEachChunk, temp_NumVertexDiffsMappingInEachChunk, targetsInfo.TargetStartsInVertexDiffs[i], targetsInfo.TargetStartsInVertexDiffsMapping[i], targetsInfo.TargetPositionDiffOffset[i], targetsInfo.TargetPositionDiffScale[i], expMeshes.Count)); } var textureStreams = ContainTextureStreams(blob, texbuffer); var model = RawTargetsToGLTF(expMeshes, expTargets, targetsInfo.Names, Rig); if (WolvenTesting.IsTesting) { return(true); } if (isGLBinary) { model.SaveGLB(outfile.FullName); } else { model.SaveGLTF(outfile.FullName); } var dir = new DirectoryInfo(outfile.FullName.Replace(Path.GetExtension(outfile.FullName), string.Empty) + "_Textures"); if (textureStreams.Count > 0) { Directory.CreateDirectory(dir.FullName); } for (var i = 0; i < textureStreams.Count; i++) { File.WriteAllBytes(dir.FullName + "\\" + Path.GetFileNameWithoutExtension(outfile.FullName) + i + ".dds", textureStreams[i].ToArray()); } targetStream.Dispose(); targetStream.Close(); return(true); }
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.Chunks.Select(_ => _.Data).OfType <CMesh>().First(); List <CMaterialInstance> ExternalMaterial = new List <CMaterialInstance>(); for (int i = 0; i < cmesh.ExternalMaterials.Count; i++) { string path = cmesh.ExternalMaterials[i].DepotPath; ulong hash = FNV1A64HashAlgorithm.HashString(path); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); var mi = _wolvenkitFileService.TryReadCr2WFile(ms); ExternalMaterial.Add(mi.Chunks[0].Data as CMaterialInstance); for (int t = 0; t < mi.Imports.Count; t++) { if (!primaryDependencies.Contains(mi.Imports[t].DepotPathStr)) { primaryDependencies.Add(mi.Imports[t].DepotPathStr); } } break; } } } for (int i = 0; i < cmesh.PreloadExternalMaterials.Count; i++) { string path = cmesh.PreloadExternalMaterials[i].DepotPath; ulong hash = FNV1A64HashAlgorithm.HashString(path); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); var mi = _wolvenkitFileService.TryReadCr2WFile(ms); ExternalMaterial.Add(mi.Chunks[0].Data as CMaterialInstance); for (int t = 0; t < mi.Imports.Count; t++) { if (!primaryDependencies.Contains(mi.Imports[t].DepotPathStr)) { primaryDependencies.Add(mi.Imports[t].DepotPathStr); } } break; } } } List <CMaterialInstance> LocalMaterial = new List <CMaterialInstance>(); bool isbuffered = true; if (cmesh.LocalMaterialBuffer.RawDataHeaders.Count == 0) { isbuffered = false; } if (isbuffered) { MemoryStream materialStream = GetMaterialStream(meshStream, cr2w); byte[] bytes = materialStream.ToArray(); for (int i = 0; i < cmesh.LocalMaterialBuffer.RawDataHeaders.Count; i++) { UInt32 offset = cmesh.LocalMaterialBuffer.RawDataHeaders[i].Offset.Value; UInt32 size = cmesh.LocalMaterialBuffer.RawDataHeaders[i].Size.Value; MemoryStream ms = new MemoryStream(bytes, (int)offset, (int)size); var mi = _wolvenkitFileService.TryReadCr2WFile(ms); for (int e = 0; e < mi.Imports.Count; e++) { if (!primaryDependencies.Contains(mi.Imports[e].DepotPathStr)) { primaryDependencies.Add(mi.Imports[e].DepotPathStr); } } LocalMaterial.Add(mi.Chunks[0].Data as CMaterialInstance); } } else { for (int i = 0; i < cr2w.Chunks.Count; i++) { if (cr2w.Chunks[i].REDType == "CMaterialInstance") { LocalMaterial.Add(cr2w.Chunks[i].Data as CMaterialInstance); } } for (int i = 0; i < cr2w.Imports.Count; i++) { if (!primaryDependencies.Contains(cr2w.Imports[i].DepotPathStr)) { primaryDependencies.Add(cr2w.Imports[i].DepotPathStr); } } } int Count = cmesh.MaterialEntries.Count; for (int i = 0; i < Count; i++) { var Entry = cmesh.MaterialEntries[i]; materialEntryNames.Add(Entry.Name.Value); if (Entry.IsLocalInstance.Value) { materialEntries.Add(LocalMaterial[Entry.Index.Value]); } else { materialEntries.Add(ExternalMaterial[Entry.Index.Value]); } } foreach (var m in materialEntries) { string path = m.BaseMaterial.DepotPath; while (!Path.GetExtension(path).Contains("mt")) { ulong hash = FNV1A64HashAlgorithm.HashString(path); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); var mi = _wolvenkitFileService.TryReadCr2WFile(ms); path = (mi.Chunks[0].Data as CMaterialInstance).BaseMaterial.DepotPath; for (int t = 0; t < mi.Imports.Count; t++) { if (!primaryDependencies.Contains(mi.Imports[t].DepotPathStr)) { primaryDependencies.Add(mi.Imports[t].DepotPathStr); } } break; } } } ulong mt = FNV1A64HashAlgorithm.HashString(path); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(mt)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, mt, ms); var mi = _wolvenkitFileService.TryReadCr2WFile(ms); for (int t = 0; t < mi.Imports.Count; t++) { if (!primaryDependencies.Contains(mi.Imports[t].DepotPathStr)) { primaryDependencies.Add(mi.Imports[t].DepotPathStr); } } break; } } } }
public bool WriteMatToMesh(ref CR2WFile cr2w, string _matData, Archive ar) { if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any() || cr2w.Buffers.Count < 1) { return(false); } ulong hash = FNV1A64HashAlgorithm.HashString("base\\characters\\common\\skin\\old_mat_instances\\skin_ma_a__head.mi"); if (!ar.Files.ContainsKey(hash)) { return(false); } var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); _wolvenkitFileService.TryReadRED4File(ms); ms.Seek(0, SeekOrigin.Begin); var obj = JsonConvert.DeserializeObject <MatData>(_matData); var materialbuffer = new MemoryStream(); List <UInt32> offsets = new List <UInt32>(); List <UInt32> sizes = new List <UInt32>(); List <string> names = new List <string>(); if (obj.Materials.Count < 1) { return(false); } for (int i = 0; i < obj.Materials.Count; i++) { var mat = obj.Materials[i]; names.Add(mat.Name); var mi = _wolvenkitFileService.TryReadRED4File(ms); ms.Seek(0, SeekOrigin.Begin); MATERIAL.WriteMatToMeshEnum(ref mi, ref mat); (mi.Chunks[0].Data as CMaterialInstance).BaseMaterial.DepotPath = mat.BaseMaterial; offsets.Add((UInt32)materialbuffer.Position); var m = new MemoryStream(); var b = new BinaryWriter(m); mi.Write(b); materialbuffer.Write(m.ToArray(), 0, (int)m.Length); sizes.Add((UInt32)m.Length); } var blob = cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First(); // remove existing data while (blob.MaterialEntries.Count != 0) { blob.MaterialEntries.Remove(blob.MaterialEntries[blob.MaterialEntries.Count - 1]); } while (blob.LocalMaterialBuffer.RawDataHeaders.Count != 0) { blob.LocalMaterialBuffer.RawDataHeaders.Remove(blob.LocalMaterialBuffer.RawDataHeaders[blob.LocalMaterialBuffer.RawDataHeaders.Count - 1]); } while (blob.PreloadLocalMaterialInstances.Count != 0) { blob.PreloadLocalMaterialInstances.Remove(blob.PreloadLocalMaterialInstances[blob.PreloadLocalMaterialInstances.Count - 1]); } while (blob.PreloadExternalMaterials.Count != 0) { blob.PreloadExternalMaterials.Remove(blob.PreloadExternalMaterials[blob.PreloadExternalMaterials.Count - 1]); } while (blob.ExternalMaterials.Count != 0) { blob.ExternalMaterials.Remove(blob.ExternalMaterials[blob.ExternalMaterials.Count - 1]); } while (blob.LocalMaterialInstances.Count != 0) { blob.LocalMaterialInstances.Remove(blob.LocalMaterialInstances[blob.LocalMaterialInstances.Count - 1]); } // for (int i = 0; i < names.Count; i++) { var c = new CMeshMaterialEntry(cr2w, blob.MaterialEntries, Convert.ToString(i)) { IsSerialized = true, }; c.IsLocalInstance = new CBool(cr2w, c, "isLocalInstance") { Value = true, IsSerialized = true }; c.Name = new CName(cr2w, c, "name") { Value = names[i], IsSerialized = true }; c.Index = new CUInt16(cr2w, c, "index") { Value = (UInt16)i, IsSerialized = true }; blob.MaterialEntries.Add(c); var m = new meshLocalMaterialHeader(cr2w, blob.LocalMaterialBuffer.RawDataHeaders, Convert.ToString(i)) { IsSerialized = true }; m.Offset = new CUInt32(cr2w, m, "offset") { Value = offsets[i], IsSerialized = true }; m.Size = new CUInt32(cr2w, m, "size") { Value = sizes[i], IsSerialized = true }; blob.LocalMaterialBuffer.RawDataHeaders.Add(m); } var compressed = new MemoryStream(); using var buff = new BinaryWriter(compressed); var(zsize, crc) = buff.CompressAndWrite(materialbuffer.ToArray()); bool check = false; check = blob.LocalMaterialBuffer.RawData.IsSerialized; if (!check) { blob.LocalMaterialBuffer.RawData = new DataBuffer(cr2w, blob.LocalMaterialBuffer, "rawData") { IsSerialized = true }; blob.LocalMaterialBuffer.RawData.Buffer = new CUInt16(cr2w, blob.LocalMaterialBuffer.RawData, "Buffer") { Value = (UInt16)(cr2w.Buffers.Count + 1), IsSerialized = true }; uint idx = (uint)cr2w.Buffers.Count; cr2w.Buffers.Add(new CR2WBufferWrapper(new CR2WBuffer() { flags = 0, index = idx, offset = 0, diskSize = zsize, memSize = (UInt32)materialbuffer.Length, crc32 = crc })); cr2w.Buffers[(int)idx].ReadData(new BinaryReader(compressed)); cr2w.Buffers[(int)idx].Offset = cr2w.Buffers[(int)idx - 1].Offset + cr2w.Buffers[(int)idx - 1].DiskSize; } else { UInt16 p = (blob.LocalMaterialBuffer.RawData.Buffer.Value); cr2w.Buffers[p - 1].DiskSize = zsize; cr2w.Buffers[p - 1].Crc32 = crc; cr2w.Buffers[p - 1].MemSize = (UInt32)materialbuffer.Length; var off = cr2w.Buffers[p - 1].Offset; cr2w.Buffers[p - 1].Offset = 0; cr2w.Buffers[p - 1].ReadData(new BinaryReader(compressed)); cr2w.Buffers[p - 1].Offset = off; } return(true); }
public bool WriteMatToMesh(ref CR2WFile cr2w, string _matData, List <Archive> archives) { if (cr2w == null || cr2w.RootChunk is not CMesh cMesh || cMesh.RenderResourceBlob.Chunk is not rendRenderMeshBlob) { return(false); } var matData = RedJsonSerializer.Deserialize <MatData>(_matData); var materialbuffer = new MemoryStream(); var offsets = new List <uint>(); var sizes = new List <uint>(); var names = new List <string>(); if (matData.Materials.Count < 1) { return(false); } var mts = new Dictionary <string, CMaterialTemplate>(); for (var i = 0; i < matData.Materials.Count; i++) { var mat = matData.Materials[i]; names.Add(mat.Name); var mi = new CR2WFile(); { var chunk = RedTypeManager.Create <CMaterialInstance>(); chunk.CookingPlatform = Enums.ECookingPlatform.PLATFORM_PC; chunk.EnableMask = true; chunk.ResourceVersion = 4; chunk.BaseMaterial = new CResourceReference <IMaterial>() { DepotPath = mat.BaseMaterial }; chunk.Values = new CArray <CKeyValuePair>(); CMaterialTemplate mt = null; if (mts.ContainsKey(mat.MaterialTemplate)) { mt = mts[mat.MaterialTemplate]; } else { var hash = FNV1A64HashAlgorithm.HashString(mat.MaterialTemplate); foreach (var ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ExtractSingleToStream(ar, hash, ms); ms.Seek(0, SeekOrigin.Begin); mt = (CMaterialTemplate)_wolvenkitFileService.ReadRed4File(ms).RootChunk; mts.Add(mat.MaterialTemplate, mt); break; } } } var fakeMaterialInstance = new CMaterialInstance() { BaseMaterial = new CResourceReference <IMaterial> { DepotPath = mat.BaseMaterial }, Values = new CArray <CKeyValuePair>() }; var orgChain = GetMaterialChain(fakeMaterialInstance, archives, ref mts); if (mt != null) { foreach (var(key, value) in matData.Materials[i].Data) { var found = false; for (var k = 0; k < mt.Parameters[2].Count; k++) { var refer = mt.Parameters[2][k].Chunk; if (refer.ParameterName == key) { found = true; object convValue = GetMaterialParameterValue(refer.GetType(), value); if (orgChain.valueDict.ContainsKey(refer.ParameterName) && !Equals(orgChain.valueDict[refer.ParameterName], convValue)) { chunk.Values.Add(new CKeyValuePair(refer.ParameterName, (IRedType)convValue)); } } } if (!found) { var wrapper = ((JsonElement)value).Deserialize <MaterialValueWrapper>(); var(type, _) = RedReflection.GetCSTypeFromRedType(wrapper.Type); var nValue = ((JsonElement)wrapper.Value).Deserialize(type, RedJsonSerializer.Options); chunk.Values.Add(new CKeyValuePair(key, (IRedType)nValue)); } } } mi.RootChunk = chunk; } offsets.Add((uint)materialbuffer.Position); using var m = new MemoryStream(); using var writer = new CR2WWriter(m); writer.WriteFile(mi); materialbuffer.Write(m.ToArray(), 0, (int)m.Length); sizes.Add((uint)m.Length); } var blob = (CMesh)cr2w.RootChunk; // remove existing data while (blob.MaterialEntries.Count != 0) { blob.MaterialEntries.Remove(blob.MaterialEntries[^ 1]);
private void ParseMaterials(CR2WFile cr2w, Stream meshStream, DirectoryInfo outDir, List <Archive> archives, string matRepo, EUncookExtension eUncookExtension = EUncookExtension.dds) { List <string> primaryDependencies = new List <string>(); List <string> materialEntryNames = new List <string>(); List <CMaterialInstance> materialEntries = new List <CMaterialInstance>(); GetMateriaEntries(cr2w, meshStream, ref primaryDependencies, ref materialEntryNames, ref materialEntries, archives); List <string> mlSetupNames = new List <string>(); List <Multilayer_Setup> mlSetups = new List <Multilayer_Setup>(); List <string> mlTemplateNames = new List <string>(); List <Multilayer_LayerTemplate> mlTemplates = new List <Multilayer_LayerTemplate>(); List <HairProfile> HairProfiles = new List <HairProfile>(); List <string> HairProfileNames = new List <string>(); List <string> TexturesList = new List <string>(); var exportArgs = new GlobalExportArgs().Register( new XbmExportArgs() { UncookExtension = eUncookExtension }, new MlmaskExportArgs() { UncookExtension = eUncookExtension } ); for (int i = 0; i < primaryDependencies.Count; i++) { if (Path.GetExtension(primaryDependencies[i]) == ".xbm") { if (!TexturesList.Contains(primaryDependencies[i])) { TexturesList.Add(primaryDependencies[i]); } ulong hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { if (!File.Exists(Path.Combine(matRepo, primaryDependencies[i].Replace("xbm", exportArgs.Get <XbmExportArgs>().UncookExtension.ToString())))) { if (Directory.Exists(matRepo)) { _modTools.UncookSingle(ar, hash, new DirectoryInfo(matRepo), exportArgs); } } break; } } } if (Path.GetExtension(primaryDependencies[i]) == ".mlmask") { if (!TexturesList.Contains(primaryDependencies[i])) { TexturesList.Add(primaryDependencies[i]); } ulong hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]); foreach (Archive 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)) { _modTools.UncookSingle(ar, hash, new DirectoryInfo(matRepo), exportArgs); } } break; } } } if (Path.GetExtension(primaryDependencies[i]) == ".hp") { if (!HairProfileNames.Contains(Path.GetFileName(primaryDependencies[i]))) { HairProfileNames.Add(Path.GetFileName(primaryDependencies[i])); ulong hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); var hp = _wolvenkitFileService.TryReadCr2WFile(ms); HairProfiles.Add(new HairProfile(hp.Chunks[0].Data as CHairProfile, Path.GetFileName(primaryDependencies[i]))); break; } } } } if (Path.GetExtension(primaryDependencies[i]) == ".mlsetup") { ulong hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); var mls = _wolvenkitFileService.TryReadCr2WFile(ms); mlSetupNames.Add(Path.GetFileName(primaryDependencies[i])); mlSetups.Add(mls.Chunks[0].Data as Multilayer_Setup); for (int e = 0; e < mls.Imports.Count; e++) { if (Path.GetExtension(mls.Imports[e].DepotPathStr) == ".xbm") { if (!TexturesList.Contains(mls.Imports[e].DepotPathStr)) { TexturesList.Add(mls.Imports[e].DepotPathStr); } ulong hash1 = FNV1A64HashAlgorithm.HashString(mls.Imports[e].DepotPathStr); foreach (Archive arr in archives) { if (arr.Files.ContainsKey(hash1)) { if (!File.Exists(Path.Combine(matRepo, mls.Imports[e].DepotPathStr.Replace("xbm", exportArgs.Get <XbmExportArgs>().UncookExtension.ToString())))) { if (Directory.Exists(matRepo)) { _modTools.UncookSingle(arr, hash1, new DirectoryInfo(matRepo), exportArgs); } } break; } } } if (Path.GetExtension(mls.Imports[e].DepotPathStr) == ".mltemplate") { ulong hash2 = FNV1A64HashAlgorithm.HashString(mls.Imports[e].DepotPathStr); foreach (Archive arr in archives) { if (arr.Files.ContainsKey(hash2)) { var mss = new MemoryStream(); ModTools.ExtractSingleToStream(arr, hash2, mss); var mlt = _wolvenkitFileService.TryReadCr2WFile(mss); mlTemplateNames.Add(Path.GetFileName(mls.Imports[e].DepotPathStr)); mlTemplates.Add(mlt.Chunks[0].Data as Multilayer_LayerTemplate); for (int eye = 0; eye < mlt.Imports.Count; eye++) { if (!TexturesList.Contains(mlt.Imports[eye].DepotPathStr)) { TexturesList.Add(mlt.Imports[eye].DepotPathStr); } ulong hash3 = FNV1A64HashAlgorithm.HashString(mlt.Imports[eye].DepotPathStr); foreach (Archive arrr in archives) { if (arrr.Files.ContainsKey(hash3)) { if (!File.Exists(Path.Combine(matRepo, mlt.Imports[eye].DepotPathStr.Replace("xbm", exportArgs.Get <XbmExportArgs>().UncookExtension.ToString())))) { if (Directory.Exists(matRepo)) { _modTools.UncookSingle(arrr, hash3, new DirectoryInfo(matRepo), exportArgs); } } break; } } } break; } } } } break; } } } } List <RawMaterial> RawMaterials = new List <RawMaterial>(); for (int i = 0; i < materialEntries.Count; i++) { RawMaterials.Add(ContainRawMaterial(materialEntries[i], materialEntryNames[i], archives)); } List <Setup> MaterialSetups = new List <Setup>(); for (int i = 0; i < mlSetups.Count; i++) { MaterialSetups.Add(new Setup(mlSetups[i], mlSetupNames[i])); } List <Template> MaterialTemplates = new List <Template>(); for (int i = 0; i < mlTemplates.Count; i++) { MaterialTemplates.Add(new Template(mlTemplates[i], mlTemplateNames[i])); } var obj = new { MaterialRepo = matRepo, Materials = RawMaterials, HairProfiles = HairProfiles, MaterialSetups = MaterialSetups, MaterialTemplates = MaterialTemplates }; var settings = new JsonSerializerSettings(); settings.NullValueHandling = NullValueHandling.Ignore; settings.Formatting = Formatting.Indented; string str = JsonConvert.SerializeObject(obj, settings); File.WriteAllLines(Path.Combine(outDir.FullName, "Textures.txt"), TexturesList); File.WriteAllText(Path.Combine(outDir.FullName, "Material.json"), str); }
public void OpenFileFromDepotPath(string path) => OpenFileFromHash(FNV1A64HashAlgorithm.HashString(path));
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; } } } }
public void CompareMemorySAsciiString() { //float result = 1; //for (int i = 2; i < 10; i++) //{ // if (i % 2 == 0) // { // result *= i; // } // else // { // result /= i; // } //} List <string> originals = new(); Dictionary <ulong, SAsciiString> hashDictionary = new(); hashDictionary.EnsureCapacity(500_000); var runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll"); var paths = new List <string>(runtimeAssemblies); var resolver = new PathAssemblyResolver(paths); var mlc = new MetadataLoadContext(resolver); var before = GC.GetTotalMemory(true); Assembly assembly; using (mlc) { assembly = mlc.LoadFromAssemblyPath("WolvenKit.Common.dll"); using var stream = assembly.GetManifestResourceStream(s_used); // read KARK header var oodleCompression = stream.ReadStruct <uint>(); if (oodleCompression != OodleHelper.KARK) { throw new DecompressionException($"Incorrect hash file."); } var outputsize = stream.ReadStruct <uint>(); // read the rest of the stream var outputbuffer = new byte[outputsize]; var inbuffer = stream.ToByteArray(true); OozNative.Kraken_Decompress(inbuffer, inbuffer.Length, outputbuffer, outputbuffer.Length); using (var ms = new MemoryStream(outputbuffer)) using (var sr = new StreamReader(ms)) { string line; while ((line = sr.ReadLine()) != null) { var hash = FNV1A64HashAlgorithm.HashString(line); if (hashDictionary.ContainsKey(hash)) { continue; } hashDictionary.Add(hash, new SAsciiString(line)); } } } var after = GC.GetTotalMemory(true); double diff = after - before; Console.WriteLine($"Memory: {diff.ToString()}"); // compare var failed = 0; foreach (var s in originals) { var hash = FNV1A64HashAlgorithm.HashString(s); var gottenString = hashDictionary[hash].ToString(); if (!gottenString.Equals(s)) { failed++; } } Assert.AreEqual(0, failed); }
/// <summary> /// Creates and archive from a folder and packs all files inside into it /// </summary> /// <param name="infolder"></param> /// <param name="outpath"></param> /// <returns></returns> public static Archive.Archive Pack(DirectoryInfo infolder, DirectoryInfo outpath) { if (!infolder.Exists) { return(null); } if (!outpath.Exists) { return(null); } var outfile = Path.Combine(outpath.FullName, $"basegame_{infolder.Name}.archive"); var ar = new Archive.Archive { ArchiveAbsolutePath = outfile, Index = new Index() }; using var fs = new FileStream(outfile, FileMode.Create); using var bw = new BinaryWriter(fs); #region write header ar.Header.Write(bw); bw.Write(new byte[132]); // some weird padding #endregion #region write files var exludedExtensions = new[] { ".buffer", ".dds", ".DS_Store", //Hooray for OSX }; var allfiles = infolder.GetFiles("*", SearchOption.AllDirectories); var parentfiles = allfiles .Where(_ => exludedExtensions.All(x => _.Extension.ToLower() != x)); var fileInfos = parentfiles .OrderBy(_ => FNV1A64HashAlgorithm.HashString(_.FullName.RelativePath(infolder))) .ToList(); Logger.LogString($"Found {fileInfos.Count} bundle entries to pack.", Logtype.Important); Thread.Sleep(1000); int progress = 0; Logger.LogProgress(0); foreach (var fileInfo in fileInfos) { var relpath = fileInfo.FullName.RelativePath(infolder); var hash = FNV1A64HashAlgorithm.HashString(relpath); if (fileInfo.Extension.ToLower() == ".bin") { hash = ulong.Parse(Path.GetFileNameWithoutExtension(relpath)); } using var fileStream = new FileStream(fileInfo.FullName, FileMode.Open); using var fileBinaryReader = new BinaryReader(fileStream); // fileinfo data uint firstimportidx = (uint)ar.Index.Dependencies.Count; uint lastimportidx = (uint)ar.Index.Dependencies.Count; uint firstoffsetidx = (uint)ar.Index.FileSegments.Count; uint lastoffsetidx = (uint)ar.Index.FileSegments.Count; int flags = 0; var cr2w = ModTools.TryReadCr2WFileHeaders(fileBinaryReader); if (cr2w != null) { //register imports foreach (var cr2WImportWrapper in cr2w.Imports) { if (!ar.Index.Dependencies.Select(_ => _.HashStr).Contains(cr2WImportWrapper.DepotPathStr)) { ar.Index.Dependencies.Add( new Dependency(FNV1A64HashAlgorithm.HashString(cr2WImportWrapper.DepotPathStr))); } } lastimportidx = (uint)ar.Index.Dependencies.Count; // kraken the file and write var cr2wfilesize = (int)cr2w.Header.objectsEnd; fileBinaryReader.BaseStream.Seek(0, SeekOrigin.Begin); var cr2winbuffer = fileBinaryReader.ReadBytes(cr2wfilesize); var offset = bw.BaseStream.Position; var(zsize, crc) = bw.CompressAndWrite(cr2winbuffer); ar.Index.FileSegments.Add(new FileSegment( (ulong)offset, zsize, (uint)cr2winbuffer.Length)); // HINT: each cr2w needs to have the buffer already kraken'd // foreach buffer write var bufferOffsets = cr2w.Buffers.Select(_ => _.Buffer); foreach (var buffer in bufferOffsets) { var bsize = buffer.memSize; var bzsize = buffer.diskSize; //compressed size of the buffer inside the cr2wfile fileBinaryReader.BaseStream.Seek(buffer.offset, SeekOrigin.Begin); var b = fileBinaryReader.ReadBytes((int)bzsize); //read bzsize bytes from the cr2w var boffset = bw.BaseStream.Position; bw.Write(b); ar.Index.FileSegments.Add(new FileSegment( (ulong)boffset, bzsize, bsize)); } lastoffsetidx = (uint)ar.Index.FileSegments.Count; flags = cr2w.Buffers.Count > 0 ? cr2w.Buffers.Count - 1 : 0; } else { // kraken the file and write fileStream.Seek(0, SeekOrigin.Begin); var cr2winbuffer = Catel.IO.StreamExtensions.ToByteArray(fileStream); var(zsize, crc) = bw.CompressAndWrite(cr2winbuffer); ar.Index.FileSegments.Add(new FileSegment((ulong)bw.BaseStream.Position, zsize, (uint)cr2winbuffer.Length)); } // save table data var sha1 = new System.Security.Cryptography.SHA1Managed(); var sha1hash = sha1.ComputeHash(Catel.IO.StreamExtensions.ToByteArray(fileBinaryReader.BaseStream)); //TODO: this is only correct for files with no buffer var item = new FileEntry(hash, DateTime.Now, (uint)flags , firstoffsetidx, lastoffsetidx, firstimportidx, lastimportidx , sha1hash); ar.Index.FileEntries.Add(hash, item); Interlocked.Increment(ref progress); Logger.LogProgress(progress / (float)fileInfos.Count); } ; #endregion #region write footer // padding to page (4096 bytes) bw.PadUntilPage(); // write tables var tableoffset = bw.BaseStream.Position; ar.Index.Write(bw); var tablesize = bw.BaseStream.Position - tableoffset; // padding to page (4096 bytes) bw.PadUntilPage(); var filesize = bw.BaseStream.Position; // write the header again ar.Header.IndexPosition = (ulong)tableoffset; ar.Header.IndexSize = (uint)tablesize; ar.Header.Filesize = (ulong)filesize; bw.BaseStream.Seek(0, SeekOrigin.Begin); ar.Header.Write(bw); #endregion return(ar); #region Local Functions #endregion }
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); }