Beispiel #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

            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);
        }
Beispiel #2
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);
        }
Beispiel #3
0
        public static int Convert(string outDir,
                                  string filepath,
                                  EUncookExtension convertFt,
                                  EFormat convertF = EFormat.R8G8B8A8_UNORM,
                                  bool overwrite   = true
                                  )
        {
            var fi = new FileInfo(textconvpath);

            if (!fi.Exists)
            {
            }

            var proc = new ProcessStartInfo(textconvpath)
            {
                WorkingDirectory       = Path.GetDirectoryName(textconvpath),
                Arguments              = $" -o {outDir} -y -f {convertF}  -ft {convertFt} {filepath}",
                UseShellExecute        = false,
                RedirectStandardOutput = true,
                CreateNoWindow         = true,
            };

            using (var p = Process.Start(proc))
            {
                p.WaitForExit();
            }

            return(1);
        }
Beispiel #4
0
        /// <summary>
        /// Uncooks a single file by hash. This will both extract and uncook the redengine file
        /// </summary>
        /// <param name="ar"></param>
        /// <param name="hash"></param>
        /// <param name="outDir"></param>
        /// <param name="uncookext"></param>
        /// <param name="flip"></param>
        /// <returns></returns>
        public static bool UncookSingle(this Archive.Archive ar, ulong hash, DirectoryInfo outDir,
                                        EUncookExtension uncookext = EUncookExtension.dds, bool flip = false)
        {
            // checks
            if (!ar.Files.ContainsKey(hash))
            {
                return(false);
            }


            // extract the main file with uncompressed buffers

            #region unbundle main file

            using var ms = new MemoryStream();
            ar.CopyFileToStream(ms, hash, false);

            var name    = ar.Files[hash].FileName;
            var outfile = new FileInfo(Path.Combine(outDir.FullName, $"{name}"));
            if (outfile.Directory == null)
            {
                return(false);
            }
            Directory.CreateDirectory(outfile.Directory.FullName);
            using var fs = new FileStream(outfile.FullName, FileMode.Create, FileAccess.Write);
            ms.Seek(0, SeekOrigin.Begin);
            ms.CopyTo(fs);

            #endregion
            var ext = Path.GetExtension(name)[1..];
        public static string Convert(string outDir,
                                     string filepath,
                                     EUncookExtension filetype,
                                     EFormat format = EFormat.R8G8B8A8_UNORM,
                                     int mipmaps    = 0
                                     )
        {
            var proc = new ProcessStartInfo(textconvpath)
            {
                WorkingDirectory       = Path.GetDirectoryName(textconvpath),
                Arguments              = $" -o \"{outDir}\" -y -f {format} -m {mipmaps} -l -ft {filetype} \"{filepath}\"",
                UseShellExecute        = false,
                RedirectStandardOutput = true,
                CreateNoWindow         = true,
            };

            using (var p = Process.Start(proc))
            {
                p.WaitForExit();
            }

            var fi = new FileInfo(Path.Combine(outDir, $"{Path.GetFileNameWithoutExtension(filepath)}.{filetype}"));

            if (!fi.Exists)
            {
                return(null);
            }

            return(fi.FullName);
        }
Beispiel #6
0
        /// <summary>
        /// Uncooks a single file by hash.
        /// </summary>
        /// <param name="hash"></param>
        /// <param name="outDir"></param>
        /// <param name="uncookext"></param>
        /// <returns></returns>
        public int UncookSingle(ulong hash, DirectoryInfo outDir, EUncookExtension uncookext = EUncookExtension.tga)
        {
            using var mmf = MemoryMappedFile.CreateFromFile(Filepath, FileMode.Open, Mmfhash, 0,
                                                            MemoryMappedFileAccess.Read);

            return(UncookSingleInner(mmf, hash, outDir, uncookext));
        }
        public void ConvertToDds(EUncookExtension type)
        {
            var testFile = Path.GetFullPath($"Resources/{GetTestFile()}.{type.ToString()}");

            Directory.CreateDirectory(Path.GetFullPath("texc"));
            var bytes = File.ReadAllBytes(testFile);

            //var blob = new TexconvNative.Blob();
            //var len = TexconvNative.ConvertToDds(bytes, ref blob, TexconvNative.ESaveFileTypes.TGA, DXGI_FORMAT.DXGI_FORMAT_UNKNOWN);
            //var outFile = Path.GetFullPath(Path.Combine("texc", "q204_columbarium_1080p_0.dds"));
            //File.WriteAllBytes(outFile, blob.GetBytes());

            var ms = new MemoryStream(bytes);

            ms.Seek(0, SeekOrigin.Begin);
            var r1       = Texconv.ConvertToDds(ms, type, DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM);
            var outFile1 = Path.GetFullPath(Path.Combine("texc", $"{GetTestFile()}_1.{type}.dds"));

            File.WriteAllBytes(outFile1, r1);

            ms.Seek(0, SeekOrigin.Begin);
            var r3       = Texconv.ConvertToDds(ms, type, DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM);
            var outFile3 = Path.GetFullPath(Path.Combine("texc", $"{GetTestFile()}_3.{type}.dds"));

            File.WriteAllBytes(outFile3, r3);

            ms.Seek(0, SeekOrigin.Begin);
            var r7       = Texconv.ConvertToDds(ms, type, DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM);
            var outFile7 = Path.GetFullPath(Path.Combine("texc", $"{GetTestFile()}_7.{type}.dds"));

            File.WriteAllBytes(outFile7, r7);
        }
Beispiel #8
0
        public static bool Convert(string outDir,
                                   string filepath,
                                   EUncookExtension filetype,
                                   EFormat format = EFormat.R8G8B8A8_UNORM,
                                   int mipmaps    = 0
                                   )
        {
            var logger = ServiceLocator.Default.ResolveType <ILoggerService>();

            var proc = new ProcessStartInfo(textconvpath)
            {
                WorkingDirectory       = Path.GetDirectoryName(textconvpath),
                Arguments              = $" -o \"{outDir}\" -y -f {format} -m {mipmaps} -l -ft {filetype} \"{filepath}\"",
                UseShellExecute        = false,
                RedirectStandardOutput = true,
                CreateNoWindow         = true,
            };

            using (var p = Process.Start(proc))
            {
                p.WaitForExit();
            }

            var fi = new FileInfo(Path.Combine(outDir, $"{Path.GetFileNameWithoutExtension(filepath)}.{filetype}"));

            if (!fi.Exists)
            {
                logger.LogString($"Could not convert {fi.FullName}.", Logtype.Error);
                return(false);
            }

            return(true);
        }
Beispiel #9
0
        public static string Convert(string outDir,
                                     string filepath,
                                     EUncookExtension filetype,
                                     EFormat format = EFormat.R8G8B8A8_UNORM,
                                     int mipmaps    = 0
                                     )
        {
            string textconvpath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Tools/DDS/texconv.exe");


            var argsss = $" -o '{outDir}' -y -f {format}  -ft {filetype} '{filepath}'";

            var proc = new ProcessStartInfo(textconvpath)
            {
                WorkingDirectory       = Path.GetDirectoryName(textconvpath),
                Arguments              = $" -o \"{outDir}\" -y -f {format} -m {mipmaps} -l -ft {filetype} \"{filepath}\"",
                UseShellExecute        = false,
                RedirectStandardOutput = true,
                CreateNoWindow         = true,
            };

            using (var p = Process.Start(proc))
            {
                p.WaitForExit();
            }

            var fi = new FileInfo(Path.Combine(outDir, $"{Path.GetFileNameWithoutExtension(filepath)}.{filetype}"));

            if (!fi.Exists)
            {
                throw new NotImplementedException();
            }

            return(fi.FullName);
        }
Beispiel #10
0
        public int ExtractSingle(ulong hash, DirectoryInfo outDir, bool extract = true,
                                 bool uncook = false,
                                 EUncookExtension uncookext = EUncookExtension.tga)
        {
            using var mmf = MemoryMappedFile.CreateFromFile(Filepath, FileMode.Open, Mmfhash, 0,
                                                            MemoryMappedFileAccess.Read);

            return(ExtractSingleInner(mmf, hash, outDir, extract, uncook, uncookext));
        }
Beispiel #11
0
        public static void ExportTask(string[] path, EUncookExtension uncookext)
        {
            if (path == null || path.Length < 1)
            {
                logger.LogString("Please fill in an input path", Logtype.Error);
                return;
            }

            Parallel.ForEach(path, file =>
            {
                ExportTaskInner(file, uncookext);
            });
        }
Beispiel #12
0
        public static void UncookTask(string[] path, string outpath,
                                      EUncookExtension uext, bool flip, ulong hash, string pattern, string regex)
        {
            if (path == null || path.Length < 1)
            {
                logger.LogString("Please fill in an input path", Logtype.Error);
                return;
            }

            Parallel.ForEach(path, file =>
            {
                UncookTaskInner(file, outpath, uext, flip, hash, pattern, regex);
            });
        }
Beispiel #13
0
        public static void ArchiveTask(string[] path, string outpath, bool extract, bool dump, bool list,
                                       bool uncook, EUncookExtension uext, ulong hash, string pattern, string regex)
        {
            if (path == null || path.Length < 1)
            {
                logger.LogString("Please fill in an input path", Logtype.Error);
                return;
            }

            Parallel.ForEach(path, file =>
            {
                ArchiveTaskInner(file, outpath, extract, dump, list,
                                 uncook, uext, hash, pattern, regex);
            });
        }
Beispiel #14
0
        /// <summary>
        /// Converts texture stream with given extension stream to dds
        /// </summary>
        public static byte[] ConvertToDds(Stream stream, EUncookExtension inExtension, DXGI_FORMAT?outFormat = null, bool vflip = false, bool hflip = false)
        {
            if (inExtension == EUncookExtension.dds)
            {
                throw new NotSupportedException("texture to convert to dds must not be dds iteslf");
            }

            byte[] rentedBuffer = null;
            try
            {
                var offset = 0;

                var len = checked ((int)stream.Length);
                rentedBuffer = ArrayPool <byte> .Shared.Rent(len);

                int readBytes;
                while (offset < len &&
                       (readBytes = stream.Read(rentedBuffer, offset, len - offset)) > 0)
                {
                    offset += readBytes;
                }

                var format = outFormat ?? DXGI_FORMAT.DXGI_FORMAT_UNKNOWN;

                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    var buffer = Array.Empty <byte>();
                    using (var blob = new ManagedBlob())
                    {
                        var l = TexconvNative.ConvertToDds(rentedBuffer, blob.GetBlob(), ToSaveFormat(inExtension),
                                                           format, vflip, hflip);
                        buffer = blob.GetBytes();
                    }
                    return(buffer);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            finally
            {
                if (rentedBuffer is object)
                {
                    ArrayPool <byte> .Shared.Return(rentedBuffer);
                }
            }
        }
Beispiel #15
0
        /// <summary>
        /// Exports (Uncooks) a REDEngine file into it's raw counterpart
        /// </summary>
        /// <param name="cr2wfile"></param>
        /// <param name="outpath"></param>
        public static bool Export(FileInfo cr2wfile, EUncookExtension uncookext = EUncookExtension.dds, bool flip = false)
        {
            #region checks

            if (cr2wfile == null)
            {
                return(false);
            }
            if (!cr2wfile.Exists)
            {
                return(false);
            }
            if (cr2wfile.Directory != null && !cr2wfile.Directory.Exists)
            {
                return(false);
            }
            var ext = Path.GetExtension(cr2wfile.FullName)[1..];
Beispiel #16
0
        /// <summary>
        /// Converts a dds stream to another texture file type and returns an image byte array
        /// </summary>
        public static unsafe byte[] ConvertToDdsMemory(
            Stream ms,
            EUncookExtension filetype,
            DXGI_FORMAT?format = null,
            bool vflip         = false,
            bool hflip         = false)
        {
            byte[] rentedBuffer = null;
            try
            {
                var offset = 0;

                var len = checked ((int)ms.Length);
                rentedBuffer = ArrayPool <byte> .Shared.Rent(len);

                int readBytes;
                while (offset < len &&
                       (readBytes = ms.Read(rentedBuffer, offset, len - offset)) > 0)
                {
                    offset += readBytes;
                }

                var span = new ReadOnlySpan <byte>(rentedBuffer, 0, len);

                fixed(byte *ptr = span)
                {
                    var fmt = format != null
                        ? (DirectXTexSharp.DXGI_FORMAT_WRAPPED)format
                        : DirectXTexSharp.DXGI_FORMAT_WRAPPED.DXGI_FORMAT_UNKNOWN;


                    var buffer = DirectXTexSharp.Texconv.ConvertToDdsArray(ptr, span.Length,
                                                                           filetype.ToSaveFormat(),
                                                                           fmt, vflip, hflip);

                    return(buffer);
                }
            }
            finally
            {
                if (rentedBuffer is object)
                {
                    ArrayPool <byte> .Shared.Return(rentedBuffer);
                }
            }
        }
Beispiel #17
0
        /// <summary>
        /// Exports (Uncooks) a REDEngine file into it's raw counterpart
        /// </summary>
        /// <param name="cr2wfile"></param>
        /// <param name="outpath"></param>
        public static bool Export(FileInfo cr2wfile, EUncookExtension uncookext = EUncookExtension.tga)
        {
            #region checks

            if (cr2wfile == null)
            {
                return(false);
            }
            if (!cr2wfile.Exists)
            {
                return(false);
            }
            if (cr2wfile.Directory != null && !cr2wfile.Directory.Exists)
            {
                return(false);
            }
            if (!Enum.GetNames(typeof(ECookedFileFormat)).Contains(cr2wfile.Extension[1..]))
Beispiel #18
0
        public void ConvertFromDds(EUncookExtension type)
        {
            var testFile = Path.GetFullPath($"Resources/{GetTestFile()}.dds");
            var bytes    = File.ReadAllBytes(testFile);

            //foreach (var type in Enum.GetValues<EUncookExtension>())
            {
                var outFile = Path.GetFullPath(Path.Combine("texc", $"{GetTestFile()}.{type.ToString()}"));

                //var blob = new TexconvNative.Blob();
                //var len = TexconvNative.ConvertFromDds(bytes, ref blob, Texconv.ToSaveFormat(type));

                using var ms = new MemoryStream(bytes);
                var buffer = Texconv.ConvertFromDds(ms, type);

                File.WriteAllBytes(outFile, buffer);
            }
        }
Beispiel #19
0
        /// <summary>
        /// Uncooks all Files to the specified directory.
        /// </summary>
        /// <param name="outDir"></param>
        /// <param name="uncookext"></param>
        /// <returns></returns>
        public (List <string>, int) UncookAll(DirectoryInfo outDir, EUncookExtension uncookext = EUncookExtension.tga)
        {
            using var pb = new ProgressBar();
            using var p1 = pb.Progress.Fork();
            int progress      = 0;
            var extractedList = new ConcurrentBag <string>();
            var failedList    = new ConcurrentBag <string>();
            int all           = 0;

            using var mmf = MemoryMappedFile.CreateFromFile(Filepath, FileMode.Open, Mmfhash, 0,
                                                            MemoryMappedFileAccess.Read);

            Parallel.For(0, FileCount, new ParallelOptions {
                MaxDegreeOfParallelism = 8
            }, i =>
            {
                var info = Files.Values.ToList()[i];

                if (CanUncook(info.NameHash64))
                {
                    Interlocked.Increment(ref all);
                    int uncooked = UncookSingleInner(mmf, info.NameHash64, outDir, uncookext);

                    if (uncooked != 0)
                    {
                        extractedList.Add(info.NameStr);
                    }
                    else
                    {
                        failedList.Add(info.NameStr);
                    }
                }

                Interlocked.Increment(ref progress);
                var perc = progress / (double)FileCount;
                p1.Report(perc, $"Loading bundle entries: {progress}/{FileCount}");
            });


            return(extractedList.ToList(), all);
        }
 public BundleFileExtractArgs(string fullpath, EUncookExtension extension = EUncookExtension.tga)
 {
     FileName  = fullpath;
     Extension = extension;
 }
Beispiel #21
0
        private static void UncookTaskInner(string path, string outpath,
                                            EUncookExtension uext, bool flip, ulong hash, string pattern, string regex)
        {
            #region checks

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

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


            if (!inputFileInfo.Exists && !inputDirInfo.Exists)
            {
                logger.LogString("Input path does not exist", Logtype.Error);
                return;
            }

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

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

            #endregion

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


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

                    if (inputDirInfo.Exists)
                    {
                        outDir = Directory.CreateDirectory(Path.Combine(
                                                               outDir.FullName,
                                                               processedarchive.Name.Replace(".archive", "")));
                    }
                }

                // read archive
                var ar = new Archive(processedarchive.FullName);

                // run
                if (hash != 0)
                {
                    ar.UncookSingle(hash, outDir, uext, flip);
                    logger.LogString($" {ar.ArchiveAbsolutePath}: Uncooked one file: {hash}", Logtype.Success);
                }
                else
                {
                    var r = ar.UncookAll(outDir, pattern, regex, uext, flip);
                    logger.LogString($" {ar.ArchiveAbsolutePath}: Uncooked {r.Item1.Count}/{r.Item2} files.",
                                     Logtype.Success);
                }
            }

            return;
        }
Beispiel #22
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);
        }
