示例#1
0
        private static int ExportTaskInner(string path, EUncookExtension uncookext)
        {
            #region checks

            if (string.IsNullOrEmpty(path))
            {
                logger.LogString("Please fill in an input path.", Logtype.Error);
                return(0);
            }
            var inputFileInfo = new FileInfo(path);
            if (!inputFileInfo.Exists)
            {
                logger.LogString("Input file does not exist.", Logtype.Error);
                return(0);
            }

            #endregion

            Stopwatch watch = new();
            watch.Restart();

            if (ModTools.Export(new FileInfo(path), uncookext))

            {
                watch.Stop();
                logger.LogString($"Successfully exported {path} in {watch.ElapsedMilliseconds.ToString()}ms.", Logtype.Success);
            }
            else
            {
                watch.Stop();
                logger.LogString($"Failed to export {path}.", Logtype.Error);
            }

            return(1);
        }
示例#2
0
        //[DataRow("lang_ar_text.archive")]
        //[DataRow("lang_cs_text.archive")]
        //[DataRow("lang_de_text.archive")]
        //[DataRow("lang_en_text.archive")]
        //[DataRow("lang_en_voice.archive")]
        //[DataRow("lang_es-es_text.archive")]
        //[DataRow("lang_es-mx_text.archive")]
        //[DataRow("lang_fr_text.archive")]
        //[DataRow("lang_hu_text.archive")]
        //[DataRow("lang_it_text.archive")]
        //[DataRow("lang_ja_text.archive")]
        //[DataRow("lang_ko_text.archive")]
        //[DataRow("lang_pl_text.archive")]
        //[DataRow("lang_pt_text.archive")]
        //[DataRow("lang_ru_text.archive")]
        //[DataRow("lang_th_text.archive")]
        //[DataRow("lang_tr_text.archive")]
        //[DataRow("lang_zh-cn_text.archive")]
        //[DataRow("lang_zh-tw_text.archive")]
        public void Test_Unbundle(string archivename)
        {
            var resultDir = Path.Combine(Environment.CurrentDirectory, s_testResultsDirectory);

            Directory.CreateDirectory(resultDir);


            var results         = new ConcurrentBag <ArchiveTestResult>();
            var archiveFullName = Path.Combine(s_gameDirectoryPath, "archive", "pc", "content", archivename);

            var archive = s_bm.Archives.Lookup(archiveFullName).Value as Archive;

            Parallel.ForEach(archive.Files, keyvalue =>
            {
                var(hash, _) = keyvalue;

                try
                {
                    using (var ms = new MemoryStream())
                    {
                        ModTools.ExtractSingleToStream(archive, hash, ms);
                    }
                    results.Add(new ArchiveTestResult()
                    {
                        ArchiveName = archivename,
                        Hash        = hash.ToString(),
                        Success     = true
                    });
                }
                catch (Exception e)
                {
                    results.Add(new ArchiveTestResult()
                    {
                        ArchiveName   = archivename,
                        Hash          = hash.ToString(),
                        Success       = false,
                        ExceptionType = e.GetType(),
                        Message       = $"{e.Message}"
                    });
                }
            });

            var totalCount = archive.Files.Count;

            // Check success
            var successCount = results.Count(r => r.Success);
            var sb           = new StringBuilder();

            sb.AppendLine($"Successfully unbundled: {successCount} / {totalCount} ({(int)(successCount / (double)totalCount * 100)}%)");
            var success = results.All(r => r.Success);

            if (success)
            {
                return;
            }

            var msg = $"Successful Writes: {successCount} / {totalCount}. ";

            Assert.Fail(msg);
        }
示例#3
0
        private static int ExportTaskInner(string path, EUncookExtension uncookext)
        {
            #region checks

            if (string.IsNullOrEmpty(path))
            {
                logger.LogString("Please fill in an input path.", Logtype.Error);
                return(0);
            }
            var inputFileInfo = new FileInfo(path);
            if (!inputFileInfo.Exists)
            {
                logger.LogString("Input file does not exist.", Logtype.Error);
                return(0);
            }

            #endregion

            if (ModTools.Export(new FileInfo(path), uncookext) == 1)
            {
                logger.LogString($"Successfully exported {path}.", Logtype.Success);
            }
            else
            {
                logger.LogString($"Failed to export {path}.", Logtype.Error);
            }

            return(1);
        }
