public bool TryReadRed4FileHeaders(BinaryReader br, [NotNullWhen(true)] out CR2WFileInfo?info)
 {
     // TODO: Shouldn't be done here...
     br.BaseStream.Seek(0, SeekOrigin.Begin);
     using var reader = new CR2WReader(br);
     return(reader.ReadFileInfo(out info) == EFileReadErrorCodes.NoError);
 }
 public bool TryReadRed4FileHeaders(Stream stream, [NotNullWhen(true)] out CR2WFileInfo?info)
 {
     // TODO: Shouldn't be done here...
     stream.Seek(0, SeekOrigin.Begin);
     using var reader = new CR2WReader(stream, Encoding.Default, true);
     return(reader.ReadFileInfo(out info) == EFileReadErrorCodes.NoError);
 }
Beispiel #3
0
        /// <summary>
        /// Rebuild a list of buffer bytearrays into a redfile
        /// </summary>
        /// <param name="redfileStream"></param>
        /// <param name="buffersenumerable"></param>
        /// <returns></returns>
        private bool Rebuild(Stream redfileStream, IEnumerable <byte[]> buffersenumerable)
        {
            var isResource = _wolvenkitFileService.IsCR2WFile(redfileStream);

            if (!isResource)
            {
                return(false);
            }

            using var reader = new CR2WReader(redfileStream);
            _ = reader.ReadFile(out var cr2w, false);

            var existingBuffers = cr2w.GetBuffers();
            var buffers         = buffersenumerable.ToList();

            if (buffers.Count != existingBuffers.Count)
            {
                throw new NotSupportedException("Rebuild: Adding/Removing buffers is not supported");
            }

            for (var i = 0; i < buffers.Count; i++)
            {
                existingBuffers[i].SetBytes(buffers[i]);
            }

            // write cr2w
            redfileStream.Seek(0, SeekOrigin.Begin);
            using var writer = new CR2WWriter(redfileStream);
            writer.WriteFile(cr2w);

            return(true);
        }
Beispiel #4
0
 static void OpenFile(string path)
 {
     Console.WriteLine(path);
     using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
         using (var br = new CR2WReader(fs, false))
         {
         }
 }
Beispiel #5
0
        //[TestMethod]
        //public void Test_All_Extensions()
        //{
        //    Test_Extension();
        //}

        //[TestMethod]
        public void Debug()
        {
            var files = s_groupedFiles[".smartobjects"].ToList();

            foreach (var file in files)
            {
                if (!file.Name.Contains("so_-008_0005_-001.smartobjects"))
                {
                    continue;
                }

                var ar = s_bm.Archives.Lookup(file.Archive.ArchiveAbsolutePath).Value as Archive;
                using var ms = new MemoryStream();
                ar?.CopyFileToStream(ms, file.NameHash64, false);
                ms.Seek(0, SeekOrigin.Begin);

                var reader     = new CR2WReader(ms);
                var readResult = reader.ReadFile(out var c);
            }
        }