Beispiel #23
0
        public bool ExportMeshWithMaterials(Stream meshStream, FileInfo outfile, List <Archive> archives, string matRepo, EUncookExtension eUncookExtension = EUncookExtension.dds, bool isGLBinary = true, bool LodFilter = true)
        {
            if (matRepo == null)
            {
                throw new Exception("Material Repository Path is not set, Please select a folder in the Material Repository Settings where your textures will output, Generating the complete dump is not required.");
            }

            var cr2w = _wolvenkitFileService.TryReadRED4File(meshStream);

            if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any())
            {
                return(false);
            }
            DirectoryInfo outDir = new DirectoryInfo(Path.Combine(outfile.DirectoryName, Path.GetFileNameWithoutExtension(outfile.FullName)));

            MESH.MeshBones meshBones = new MESH.MeshBones();

            meshBones.boneCount = cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First().BoneNames.Count;

            if (meshBones.boneCount != 0)    // for rigid meshes
            {
                meshBones.Names     = RIG.GetboneNames(cr2w);
                meshBones.WorldPosn = MESH.GetMeshBonesPosn(cr2w);
            }
            RawArmature Rig = MESH.GetNonParentedRig(meshBones);

            MemoryStream ms       = MESH.GetMeshBufferStream(meshStream, cr2w);
            MeshesInfo   meshinfo = MESH.GetMeshesinfo(cr2w);

            List <RawMeshContainer> expMeshes = MESH.ContainRawMesh(ms, meshinfo, LodFilter);

            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);

            ModelRoot model = MESH.RawMeshesToGLTF(expMeshes, Rig);

            if (!outDir.Exists)
            {
                Directory.CreateDirectory(outDir.FullName);
            }

            ParseMaterials(cr2w, meshStream, outDir, archives, matRepo, eUncookExtension);

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

            meshStream.Dispose();
            meshStream.Close();

            return(true);
        }
