Esempio n. 1
0
 public void Deserialize(BinaryReader reader, PackageFile package)
 {
     Name = new FName();
     Name.Deserialize(reader, package);
     Type = new FName();
     Type.Deserialize(reader, package);
     Size  = reader.ReadInt32();
     Index = reader.ReadInt32();
 }
Esempio n. 2
0
 public void Deserialize(BinaryReader reader, PackageFile package)
 {
     ClassPackage = new FName();
     ClassPackage.Deserialize(reader, package);
     ClassName = new FName();
     ClassName.Deserialize(reader, package);
     PackageRef = new PackageIndex();
     PackageRef.Deserialize(reader, package);
     ObjectName = new FName();
     ObjectName.Deserialize(reader, package);
 }
Esempio n. 3
0
        public void Deserialize(BinaryReader reader, PackageFile package)
        {
            ClassIndex = new PackageIndex();
            ClassIndex.Deserialize(reader, package);
            SuperIndex = new PackageIndex();
            SuperIndex.Deserialize(reader, package);

            if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_TemplateIndex_IN_COOKED_EXPORTS))
            {
                TemplateIndex = new PackageIndex();
                TemplateIndex.Deserialize(reader, package);
            }

            OuterIndex = new PackageIndex();
            OuterIndex.Deserialize(reader, package);

            ObjectName = new FName();
            ObjectName.Deserialize(reader, package);

            ObjectFlags = reader.ReadUInt32();

            SerialSize   = package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_64BIT_EXPORTMAP_SERIALSIZES) ? reader.ReadInt64() : reader.ReadInt32();
            SerialOffset = package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_64BIT_EXPORTMAP_SERIALSIZES) ? reader.ReadInt64() : reader.ReadInt32();

            bForcedExport = reader.ReadInt32();
            bNotForClient = reader.ReadInt32();
            bNotForServer = reader.ReadInt32();

            PackageGuid  = reader.ReadBytes(0x10);
            PackageFlags = reader.ReadUInt32();

            if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_LOAD_FOR_EDITOR_GAME))
            {
                bNotAlwaysLoadedForEditorGame = reader.ReadInt32();
            }

            if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_COOKED_ASSETS_IN_EDITOR_SUPPORT))
            {
                bIsAsset = reader.ReadInt32();
            }

            if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_PRELOAD_DEPENDENCIES_IN_COOKED_EXPORTS))
            {
                FirstExportDependency = reader.ReadInt32();
                SerializationBeforeSerializationDependencies = reader.ReadInt32();
                CreateBeforeSerializationDependencies        = reader.ReadInt32();
                SerializationBeforeCreateDependencies        = reader.ReadInt32();
                CreateBeforeCreateDependencies = reader.ReadInt32();
            }
        }
Esempio n. 4
0
        public object DeserializeValue(Type type, SerializerAttribute settings, BinaryReader reader, PackageFile package, bool isListElement = false)
        {
            switch (type.Name)
            {
            case "String":     // FString
                return(reader.ReadFString());

            case "Byte[]":
                int    sz   = settings?.Size ?? 0;
                byte[] data = reader.ReadBytes(sz);
                return(data);

            case "Boolean":
                return(DeserializeBool(settings, reader, package, isListElement));

            case "Byte":
                return(reader.ReadByte());

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

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

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

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

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

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

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

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

            case "List`1":
                // TArray
                var elementType = type.GetGenericArguments()[0];
                var listType    = typeof(List <>).MakeGenericType(elementType);
                var list        = Activator.CreateInstance(listType) as IList;

                int count = reader.ReadInt32();
                for (int i = 0; i < count; i++)
                {
                    list.Add(DeserializeValue(elementType, settings, reader, package, true));
                }

                return(list);

            case "FName":
                var name = new FName();
                name.Deserialize(reader, package);
                return(name);

            default:
                if (type.IsEnum)
                {
                    var enumType = Enum.GetUnderlyingType(type);
                    return(DeserializeValue(enumType, settings, reader, package));
                }
                if (type.GetInterfaces().Contains(typeof(ISerializable)))
                {
                    var obj = Activator.CreateInstance(type) as ISerializable;
                    obj.Deserialize(reader, package);
                    return(obj);
                }
                break;
            }

            return(null);
        }
Esempio n. 5
0
        public void Deserialize(BinaryReader reader, PackageFile package)
        {
            PropertyTags = new List <PropertyTag>();
            Properties   = new List <ISerializable>();
            while (true)
            {
                var pos  = reader.BaseStream.Position;
                var name = new FName();
                name.Deserialize(reader, package);
                if (name.Value == "None")
                {
                    break;
                }

                reader.BaseStream.Position = pos;

                var tag = new PropertyTag();
                tag.Deserialize(reader, package);
                PropertyTags.Add(tag);

                Type?propertyType;
                if (!PackageFile.KnownTypes.TryGetValue(tag.Type.Value, out propertyType))
                {
                    if (!PackageFile.KnownTypes.TryGetValue("F" + tag.Type.Value, out propertyType))
                    {
                        throw new Exception($"UAsset uses unknown struct type {tag.Type.Value}!");
                    }
                }

                var prop = Activator.CreateInstance(propertyType) as ISerializable;
                prop.Deserialize(reader, package);
                Properties.Add(prop);
            }
            Reserved = reader.ReadUInt32();

            // ObjectProperty data comes after the properties/propertytags section
            // I don't know if any other properties are handled this way, probably not, doing this is likely wrong for 99% of other UE4 properties

            PropertiesData = new Dictionary <FName, ISerializableText>();
            foreach (var prop in Properties)
            {
                if (prop.GetType() != typeof(ObjectProperty))
                {
                    continue;
                }

                var objectProperty = prop as ObjectProperty;

                Type?propertyType;
                if (!PackageFile.KnownTypes.TryGetValue(objectProperty.Value.ImportObject.ObjectName.Value, out propertyType))
                {
                    if (!PackageFile.KnownTypes.TryGetValue("F" + objectProperty.Value.ImportObject.ObjectName.Value, out propertyType))
                    {
                        throw new Exception($"UAsset uses unknown struct type {objectProperty.Value.ImportObject.ObjectName.Value}!");
                    }
                }

                if (propertyType == typeof(FJackDataTableNativizationAsset) || propertyType == typeof(FJackDataTableBlueprintClass))
                {
                    Program.DoFNameCleanup = false; // contains a bunch of unreferenced FNames, can't cleanup properly :(
                }
                if (package.SkipPropertyDataLoad)
                {
                    continue;
                }

                int count = reader.ReadInt32();
                for (int i = 0; i < count; i++)
                {
                    var rowName = new FName();
                    rowName.Deserialize(reader, package);

                    var position = reader.BaseStream.Position;
                    if (propertyType.BaseType.GetInterfaces().Contains(typeof(ISerializableText)))
                    {
                        int structSize = 0;
                        var settings   = propertyType.GetCustomAttribute <SerializerAttribute>();
                        if (settings == null || !settings.NoStructSize)
                        {
                            structSize = reader.ReadInt32();
                            position   = reader.BaseStream.Position;
                        }

                        var propData = Activator.CreateInstance(propertyType) as ISerializableText;
                        propData.Deserialize(reader, package);

                        var length = reader.BaseStream.Position - position;
                        if (structSize != 0 && length != structSize)
                        {
                            throw new Exception($"DataTable read incorrect number of bytes (read {length}, expected {structSize}!)");
                            reader.BaseStream.Position = position + structSize;
                        }

                        PropertiesData.Add(rowName, propData);
                    }
                }
            }
        }