示例#4
0
        public void DumpExtensionInfo()
        {
            var parser = ServiceLocator.Default.ResolveType <Red4ParserService>();

            var results = new Dictionary <string, ConcurrentDictionary <string, ulong> >();

            foreach (var e in s_groupedFiles)
            {
                results.Add(e.Key, new ConcurrentDictionary <string, ulong>());
            }

            var excludedExtensions = new List <string>()
            {
                ".wem", ".bin", ".bnk", ".opuspak", ".opusinfo", ".bk2", ".dat"
            };

            // Run Test
            foreach (var item in s_groupedFiles.Where(_ => !excludedExtensions.Contains(_.Key)))
            {
                var ext   = item.Key;
                var files = item.Value;

                Parallel.ForEach(files, file =>
                {
                    var hash    = file.Key;
                    var archive = file.Archive as Archive;

                    try
                    {
                        using var originalMemoryStream = new MemoryStream();
                        ModTools.ExtractSingleToStream(archive, hash, originalMemoryStream);
                        var originalFile = parser.TryReadRED4FileHeaders(originalMemoryStream);
                        if (originalFile != null)
                        {
                            var c = originalFile.StringDictionary[1];
                            results[ext].TryAdd(c, 0);
                        }
                        else
                        {
                        }
                    }
                    catch (Exception)
                    {
                    }
                });
            }

            var resultDir = Path.Combine(Environment.CurrentDirectory, s_testResultsDirectory);

            Directory.CreateDirectory(resultDir);

            using var sw = new StringWriter();
            foreach (var(key, classes) in results)
            {
                sw.WriteLine($"{key}: {string.Join(",", classes.Keys.ToList())}");
            }
            File.WriteAllText(Path.Combine(resultDir, "classes.txt"), sw.ToString());
        }
示例#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 static void PackTaskInner(string path, string outpath, int cp = 0)
        {
            #region checks

            if (string.IsNullOrEmpty(path))
            {
                logger.LogString("Please fill in an input path.", Logtype.Error);
                return;
            }

            var inputDirInfo = new DirectoryInfo(path);
            if (!Directory.Exists(path) || !inputDirInfo.Exists)
            {
                logger.LogString("Input path does not exist.", Logtype.Error);
                return;
            }

            var basedir = inputDirInfo;
            if (basedir?.Parent == null)
            {
                return;
            }

            DirectoryInfo outDir;
            if (string.IsNullOrEmpty(outpath))
            {
                outDir = basedir.Parent;
            }
            else
            {
                outDir = new DirectoryInfo(outpath);
                if (!outDir.Exists)
                {
                    outDir = Directory.CreateDirectory(outpath);
                }
            }

            #endregion checks

            var ar = ModTools.Pack(basedir, outDir);
            if (ar != null)
            {
                logger.LogString($"Finished packing {ar.ArchiveAbsolutePath}.", Logtype.Success);
            }
            else
            {
                logger.LogString($"Packing failed.", Logtype.Error);
            }

            return;
        }
示例#7
0
        /// <summary>
        /// Runs Emergency 5
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_RunEmergency_Click(object sender, RoutedEventArgs e)
        {
            ModTools.writeJsonModFile(dataContext.InstalledMods, dataContext.AppDataModificationsJsonFile);

            EmergencyInstallation myEmergencyInstallation = new EmergencyInstallation();

            try
            {
                System.Diagnostics.Process.Start(myEmergencyInstallation.getEmergencyInstallationPath() + @"\bin\em5_launcher.exe");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
示例#8
0
 protected void SetupImage()
 {
     using var ddsstream = new MemoryStream();
     try
     {
         if (ModTools.ConvertRedClassToDdsStream(_data, ddsstream, out _))
         {
             _ = LoadImageFromStream(ddsstream);
         }
     }
     catch (Exception e)
     {
         Console.WriteLine(e.Message);
         throw;
     }
 }
示例#9
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);
 }
示例#10
0
        /// <summary>
        /// Handels the clicks on the down arrow
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDecreaseOrderingIndex_Click(object sender, RoutedEventArgs e)
        {
            //  if nothing is selected
            //
            if (liModificationList.SelectedIndex == -1 | (liModificationList.SelectedIndex - 1 == -1))
            {
                MessageBox.Show("Übersetzung", Properties.Resources.changeOrderingIndexDialogeTitle, MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            // store the number of the current selected item to send it into decreasing and reselecting
            // decrease the ordering index and sort our collection to display the result withthe decreaseOrderingIndex method
            //
            int currentlySelected = liModificationList.SelectedIndex;

            ModTools.decreaseOrderingIndex(currentlySelected, dataContext.InstalledMods);

            // also let it selcted
            liModificationList.SelectedItem = liModificationList.Items[currentlySelected - 1];
        }
示例#11
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);
        }
示例#12
0
        private static void RebuildTaskInner(string path,
                                             bool buffers,
                                             bool textures,
                                             bool import,
                                             bool keep,
                                             bool clean,
                                             bool unsaferaw
                                             )
        {
            #region checks

            if (string.IsNullOrEmpty(path))
            {
                logger.LogString("Please fill in an input path", Logtype.Error);
                return;
            }

            var inputDirInfo = new DirectoryInfo(path);
            if (!Directory.Exists(path) || !inputDirInfo.Exists)
            {
                logger.LogString("Input path does not exist", Logtype.Error);
                return;
            }

            var basedir = inputDirInfo;
            if (basedir?.Parent == null)
            {
                return;
            }

            #endregion


            ModTools.Recombine(basedir, buffers, textures, import, keep, clean, unsaferaw);

            return;
        }