Beispiel #24
0
        public static void ArchiveTask(string path, string outpath, bool extract, bool dump, bool list,
                                       bool uncook, EUncookExtension uext, ulong hash)
        {
            #region checks

            if (string.IsNullOrEmpty(path))
            {
                Console.WriteLine("Input file does not exist");
                return;
            }
            var inputFileInfo = new FileInfo(path);
            if (!inputFileInfo.Exists)
            {
                Console.WriteLine("Input file does not exist");
                return;
            }
            if (inputFileInfo.Extension != ".archive")
            {
                Console.WriteLine("Input file is not an .archive");
                return;
            }
            var indir = new FileInfo(path).Directory;
            if (indir == null)
            {
                return;
            }

            #endregion

            if (extract || dump || list || uncook)
            {
                // get outdirectory
                var outDir = Directory.CreateDirectory(Path.Combine(
                                                           indir.FullName,
                                                           inputFileInfo.Name.Replace(".archive", "")));
                if (!string.IsNullOrEmpty(outpath))
                {
                    outDir = new DirectoryInfo(outpath);
                    if (!outDir.Exists)
                    {
                        Console.WriteLine("Output directory does not exist");
                        return;
                    }
                }
                if (!outDir.Exists)
                {
                    Directory.CreateDirectory(outDir.FullName);
                }

                // read archive
                var ar = new Archive(inputFileInfo.FullName);

                // run
                if (extract || uncook)
                {
                    if (hash != 0)
                    {
                        ar.ExtractSingle(hash, outDir, extract, uncook, uext);
                    }
                    else
                    {
                        Console.WriteLine($"{path}: Found {ar.FileCount} files.");
                        var result = ar.ExtractAll(outDir, extract, uncook, uext);
                        Console.WriteLine($"{path}: Extracted {result.Count} files.");
                    }
                }

                if (dump)
                {
                    ar.DumpInfo(outDir);
                    Console.WriteLine($"Finished dumping {path}.");
                }

                if (list)
                {
                    foreach (var entry in ar.Files)
                    {
                        Console.WriteLine(entry.Value.NameStr);
                    }
                }
            }

            return;
        }
