Example #1
0
        public FObjectExport(IAssetConverter converter)
        {
            FPackageFileSummary?summ = converter.GetSummary();

            using (BinaryReader br = new BinaryReader(converter.GetAssetStream(), Encoding.UTF8, true))
            {
                this.ClassIndex = br.ReadInt32();
                this.SuperIndex = br.ReadInt32();

                if (summ.GetUE4Version() >= 508)
                {
                    this.TemplateIndex = br.ReadInt32();
                }

                FObjectResource resource = new FObjectResource(converter);
                this.Index      = resource.Index;
                this.ObjectName = resource.ObjectName;

                this.ObjectFlags = (EObjectFlags)br.ReadInt32();

                if (summ.GetUE4Version() >= 511)
                {
                    this.SerialSize   = br.ReadInt64();
                    this.SerialOffset = br.ReadInt64();
                }
                else
                {
                    this.SerialSize   = br.ReadInt32();
                    this.SerialOffset = br.ReadInt32();
                }

                this.ExportFileOffset = SerialOffset - summ.TotalSize;

                this.IsForcedExport = br.ReadInt32() != 0;
                this.IsNotForClient = br.ReadInt32() != 0;
                this.IsNotForServer = br.ReadInt32() != 0;

                this.PackageGuid  = new FGuid(converter.GetAssetStream());
                this.PackageFlags = (EPackageFlags)br.ReadInt32();

                if (summ.GetUE4Version() >= 365)
                {
                    this.IsNotAlwaysLoadedForEditorGame = br.ReadInt32() != 0;
                }

                if (summ.GetUE4Version() >= 485)
                {
                    this.IsAsset = br.ReadInt32() != 0;
                }

                if (summ.GetUE4Version() >= 507)
                {
                    this.FirstExportDependency = br.ReadInt32();
                    this.SerializationBeforeSerializationDependencies = br.ReadInt32();
                    this.CreateBeforeSerializationDependencies        = br.ReadInt32();
                    this.SerializationBeforeCreateDependencies        = br.ReadInt32();
                    this.CreateBeforeCreateDependencies = br.ReadInt32();
                }
            }
        }
Example #2
0
 /// <summary>
 /// Used to safely check whether all of the passed in flags are set.
 /// </summary>
 /// <param name="flagsToCheck">Package flags to check for</param>
 /// <returns>true if all of the passed in flags are set (including no flags passed in), false otherwise</returns>
 public bool HasAllPackagesFlags(EPackageFlags flagsToCheck)
 {
     return(Native_UPackage.HasAllPackagesFlags(Address, flagsToCheck));
 }
Example #3
0
 /// <summary>
 /// Set the specified flags to false. Does not affect any other flags.
 /// </summary>
 /// <param name="newFlags">Package flags to disable</param>
 public void ClearPackageFlags(EPackageFlags newFlags)
 {
     Native_UPackage.ClearPackageFlags(Address, newFlags);
 }
Example #4
0
 /// <summary>
 /// Set the specified flags to true. Does not affect any other flags.
 /// </summary>
 /// <param name="newFlags">Package flags to enable</param>
 public void SetPackageFlags(EPackageFlags newFlags)
 {
     Native_UPackage.SetPackageFlags(Address, newFlags);
 }
