Example #1
0
 def __init__(self, reader: BinaryStream):
     self.Protocol = reader.readFString()
     self.Host = reader.readFString()
     self.Map = reader.readFString()
     self.Portal = reader.readFString()
     self.Op = reader.readTArray(reader.readFString)
     self.Port = reader.readInt32()
     self.Valid = reader.readInt32()
Example #2
0
    def __init__(self, reader: BinaryStream):
        self.TableNamespace = reader.readFString()

        self.KeysToMetadata = {}

        NumEntries = reader.readInt32()
        for i in range(NumEntries):
            key = reader.readFString()
            text = reader.readFString()
            self.KeysToMetadata[key] = text
Example #3
0
    def __init__(self, reader: BinaryStream, Case_insensitive: bool):
        self.MountPoint = reader.readFString()

        if self.MountPoint.startswith("../../.."):
            self.MountPoint = self.MountPoint[8::]

        if Case_insensitive:
            self.MountPoint = self.MountPoint.lower()

        self.DirectoryEntries = reader.readTArray(FIoDirectoryIndexEntry,
                                                  reader)
        self.FileEntries = reader.readTArray(FIoFileIndexEntry, reader)
        self.StringTable = reader.readTArray(reader.readFString)
    def deserialize(self, reader: BinaryStream, ubulk: BinaryStream,
                    ubulkOffset: int):
        self.SizeX = reader.readInt32()
        self.SizeY = reader.readInt32()
        self.NumSlices = reader.readInt32()  # 1 for normal textures
        self.PixelFormat = EPixelFormat[reader.readFString()]

        self.FirstMipToSerialize = reader.readInt32() - 1
        self.Mips = reader.readTArray_W_Arg(FTexture2DMipMap, reader, ubulk,
                                            ubulkOffset)
        if reader.game >= GAME_UE4(23):
            self.bIsVirtual = reader.readInt32() != 0
            if self.bIsVirtual:
                raise NotImplementedError(
                    "Virtual Textures ar not Not implemented")
Example #5
0
 def __init__(self, reader: BinaryStream) -> None:
     self.Major = reader.readUInt16()
     self.Minor = reader.readUInt16()
     self.Patch = reader.readUInt16()
     self.Changelist = reader.readUInt32()
     self.Branch = reader.readFString()
Example #6
0
 def __init__(self, reader: BinaryStream) -> None:
     self.Namespace = reader.readFString() or ""
     self.Key = reader.readFString() or ""
     self.SourceString = reader.readFString()
Example #7
0
 def __init__(self, reader: BinaryStream) -> None:
     self.position = reader.base_stream.tell()
     self.Value = reader.readFString()
 def __init__(self, reader: BinaryStream) -> None:
     self.ObjectId = FUniqueObjectGuid(reader)
     self.ObjectPath = reader.readFString()