Beispiel #25
0
 public static ESaveFileTypes ToSaveFormat(EUncookExtension extension) =>
 extension switch
 {
Beispiel #26
0
        private void GenerateMaterialRepo(DirectoryInfo materialRepoDir, EUncookExtension texturesExtension)
        {
            var cp77Controller = _gameControllerFactory.GetRed4Controller();
            var bm             = cp77Controller.GetArchiveManagers(false).OfType <ArchiveManager>().FirstOrDefault();

            if (bm == null)
            {
                return;
            }

            var unbundle = new List <string>()
            {
                ".gradient",
                ".w2mi",
                ".matlib",
                ".remt",
                ".sp",
                ".hp",
                ".fp",
                ".mi",
                ".mt",
                ".mlsetup",
                ".mltemplate",
                ".texarray",
            };
            var uncook = new List <string>()
            {
                ".xbm",
                ".mlmask"
            };
            var groupedFiles = bm.GroupedFiles;

            // unbundle
            foreach (var(key, fileEntries) in groupedFiles)
            {
                if (!unbundle.Contains(key))
                {
                    continue;
                }
                var fileslist = groupedFiles[key].ToList();
                _loggerService.Info($"{key}: Found {fileslist.Count} entries to uncook");
                var progress = 0;
                _progress.Report(0);

                Parallel.ForEach(fileslist, entry =>
                {
                    var endPath = Path.Combine(materialRepoDir.FullName, entry.Name);
                    var dirpath = Path.GetDirectoryName(endPath);
                    Directory.CreateDirectory(dirpath);
                    using (var fs = new FileStream(endPath, FileMode.Create, FileAccess.Write))
                    {
                        entry.Extract(fs);
                    }
                    Interlocked.Increment(ref progress);
                    _progress.Report(progress / (float)fileslist.Count);
                }
                                 );

                _loggerService.Success($"{key}: Unbundled {fileslist.Count} files.");
            }

            // uncook
            var exportArgs =
                new GlobalExportArgs().Register(
                    new XbmExportArgs()
            {
                UncookExtension = texturesExtension
            },
                    new MlmaskExportArgs()
            {
                UncookExtension = texturesExtension
            }
                    );

            foreach (var(key, fileEntries) in groupedFiles)
            {
                if (!uncook.Contains(key))
                {
                    continue;
                }
                var fileslist = groupedFiles[key].ToList();
                _loggerService.Info($"{key}: Found {fileslist.Count} entries to uncook");
                var progress = 0;
                _progress.Report(0);

                Parallel.ForEach(fileslist, entry =>
                {
                    _modTools.UncookSingle(entry.Archive as Archive, entry.Key, materialRepoDir, exportArgs);

                    Interlocked.Increment(ref progress);
                    _progress.Report(progress / (float)fileslist.Count);
                }
                                 );

                _loggerService.Success($"{key}: Uncooked {fileslist.Count} files.");
            }
        }
Beispiel #27
0
        public bool ExportMeshWithMaterials(Stream meshStream, FileInfo outfile, List <Archive> archives, string matRepo, EUncookExtension eUncookExtension = EUncookExtension.dds, bool isGLBinary = true, bool LodFilter = true)
        {
            if (matRepo == null)
            {
                throw new Exception("Material Repository Path is not set, Please select a folder in the Material Repository Settings where your textures will output, Generating the complete dump is not required.");
            }

            var cr2w = _wolvenkitFileService.ReadRed4File(meshStream);

            if (cr2w == null || cr2w.RootChunk is not CMesh cMesh || cMesh.RenderResourceBlob.Chunk is not rendRenderMeshBlob rendblob)
            {
                return(false);
            }

            using var ms = new MemoryStream(rendblob.RenderBuffer.Buffer.GetBytes());

            var meshesinfo = MeshTools.GetMeshesinfo(rendblob, cr2w);

            var expMeshes = MeshTools.ContainRawMesh(ms, meshesinfo, LodFilter);

            MeshTools.UpdateSkinningParamCloth(ref expMeshes, meshStream, cr2w);

            var Rig = MeshTools.GetOrphanRig(rendblob, cr2w);

            var model = MeshTools.RawMeshesToGLTF(expMeshes, Rig);

            ParseMaterials(cr2w, meshStream, outfile, archives, matRepo, eUncookExtension);

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

            meshStream.Dispose();
            meshStream.Close();

            return(true);
        }
Beispiel #28
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);
        }
