Ejemplo n.º 1
0
        private RedBaseClass ReadChunk(Package04ChunkHeader c)
        {
            // needs header offset
            //Debug.Assert(BaseStream.Position == c.offset);
            var redTypeName = GetStringValue((ushort)c.typeID);

            var(type, _) = RedReflection.GetCSTypeFromRedType(redTypeName);
            if (type == typeof(RedBaseClass))
            {
                throw new TypeNotFoundException(redTypeName);
            }

            return(ReadClass(type));
        }
Ejemplo n.º 2
0
        public RedBaseClass ReadClass(Type type)
        {
            var instance = RedTypeManager.Create(type);

            var baseOff    = BaseStream.Position;
            var fieldCount = _reader.ReadUInt16();
            //var unk = _reader.ReadUInt16();
            var fields = BaseStream.ReadStructs <Package04FieldHeader>(fieldCount);

            foreach (var f in fields)
            {
                var varName  = GetStringValue(f.nameID);
                var typeName = GetStringValue(f.typeID);
                var(fieldType, flags) = RedReflection.GetCSTypeFromRedType(typeName);

                var prop = RedReflection.GetPropertyByRedName(type, varName);

                IRedType value;

                BaseStream.Position = baseOff + f.offset;
                if (prop == null)
                {
                    value = Read(fieldType, 0, Flags.Empty);
                    RedReflection.AddDynamicProperty(instance, varName, value);
                }
                else
                {
                    if (fieldType != prop.Type)
                    {
                        var propName = $"{RedReflection.GetRedTypeFromCSType(instance.GetType())}.{varName}";
                        throw new InvalidRTTIException(propName, prop.Type, fieldType);
                    }

                    value = Read(prop.Type, 0, flags);
                    prop.SetValue(instance, value);
                }
            }

            return(instance);
        }
Ejemplo n.º 3
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]);
Ejemplo n.º 4
0
        public bool ReadVariable(RedBaseClass cls)
        {
            var nameId = _reader.ReadUInt16();

            if (nameId == 0)
            {
                return(false);
            }
            var varName = GetStringValue(nameId);

            // Read Type
            var typeId   = _reader.ReadUInt16();
            var typename = GetStringValue(typeId);

            // Read Size
            var sizepos = _reader.BaseStream.Position;
            var size    = _reader.ReadUInt32();

            var(type, flags) = RedReflection.GetCSTypeFromRedType(typename);

            IRedType value;
            var      prop = RedReflection.GetPropertyByRedName(cls.GetType(), varName);

            if (prop == null)
            {
                value = Read(type, size - 4, flags);

                RedReflection.AddDynamicProperty(cls, varName, value);
            }
            else
            {
                value = Read(prop.Type, size - 4, prop.Flags.Clone());

                var typeInfo = RedReflection.GetTypeInfo(cls.GetType());

                var propName = $"{RedReflection.GetRedTypeFromCSType(cls.GetType())}.{varName}";
                if (type != prop.Type)
                {
                    throw new InvalidRTTIException(propName, prop.Type, type);
                }

#if DEBUG
                if (!typeInfo.SerializeDefault && !prop.SerializeDefault && RedReflection.IsDefault(cls.GetType(), varName, value))
                {
                    throw new InvalidParsingException($"Invalid default val for: \"{propName}\"");
                }
#endif

                prop.SetValue(cls, value);
            }

            PostProcess();

            return(true);

            void PostProcess()
            {
                if (value is IRedBufferPointer buf)
                {
                    buf.GetValue().ParentTypes.Add($"{cls.GetType().Name}.{varName}");
                }

                if (value is IRedArray arr)
                {
                    if (typeof(IRedBufferPointer).IsAssignableFrom(arr.InnerType))
                    {
                        foreach (IRedBufferPointer entry in arr)
                        {
                            entry.GetValue().ParentTypes.Add($"{cls.GetType().Name}.{varName}");
                        }
                    }
                }
            }
        }