Example #5
0
 /// <summary>
 /// Checks whether this object's top-most package has any of the specified flags
 /// </summary>
 /// <param name="checkFlagMask">a bitmask of EPackageFlags values to check for</param>
 /// <returns></returns>
 public bool RootPackageHasAnyFlags(EPackageFlags checkFlagMask)
 {
     return(Native_UObjectBaseUtility.RootPackageHasAnyFlags(Address, checkFlagMask));
 }
        internal FPackageFileSummary(BinaryReader reader)
        {
            bUnversioned           = false;
            CustomVersionContainer = default;

            var Tag = reader.ReadInt32();

            if (Tag != PACKAGE_FILE_TAG && Tag != PACKAGE_FILE_TAG_SWAPPED)
            {
                throw new FileLoadException("Not a UE package");
            }

            // The package has been stored in a separate endianness than the linker expected so we need to force
            // endian conversion. Latent handling allows the PC version to retrieve information about cooked packages.
            if (Tag == PACKAGE_FILE_TAG_SWAPPED)
            {
                // Set proper tag.
                Tag = PACKAGE_FILE_TAG;
                // Toggle forced byte swapping.
                throw new NotImplementedException("Byte swapping for packages not implemented");
            }

            /**
             * The package file version number when this package was saved.
             *
             * Lower 16 bits stores the UE3 engine version
             * Upper 16 bits stores the UE4/licensee version
             * For newer packages this is -7
             *		-2 indicates presence of enum-based custom versions
             *		-3 indicates guid-based custom versions
             *		-4 indicates removal of the UE3 version. Packages saved with this ID cannot be loaded in older engine versions
             *		-5 indicates the replacement of writing out the "UE3 version" so older versions of engine can gracefully fail to open newer packages
             *		-6 indicates optimizations to how custom versions are being serialized
             *		-7 indicates the texture allocation info has been removed from the summary
             */
            var LegacyFileVersion = reader.ReadInt32();

            if (LegacyFileVersion < 0)      // means we have modern version numbers
            {
                if (LegacyFileVersion < -7) // CurrentLegacyFileVersion
                {
                    // we can't safely load more than this because the legacy version code differs in ways we can not predict.
                    // Make sure that the linker will fail to load with it.
                    throw new FileLoadException("Can't load legacy UE3 file");
                }

                if (LegacyFileVersion != -4)
                {
                    reader.BaseStream.Position += 4; // LegacyUE3Version (int32)
                }
                FileVersionUE4         = (EUnrealEngineObjectUE4Version)reader.ReadInt32();
                FileVersionLicenseeUE4 = (EUnrealEngineObjectLicenseeUE4Version)reader.ReadInt32();

                if (LegacyFileVersion <= -2)
                {
                    CustomVersionContainer = new FCustomVersionContainer(reader);
                }

                if (FileVersionUE4 != 0 && FileVersionLicenseeUE4 != 0)
                {
                    // this file is unversioned, remember that, then use current versions
                    bUnversioned = true;

                    // set the versions to latest here, etc.
                }
            }
            else
            {
                // This is probably an old UE3 file, make sure that the linker will fail to load with it.
                throw new FileLoadException("Can't load legacy UE3 file");
            }

            TotalHeaderSize = reader.ReadInt32();
            FolderName      = reader.ReadFString();
            PackageFlags    = (EPackageFlags)reader.ReadUInt32();
            NameCount       = reader.ReadInt32();
            NameOffset      = reader.ReadInt32();

            // only serialize when file version is past VER_UE4_SERIALIZE_TEXT_IN_PACKAGES
            GatherableTextDataCount  = reader.ReadInt32();
            GatherableTextDataOffset = reader.ReadInt32();

            ExportCount   = reader.ReadInt32();
            ExportOffset  = reader.ReadInt32();
            ImportCount   = reader.ReadInt32();
            ImportOffset  = reader.ReadInt32();
            DependsOffset = reader.ReadInt32();

            // only serialize when file version is past VER_UE4_ADD_STRING_ASSET_REFERENCES_MAP
            SoftPackageReferencesCount  = reader.ReadInt32();
            SoftPackageReferencesOffset = reader.ReadInt32();

            // only serialize when file version is past VER_UE4_ADDED_SEARCHABLE_NAMES
            SearchableNamesOffset = reader.ReadInt32();

            ThumbnailTableOffset = reader.ReadInt32();
            Guid = new FGuid(reader);

            {
                var GenerationCount = reader.ReadInt32();
                if (GenerationCount > 0)
                {
                    Generations = new FGenerationInfo[GenerationCount];
                    for (int i = 0; i < Generations.Length; i++)
                    {
                        Generations[i] = new FGenerationInfo(reader);
                    }
                }
                else
                {
                    Generations = null;
                }
            }

            // only serialize when file version is past VER_UE4_ENGINE_VERSION_OBJECT
            SavedByEngineVersion = new FEngineVersion(reader);

            // only serialize when file version is past VER_UE4_PACKAGE_SUMMARY_HAS_COMPATIBLE_ENGINE_VERSION
            CompatibleWithEngineVersion = new FEngineVersion(reader);

            CompressionFlags = (ECompressionFlags)reader.ReadUInt32();
            if (CompressionFlags != ECompressionFlags.COMPRESS_None) // No support for deprecated compression
            {
                throw new FileLoadException($"Incompatible compression flags ({(uint)CompressionFlags})");
            }

            if (reader.ReadTArray(() => new FCompressedChunk(reader)).Length != 0) // "CompressedChunks"
            {
                throw new FileLoadException("Package level compression is enabled");
            }

            PackageSource = reader.ReadUInt32();
            reader.ReadTArray(() => reader.ReadFString()); // "AdditionalPackagesToCook"

            if (LegacyFileVersion > -7)
            {
                // We haven't used texture allocation info for ages and it's no longer supported anyway
                if (reader.ReadInt32() != 0) // "NumTextureAllocations"
                {
                    throw new FileLoadException("Can't load legacy UE3 file");
                }
            }

            AssetRegistryDataOffset = reader.ReadInt32();
            BulkDataStartOffset     = reader.ReadInt64();

            // only serialize when file version is past VER_UE4_WORLD_LEVEL_INFO
            WorldTileInfoDataOffset = reader.ReadInt32();

            // only serialize when file version is past VER_UE4_CHANGED_CHUNKID_TO_BE_AN_ARRAY_OF_CHUNKIDS
            ChunkIDs = reader.ReadTArray(() => reader.ReadInt32());

            // only serialize when file version is past VER_UE4_PRELOAD_DEPENDENCIES_IN_COOKED_EXPORTS
            PreloadDependencyCount  = reader.ReadInt32();
            PreloadDependencyOffset = reader.ReadInt32();
        }
        internal FPackageFileSummary(FArchive Ar)
        {
            Tag = Ar.Read <uint>();

            /*
             * The package file version number when this package was saved.
             *
             * Lower 16 bits stores the UE3 engine version
             * Upper 16 bits stores the UE4/licensee version
             * For newer packages this is -7
             *		-2 indicates presence of enum-based custom versions
             *		-3 indicates guid-based custom versions
             *		-4 indicates removal of the UE3 version. Packages saved with this ID cannot be loaded in older engine versions
             *		-5 indicates the replacement of writing out the "UE3 version" so older versions of engine can gracefully fail to open newer packages
             *		-6 indicates optimizations to how custom versions are being serialized
             *		-7 indicates the texture allocation info has been removed from the summary
             *		-8 indicates that the UE5 version has been added to the summary
             */
            const int CurrentLegacyFileVersion = -8;
            var       legacyFileVersion        = CurrentLegacyFileVersion;

            if (Tag == PACKAGE_FILE_TAG_ONE) // SOD2, "one"
            {
                Ar.Game                = EGame.GAME_StateOfDecay2;
                Ar.Ver                 = Ar.Game.GetVersion();
                legacyFileVersion      = Ar.Read <int>(); // seems to be always int.MinValue
                bUnversioned           = true;
                FileVersionUE          = Ar.Ver;
                CustomVersionContainer = Array.Empty <FCustomVersion>();
                FolderName             = "None";
                PackageFlags           = EPackageFlags.PKG_FilterEditorOnly;
                goto afterPackageFlags;
            }

            if (Tag != PACKAGE_FILE_TAG && Tag != PACKAGE_FILE_TAG_SWAPPED)
            {
                throw new ParserException($"Invalid uasset magic: 0x{Tag:X8} != 0x{PACKAGE_FILE_TAG:X8}");
            }

            // The package has been stored in a separate endianness than the linker expected so we need to force
            // endian conversion. Latent handling allows the PC version to retrieve information about cooked packages.
            if (Tag == PACKAGE_FILE_TAG_SWAPPED)
            {
                // Set proper tag.
                //Tag = PACKAGE_FILE_TAG;
                // Toggle forced byte swapping.
                throw new ParserException("Byte swapping for packages not supported");
            }

            legacyFileVersion = Ar.Read <int>();

            if (legacyFileVersion < 0) // means we have modern version numbers
            {
                if (legacyFileVersion < CurrentLegacyFileVersion)
                {
                    // we can't safely load more than this because the legacy version code differs in ways we can not predict.
                    // Make sure that the linker will fail to load with it.
                    FileVersionUE.Reset();
                    FileVersionLicenseeUE = 0;
                    throw new ParserException("Can't load legacy UE3 file");
                }

                if (legacyFileVersion != -4)
                {
                    var legacyUE3Version = Ar.Read <int>();
                }

                FileVersionUE.FileVersionUE4 = Ar.Read <int>();

                if (legacyFileVersion <= -8)
                {
                    FileVersionUE.FileVersionUE5 = Ar.Read <int>();
                }

                FileVersionLicenseeUE  = Ar.Read <EUnrealEngineObjectLicenseeUEVersion>();
                CustomVersionContainer = legacyFileVersion <= -2 ? Ar.ReadArray <FCustomVersion>() : Array.Empty <FCustomVersion>();

                if (Ar.Versions.CustomVersions == null && CustomVersionContainer.Length > 0)
                {
                    Ar.Versions.CustomVersions = CustomVersionContainer.ToList();
                }

                if (FileVersionUE.FileVersionUE4 == 0 && FileVersionUE.FileVersionUE5 == 0 && FileVersionLicenseeUE == 0)
                {
                    // this file is unversioned, remember that, then use current versions
                    bUnversioned          = true;
                    FileVersionUE         = Ar.Ver;
                    FileVersionLicenseeUE = EUnrealEngineObjectLicenseeUEVersion.VER_LIC_AUTOMATIC_VERSION;
                }
                else
                {
                    bUnversioned = false;
                    // Only apply the version if an explicit version is not set
                    if (!Ar.Versions.bExplicitVer)
                    {
                        Ar.Ver = FileVersionUE;
                    }
                }
            }
            else
            {
                // This is probably an old UE3 file, make sure that the linker will fail to load with it.
                throw new ParserException("Can't load legacy UE3 file");
            }

            TotalHeaderSize = Ar.Read <int>();
            FolderName      = Ar.ReadFString();
            PackageFlags    = Ar.Read <EPackageFlags>();

            /*if (PackageFlags.HasFlag(EPackageFlags.PKG_FilterEditorOnly))
             * {
             *  TODO Ar.SetFilterEditorOnly(true);
             * }*/

afterPackageFlags:
            NameCount  = Ar.Read <int>();
            NameOffset = Ar.Read <int>();

            if (!PackageFlags.HasFlag(EPackageFlags.PKG_FilterEditorOnly))
            {
                if (FileVersionUE >= EUnrealEngineObjectUE4Version.ADDED_PACKAGE_SUMMARY_LOCALIZATION_ID)
                {
                    LocalizationId = Ar.ReadFString();
                }
            }

            if (FileVersionUE >= EUnrealEngineObjectUE4Version.SERIALIZE_TEXT_IN_PACKAGES)
            {
                GatherableTextDataCount  = Ar.Read <int>();
                GatherableTextDataOffset = Ar.Read <int>();
            }

            ExportCount   = Ar.Read <int>();
            ExportOffset  = Ar.Read <int>();
            ImportCount   = Ar.Read <int>();
            ImportOffset  = Ar.Read <int>();
            DependsOffset = Ar.Read <int>();

            if (FileVersionUE < EUnrealEngineObjectUE4Version.OLDEST_LOADABLE_PACKAGE || FileVersionUE > EUnrealEngineObjectUE4Version.AUTOMATIC_VERSION)
            {
                Generations = Array.Empty <FGenerationInfo>();
                ChunkIds    = Array.Empty <int>();
                return; // we can't safely load more than this because the below was different in older files.
            }

            if (FileVersionUE >= EUnrealEngineObjectUE4Version.ADD_STRING_ASSET_REFERENCES_MAP)
            {
                SoftPackageReferencesCount  = Ar.Read <int>();
                SoftPackageReferencesOffset = Ar.Read <int>();
            }

            if (FileVersionUE >= EUnrealEngineObjectUE4Version.ADDED_SEARCHABLE_NAMES)
            {
                SearchableNamesOffset = Ar.Read <int>();
            }

            ThumbnailTableOffset = Ar.Read <int>();

            if (Ar.Game == EGame.GAME_Valorant)
            {
                Ar.Position += 8;
            }

            Guid = Ar.Read <FGuid>();

            if (!PackageFlags.HasFlag(EPackageFlags.PKG_FilterEditorOnly))
            {
                if (FileVersionUE >= EUnrealEngineObjectUE4Version.ADDED_PACKAGE_OWNER)
                {
                    PersistentGuid = Ar.Read <FGuid>();
                }
                else
                {
                    // By assigning the current package guid, we maintain a stable persistent guid, so we can reference this package even if it wasn't resaved.
                    PersistentGuid = Guid;
                }

                // The owner persistent guid was added in VER_UE4_ADDED_PACKAGE_OWNER but removed in the next version VER_UE4_NON_OUTER_PACKAGE_IMPORT
                if (FileVersionUE >= EUnrealEngineObjectUE4Version.ADDED_PACKAGE_OWNER && FileVersionUE < EUnrealEngineObjectUE4Version.NON_OUTER_PACKAGE_IMPORT)
                {
                    var ownerPersistentGuid = Ar.Read <FGuid>();
                }
            }

            Generations = Ar.ReadArray <FGenerationInfo>();

            if (FileVersionUE >= EUnrealEngineObjectUE4Version.ENGINE_VERSION_OBJECT)
            {
                SavedByEngineVersion = new FEngineVersion(Ar);
                FixCorruptEngineVersion(FileVersionUE, SavedByEngineVersion);
            }
            else
            {
                var engineChangelist = Ar.Read <int>();

                if (engineChangelist != 0)
                {
                    SavedByEngineVersion = new FEngineVersion(4, 0, 0, (uint)engineChangelist, string.Empty);
                }
            }

            if (FileVersionUE >= EUnrealEngineObjectUE4Version.PACKAGE_SUMMARY_HAS_COMPATIBLE_ENGINE_VERSION)
            {
                CompatibleWithEngineVersion = new FEngineVersion(Ar);
                FixCorruptEngineVersion(FileVersionUE, CompatibleWithEngineVersion);
            }
            else
            {
                CompatibleWithEngineVersion = SavedByEngineVersion;
            }
Example #8
0
 public bool HasFlags(EPackageFlags flags) => Summary.PackageFlags.HasFlag(flags);
        internal FPackageFileSummary(FAssetArchive Ar)
        {
            Tag = Ar.Read <uint>();

            if (Tag == PACKAGE_FILE_TAG_ONE) // SOD2, "one"
            {
                Ar.Game = EGame.GAME_SOD2;
                Ar.Ver  = Ar.Game.GetVersion();
                var legacyFileVersion = Ar.Read <int>(); // seems to be always int.MinValue
                bUnversioned           = true;
                FileVersionUE4         = (EUnrealEngineObjectUE4Version)Ar.Ver;
                CustomVersionContainer = Array.Empty <FCustomVersion>();
                FolderName             = "None";
                PackageFlags           = EPackageFlags.PKG_FilterEditorOnly;
                goto afterPackageFlags;
            }

            if (Tag != PACKAGE_FILE_TAG && Tag != PACKAGE_FILE_TAG_SWAPPED)
            {
                throw new ParserException($"Invalid uasset magic: 0x{Tag:X8} != 0x{PACKAGE_FILE_TAG:X8}");
            }

            // The package has been stored in a separate endianness than the linker expected so we need to force
            // endian conversion. Latent handling allows the PC version to retrieve information about cooked packages.
            if (Tag == PACKAGE_FILE_TAG_SWAPPED)
            {
                // Set proper tag.
                //Tag = PACKAGE_FILE_TAG;
                // Toggle forced byte swapping.
                throw new ParserException("Byte swapping for packages not supported");
            }

            /*
             * The package file version number when this package was saved.
             *
             * Lower 16 bits stores the UE3 engine version
             * Upper 16 bits stores the UE4/licensee version
             * For newer packages this is -7
             *		-2 indicates presence of enum-based custom versions
             *		-3 indicates guid-based custom versions
             *		-4 indicates removal of the UE3 version. Packages saved with this ID cannot be loaded in older engine versions
             *		-5 indicates the replacement of writing out the "UE3 version" so older versions of engine can gracefully fail to open newer packages
             *		-6 indicates optimizations to how custom versions are being serialized
             *		-7 indicates the texture allocation info has been removed from the summary
             */
            const int CurrentLegacyFileVersion = -7;

            LegacyFileVersion = Ar.Read <int>();

            if (LegacyFileVersion < 0) // means we have modern version numbers
            {
                if (LegacyFileVersion < CurrentLegacyFileVersion)
                {
                    // we can't safely load more than this because the legacy version code differs in ways we can not predict.
                    // Make sure that the linker will fail to load with it.
                    throw new ParserException("Can't load legacy UE3 file");
                }

                LegacyUE3Version       = LegacyFileVersion != -4 ? Ar.Read <LegacyUE3Version>() : 0;
                FileVersionUE4         = Ar.Read <EUnrealEngineObjectUE4Version>();
                FileVersionLicenseUE4  = Ar.Read <EUnrealEngineObjectLicenseeUE4Version>();
                CustomVersionContainer = LegacyFileVersion <= -2 ? Ar.ReadArray <FCustomVersion>() : Array.Empty <FCustomVersion>();

                if (Ar.Versions.CustomVersions == null && CustomVersionContainer.Length > 0)
                {
                    Ar.Versions.CustomVersions = CustomVersionContainer.ToList();
                }

                if (FileVersionUE4 == 0 && FileVersionLicenseUE4 == 0)
                {
                    // this file is unversioned, remember that, then use current versions
                    bUnversioned = true;
                    // set the versions to latest here, etc.
                    FileVersionUE4        = (EUnrealEngineObjectUE4Version)Ar.Ver;
                    FileVersionLicenseUE4 = EUnrealEngineObjectLicenseeUE4Version.VER_LIC_AUTOMATIC_VERSION;
                }
                else
                {
                    bUnversioned = false;
                    // Only apply the version if an explicit version is not set
                    if (Ar.Ver == UE4Version.VER_UE4_DETERMINE_BY_GAME)
                    {
                        Ar.Ver = (UE4Version)FileVersionUE4;
                    }
                }
            }
            else
            {
                // This is probably an old UE3 file, make sure that the linker will fail to load with it.
                throw new ParserException("Can't load legacy UE3 file");
            }

            TotalHeaderSize = Ar.Read <int>();
            FolderName      = Ar.ReadFString();
            PackageFlags    = Ar.Read <EPackageFlags>();

afterPackageFlags:
            NameCount  = Ar.Read <int>();
            NameOffset = Ar.Read <int>();

            LocalizationId = !PackageFlags.HasFlag(EPackageFlags.PKG_FilterEditorOnly) && FileVersionUE4 >= VER_UE4_ADDED_PACKAGE_SUMMARY_LOCALIZATION_ID?Ar.ReadFString() : null;

            if (FileVersionUE4 >= VER_UE4_SERIALIZE_TEXT_IN_PACKAGES)
            {
                GatherableTextDataCount  = Ar.Read <int>();
                GatherableTextDataOffset = Ar.Read <int>();
            }
            else
            {
                GatherableTextDataCount = GatherableTextDataOffset = 0;
            }

            ExportCount   = Ar.Read <int>();
            ExportOffset  = Ar.Read <int>();
            ImportCount   = Ar.Read <int>();
            ImportOffset  = Ar.Read <int>();
            DependsOffset = Ar.Read <int>();

            if (FileVersionUE4 is < VER_UE4_OLDEST_LOADABLE_PACKAGE or > VER_UE4_AUTOMATIC_VERSION)
            {
                SoftPackageReferencesCount  = 0;
                SoftPackageReferencesOffset = 0;
                SearchableNamesOffset       = 0;
                ThumbnailTableOffset        = 0;
                Guid                        = default;
                Generations                 = Array.Empty <FGenerationInfo>();
                SavedByEngineVersion        = default;
                CompatibleWithEngineVersion = default;
                CompressionFlags            = COMPRESS_None;
                PackageSource               = 0;
                AssetRegistryDataOffset     = 0;
                WorldTileInfoDataOffset     = 0;
                ChunkIds                    = Array.Empty <int>();
                AdditionalPackagesToCook    = Array.Empty <string>();
                CompressedChunks            = Array.Empty <FCompressedChunk>();
                PreloadDependencyCount      = 0;
                PreloadDependencyOffset     = 0;
                return; // we can't safely load more than this because the below was different in older files.
            }

            if (FileVersionUE4 >= VER_UE4_ADD_STRING_ASSET_REFERENCES_MAP)
            {
                SoftPackageReferencesCount  = Ar.Read <int>();
                SoftPackageReferencesOffset = Ar.Read <int>();
            }
            else
            {
                SoftPackageReferencesCount = SoftPackageReferencesOffset = 0;
            }

            SearchableNamesOffset = FileVersionUE4 >= VER_UE4_ADDED_SEARCHABLE_NAMES?Ar.Read <int>() : 0;

            ThumbnailTableOffset = Ar.Read <int>();

            if (Ar.Game == EGame.GAME_VALORANT)
            {
                Ar.Position += 8;
            }

            Guid = Ar.Read <FGuid>();

            Generations = Ar.ReadArray <FGenerationInfo>();

            if (FileVersionUE4 >= VER_UE4_ENGINE_VERSION_OBJECT)
            {
                SavedByEngineVersion = new FEngineVersion(Ar);

                if (FileVersionUE4 < VER_UE4_CORRECT_LICENSEE_FLAG &&
                    SavedByEngineVersion.Major == 4 &&
                    SavedByEngineVersion.Minor == 26 &&
                    SavedByEngineVersion.Patch == 0 &&
                    SavedByEngineVersion.Changelist >= 12740027 &&
                    SavedByEngineVersion.IsLicenseeVersion())
                {
                    SavedByEngineVersion.Set(4, 26, 0, SavedByEngineVersion.Changelist, SavedByEngineVersion.Branch);
                }
            }
            else
            {
                var engineChangelist = Ar.Read <int>();
                SavedByEngineVersion = engineChangelist == 0 ? null : new FEngineVersion(4, 0, 0, (uint)engineChangelist, string.Empty);
            }

            CompatibleWithEngineVersion = FileVersionUE4 >= VER_UE4_PACKAGE_SUMMARY_HAS_COMPATIBLE_ENGINE_VERSION ? new FEngineVersion(Ar) : SavedByEngineVersion;
Example #10
0
        private FPackageFileSummary(Stream stream)
        {
            if (stream.Length < 32)
            {
                Console.WriteLine("Failed to read Package File Summary - File too small");
                return;
            }

            using (BinaryReader br = new BinaryReader(stream, Encoding.UTF8, true))
            {
                this._tag = br.ReadUInt32();
                if (this._tag != PACKAGE_FILE_TAG)
                {
                    throw new InvalidDataException("The file contains unrecognizable data, check that it is of the expected type.");
                }

                this._legacyFileVersion = br.ReadInt32();
                if (this._legacyFileVersion < 0)
                {
                    if (this._legacyFileVersion < CURRENT_LEGACY_FILE_VERSION)
                    {
                        this._fileVersionUE4         = 0;
                        this._fileVersionLicenseeUE4 = 0;
                        return;
                    }

                    if (this._legacyFileVersion != -4)
                    {
                        this._legacyUE3Version = br.ReadInt32();
                    }

                    this._fileVersionUE4         = br.ReadInt32();
                    this._fileVersionLicenseeUE4 = br.ReadInt32();

                    if (this._legacyFileVersion <= -2)
                    {
                        this.CustomVersion = new FCustomVersionContainer(stream);
                    }

                    if (this._fileVersionUE4 == 0 && this._fileVersionLicenseeUE4 == 0)
                    {
                        this.IsUnversioned   = true;
                        this._fileVersionUE4 = 516;
                        CustomVersion        = new FCustomVersionContainer();
                    }
                }
                else
                {
                    this._fileVersionUE4         = 0;
                    this._fileVersionLicenseeUE4 = 0;
                }

                this.TotalSize    = br.ReadInt32();
                this.FolderName   = new FString(stream);
                this.PackageFlags = (EPackageFlags)br.ReadInt32();

                if (this.PackageFlags.HasFlag(EPackageFlags.PKG_FilterEditorOnly))
                {
                    this._isFilterEditorOnly = true;
                }

                this.NameCount  = br.ReadInt32();
                this.NameOffset = br.ReadInt32();

                if (this._fileVersionUE4 >= 459)
                {
                    this.GathereableTextDataCount = br.ReadInt32();
                    this.GatherableTextDataOffset = br.ReadInt32();
                }

                this.ExportCount  = br.ReadInt32();
                this.ExportOffset = br.ReadInt32();

                this.ImportCount  = br.ReadInt32();
                this.ImportOffset = br.ReadInt32();

                this.DependsOffset = br.ReadInt32();

                if (this._fileVersionUE4 < 214 || this._fileVersionUE4 > 516)
                {
                    Console.WriteLine($"Unsupported Package Version '{this._fileVersionUE4}'. Can not read further.");
                    return;
                }

                if (this._fileVersionUE4 >= 384)
                {
                    this.SoftPackageReferencesCount  = br.ReadInt32();
                    this.SoftPackageReferencesOffset = br.ReadInt32();
                }

                if (this._fileVersionUE4 >= 510)
                {
                    this.SearchableNamesOffset = br.ReadInt32();
                }

                this.ThumbnailTableOffset = br.ReadInt32();

                this.Guid = new FGuid(stream);
                int generationCount = br.ReadInt32();
                this.Generations = new FGenerationInfo[generationCount];
                for (int i = 0; i < generationCount; i++)
                {
                    this.Generations[i] = new FGenerationInfo(stream);
                }

                if (this._fileVersionUE4 >= 336)
                {
                    this.SavedByEngineVersion = new FEngineVersion(stream);
                }
                else
                {
                    this.SavedByEngineVersion = new FEngineVersion();
                }

                if (this._fileVersionUE4 >= 444)
                {
                    this.CompatibleWithEngineVersion = new FEngineVersion(stream);
                }
                else
                {
                    this.CompatibleWithEngineVersion = this.SavedByEngineVersion;
                }

                this.CompressionFlags = (ECompressionFlags)br.ReadInt32();

                if (((int)this.CompressionFlags & (int)~(CompressionFlagMasks.COMPRESSION_FLAGS_TYPE_MASK | CompressionFlagMasks.COMPRESSION_FLAGS_OPTIONS_MASK)) != 0)
                {
                    Console.WriteLine("Invalid Compression Flags");
                    return;
                }

                int compressedChunkCount = br.ReadInt32();
                if (compressedChunkCount > 0)
                {
                    // This file has package level compression, we won't load it.
                    Console.WriteLine("Failed to read package file summary, the file has package level compression (and is probably cooked). These old files cannot be loaded.");
                    this._fileVersionUE4 = 213;
                    return; // We can't safely load more than this because we just changed the version to something it is not.
                }

                this.PackageSource = br.ReadInt32();

                int       numAddPackages           = br.ReadInt32();
                FString[] AdditionalPackagesToCook = new FString[numAddPackages];
                for (int i = 0; i < numAddPackages; i++)
                {
                    AdditionalPackagesToCook[i] = new FString(stream);
                }

                if (this._legacyFileVersion > -7)
                {
                    // Read unused texture allocation info
                    br.ReadInt32();
                }

                this.AssetRegistryDataOffset = br.ReadInt32();
                this.BulkDataStartOffset     = br.ReadInt64();

                if (this._fileVersionUE4 >= 224)
                {
                    this.WorldTileInfoDataOffset = br.ReadInt32();
                }

                if (this._fileVersionUE4 >= 326)
                {
                    int numChunks = br.ReadInt32();
                    this.ChunkIds = new List <int>();
                    for (int i = 0; i < numChunks; i++)
                    {
                        this.ChunkIds.Add(br.ReadInt32());
                    }
                }
                else if (this._fileVersionUE4 >= 278)
                {
                    this.ChunkIds = new List <int>()
                    {
                        br.ReadInt32()
                    };
                }

                this.PreloadDependencyCount  = -1;
                this.PreloadDependencyOffset = 0;
            }
        }