Beispiel #1
0
    def Info(self, reader: BinaryStream, offset):
        self.EncryptionKeyGuid = FGuid(reader).read()
        self.bEncryptedIndex = reader.readByte() != b'\x00'

        magic = reader.readUInt32()
        if magic != self.PAK_FILE_MAGIC:
            self.Version = EPakVersion.INVALID
            self.SubVersion = 0
            self.IndexOffset = 0
            self.IndexSize = 0
            self.IndexHash = None
            self.CompressionMethods = None
            return self

        self.Version = EPakVersion(reader.readInt32())

        # FGame.Version = self.Version
        # FGame.SubVersion = self.SubVersion

        self.SubVersion = 1 if offset == self._SIZE8A and self.Version == EPakVersion.FNAME_BASED_COMPRESSION_METHOD else 0
        self.IndexOffset = reader.readInt64()
        self.IndexSize = reader.readInt64()
        self.IndexHash = FSHAHash(reader)
        if self.Version == EPakVersion.FROZEN_INDEX:
            reader.readByte()  # bIndexIsFrozen

        if self.Version.value < EPakVersion.FNAME_BASED_COMPRESSION_METHOD.value:
            self.CompressionMethods = ["Zlib", "Gzip", "Oodle", "LZ4"]
        else:
            BufferSize: int = self.COMPRESSION_METHOD_NAME_LEN * 4
            Methods: bytes = reader.readBytes(BufferSize)
            MethodList = []
            for i in range(4):
                if int(Methods[i * self.COMPRESSION_METHOD_NAME_LEN]) != 0:
                    methods = Methods
                    byteIndex = i * self.COMPRESSION_METHOD_NAME_LEN
                    byteCount = self.COMPRESSION_METHOD_NAME_LEN

                    decoded = methods[byteIndex:byteCount].decode("utf-8")

                    MethodList.append(decoded)
            self.CompressionMethods = MethodList

        if self.Version.value < EPakVersion.INDEX_ENCRYPTION.value:
            self.bEncryptedIndex = False
        if self.Version.value < EPakVersion.ENCRYPTION_KEY_GUID.value:
            self.EncryptionKeyGuid = FGuid().construct(0, 0, 0, 0)

        return self
    def __init__(self, reader: BinaryStream):
        magic = reader.readBytes(16)
        if magic != bytes(self._TocMagic, "utf-8"):
            raise Exceptions.InvalidMagic("invalid utoc magic")

        self.Version = EIoStoreTocVersion(reader.readByteToInt())
        self.Reserved0 = reader.readByte()
        self.Reserved1 = reader.readUInt16()
        self.TocHeaderSize = reader.readUInt32()
        self.TocEntryCount = reader.readUInt32()
        self.TocCompressedBlockEntryCount = reader.readUInt32()
        self.TocCompressedBlockEntrySize = reader.readUInt32()
        self.CompressionMethodNameCount = reader.readUInt32()
        self.CompressionMethodNameLength = reader.readUInt32()
        self.CompressionBlockSize = reader.readUInt32()
        self.DirectoryIndexSize = reader.readUInt32()
        self.PartitionCount = reader.readUInt32()
        self.ContainerId = FIoContainerId(reader)
        self.EncryptionKeyGuid = FGuid(reader)
        self.ContainerFlags = reader.readByteToInt()
        try:
            self.ContainerFlags = EIoContainerFlags(self.ContainerFlags).value
        except:
            pass
        self.Reserved3 = reader.readByteToInt()
        self.Reserved4 = reader.readUInt16()
        self.Reserved5 = reader.readUInt32()
        self.PartitionSize = reader.readUInt64()
Beispiel #3
0
    def __init__(self, reader: BinaryStream) -> None:
        self.position = reader.base_stream.tell()
        length = reader.readInt32()

        for _ in range(length):
            self.Map[FGuid(
                reader).read()] = FLevelSequenceLegacyObjectReference(reader)
Beispiel #4
0
    def deserialize(self, validpos): # 7680
        if self.reader.has_unversioned_properties:
            self.Dict = self.deserializeUnVersioned()
        else:
            self.Dict = self.deserializeVersioned()

        if self.structFallback:
            return

        pos = self.reader.tell()
        if pos + 4 <= validpos:
            val = self.reader.readInt32()
            if val not in [0, 1]:
                self.reader.seek(-4)
                return
            boolval = val != 0
            if not self.flag & EObjectFlags.RF_ClassDefaultObject and boolval:
                self.ObjectGuid = FGuid(self.reader)
Beispiel #5
0
 def __init__(self, reader: BinaryStream):
     self.key = FGuid(reader)
     self.Version = reader.readInt32()
