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