示例#13
0
        private static void Cr2wTaskInner(string path, string outpath, bool chunks, string pattern = "", string regex = "")
        {
            #region checks

            if (string.IsNullOrEmpty(path))
            {
                logger.LogString("Please fill in an input path.", Logtype.Error);
                return;
            }

            var inFileInfo  = new FileInfo(path);
            var inDirInfo   = new DirectoryInfo(path);
            var isDirectory = !inFileInfo.Exists && inDirInfo.Exists;
            var isFile      = inFileInfo.Exists && !inDirInfo.Exists;

            if (!isDirectory && !isFile)
            {
                logger.LogString("Input file does not exist.", Logtype.Error);
                return;
            }
            #endregion

            Stopwatch watch = new();
            watch.Restart();

            // get all files
            var fileInfos = isDirectory
                ? inDirInfo.GetFiles("*", SearchOption.AllDirectories).ToList()
                : new List <FileInfo> {
                inFileInfo
            };

            // check search pattern then regex
            IEnumerable <FileInfo> finalmatches = fileInfos;
            if (!string.IsNullOrEmpty(pattern))
            {
                finalmatches = fileInfos.MatchesWildcard(item => item.FullName, pattern);
            }
            if (!string.IsNullOrEmpty(regex))
            {
                var searchTerm         = new System.Text.RegularExpressions.Regex($@"{regex}");
                var queryMatchingFiles =
                    from file in finalmatches
                    let matches = searchTerm.Matches(file.FullName)
                                  where matches.Count > 0
                                  select file;

                finalmatches = queryMatchingFiles;
            }

            var finalMatchesList = finalmatches.ToList();
            logger.LogString($"Found {finalMatchesList.Count} files to dump.", Logtype.Important);

            Thread.Sleep(1000);
            int progress = 0;
            logger.LogProgress(0);
            Parallel.ForEach(finalMatchesList, fileInfo =>
            {
                var outputDirInfo = string.IsNullOrEmpty(outpath)
                    ? fileInfo.Directory
                    : new DirectoryInfo(outpath);
                if (outputDirInfo == null || !outputDirInfo.Exists)
                {
                    logger.LogString("Output directory is not valid.", Logtype.Error);
                    return;
                }

                if (chunks)
                {
                    var f        = File.ReadAllBytes(fileInfo.FullName);
                    using var fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read);
                    var cr2w     = ModTools.TryReadCr2WFile(fs);
                    if (cr2w == null)
                    {
                        return;
                    }

                    //write
                    File.WriteAllText(Path.Combine(outputDirInfo.FullName, $"{fileInfo.Name}.json"),
                                      JsonConvert.SerializeObject(cr2w, Formatting.Indented, new JsonSerializerSettings()
                    {
                        ReferenceLoopHandling      = ReferenceLoopHandling.Ignore,
                        PreserveReferencesHandling = PreserveReferencesHandling.None,
                        TypeNameHandling           = TypeNameHandling.None
                    }));
                }

                Interlocked.Increment(ref progress);
                logger.LogProgress(progress / (float)finalMatchesList.Count);
            });

            watch.Stop();
            logger.LogString(
                $"Finished. Dumped {finalMatchesList.Count} files to json in {watch.ElapsedMilliseconds.ToString()}ms.",
                Logtype.Success);
        }
示例#14
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;
                    }
                }
            }
        }
示例#15
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);
        }
示例#16
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);
        }
示例#17
0
 public MATERIAL(Red4ParserService fileservice, ModTools modtools)
 {
     _wolvenkitFileService = fileservice;
     _modTools             = modtools;
 }