Beispiel #6
0
    def __init__(self, reader: BinaryStream, propMappings: StructProps = None):
        if propMappings:
            propdata = propMappings.data

            self.Name = FName(propMappings.Name)
            self.ArrayIndex = propMappings.ArraySize

            # data section
            for attr in [
                    "EnumName", "InnerType", "StructName", "ValueType", "Type"
            ]:
                val = getattr(propdata, attr, None)
                if val is None:
                    continue

                if attr == "InnerType":
                    self.InnerData = val  #FPropertyTag2(**val)
                elif attr == "ValueType":
                    self.ValueData = val  #FPropertyTag2(val)

                if isinstance(val, str):
                    val = FName(val)
                if isinstance(val, UsmapTag):
                    val = FName(val.Type)
                setattr(self, attr, val)
            return

        self.Name = reader.readFName()
        if self.Name.isNone:
            return

        self.Type = reader.readFName()
        self.Size = reader.readInt32()
        self.ArrayIndex = reader.readInt32()

        self.position = reader.base_stream.tell()
        if self.Type.Number == 0:
            Type = self.Type.string
            if Type == "StructProperty":
                self.StructName = reader.readFName()
                if reader.version >= UE4Versions.VER_UE4_STRUCT_GUID_IN_PROPERTY_TAG:
                    self.StructGuid = FGuid(reader)
            elif Type == "BoolProperty":
                self.BoolVal = reader.readByteToInt()
            elif Type == "ByteProperty" or Type == "EnumProperty":
                self.EnumName = reader.readFName()
            elif Type == "ArrayProperty":
                if reader.version >= UE4Versions.VAR_UE4_ARRAY_PROPERTY_INNER_TAGS:
                    self.InnerType = reader.readFName()
            elif Type == "SetProperty":
                if reader.version >= UE4Versions.VER_UE4_PROPERTY_TAG_SET_MAP_SUPPORT:
                    self.InnerType = reader.readFName()
            elif Type == "MapProperty":
                if reader.version >= UE4Versions.VER_UE4_PROPERTY_TAG_SET_MAP_SUPPORT:
                    self.InnerType = reader.readFName()
                    self.ValueType = reader.readFName()

        HasPropertyGuid = reader.readByteToInt()
        if HasPropertyGuid != 0:
            FGuid(reader)
        self.end_pos = reader.tell()
Beispiel #7
0
def ReadAsObject(reader, tag: FPropertyTag = None, type_: FName = None, readType: ReadType = None):
    type_ = type_.string  if isinstance(type_, FName) else type_

    if type_ != "EnumProperty" and readType == ReadType.ZERO:
        print(f"ReadType::Zero and it's not EnumProperty, {type_!r}")


    prop: object
    if switch("ByteProperty", type_):
        prop = ByteProperty(reader,  readType,tag)
    elif switch("BoolProperty", type_):
        prop = BoolProperty(reader, tag, readType)
    elif switch("IntProperty", type_):
        prop = IntProperty(reader)
    elif switch("FloatProperty", type_):
        prop = FloatProperty(reader)
    elif switch("ObjectProperty", type_):
        prop = ObjectProperty(reader)
    elif switch("NameProperty", type_):
        prop = NameProperty(reader)
    elif switch("DelegateProperty", type_):
        prop = DelegateProperty(reader)
    elif switch("DoubleProperty", type_):
        prop = DoubleProperty(reader)
    elif switch("ArrayProperty", type_):
        prop = ArrayProperty(reader, tag)
    elif switch("StructProperty", type_):
        prop = StructProperty(reader, tag)
    elif switch("StrProperty", type_):
        prop = StrProperty(reader)
    elif switch("TextProperty", type_):
        prop = TextProperty(reader)
    # elif switch("InterfaceProperty", type_):
    #     prop = InterfaceProperty(reader)
    # # elif switch("MulticastDelegateProperty", type_):
    #     # prop = MulticastDelegateProperty(reader, tag)
    elif switch("LazyObjectProperty", type_):
        prop = LazyObjectProperty(reader, readType)  # (reader, tag)
    elif switch("SoftObjectProperty", type_):
        prop = SoftObjectProperty(reader, readType)
    elif switch("AssetObjectProperty", type_):
        prop = SoftObjectProperty(reader, readType)
    elif switch("UInt64Property", type_):
        prop = UInt64Property(reader)
    elif switch("UInt32Property", type_):
        prop = UInt32Property(reader)
    elif switch("UInt16Property", type_):
        prop = UInt16Property(reader)
    elif switch("Int64Property", type_):
        prop = Int64Property(reader)
    elif switch("Int16Property", type_):
        prop = Int16Property(reader)
    elif switch("Int8Property", type_):
        prop = Int8Property(reader)
    elif switch("MapProperty", type_):
        prop = MapProperty(reader, tag)
    elif switch("SetProperty", type_):
        prop = SetProperty(reader, tag)
    elif switch("EnumProperty", type_):
        prop = EnumProperty(reader, tag, readType)
    elif switch("Guid", type_):
        prop = FGuid(reader)
    else:
        return None

    return prop
