示例#1
0
        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.");
        }
示例#2
0
        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));
        }
示例#3
0
        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);
        }
示例#4
0
        public ulong RegisterVanillaPath(string path)
        {
            var hashint = FNV1A64HashAlgorithm.HashString(path);

            if (!HashdumpDict.ContainsKey(path))
            {
                HashdumpDict.Add(path, hashint);
            }
            return(hashint);
        }
示例#5
0
        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();
                }
            }
        }
示例#6
0
        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));
        }
示例#7
0
        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);
        }
示例#8
0
        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);
            }
        }
示例#9
0
        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);
        }
示例#10
0
 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);
 }
示例#11
0
        /// <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)..];
示例#12
0
        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);
            }
        }
示例#13
0
        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);
        }
示例#14
0
        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);
        }
示例#15
0
        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);
        }
示例#16
0
 public void TestFNV1a64_ByteSpan(byte[] test, ulong result)
 {
     Assert.AreEqual(FNV1A64HashAlgorithm.HashReadOnlySpan(test), result);
 }
示例#17
0
 public void TestFNV1a64_NullEnded(string test, ulong result)
 {
     Assert.AreEqual(FNV1A64HashAlgorithm.HashString(test, Encoding.ASCII, true), result);
 }
示例#18
0
 public void TestFNV1a64(string test, ulong result)
 {
     // Assert.AreEqual(FNV1A64HashAlgorithm.HashString(test), result);
     Assert.AreEqual(FNV1A64HashAlgorithm.HashString(test), result);
 }
示例#19
0
 public void TestFNV1a64_CharSpan(string test, ulong result)
 {
     Assert.AreEqual(FNV1A64HashAlgorithm.HashReadOnlySpan(test.AsSpan()), result);
 }
示例#20
0
 public ulong GetRedHash(EditorProject project) => FNV1A64HashAlgorithm.HashString(GetRelativeName(project));
示例#21
0
        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);
        }
示例#22
0
        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;
                    }
                }
            }
        }
示例#23
0
        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);
        }
示例#24
0
        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]);
示例#25
0
        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);
        }
示例#26
0
 public void OpenFileFromDepotPath(string path) => OpenFileFromHash(FNV1A64HashAlgorithm.HashString(path));
示例#27
0
        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;
                    }
                }
            }
        }
示例#28
0
        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);
        }
示例#29
0
        /// <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
        }
示例#30
0
        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);
        }