Beispiel #6
0
        private void GetMateriaEntries(CR2WFile cr2w, Stream meshStream, ref List <string> primaryDependencies, ref List <string> materialEntryNames, ref List <CMaterialInstance> materialEntries, List <Archive> archives)
        {
            var cmesh = cr2w.RootChunk as CMesh;

            var ExternalMaterial = new List <CMaterialInstance>();

            for (var i = 0; i < cmesh.ExternalMaterials.Count; i++)
            {
                string path = cmesh.ExternalMaterials[i].DepotPath;

                var hash = FNV1A64HashAlgorithm.HashString(path);
                foreach (var ar in archives)
                {
                    if (ar.Files.ContainsKey(hash))
                    {
                        var ms = new MemoryStream();
                        ExtractSingleToStream(ar, hash, ms);
                        ms.Seek(0, SeekOrigin.Begin);

                        var isResource = _wolvenkitFileService.IsCR2WFile(ms);
                        if (!isResource)
                        {
                            throw new InvalidParsingException("not a cr2w file");
                        }

                        using var reader = new CR2WReader(ms);
                        _ = reader.ReadFile(out var mi, false);

                        ExternalMaterial.Add(mi.RootChunk as CMaterialInstance);

                        foreach (var import in reader.ImportsList)
                        {
                            if (!primaryDependencies.Contains(import.DepotPath))
                            {
                                primaryDependencies.Add(import.DepotPath);
                            }
                        }

                        break;
                    }
                }
            }
            for (var i = 0; i < cmesh.PreloadExternalMaterials.Count; i++)
            {
                string path = cmesh.PreloadExternalMaterials[i].DepotPath;

                var hash = FNV1A64HashAlgorithm.HashString(path);
                foreach (var ar in archives)
                {
                    if (ar.Files.ContainsKey(hash))
                    {
                        var ms = new MemoryStream();
                        ExtractSingleToStream(ar, hash, ms);
                        ms.Seek(0, SeekOrigin.Begin);

                        var isResource = _wolvenkitFileService.IsCR2WFile(ms);
                        if (!isResource)
                        {
                            throw new InvalidParsingException("not a cr2w file");
                        }

                        using var reader = new CR2WReader(ms);
                        _ = reader.ReadFile(out var mi, false);

                        ExternalMaterial.Add(mi.RootChunk as CMaterialInstance);

                        foreach (var import in reader.ImportsList)
                        {
                            if (!primaryDependencies.Contains(import.DepotPath))
                            {
                                primaryDependencies.Add(import.DepotPath);
                            }
                        }

                        break;
                    }
                }
            }

            var LocalMaterial = new List <CMaterialInstance>();

            if (cmesh.LocalMaterialBuffer.RawDataHeaders.Count != 0)
            {
                var materialStream = GetMaterialStream(meshStream, cr2w);
                var bytes          = materialStream.ToArray();
                for (var i = 0; i < cmesh.LocalMaterialBuffer.RawDataHeaders.Count; i++)
                {
                    uint offset = cmesh.LocalMaterialBuffer.RawDataHeaders[i].Offset;
                    uint size   = cmesh.LocalMaterialBuffer.RawDataHeaders[i].Size;

                    var ms = new MemoryStream(bytes, (int)offset, (int)size);

                    var isResource = _wolvenkitFileService.IsCR2WFile(ms);
                    if (!isResource)
                    {
                        throw new InvalidParsingException("not a cr2w file");
                    }

                    using var reader = new CR2WReader(ms);
                    _ = reader.ReadFile(out var mi, false);

                    //MemoryStream ms = new MemoryStream(bytes, (int)offset, (int)size);
                    //var mi = _wolvenkitFileService.ReadRed4File(ms);

                    foreach (var import in reader.ImportsList)
                    {
                        if (!primaryDependencies.Contains(import.DepotPath))
                        {
                            primaryDependencies.Add(import.DepotPath);
                        }
                    }

                    LocalMaterial.Add(mi.RootChunk as CMaterialInstance);
                }
            }
            else
            {
                foreach (var handle in cmesh.PreloadLocalMaterialInstances)
                {
                    if (handle.Chunk is CMaterialInstance mi1)
                    {
                        LocalMaterial.Add(mi1);
                    }
                }

                //throw new TodoException("get import info from cr2w file?");

                /*foreach (var import in cr2w.Debug.ImportInfos)
                 * {
                 *
                 *  if (!primaryDependencies.Contains(import.DepotPath))
                 *  {
                 *      primaryDependencies.Add(import.DepotPath);
                 *  }
                 * }*/
            }

            var Count = cmesh.MaterialEntries.Count;

            for (var i = 0; i < Count; i++)
            {
                var Entry = cmesh.MaterialEntries[i];
                materialEntryNames.Add(Entry.Name);
                if (Entry.IsLocalInstance)
                {
                    materialEntries.Add(LocalMaterial[Entry.Index]);
                }
                else
                {
                    materialEntries.Add(ExternalMaterial[Entry.Index]);
                }
            }
            foreach (var m in materialEntries)
            {
                string path = m.BaseMaterial.DepotPath;
                while (!Path.GetExtension(path).Contains("mt"))
                {
                    var hash = FNV1A64HashAlgorithm.HashString(path);
                    foreach (var ar in archives)
                    {
                        if (ar.Files.ContainsKey(hash))
                        {
                            var ms = new MemoryStream();
                            ExtractSingleToStream(ar, hash, ms);
                            ms.Seek(0, SeekOrigin.Begin);

                            var isResource = _wolvenkitFileService.IsCR2WFile(ms);
                            if (!isResource)
                            {
                                throw new InvalidParsingException("not a cr2w file");
                            }

                            using var reader = new CR2WReader(ms);
                            _ = reader.ReadFile(out var mi, false);

                            path = (mi.RootChunk as CMaterialInstance).BaseMaterial.DepotPath;

                            foreach (var import in reader.ImportsList)
                            {
                                if (!primaryDependencies.Contains(import.DepotPath))
                                {
                                    primaryDependencies.Add(import.DepotPath);
                                }
                            }
                            break;
                        }
                    }
                }
                var mt = FNV1A64HashAlgorithm.HashString(path);
                foreach (var ar in archives)
                {
                    if (ar.Files.ContainsKey(mt))
                    {
                        var ms = new MemoryStream();
                        ExtractSingleToStream(ar, mt, ms);
                        ms.Seek(0, SeekOrigin.Begin);

                        var isResource = _wolvenkitFileService.IsCR2WFile(ms);
                        if (!isResource)
                        {
                            throw new InvalidParsingException("not a cr2w file");
                        }
                        using var reader = new CR2WReader(ms);
                        _ = reader.ReadFile(out var mi, false);


                        foreach (var import in reader.ImportsList)
                        {
                            if (!primaryDependencies.Contains(import.DepotPath))
                            {
                                primaryDependencies.Add(import.DepotPath);
                            }
                        }
                        break;
                    }
                }
            }
        }