Example #9
0
    def __init__(self, reader: BinaryStream) -> None:
        Tag = reader.readUInt32()
        if Tag != PACKAGE_FILE_TAG and Tag != PACKAGE_FILE_TAG_SWAPPED:
            raise InvalidMagic("Not a UE package")

        if Tag == PACKAGE_FILE_TAG_SWAPPED:
            raise NotImplementedError(
                "Byte swapping for packages is not implemented")

        LegacyFileVersion = reader.readInt32()
        if LegacyFileVersion < 0:
            if LegacyFileVersion < -7:
                raise ParserException("Can not load UE3 packages.")
            if LegacyFileVersion != -4:
                reader.readInt32()  # VersionUE3

            version = reader.readInt32()
            self.FileVersionUE4 = EUnrealEngineObjectUE4Version(
                version)  # version

            self.FileVersionLicenseeUE4 = EUnrealEngineObjectLicenseeUE4Version(
                reader.readInt32())  # Licensee Version
            if LegacyFileVersion <= -2:
                self.CustomVersionContainer = FCustomVersionContainer(reader)

            if self.FileVersionUE4.value != 0 and self.FileVersionLicenseeUE4.value != 0:
                self.bUnversioned = True
        else:
            raise ParserException("Can not load UE3 packages.")

        self.TotalHeaderSize = reader.readInt32()
        self.FolderName = reader.readFString()

        self.PackageFlags = reader.readUInt32()
        with suppress(ValueError):
            self.PackageFlags = EPackageFlags(self.PackageFlags)

        self.NameCount = reader.readInt32()
        self.NameOffset = reader.readInt32()

        if self.FileVersionUE4.value >= EUnrealEngineObjectUE4Version.VER_UE4_ADDED_PACKAGE_SUMMARY_LOCALIZATION_ID.value:
            self.LocalizationId = reader.readFString()

        if self.FileVersionUE4.value >= EUnrealEngineObjectUE4Version.VER_UE4_SERIALIZE_TEXT_IN_PACKAGES.value or self.FileVersionUE4.value == 0:
            self.GatherableTextDataCount = reader.readInt32()
            self.GatherableTextDataOffset = reader.readInt32()

        self.ExportCount = reader.readInt32()
        self.ExportOffset = reader.readInt32()
        self.ImportCount = reader.readInt32()
        self.ImportOffset = reader.readInt32()
        self.DependsOffset = reader.readInt32()
        if self.FileVersionUE4.value >= EUnrealEngineObjectUE4Version.VER_UE4_ADD_STRING_ASSET_REFERENCES_MAP.value or self.FileVersionUE4.value == 0:
            self.SoftPackageReferencesCount = reader.readInt32()
            self.SoftPackageReferencesOffset = reader.readInt32()

        if self.FileVersionUE4.value >= EUnrealEngineObjectUE4Version.VER_UE4_ADDED_SEARCHABLE_NAMES.value or self.FileVersionUE4.value == 0:
            self.SearchableNamesOffset = reader.readInt32()

        self.ThumbnailTableOffset = reader.readInt32()
        self.Guid = FGuid(reader)

        if reader.game == EUEVersion.GAME_VALORANT:
            reader.readInt64()  # valorant

        self.GenerationCount = reader.readInt32()
        self.Generations = []
        if self.GenerationCount > 0:
            for _ in range(self.GenerationCount):
                self.Generations.append(FGenerationInfo(reader))

        if self.FileVersionUE4.value >= EUnrealEngineObjectUE4Version.VER_UE4_ENGINE_VERSION_OBJECT.value or self.FileVersionUE4.value == 0:
            self.SavedByEngineVersion = FEngineVersion(reader)

        if self.GetFileVersionUE4(
        ).value >= EUnrealEngineObjectUE4Version.VER_UE4_PACKAGE_SUMMARY_HAS_COMPATIBLE_ENGINE_VERSION.value or self.FileVersionUE4.value == 0:
            self.CompatibleWithEngineVersion = FEngineVersion(reader)

        self.CompressionFlags = ECompressionFlags(reader.readUInt32())
        if self.CompressionFlags.name != "COMPRESS_None":
            raise ParserException(
                f"Incompatible compression flags {self.CompressionFlags.name}")

        self.CompressedChunks: List[FCompressedChunk] = reader.readTArray(
            FCompressedChunk)
        if len(self.CompressedChunks) != 0:  # "CompressedChunks"
            raise ParserException("Package level compression is enabled")

        self.PackageSource = reader.readUInt32()
        self.AdditionalPackagesToCook = reader.readTArray(
            reader.readFString)  # AdditionalPackagesToCook

        if LegacyFileVersion > -7:
            if reader.readInt32() != 0:  # "NumTextureAllocations"
                raise ParserException("Can't load legacy UE3 file")

        # if reader.Ver >= VER_UE4_ASSET_REGISTRY_TAGS
        self.AssetRegistryDataOffset = reader.readInt32()

        self.BulkDataStartOffset = reader.readInt64()
        self.WorldTileInfoDataOffset = reader.readInt32()
        self.ChunkIDs = reader.readTArray(reader.readInt32)
        self.PreloadDependencyCount = reader.readInt32()
        self.PreloadDependencyOffset = reader.readInt32()