示例#18
0
        public static int DumpTaskInner(string path, bool imports, bool missinghashes,
                                        bool texinfo, bool classinfo, bool dump, bool list)
        {
            #region checks

            if (string.IsNullOrEmpty(path))
            {
                ConsoleFunctions.logger.LogString("Please fill in an input path.", Logtype.Error);
                return(0);
            }

            var isDirectory   = false;
            var inputFileInfo = new FileInfo(path);
            var inputDirInfo  = new DirectoryInfo(path);
            if (!inputFileInfo.Exists)
            {
                if (!inputDirInfo.Exists)
                {
                    return(0);
                }
                else
                {
                    isDirectory = true;
                }
            }

            #endregion checks

            var archives = new List <Archive>();

            if (isDirectory)
            {
                archives.AddRange(inputDirInfo
                                  .GetFiles("*.archive", SearchOption.AllDirectories)
                                  .Select(_ => new Archive(_.FullName)));
            }
            else
            {
                archives.Add(new Archive(inputFileInfo.FullName));
            }

            var mainController = ServiceLocator.Default.ResolveType <IHashService>();
            var logger         = ServiceLocator.Default.ResolveType <ILoggerService>();
            var typedict       = new ConcurrentDictionary <string, IEnumerable <string> >();

            // Parallel
            foreach (var ar in archives)
            {
                if (classinfo)
                {
                    // using var mmf = MemoryMappedFile.CreateFromFile(ar.Filepath, FileMode.Open,
                    //     ar.Filepath.GetHashMD5(), 0,
                    //     MemoryMappedFileAccess.Read);

                    var fileinfo = ar.Files.Values;
                    var query    = fileinfo.GroupBy(
                        ext => Path.GetExtension(ext.FileName),
                        file => file,
                        (ext, finfo) => new
                    {
                        Key  = ext,
                        File = fileinfo.Where(_ => Path.GetExtension(_.FileName) == ext)
                    }).ToList();

                    var total = query.Count;
                    logger.LogString($"Exporting {total} bundle entries ");

                    Thread.Sleep(1000);
                    int progress = 0;
                    logger.LogProgress(0);

                    // foreach extension
                    Parallel.ForEach(query, result =>
                    {
                        if (!string.IsNullOrEmpty(result.Key))
                        {
                            Parallel.ForEach(result.File, fi =>
                            {
                                using var ms = new MemoryStream();
                                ar.CopyFileToStream(ms, fi.NameHash64, false);
                                var cr2w = ModTools.TryReadCr2WFile(ms);
                                if (cr2w == null)
                                {
                                    return;
                                }

                                foreach (var o in cr2w.Chunks.Select(chunk => (chunk as CR2WExportWrapper).GetDumpObject(ms))
                                         .Where(o => o != null))
                                {
                                    Register(o);
                                }
                            });
                        }

                        Interlocked.Increment(ref progress);
                        logger.LogProgress(progress / (float)total);

                        logger.LogString($"Dumped extension {result.Key}", Logtype.Normal);
                    });
                }
                if (imports || texinfo)
                {
                    // using var mmf = MemoryMappedFile.CreateFromFile(ar.Filepath, FileMode.Open,
                    //     ar.Filepath.GetHashMD5(), 0,
                    //     MemoryMappedFileAccess.Read);

                    var fileDictionary = new ConcurrentDictionary <ulong, Cr2wChunkInfo>();
                    var texDictionary  = new ConcurrentDictionary <ulong, Cr2wTextureInfo>();

                    // get info
                    var count = ar.FileCount;
                    logger.LogString($"Exporting {count} bundle entries ");

                    Thread.Sleep(1000);
                    int progress = 0;
                    logger.LogProgress(0);

                    Parallel.For(0, count, i =>
                    {
                        var(hash, fileEntry) = ar.Files.ToList()[i];
                        var filename         = string.IsNullOrEmpty(fileEntry.FileName) ? hash.ToString() : fileEntry.FileName;

                        if (imports)
                        {
                            using var ms = new MemoryStream();
                            ar.CopyFileToStream(ms, fileEntry.NameHash64, false);
                            var cr2w = ModTools.TryReadCr2WFileHeaders(ms);
                            if (cr2w == null)
                            {
                                return;
                            }

                            var obj = new Cr2wChunkInfo
                            {
                                Filename = filename,
                                Imports  = cr2w.Imports
                            };

                            fileDictionary.AddOrUpdate(hash, obj, (arg1, o) => obj);
                        }

                        if (texinfo)
                        {
                            if (!string.IsNullOrEmpty(fileEntry.FileName) && fileEntry.FileName.Contains(".xbm"))
                            {
                                using var ms = new MemoryStream();
                                ar.CopyFileToStream(ms, fileEntry.NameHash64, false);
                                var cr2w = ModTools.TryReadCr2WFile(ms);

                                if (cr2w?.Chunks.FirstOrDefault()?.data is not CBitmapTexture xbm ||
                                    !(cr2w.Chunks[1]?.data is rendRenderTextureBlobPC blob))
                                {
                                    return;
                                }

                                // create dds header
                                var texinfoObj = new Cr2wTextureInfo()
                                {
                                    Filename    = filename,
                                    width       = blob.Header.SizeInfo.Width.Value,
                                    height      = blob.Header.SizeInfo.Height.Value,
                                    mips        = blob.Header.TextureInfo.MipCount.Value,
                                    slicecount  = blob.Header.TextureInfo.SliceCount.Value,
                                    alignment   = blob.Header.TextureInfo.DataAlignment.Value,
                                    compression = xbm.Setup.Compression,
                                    Group       = xbm.Setup.Group,
                                    rawFormat   = xbm.Setup.RawFormat,
                                };

                                texDictionary.AddOrUpdate(hash, texinfoObj, (arg1, o) => texinfoObj);
                            }
                        }

                        Interlocked.Increment(ref progress);
                        logger.LogProgress(progress / (float)count);
                    });
示例#19
0
        private void UnbundleTaskInner(string path, string outpath,
                                       string hash, string pattern, string regex, bool DEBUG_decompress = false)
        {
            #region checks

            if (string.IsNullOrEmpty(path))
            {
                _loggerService.Warning("Please fill in an input path.");
                return;
            }

            var inputFileInfo = new FileInfo(path);
            var inputDirInfo  = new DirectoryInfo(path);

            if (!inputFileInfo.Exists && !inputDirInfo.Exists)
            {
                _loggerService.Warning("Input path does not exist.");
                return;
            }

            if (inputFileInfo.Exists && inputFileInfo.Extension != ".archive")
            {
                _loggerService.Warning("Input file is not an .archive.");
                return;
            }
            else if (inputDirInfo.Exists && inputDirInfo.GetFiles().All(_ => _.Extension != ".archive"))
            {
                _loggerService.Warning("No .archive file to process in the input directory.");
                return;
            }

            var isDirectory = !inputFileInfo.Exists;
            var basedir     = inputFileInfo.Exists ? new FileInfo(path).Directory : inputDirInfo;

            #endregion checks

            List <FileInfo> archiveFileInfos;
            if (isDirectory)
            {
                _archiveManager.LoadFromFolder(basedir);
                // TODO: use the manager here?
                archiveFileInfos = _archiveManager.Archives.Items.Select(_ => new FileInfo(_.ArchiveAbsolutePath)).ToList();
            }
            else
            {
                archiveFileInfos = new List <FileInfo> {
                    inputFileInfo
                };
            }

            foreach (var fileInfo in archiveFileInfos)
            {
                // get outdirectory
                DirectoryInfo outDir;
                if (string.IsNullOrEmpty(outpath))
                {
                    outDir = new DirectoryInfo(Path.Combine(
                                                   basedir.FullName,
                                                   fileInfo.Name.Replace(".archive", "")));
                }
                else
                {
                    outDir = new DirectoryInfo(outpath);
                    if (!outDir.Exists)
                    {
                        outDir = new DirectoryInfo(outpath);
                    }

                    if (inputDirInfo.Exists)
                    {
                        outDir = new DirectoryInfo(Path.Combine(
                                                       outDir.FullName,
                                                       fileInfo.Name.Replace(".archive", "")));
                    }
                }

                // read archive
                var ar = Red4ParserServiceExtensions.ReadArchive(fileInfo.FullName, _hashService);

                var isHash = ulong.TryParse(hash, out var hashNumber);

                // run
                if (!isHash && File.Exists(hash))
                {
                    var hashlist = File.ReadAllLines(hash)
                                   .ToList().Select(_ => ulong.TryParse(_, out var res) ? res : 0);
                    _loggerService.Info($"Extracing all files from the hashlist ({hashlist.Count()}hashes) ...");
                    foreach (var hashNum in hashlist)
                    {
                        var r = ModTools.ExtractSingle(ar, hashNum, outDir, DEBUG_decompress);
                        if (r > 0)
                        {
                            _loggerService.Success($" {ar.ArchiveAbsolutePath}: Extracted one file: {hashNum}");
                        }
                        else
                        {
                            _loggerService.Info($" {ar.ArchiveAbsolutePath}: No file found with hash {hashNum}");
                        }
                    }

                    _loggerService.Success($"Bulk extraction from hashlist file completed.");
                }
                else if (isHash && hashNumber != 0)
                {
                    var r = ModTools.ExtractSingle(ar, hashNumber, outDir, DEBUG_decompress);
                    if (r > 0)
                    {
                        _loggerService.Success($" {ar.ArchiveAbsolutePath}: Extracted one file: {hashNumber}");
                    }
                    else
                    {
                        _loggerService.Info($" {ar.ArchiveAbsolutePath}: No file found with hash {hashNumber}");
                    }
                }
                else
                {
                    _modTools.ExtractAll(ar, outDir, pattern, regex, DEBUG_decompress);
                }
            }

            return;
        }
        private static void Test_Extension(string extension)
        {
            var parsers = _host.Services.GetRequiredService <Red4ParserService>();

            var resultDir = Path.Combine(Environment.CurrentDirectory, s_testResultsDirectory);

            Directory.CreateDirectory(resultDir);
            foreach (var file in Directory.GetFiles(resultDir))
            {
                File.Delete(file);
            }

            var results = new ConcurrentBag <ArchiveTestResult>();
            var files   = s_groupedFiles[extension].ToList();

#if IS_PARALLEL
            Parallel.ForEach(files, file =>
#else
            foreach (var file in files)
#endif
            {
                var hash    = file.Key;
                var archive = file.Archive as Archive;
                ArgumentNullException.ThrowIfNull(archive);

                try
                {
                    #region convert to json
                    using var originalMemoryStream = new MemoryStream();
                    ModTools.ExtractSingleToStream(archive, hash, originalMemoryStream);
                    if (!parsers.TryReadRed4File(originalMemoryStream, out var originalFile))
                    {
#if IS_PARALLEL
                        return;
#else
                        continue;
#endif
                    }

                    var dto  = new RedFileDto(originalFile);
                    var json = RedJsonSerializer.Serialize(dto);
                    if (string.IsNullOrEmpty(json))
                    {
                        throw new SerializationException();
                    }

                    #endregion

                    #region convert back from json

                    var newdto = RedJsonSerializer.Deserialize <RedFileDto>(json);
                    if (newdto == null)
                    {
                        throw new SerializationException();
                    }

                    var newFile = newdto.Data;

                    #endregion

                    #region compare

                    // old file
                    var header        = originalFile.MetaData;
                    var objectsend    = (int)header.ObjectsEnd;
                    var originalBytes = originalMemoryStream.ToByteArray().Take(objectsend);

                    // write the new file
                    using var newMemoryStream = new MemoryStream();
                    using var writer          = new CR2WWriter(newMemoryStream);
                    writer.WriteFile(newFile);

                    // hack to compare buffers
                    var newBytes = newMemoryStream.ToByteArray();

                    newMemoryStream.Seek(0, SeekOrigin.Begin);
                    var dbg = parsers.ReadRed4File(newMemoryStream);
                    //var newExportStartOffset = (int)dbg.Chunks.FirstOrDefault().GetOffset();



                    //                    var originalExportStartOffset = (int)originalFile.Chunks.FirstOrDefault().GetOffset();
                    //                    if (!originalBytes.Skip(160).SequenceEqual(newBytes.Skip(160)))
                    //                    {
                    //                        // check again skipping the tables
                    //                        if (originalExportStartOffset == newExportStartOffset)
                    //                        {
                    //                            if (!originalBytes.Skip(originalExportStartOffset).SequenceEqual(newBytes.Skip(newExportStartOffset)))
                    //                            {
                    //#if WRITE
                    //                                File.WriteAllBytes(Path.Combine(resultDir, $"{file.Key}.o.bin"), originalBytes.ToArray());
                    //                                File.WriteAllBytes(Path.Combine(resultDir, $"{file.Key}.bin"), newBytes.ToArray());
                    //#endif
                    //                                throw new SerializationException("Exports not equal");
                    //                            }
                    //                            else
                    //                            {

                    //                            }
                    //                        }
                    //                        else
                    //                        {
                    //#if WRITE
                    //                            File.WriteAllBytes(Path.Combine(resultDir, $"{file.Key}.o.bin"), originalBytes.ToArray());
                    //                            File.WriteAllBytes(Path.Combine(resultDir, $"{file.Key}.bin"), newBytes.ToArray());
                    //#endif
                    //                            throw new SerializationException("Header not equal");
                    //                        }



                    //                    }
                    //                    else
                    //                    {

                    //                    }

                    #endregion

                    results.Add(new ArchiveTestResult()
                    {
                        ArchiveName = archive.Name,
                        Hash        = hash.ToString(),
                        Success     = true
                    });
                }
                catch (Exception e)
                {
                    Console.WriteLine($"{hash} - {e.Message} - {e.StackTrace}");
                    results.Add(new ArchiveTestResult()
                    {
                        ArchiveName   = archive.Name,
                        Hash          = hash.ToString(),
                        Success       = false,
                        ExceptionType = e.GetType(),
                        Message       = $"{e.Message}"
                    });
                }
#if IS_PARALLEL
            });
示例#21
0
        public bool ExportMorphTargets(Stream targetStream, FileInfo outfile, List <Archive> archives, bool isGLBinary = true)
        {
            var cr2w = _wolvenkitFileService.TryReadRED4File(targetStream);

            if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any())
            {
                return(false);
            }

            RawArmature             Rig        = null;
            MemoryStream            meshbuffer = MESH.GetMeshBufferStream(targetStream, cr2w);
            MeshesInfo              meshinfo   = MESH.GetMeshesinfo(cr2w);
            List <RawMeshContainer> expMeshes  = MESH.ContainRawMesh(meshbuffer, meshinfo, true);
            int subMeshC = expMeshes.Count;

            var    buffers      = cr2w.Buffers;
            var    blob         = cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMorphTargetMeshBlob>().First();
            string baseMeshPath = cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().First().BaseMesh.DepotPath;
            ulong  hash         = FNV1A64HashAlgorithm.HashString(baseMeshPath);

            foreach (Archive ar in archives)
            {
                if (ar.Files.ContainsKey(hash))
                {
                    var meshStream = new MemoryStream();
                    ModTools.ExtractSingleToStream(ar, hash, meshStream);
                    var meshCr2w = _wolvenkitFileService.TryReadRED4File(meshStream);

                    if (meshCr2w == null || !meshCr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !meshCr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any())
                    {
                        break;
                    }

                    MESH.MeshBones meshBones = new MESH.MeshBones();
                    meshBones.boneCount = meshCr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First().BoneNames.Count;
                    if (meshBones.boneCount != 0)    // for rigid meshes
                    {
                        meshBones.Names     = RIG.GetboneNames(meshCr2w);
                        meshBones.WorldPosn = MESH.GetMeshBonesPosn(meshCr2w);
                    }

                    Rig = MESH.GetNonParentedRig(meshBones);

                    MemoryStream ms = MESH.GetMeshBufferStream(meshStream, meshCr2w);
                    meshinfo  = MESH.GetMeshesinfo(meshCr2w);
                    expMeshes = MESH.ContainRawMesh(ms, meshinfo, true);
                    subMeshC  = expMeshes.Count;
                    if (meshBones.boneCount == 0)    // for rigid meshes
                    {
                        for (int i = 0; i < expMeshes.Count; i++)
                        {
                            expMeshes[i].weightcount = 0;
                        }
                    }
                    MESH.UpdateMeshJoints(ref expMeshes, Rig, meshBones);

                    break;
                }
            }

            MemoryStream diffsbuffer   = new MemoryStream();
            MemoryStream mappingbuffer = new MemoryStream();
            MemoryStream texbuffer     = new MemoryStream();

            if (blob.DiffsBuffer.IsSerialized)
            {
                targetStream.Seek(cr2w.Buffers[blob.DiffsBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin);
                targetStream.DecompressAndCopySegment(diffsbuffer, buffers[blob.DiffsBuffer.Buffer.Value - 1].DiskSize, buffers[blob.DiffsBuffer.Buffer.Value - 1].MemSize);
            }

            if (blob.MappingBuffer.IsSerialized)
            {
                targetStream.Seek(cr2w.Buffers[blob.MappingBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin);
                targetStream.DecompressAndCopySegment(mappingbuffer, buffers[blob.MappingBuffer.Buffer.Value - 1].DiskSize, buffers[blob.MappingBuffer.Buffer.Value - 1].MemSize);
            }

            if (blob.TextureDiffsBuffer.IsSerialized)
            {
                targetStream.Seek(cr2w.Buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin);
                targetStream.DecompressAndCopySegment(texbuffer, buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].DiskSize, buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].MemSize);
            }

            TargetsInfo targetsInfo = GetTargetInfos(cr2w, subMeshC);

            List <RawTargetContainer[]> expTargets = new List <RawTargetContainer[]>();

            for (int i = 0; i < targetsInfo.NumTargets; i++)
            {
                UInt32[] temp_NumVertexDiffsInEachChunk        = new UInt32[subMeshC];
                UInt32[] temp_NumVertexDiffsMappingInEachChunk = new UInt32[subMeshC];
                for (int e = 0; e < subMeshC; 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], subMeshC));
            }

            string[] names = new string[targetsInfo.NumTargets];
            for (int i = 0; i < targetsInfo.NumTargets; i++)
            {
                names[i] = targetsInfo.Names[i] + "_" + targetsInfo.RegionNames[i];
            }

            List <MemoryStream> textureStreams = ContainTextureStreams(cr2w, texbuffer);
            ModelRoot           model          = RawTargetsToGLTF(expMeshes, expTargets, names, Rig);

            if (WolvenTesting.IsTesting)
            {
                return(true);
            }
            model.Extras = SharpGLTF.IO.JsonContent.Serialize(new { BaseMesh = targetsInfo.BaseMesh });
            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 (int 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
        public bool ExportAnim(Stream animStream, List <Archive> archives, FileInfo outfile, bool isGLBinary = true)
        {
            var cr2w = _wolvenkitFileService.TryReadRED4File(animStream);

            if (!cr2w.Chunks.Select(_ => _.Data).OfType <animAnimSet>().Any())
            {
                return(false);
            }
            var blob = cr2w.Chunks.Select(_ => _.Data).OfType <animAnimSet>().First();

            List <MemoryStream> animDataBuffers = new List <MemoryStream>();

            foreach (var chk in blob.AnimationDataChunks)
            {
                UInt16 bufferIdx = chk.Buffer.Buffer.Value;
                var    b         = cr2w.Buffers[bufferIdx - 1];
                animStream.Seek(b.Offset, SeekOrigin.Begin);
                var ms = new MemoryStream();
                animStream.DecompressAndCopySegment(ms, b.DiskSize, b.MemSize);
                animDataBuffers.Add(ms);
            }
            RawArmature Rig = null;

            {
                ulong hash = FNV1A64HashAlgorithm.HashString(blob.Rig.DepotPath);
                foreach (Archive ar in archives)
                {
                    if (ar.Files.ContainsKey(hash))
                    {
                        var ms = new MemoryStream();
                        ModTools.ExtractSingleToStream(ar, hash, ms);
                        Rig = new RIG(_wolvenkitFileService).ProcessRig(ms);
                        break;
                    }
                }
            }
            if (Rig.BoneCount < 1)
            {
                return(false);
            }
            var model = ModelRoot.CreateModel();
            var skin  = model.CreateSkin();

            skin.BindJoints(RIG.ExportNodes(ref model, Rig).Values.ToArray());

            for (int i = 0; i < blob.Animations.Count; i++)
            {
                var setEntry    = (blob.Animations[i].GetReference().Data as animAnimSetEntry);
                var animAnimDes = (setEntry.Animation.GetReference().Data as animAnimation);
                if (animAnimDes.AnimationType.Value != Enums.animAnimationType.Normal)
                {
                    continue;
                }
                switch (animAnimDes.AnimBuffer.GetReference().REDType)
                {
                case "animAnimationBufferSimd":
                {
                    var animBuff  = (animAnimDes.AnimBuffer.GetReference().Data as animAnimationBufferSimd);
                    var bufferIdx = animBuff.DefferedBuffer.Buffer.Value;
                    var b         = cr2w.Buffers[bufferIdx - 1];
                    animStream.Seek(b.Offset, SeekOrigin.Begin);
                    var defferedBuffer = new MemoryStream();
                    animStream.DecompressAndCopySegment(defferedBuffer, b.DiskSize, b.MemSize);
                    SIMD.AddAnimationSIMD(ref model, animBuff, animAnimDes.Name.Value, defferedBuffer);
                }
                break;

                case "animAnimationBufferCompressed":
                {
                    var    animBuff = (animAnimDes.AnimBuffer.GetReference().Data as animAnimationBufferCompressed);
                    var    dataAddr = animBuff.DataAddress;
                    Byte[] bytes    = new Byte[dataAddr.ZeInBytes.Value];
                    animDataBuffers[(int)dataAddr.UnkIndex.Value].Seek(dataAddr.FsetInBytes.Value, SeekOrigin.Begin);
                    animDataBuffers[(int)dataAddr.UnkIndex.Value].Read(bytes, 0, (int)dataAddr.ZeInBytes.Value);
                    var defferedBuffer = new MemoryStream(bytes);
                    SPLINE.AddAnimationSpline(ref model, animBuff, animAnimDes.Name.Value, defferedBuffer);
                }
                break;

                default:
                    break;
                }
            }
            if (isGLBinary)
            {
                model.SaveGLB(outfile.FullName);
            }
            else
            {
                model.SaveGLTF(outfile.FullName);
            }

            return(true);
        }
示例#23
0
        public bool ImportWavs(params string[] wavFiles)
        {
            if (wavFiles.Length < 1)
            {
                return(false);
            }

            var foundids = new List <uint>();

            foreach (var wav in wavFiles)
            {
                try
                {
                    var idddd = Convert.ToUInt32(Path.GetFileNameWithoutExtension(wav));
                    foundids.Add(idddd);
                }
                catch { }
            }

            var validids = new List <uint>();

            for (var i = 0; i < foundids.Count; i++)
            {
                for (var e = 0; e < Info.OpusCount; e++)
                {
                    if (Info.OpusHashes[e] == foundids[i])
                    {
                        validids.Add(foundids[i]);
                        break;
                    }
                }
            }
            if (validids.Count < 1)
            {
                return(false);
            }

            var modStreams = new Stream[Info.PackIndices[Info.OpusCount - 1] + 1];

            for (var i = 0; i < validids.Count; i++)
            {
                var name = Path.Combine(_rawFolder.FullName, Convert.ToString(validids[i]) + ".opus");
                var proc = new ProcessStartInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "opus-tools\\opusenc.exe"))
                {
                    WorkingDirectory       = AppDomain.CurrentDomain.BaseDirectory,
                    Arguments              = $" \"{name.Replace("opus", "wav")}\" \"{name}\" --serial 42 --quiet --padding 0 --vbr --comp 10 --framesize 20 ",
                    UseShellExecute        = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow         = true,
                };
                using (var p = Process.Start(proc))
                {
                    p.WaitForExit();
                }

                var procnew = new ProcessStartInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "opus-tools\\opusdec.exe"))
                {
                    WorkingDirectory       = AppDomain.CurrentDomain.BaseDirectory,
                    Arguments              = $" \"{name}\" \"{name.Replace("opus", "wav")}\"",
                    UseShellExecute        = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow         = true,
                };
                using (var p = Process.Start(procnew))
                {
                    p.WaitForExit();
                }

                var procn = new ProcessStartInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "opus-tools\\opusenc.exe"))
                {
                    WorkingDirectory       = AppDomain.CurrentDomain.BaseDirectory,
                    Arguments              = $" \"{name.Replace("opus", "wav")}\" \"{name}\" --serial 42 --quiet --padding 0 --vbr --comp 10 --framesize 20 ",
                    UseShellExecute        = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow         = true,
                };
                using (var p = Process.Start(procn))
                {
                    p.WaitForExit();
                }

                if (File.Exists(name))
                {
                    for (var e = 0; e < Info.OpusCount; e++)
                    {
                        if (validids[i] == Info.OpusHashes[e])
                        {
                            int pakIdx = Info.PackIndices[e];
                            if (modStreams[pakIdx] == null)
                            {
                                var pakName = "base\\sound\\soundbanks\\sfx_container_" + pakIdx + ".opuspak";
                                if (_isModded && File.Exists(Path.Combine(_modFolder.FullName, pakName)))
                                {
                                    modStreams[pakIdx] = new MemoryStream(File.ReadAllBytes(Path.Combine(_modFolder.FullName, pakName)));
                                }
                                else
                                {
                                    var containerHash = FNV1A64HashAlgorithm.HashString(pakName);
                                    modStreams[pakIdx] = new MemoryStream();
                                    ModTools.ExtractSingleToStream(_soundBanks, containerHash, modStreams[pakIdx]);
                                }
                            }
                            Info.WriteOpusToPak(new MemoryStream(File.ReadAllBytes(name)), ref modStreams[pakIdx], validids[i], new MemoryStream(File.ReadAllBytes(name.Replace("opus", "wav"))));
                        }
                    }
                }
            }

            var writeinfo = false;

            for (var i = 0; i < modStreams.Length; i++)
            {
                if (modStreams[i] != null)
                {
                    var pakName = "base\\sound\\soundbanks\\sfx_container_" + i + ".opuspak";
                    var temp    = modStreams[i];
                    temp.Position = 0;
                    var bytes = new byte[temp.Length];
                    temp.Read(bytes, 0, Convert.ToInt32(temp.Length));
                    File.WriteAllBytes(Path.Combine(_modFolder.FullName, pakName), bytes);
                    writeinfo = true;
                }
            }
            if (writeinfo)
            {
                Info.WriteOpusInfo(new DirectoryInfo(Path.Combine(_modFolder.FullName, "base\\sound\\soundbanks")));

                return(true);
            }

            return(false);
        }
示例#24
0
 // Close the whole application if mainwindow is closed
 //
 private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
 {
     ModTools.writeJsonModFile(dataContext.InstalledMods, dataContext.AppDataModificationsJsonFile);
     App.Current.Shutdown();
 }