Пример #1
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);
        }
Пример #2
0
        static void TestWriter()
        {
            var mem = new FileStream(@"D:\ModKit\testing_workspace\dumptests\files\block4test.CR2W", FileMode.Create, FileAccess.ReadWrite);

            var bw = new CR2WWriter(mem);

            bw.Serialize();

            //bw.Dispose();

            var br = new CR2WTestReader(mem, Console.Out);

            br.ReadAll();
        }
Пример #3
0
        private void Write(FileInfo f)
        {
            var cr2w = new CR2WFile();
            var mask = new Multilayer_Mask
            {
                CookingPlatform = Enums.ECookingPlatform.PLATFORM_PC
            };

            cr2w.RootChunk = mask;

            var blob = new rendRenderMultilayerMaskBlobPC
            {
                Header = new rendRenderMultilayerMaskBlobHeader
                {
                    Version       = 3,
                    AtlasWidth    = _mlmask.AtlasWidth,
                    AtlasHeight   = _mlmask.AtlasHeight,
                    NumLayers     = (uint)_mlmask.Layers.Length,
                    MaskWidth     = _mlmask.WidthHigh,
                    MaskHeight    = _mlmask.HeightHigh,
                    MaskWidthLow  = _mlmask.WidthLow,
                    MaskHeightLow = _mlmask.HeightLow,
                    MaskTileSize  = _mlmask.TileSize,
                    Flags         = 2
                },
                AtlasData = new SerializationDeferredDataBuffer(_mlmask.AtlasBuffer),
                TilesData = new SerializationDeferredDataBuffer(_mlmask.TilesBuffer)
            };

            mask.RenderResourceBlob.RenderResourceBlobPC = blob;

            if (!Directory.Exists(f.Directory.FullName))
            {
                Directory.CreateDirectory(f.Directory.FullName);
            }
            using var fs     = new FileStream(f.FullName, FileMode.Create, FileAccess.Write);
            using var writer = new CR2WWriter(fs);
            writer.WriteFile(cr2w);
        }
Пример #4
0
        public async Task OpenFromNewFileTask(NewFileViewModel file)
        {
            Stream stream = null;

            switch (file.SelectedFile.Type)
            {
            case EWolvenKitFile.Redscript:
            case EWolvenKitFile.Tweak:
                if (!string.IsNullOrEmpty(file.SelectedFile.Template))
                {
                    await using (var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream($"WolvenKit.App.Resources.{file.SelectedFile.Template}"))
                    {
                        stream = new FileStream(file.FullPath, FileMode.Create, FileAccess.Write);
                        resource.CopyTo(stream);
                    }
                }
                else
                {
                    stream = File.Create(file.FullPath);
                }
                break;

            case EWolvenKitFile.Cr2w:
                var redType = file.SelectedFile.Name;
                if (redType != "")
                {
                    var cr2w = new CR2WFile()
                    {
                        RootChunk = RedTypeManager.Create(redType)
                    };
                    stream = new FileStream(file.FullPath, FileMode.Create, FileAccess.Write);
                    using (var writer = new CR2WWriter(stream))
                    {
                        writer.WriteFile(cr2w);
                    }
                }
                break;
            }
            stream.Dispose();

            //return Task.CompletedTask;

            // Open file
            //await Locator.Current.GetService<AppViewModel>().RequestFileOpen(file.FullPath);


            //if (file != null)
            //{
            //    _progressService.IsIndeterminate = true;
            //    try
            //    {
            //        var fileViewModel = new RedDocumentViewModel(file.FileName);
            //        await using (var stream = new MemoryStream())
            //        {
            //            file.Extract(stream);
            //            fileViewModel.OpenStream(stream, null);
            //        }

            //        if (!DockedViews.Contains(fileViewModel))
            //            DockedViews.Add(fileViewModel);
            //        ActiveDocument = fileViewModel;
            //        UpdateTitle();
            //    }
            //    catch (Exception e)
            //    {
            //        _loggerService.Error(e.Message);
            //    }
            //    finally
            //    {
            //        _progressService.IsIndeterminate = false;
            //    }
            //}
        }
Пример #5
0
        private static void Test_Extension(string extension)
        {
            var parsers = _host.Services.GetRequiredService <Red4ParserService>();

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

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

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

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

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

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

                    #endregion

                    #region convert back from json

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

                    var newFile = newdto.Data;

                    #endregion

                    #region compare

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

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

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

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



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

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



                    //                    }
                    //                    else
                    //                    {

                    //                    }

                    #endregion

                    results.Add(new ArchiveTestResult()
                    {
                        ArchiveName = archive.Name,
                        Hash        = hash.ToString(),
                        Success     = true
                    });
                }
                catch (Exception e)
                {
                    Console.WriteLine($"{hash} - {e.Message} - {e.StackTrace}");
                    results.Add(new ArchiveTestResult()
                    {
                        ArchiveName   = archive.Name,
                        Hash          = hash.ToString(),
                        Success       = false,
                        ExceptionType = e.GetType(),
                        Message       = $"{e.Message}"
                    });
                }