Example #10
0
 def __init__(self, reader: BinaryStream) -> None:
     if reader.readBool():
         self.CultureInvariantString = reader.readFString()
    def __init__(self, reader: BinaryStream) -> None:
        self.Entries = {}
        magic = FGuid(reader)

        VersionNumber = ELocResVersion.Legacy
        if magic == self.LocResMagic:
            VersionNumber = ELocResVersion(reader.readByteToInt())
        else:
            reader.seek(0)

        if VersionNumber > ELocResVersion.Latest:
            raise ParserException(
                f"LocRes is too new to be loaded (File Version: {VersionNumber.value}, Loader Version: {ELocResVersion.Latest.value})"
            )

        LocalizedStringArray: List[FTextLocalizationResourceString] = []
        if VersionNumber >= ELocResVersion.Compact:
            LocalizedStringArrayOffset = -1
            LocalizedStringArrayOffset = reader.readInt64()
            CurrentFileOffset = reader.tell()
            reader.seek(LocalizedStringArrayOffset, 0)

            if LocalizedStringArrayOffset != -1:
                if VersionNumber >= ELocResVersion.Optimized_CRC32:
                    LocalizedStringArray = reader.readTArray_W_Arg(
                        FTextLocalizationResourceString, reader)
                    reader.seek(CurrentFileOffset, 0)
            else:
                TmpLocalizedStringArray: List[str]
                TmpLocalizedStringArray = reader.readTArray(reader.readFString)
                reader.seek(CurrentFileOffset, 0)
                for LocalizedString in TmpLocalizedStringArray:
                    LocalizedStringArray.append(
                        FTextLocalizationResourceString().construct(
                            LocalizedString, -1))

        if VersionNumber >= ELocResVersion.Optimized_CRC32:
            reader.seek(4)  # EntriesCount uint

        NamespaceCount = reader.readUInt32()
        for _ in range(NamespaceCount):
            if VersionNumber >= ELocResVersion.Optimized_CRC32:
                reader.seek(4)  # StrHash uint

            Namespace = reader.readFString()
            KeyCount = reader.readUInt32()
            Entries: Dict[str, str] = {}
            for i in range(KeyCount):
                if VersionNumber >= ELocResVersion.Optimized_CRC32:
                    reader.seek(4)  # StrHash uint

                Key: str = reader.readFString()
                reader.seek(4)  # SourceStringHash

                EntryLocalizedString: str
                if VersionNumber >= ELocResVersion.Compact:
                    LocalizedStringIndex = reader.readInt32()

                    if LocalizedStringIndex < len(LocalizedStringArray):
                        LocalizedString = LocalizedStringArray[
                            LocalizedStringIndex]
                        EntryLocalizedString = LocalizedString.String
                        LocalizedString.RefCount -= 1
                    else:
                        raise ParserException(
                            f"LocRes has an invalid localized string index for namespace '{Namespace}' and key '{Key}'. This entry will have no translation."
                        )
                else:
                    EntryLocalizedString = reader.readFString()

                Entries[Key] = EntryLocalizedString
            self.Entries[Namespace] = Entries
Example #12
0
 def __init__(self, reader: BinaryStream):
     self.TableId = reader.readFName()
     self.Key = reader.readFString()
Example #13
0
    def ReadIndex(self, key: str = None):
        self.AesKey = key
        starttime = time.time()
        self.reader.seek(self.Info.IndexOffset, 0)

        if not self.Info.bEncryptedIndex:
            IndexReader = self.reader
        else:
            if not CrytoAval:
                raise ImportError(
                    "Failed to Import \"pycryptodome\", Index is Encrypted it is required for decryption."
                )
            if key is None:
                raise InvalidEncryptionKey(
                    "Index is Encrypted and Key was not provided.")

            bytekey = bytearray.fromhex(key)
            decryptor = AES.new(bytekey, AES.MODE_ECB)
            IndexReader = BinaryStream(
                io.BytesIO(
                    decryptor.decrypt(
                        self.reader.readBytes(self.Info.IndexSize))))

            stringLen = IndexReader.readInt32()
            if stringLen > 512 or stringLen < -512:
                raise InvalidEncryptionKey(
                    f"Provided key didn't work with {self.FileName}")
            if stringLen < 0:
                IndexReader.base_stream.seek((stringLen - 1) * 2, 1)
                if IndexReader.readUInt16() != 0:
                    raise InvalidEncryptionKey(
                        f"Provided key didn't work with {self.FileName}")
            else:
                IndexReader.base_stream.seek(stringLen - 1, 1)
                if int.from_bytes(IndexReader.readByte(), "little") != 0:
                    raise InvalidEncryptionKey(
                        f"Provided key didn't work with {self.FileName}")
            IndexReader.seek(0, 0)

        if self.Info.Version.value >= EPakVersion.PATH_HASH_INDEX.value:
            index = self.ReadUpdatedIndex(IndexReader, key,
                                          self.Case_insensitive)
        else:
            self.MountPoint = IndexReader.readFString() or ""

            if self.MountPoint.startswith("../../.."):
                self.MountPoint = self.MountPoint[8::]

            # if self.Case_insensitive:
            #     self.MountPoint = self.MountPoint.lower()

            self.NumEntries = IndexReader.readInt32()

            tempfiles: Dict[str, FPakEntry] = {}
            for _ in range(self.NumEntries):
                entry = FPakEntry(IndexReader, self.Info.Version,
                                  self.Info.SubVersion, self.FileName)
                if self.Case_insensitive:
                    tempfiles[self.MountPoint.lower() +
                              entry.Name.lower()] = entry
                else:
                    tempfiles[self.MountPoint + entry.Name] = entry

            index = UpdateIndex(self.FileName, self, tempfiles)
            del tempfiles

        time_taken = round(time.time() - starttime, 2)
        logger.info(
            f"{self.FileName} contains {self.NumEntries} files, mount point: {self.MountPoint}, version: {self.Info.Version.value}, in: {time_taken}s"
        )

        return index
