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()
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
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")
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()
def __init__(self, reader: BinaryStream) -> None: self.Namespace = reader.readFString() or "" self.Key = reader.readFString() or "" self.SourceString = reader.readFString()
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()
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()
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
def __init__(self, reader: BinaryStream): self.TableId = reader.readFName() self.Key = reader.readFString()
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
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
def __init__(self, reader: BinaryStream) -> None: self.position = reader.base_stream.tell() self.AssetPathName = reader.readFName() self.SubPathString = reader.readFString()
def __init__(self, reader: BinaryStream): self.FileName = reader.readFString() self.Location = reader.readInt32()