Beispiel #29
0
        private static void ArchiveTaskInner(string path, string outpath, bool extract, bool dump, bool list,
                                             bool uncook, EUncookExtension uext, bool flip, ulong hash, string pattern, string regex)
        {
            #region checks

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

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


            if (!inputFileInfo.Exists && !inputDirInfo.Exists)
            {
                logger.LogString("Input path does not exist", Logtype.Error);
                return;
            }

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

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

            #endregion

            if (extract || dump || list || uncook)
            {
                List <FileInfo> archiveFileInfos;
                if (isDirectory)
                {
                    var archiveManager = new ArchiveManager(basedir);
                    // TODO: use the manager here?
                    archiveFileInfos = archiveManager.Archives.Select(_ => new FileInfo(_.Filepath)).ToList();
                }
                else
                {
                    archiveFileInfos = new List <FileInfo> {
                        inputFileInfo
                    };
                }


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

                    // read archive
                    var ar = new Archive(processedarchive.FullName);

                    // run
                    if (extract || uncook)
                    {
                        if (hash != 0)
                        {
                            if (extract)
                            {
                                ar.ExtractSingle(hash, outDir);
                                logger.LogString($" {ar.Filepath}: Extracted one file: {hash}", Logtype.Success);
                            }

                            if (uncook)
                            {
                                ar.UncookSingle(hash, outDir, uext, flip);
                                logger.LogString($" {ar.Filepath}: Uncooked one file: {hash}", Logtype.Success);
                            }
                        }
                        else
                        {
                            if (extract)
                            {
                                var r = ar.ExtractAll(outDir, pattern, regex);
                                logger.LogString($"{ar.Filepath}: Extracted {r.Item1.Count}/{r.Item2} files.", Logtype.Success);
                            }

                            if (uncook)
                            {
                                var r = ar.UncookAll(outDir, pattern, regex, uext, flip);
                                logger.LogString($" {ar.Filepath}: Uncooked {r.Item1.Count}/{r.Item2} files.", Logtype.Success);
                            }
                        }
                    }

                    if (dump)
                    {
                        File.WriteAllText(Path.Combine(outDir.Parent.FullName, $"{ar.Name}.json"),
                                          JsonConvert.SerializeObject(ar, Formatting.Indented, new JsonSerializerSettings()
                        {
                            ReferenceLoopHandling      = ReferenceLoopHandling.Ignore,
                            PreserveReferencesHandling = PreserveReferencesHandling.None,
                            TypeNameHandling           = TypeNameHandling.None
                        }));

                        logger.LogString($"Finished dumping {processedarchive.FullName}.", Logtype.Success);
                    }

                    if (list)
                    {
                        foreach (var entry in ar.Files)
                        {
                            logger.LogString(entry.Value.FileName, Logtype.Normal);
                        }
                    }
                }
            }
            return;
        }