Example #14
0
    def ReadUpdatedIndex(self, IndexReader: BinaryStream, key,
                         Case_insensitive: bool) -> dict:
        self.MountPoint = IndexReader.readFString() or ""

        if self.MountPoint.startswith("../../.."):
            self.MountPoint = self.MountPoint[8::]

        if Case_insensitive:
            self.MountPoint = self.MountPoint.lower()

        self.NumEntries = IndexReader.readInt32()
        PathHashSeed = IndexReader.readUInt64()

        if IndexReader.readInt32() == 0:
            raise Exception("No path hash index")

        IndexReader.seek(
            8 + 8 + 20
        )  # PathHashIndexOffset(long) + PathHashIndexSize(long) + PathHashIndexHash(20bytes)

        if IndexReader.readInt32() == 0:
            raise Exception("No directory index")

        FullDirectoryIndexOffset = IndexReader.readInt64()
        FullDirectoryIndexSize = IndexReader.readInt64()
        FullDirectoryIndexHash = FSHAHash(IndexReader)

        PakEntry_Size = IndexReader.readInt32()
        EncodedPakEntries = IndexReader.readBytes(PakEntry_Size)  # TArray

        file_num = IndexReader.readInt32()
        if file_num < 0:
            raise Exception("Corrupt PrimaryIndex")

        self.reader.seek(FullDirectoryIndexOffset, 0)

        PathHashIndexData: bytes = self.reader.base_stream.read(
            FullDirectoryIndexSize)
        if self.Info.bEncryptedIndex:
            bytekey = bytearray.fromhex(key)
            decryptor = AES.new(bytekey, AES.MODE_ECB)
            PathHash_Reader = BinaryStream(
                io.BytesIO(decryptor.decrypt(PathHashIndexData)))
        else:
            PathHash_Reader = BinaryStream(io.BytesIO(PathHashIndexData))

        PathHashIndex = PathHash_Reader.readTArray_W_Arg(
            FPakDirectoryEntry, PathHash_Reader)
        PathHash_Reader.base_stream.close()

        encodedEntryReader = BinaryStream(io.BytesIO(EncodedPakEntries))
        tempentries = {}
        for directoryEntry in PathHashIndex:
            for hasIndexEntry in directoryEntry.Entries:
                path = directoryEntry.Directory + hasIndexEntry.FileName
                if Case_insensitive:
                    path = path.lower()

                encodedEntryReader.seek(hasIndexEntry.Location, 0)
                entry = self.BitEntry(path, encodedEntryReader)
                tempentries[self.MountPoint + path] = entry

        index = UpdateIndex(self.FileName, self, tempentries)

        del tempentries
        encodedEntryReader.base_stream.close()
        return index
Example #15
0
 def __init__(self, reader: BinaryStream) -> None:
     self.position = reader.base_stream.tell()
     self.AssetPathName = reader.readFName()
     self.SubPathString = reader.readFString()
Example #16
0
 def __init__(self, reader: BinaryStream):
     self.FileName = reader.readFString()
     self.Location = reader.readInt32()