Beispiel #8
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()
    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
Beispiel #10
0
    def deserialize(self, validpos) -> None:
        super().deserialize(validpos)
        reader = self.reader

        self.StripData = FStripDataFlags(reader)
        bCooked = reader.readBool()
        self.BodySetup = reader.readObject()

        if reader.version >= Versions.VER_UE4_STATIC_MESH_STORE_NAV_COLLISION:
            self.NavCollision = reader.readObject()

        if not self.StripData.isEditorDataStripped():
            if reader.version < Versions.VER_UE4_DEPRECATED_STATIC_MESH_THUMBNAIL_PROPERTIES_REMOVED:
                FRotator(reader)  # dummyThumbnailAngle
                reader.readFloat()  # dummyThumbnailDistance
            highResSourceMeshName = reader.readString(
            )  # highResSourceMeshName
            highResSourceMeshCRC = reader.readUInt32()  #

        self.LightingGuid = FGuid(reader)

        self.Sockets = reader.readTArray(reader.readObject)

        if not self.StripData.isEditorDataStripped:
            raise ParserException("Mesh with editor data not supported")

        # FStaticMeshRenderData
        if bCooked:
            if not bCooked:  # how possible
                pass  # https://github.com/FabianFG/JFortniteParse/blob/558fb2b96985aad5b90c96c8f28950021cf801a0/src/main/kotlin/me/fungames/jfortniteparse/ue4/assets/exports/UStaticMesh.kt#L59
            # if unversioned MinMobileLODIdx int32
            self.LODs = reader.readTArray_W_Arg(FStaticMeshLODResources,
                                                reader)  #TODO fix this

            if reader.game >= GAME_UE4(23):
                NumInlinedLODs = reader.readUInt8()

            if bCooked:
                if reader.version >= Versions.VER_UE4_RENAME_CROUCHMOVESCHARACTERDOWN:
                    isStripped = False
                    if reader.version >= Versions.VER_UE4_RENAME_WIDGET_VISIBILITY:
                        stripflag = FStripDataFlags(reader)
                        isStripped = stripflag.isDataStrippedForServer()
                        if reader.game >= GAME_UE4(21):
                            # 4.21 uses additional strip flag for distance field
                            distanceFieldDataStripFlag = 1
                            isStripped = isStripped | stripflag.isClassDataStripped(
                                distanceFieldDataStripFlag)  # ?
                    if not isStripped:
                        # serialize FDistanceFieldVolumeData for each LOD
                        for _ in range(len(self.LODs) - 1):  # wut why
                            hasDistanceDataField = reader.readBool()
                            if hasDistanceDataField:
                                FDistanceFieldVolumeData(reader)  # VolumeData

            self.Bounds = FBoxSphereBounds(reader)

            if reader.game != GAME_UE4(15):
                self.LODsShareStaticLighting = reader.readBool()

            if reader.game < GAME_UE4(15):
                reader.readBool()  # bReducedBySimplygon

            if FRenderingObjectVersion().get(
                    reader
            ) < FRenderingObjectVersion.TextureStreamingMeshUVChannelData:
                for _ in range(
                        MAX_STATIC_UV_SETS_UE4):  # StreamingTextureFactors
                    reader.readFloat(
                    )  # StreamingTextureFactor for each UV set
                reader.readFloat()  # MaxStreamingTextureFactor

            if bCooked:
                maxNumLods = MAX_STATIC_LODS_UE4 if reader.game >= GAME_UE4(
                    9) else 4
                for x in range(maxNumLods):
                    if reader.game >= GAME_UE4(20):
                        reader.readBool()  # bFloatCooked
                    self.ScreenSize.append(reader.readFloat())
        # End of FStaticMeshRenderData

        if bCooked and reader.game >= GAME_UE4(20):
            hasOccluderData = reader.readBool()
            if hasOccluderData:
                reader.readTArray(FVector, reader)  # Vertices
                reader.readTArray(reader.readUInt16)  # Indics

        if reader.game >= GAME_UE4(14):
            hasSpeedTreeWind = reader.readBool()
            if hasSpeedTreeWind:
                pass  # ignore
            else:
                if FEditorObjectVersion().get(
                        reader
                ) >= FEditorObjectVersion.RefactorMeshEditorMaterials:
                    # UE4.14+ - "Materials" are deprecated, added StaticMaterials
                    self.StaticMaterials = reader.readTArray_W_Arg(
                        FStaticMaterial, reader)

        if len(self.Materials) == 0 and len(self.StaticMaterials) > 0:
            material: FStaticMaterial
            for material in self.StaticMaterials:
                self.Materials.append(material.MaterialInterface)
Beispiel #11
0
 def __init__(self, reader: BinaryStream) -> None:
     self.Guid = FGuid(reader).read()