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);
        }
Beispiel #2
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}");
                        }
                    }
                }
            }
        }