Beispiel #7
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);
        }
        private static IEnumerable <ReadTestResult> Read_Archive_Items(IEnumerable <FileEntry> files)
        {
            ArgumentNullException.ThrowIfNull(s_bm);
            var results = new ConcurrentBag <ReadTestResult>();

            var filesGroups = files.Select((f, i) => new { Value = f, Index = i })
                              .GroupBy(item => item.Value.Archive.ArchiveAbsolutePath);

            foreach (var fileGroup in filesGroups)
            {
                var fileList = fileGroup.ToList();

                var ar = s_bm.Archives.Lookup(fileGroup.Key).Value as Archive;

                using var fs  = new FileStream(fileGroup.Key, FileMode.Open, FileAccess.Read, FileShare.Read);
                using var mmf = MemoryMappedFile.CreateFromFile(fs, null, 0, MemoryMappedFileAccess.Read, HandleInheritability.None, false);

#if IS_PARALLEL
                Parallel.ForEach(fileList, tmpFile =>
#else
                foreach (var tmpFile in fileList)
#endif
                {
                    var file = tmpFile.Value;
                    try
                    {
                        using var ms = new MemoryStream();
                        ar?.CopyFileToStream(ms, file.NameHash64, false, mmf);
                        ms.Seek(0, SeekOrigin.Begin);

                        using var reader = new CR2WReader(ms);
                        var readResult   = reader.ReadFile(out var c, DECOMPRESS_BUFFERS);

                        switch (readResult)
                        {
                        case EFileReadErrorCodes.NoCr2w:
                            results.Add(new ReadTestResult
                            {
                                FileEntry  = file,
                                Success    = true,
                                ReadResult = ReadTestResult.ReadResultType.NoCr2W
                            });
                            break;

                        case EFileReadErrorCodes.UnsupportedVersion:
                            results.Add(new ReadTestResult
                            {
                                FileEntry  = file,
                                Success    = false,
                                ReadResult = ReadTestResult.ReadResultType.UnsupportedVersion,
                                Message    = $"Unsupported Version ({c.MetaData.Version})"
                            });
                            break;

                        case EFileReadErrorCodes.NoError:
                            c.MetaData.FileName = file.NameOrHash;

                            var res = ReadTestResult.ReadResultType.NoError;
                            var msg = "";

                            var additionalCr2WFileBytes =
                                (int)(reader.BaseStream.Length - reader.BaseStream.Position);
                            if (additionalCr2WFileBytes > 0)
                            {
                                res |= ReadTestResult.ReadResultType.HasAdditionalBytes;
                                msg += $"Additional Bytes: {additionalCr2WFileBytes}";
                            }

                            results.Add(new ReadTestResult
                            {
                                FileEntry       = file,
                                Success         = true /*!hasAdditionalBytes && !hasUnknownBytes*/,
                                ReadResult      = res,
                                Message         = msg,
                                AdditionalBytes = additionalCr2WFileBytes
                            });
                            break;

                        default:
                            throw new Exception();
                        }
                    }
                    catch (Exception e)
                    {
                        results.Add(new ReadTestResult
                        {
                            FileEntry     = file,
                            Success       = false,
                            ReadResult    = ReadTestResult.ReadResultType.RuntimeException,
                            ExceptionType = e.GetType(),
                            Message       = $"{e.Message}"
                        });
                    }
#if IS_PARALLEL
                });