Beispiel #30
0
        private void ParseMaterials(CR2WFile cr2w, Stream meshStream, FileInfo outfile, List <Archive> archives, string matRepo, EUncookExtension eUncookExtension = EUncookExtension.dds)
        {
            var settings = new JsonSerializerSettings();

            settings.NullValueHandling = NullValueHandling.Ignore;
            settings.Formatting        = Formatting.Indented;

            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 <string> mlTemplateNames = new List <string>();

            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, 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]);
                    }
                    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))
                                {
                                    UncookSingle(ar, hash, new DirectoryInfo(matRepo), exportArgs);
                                }
                            }
                            break;
                        }
                    }
                }

                if (Path.GetExtension(primaryDependencies[i]) == ".hp")
                {
                    if (!HairProfileNames.Contains(primaryDependencies[i]))
                    {
                        ulong hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]);
                        foreach (Archive ar in archives)
                        {
                            if (ar.Files.ContainsKey(hash))
                            {
                                var ms = new MemoryStream();
                                ExtractSingleToStream(ar, hash, ms);
                                var hp = _wolvenkitFileService.TryReadCr2WFile(ms);
                                HairProfileNames.Add(primaryDependencies[i]);
                                string 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 doc = JsonConvert.SerializeObject(new HairProfile(hp.Chunks[0].Data as CHairProfile, Path.GetFileName(primaryDependencies[i])), settings);
                                    File.WriteAllText(path, doc);
                                }
                                break;
                            }
                        }
                    }
                }

                if (Path.GetExtension(primaryDependencies[i]) == ".mlsetup")
                {
                    if (!mlSetupNames.Contains(primaryDependencies[i]))
                    {
                        ulong hash = FNV1A64HashAlgorithm.HashString(primaryDependencies[i]);
                        foreach (Archive ar in archives)
                        {
                            if (ar.Files.ContainsKey(hash))
                            {
                                var ms = new MemoryStream();
                                ExtractSingleToStream(ar, hash, ms);
                                var mls = _wolvenkitFileService.TryReadCr2WFile(ms);
                                mlSetupNames.Add(primaryDependencies[i]);

                                string 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);
                                    }
                                    var doc = JsonConvert.SerializeObject(new Setup(mls.Chunks[0].Data as Multilayer_Setup, Path.GetFileName(primaryDependencies[i])), settings);
                                    File.WriteAllText(path, doc);
                                }

                                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, Path.ChangeExtension(mls.Imports[e].DepotPathStr, "." + exportArgs.Get <XbmExportArgs>().UncookExtension.ToString()))))
                                                {
                                                    if (Directory.Exists(matRepo))
                                                    {
                                                        UncookSingle(arr, hash1, new DirectoryInfo(matRepo), exportArgs);
                                                    }
                                                }
                                                break;
                                            }
                                        }
                                    }
                                    if (Path.GetExtension(mls.Imports[e].DepotPathStr) == ".mltemplate")
                                    {
                                        if (!mlTemplateNames.Contains(mls.Imports[e].DepotPathStr))
                                        {
                                            ulong hash2 = FNV1A64HashAlgorithm.HashString(mls.Imports[e].DepotPathStr);
                                            foreach (Archive arr in archives)
                                            {
                                                if (arr.Files.ContainsKey(hash2))
                                                {
                                                    var mss = new MemoryStream();
                                                    ExtractSingleToStream(arr, hash2, mss);

                                                    var mlt = _wolvenkitFileService.TryReadCr2WFile(mss);
                                                    mlTemplateNames.Add(mls.Imports[e].DepotPathStr);

                                                    string path1 = Path.Combine(matRepo, Path.ChangeExtension(mls.Imports[e].DepotPathStr, ".mltemplate.json"));
                                                    if (!File.Exists(path1))
                                                    {
                                                        if (!new FileInfo(path1).Directory.Exists)
                                                        {
                                                            Directory.CreateDirectory(new FileInfo(path1).Directory.FullName);
                                                        }
                                                        var doc1 = JsonConvert.SerializeObject(new Template(mlt.Chunks[0].Data as Multilayer_LayerTemplate, Path.GetFileName(mls.Imports[e].DepotPathStr)), settings);
                                                        File.WriteAllText(path1, doc1);
                                                    }

                                                    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, Path.ChangeExtension(mlt.Imports[eye].DepotPathStr, "." + exportArgs.Get <XbmExportArgs>().UncookExtension.ToString()))))
                                                                {
                                                                    if (Directory.Exists(matRepo))
                                                                    {
                                                                        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));
            }
            var obj = new { MaterialRepo = matRepo, Materials = RawMaterials, Description = "Following Texture List is for user reference and has no purpose for importing materials", TexturesList };

            string str = JsonConvert.SerializeObject(obj, settings);

            File.WriteAllText(Path.ChangeExtension(outfile.FullName, ".Material.json"), str);
        }