Beispiel #1
0
        protected object ParseProperty(CR2WBinaryReader br, Type proptype)
        {
            //Basic / Value Types
            switch (proptype.Name)
            {
            case "Byte":              return(br.ReadByte());

            case "UInt16":            return(br.ReadUInt16());

            case "UInt32":            return(br.ReadUInt32());

            case "UInt64":            return(br.ReadUInt64());

            case "SByte":             return(br.ReadSByte());

            case "Int16":             return(br.ReadInt16());

            case "Int32":             return(br.ReadInt32());

            case "Int64":             return(br.ReadInt64());

            case "Boolean":           return(br.ReadBoolean());

            case "Single":            return(br.ReadSingle());

            case "String":            return(br.ReadString());

            case "Double":            return(br.ReadDouble());

            case "CName":             return(br.ReadCName());

            case "CGUID":             return(br.ReadCGUID());

            case "IdTag":             return(br.ReadIdTag());

            case "TagList":           return(br.ReadTagList());

            case "EngineTransform":   return(br.ReadEngineTransform());

            case "EngineQsTransform": return(br.ReadEngineQsTransform());

            case "CDateTime":         return(br.ReadCDateTime());
            }

            //Parse Enumerators
            if (proptype.IsEnum)
            {
                return(br.ReadEnumerator(proptype));
            }

            //Parse Generic Types (Array, Soft, Ptr, Handle)
            if (proptype.IsGenericType)
            {
                var instance = Activator.CreateInstance(proptype);
                var genprop  = proptype.GetTypeInfo().GenericTypeArguments[0];
                if (proptype.GetGenericTypeDefinition() == typeof(Array <>))
                {
                    var length = br.ReadUInt32();
                    for (int i = 0; i < length; i++)
                    {
                        var value = ParseProperty(br, genprop);
                        proptype.GetMethod("Add").Invoke(instance, new[] { value });
                    }
                }
                else if (proptype.GetGenericTypeDefinition() == typeof(Soft <>))
                {
                    var id = br.ReadUInt16() - 1;
                    if (br.resources[id].type != genprop.Name)
                    {
                        throw new InvalidOperationException($"Soft type mismatch. Expected Type: {genprop.Name}. Type Read: {br.resources[id].type}.");
                    }
                    proptype.GetProperty("DepotPath").SetValue(instance, br.resources[id].path);
                    proptype.GetProperty("Flags").SetValue(instance, br.resources[id].flags);
                }
                else if (proptype.GetGenericTypeDefinition() == typeof(Ptr <>))
                {
                    var id = br.ReadUInt32();
                    proptype.GetProperty("Index").SetValue(instance, id);
                }
                else if (proptype.GetGenericTypeDefinition() == typeof(Handle <>))
                {
                    var id = br.ReadInt32();
                    if (id >= 0)
                    {
                        proptype.GetProperty("HandleType").SetValue(instance, EHandleType.ReferenceHandle);
                        proptype.GetProperty("Index").SetValue(instance, id);
                    }
                    else
                    {
                        id *= -1;
                        proptype.GetProperty("HandleType").SetValue(instance, EHandleType.ResourceHandle);
                        proptype.GetProperty("DepotPath").SetValue(instance, br.resources[id - 1].path);
                        proptype.GetProperty("Flags").SetValue(instance, br.resources[id - 1].flags);
                    }
                }
                return(instance);
            }

            //Parse classes
            if (proptype.IsClass || proptype.IsDefined(typeof(REDClassAttribute)))
            {
                var instance = Activator.CreateInstance(proptype);
                ParseClass(br, instance);
                return(instance);
            }

            //Any Unknown Type
            //Should be impossible to reach if all types get covered above.
            return(null);
        }