#if IS_PARALLEL
            });
Пример #6
0
        public bool WriteMatToMesh(ref CR2WFile cr2w, string _matData, List <Archive> archives)
        {
            if (cr2w == null || cr2w.RootChunk is not CMesh cMesh || cMesh.RenderResourceBlob.Chunk is not rendRenderMeshBlob)
            {
                return(false);
            }

            var matData = RedJsonSerializer.Deserialize <MatData>(_matData);

            var materialbuffer = new MemoryStream();
            var offsets        = new List <uint>();
            var sizes          = new List <uint>();
            var names          = new List <string>();

            if (matData.Materials.Count < 1)
            {
                return(false);
            }

            var mts = new Dictionary <string, CMaterialTemplate>();

            for (var i = 0; i < matData.Materials.Count; i++)
            {
                var mat = matData.Materials[i];
                names.Add(mat.Name);
                var mi = new CR2WFile();
                {
                    var chunk = RedTypeManager.Create <CMaterialInstance>();
                    chunk.CookingPlatform = Enums.ECookingPlatform.PLATFORM_PC;
                    chunk.EnableMask      = true;
                    chunk.ResourceVersion = 4;
                    chunk.BaseMaterial    = new CResourceReference <IMaterial>()
                    {
                        DepotPath = mat.BaseMaterial
                    };
                    chunk.Values = new CArray <CKeyValuePair>();

                    CMaterialTemplate mt = null;
                    if (mts.ContainsKey(mat.MaterialTemplate))
                    {
                        mt = mts[mat.MaterialTemplate];
                    }
                    else
                    {
                        var hash = FNV1A64HashAlgorithm.HashString(mat.MaterialTemplate);
                        foreach (var ar in archives)
                        {
                            if (ar.Files.ContainsKey(hash))
                            {
                                var ms = new MemoryStream();
                                ExtractSingleToStream(ar, hash, ms);
                                ms.Seek(0, SeekOrigin.Begin);

                                mt = (CMaterialTemplate)_wolvenkitFileService.ReadRed4File(ms).RootChunk;
                                mts.Add(mat.MaterialTemplate, mt);
                                break;
                            }
                        }
                    }

                    var fakeMaterialInstance = new CMaterialInstance()
                    {
                        BaseMaterial = new CResourceReference <IMaterial> {
                            DepotPath = mat.BaseMaterial
                        },
                        Values = new CArray <CKeyValuePair>()
                    };
                    var orgChain = GetMaterialChain(fakeMaterialInstance, archives, ref mts);

                    if (mt != null)
                    {
                        foreach (var(key, value) in matData.Materials[i].Data)
                        {
                            var found = false;

                            for (var k = 0; k < mt.Parameters[2].Count; k++)
                            {
                                var refer = mt.Parameters[2][k].Chunk;

                                if (refer.ParameterName == key)
                                {
                                    found = true;

                                    object convValue = GetMaterialParameterValue(refer.GetType(), value);
                                    if (orgChain.valueDict.ContainsKey(refer.ParameterName) && !Equals(orgChain.valueDict[refer.ParameterName], convValue))
                                    {
                                        chunk.Values.Add(new CKeyValuePair(refer.ParameterName, (IRedType)convValue));
                                    }
                                }
                            }

                            if (!found)
                            {
                                var wrapper = ((JsonElement)value).Deserialize <MaterialValueWrapper>();
                                var(type, _) = RedReflection.GetCSTypeFromRedType(wrapper.Type);

                                var nValue = ((JsonElement)wrapper.Value).Deserialize(type, RedJsonSerializer.Options);
                                chunk.Values.Add(new CKeyValuePair(key, (IRedType)nValue));
                            }
                        }
                    }

                    mi.RootChunk = chunk;
                }

                offsets.Add((uint)materialbuffer.Position);

                using var m      = new MemoryStream();
                using var writer = new CR2WWriter(m);
                writer.WriteFile(mi);

                materialbuffer.Write(m.ToArray(), 0, (int)m.Length);
                sizes.Add((uint)m.Length);
            }

            var blob = (CMesh)cr2w.RootChunk;

            // remove existing data
            while (blob.MaterialEntries.Count != 0)
            {
                blob.MaterialEntries.Remove(blob.MaterialEntries[^ 1]);