Repository: atenfyr/UAssetAPI
Branch: master
Commit: cb4206007d86
Files: 1498
Total size: 90.0 MB
Directory structure:
gitextract_6utsa1vi/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── config.yml
│ │ └── feature_request.md
│ ├── pull_request_template.md
│ └── workflows/
│ ├── build.yml
│ └── main.yml
├── .gitignore
├── LICENSE
├── NOTICE.md
├── README.md
├── UAssetAPI/
│ ├── AC7Decrypt.cs
│ ├── AssetBinaryReader.cs
│ ├── AssetBinaryWriter.cs
│ ├── CRCGenerator.cs
│ ├── CustomVersion.cs
│ ├── CustomVersions/
│ │ └── CustomVersions.cs
│ ├── ExportTypes/
│ │ ├── AssetImportDataExport.cs
│ │ ├── ClassExport.cs
│ │ ├── DataTableExport.cs
│ │ ├── EnumExport.cs
│ │ ├── Export.cs
│ │ ├── FieldExport.cs
│ │ ├── FunctionExport.cs
│ │ ├── LevelExport.cs
│ │ ├── MetaDataExport.cs
│ │ ├── NormalExport.cs
│ │ ├── PropertyExport.cs
│ │ ├── RawExport.cs
│ │ ├── StringTableExport.cs
│ │ ├── StructExport.cs
│ │ └── UserDefinedStructExport.cs
│ ├── FieldTypes/
│ │ ├── EArrayDim.cs
│ │ ├── ELifetimeCondition.cs
│ │ ├── FField.cs
│ │ └── UField.cs
│ ├── Import.cs
│ ├── JSON/
│ │ ├── ByteArrayJsonConverter.cs
│ │ ├── FNameJsonConverter.cs
│ │ ├── FPackageIndexJsonConverter.cs
│ │ ├── FSignedZeroJsonConverter.cs
│ │ ├── FStringJsonConverter.cs
│ │ ├── FStringTableJsonConverter.cs
│ │ ├── GuidJsonConverter.cs
│ │ ├── TMapJsonConverter.cs
│ │ └── UAssetContractResolver.cs
│ ├── Kismet/
│ │ ├── Bytecode/
│ │ │ ├── EBlueprintTextLiteralType.cs
│ │ │ ├── EExprToken.cs
│ │ │ ├── EScriptInstrumentationType.cs
│ │ │ ├── ExpressionSerializer.cs
│ │ │ ├── Expressions/
│ │ │ │ ├── EX_AddMulticastDelegate.cs
│ │ │ │ ├── EX_ArrayConst.cs
│ │ │ │ ├── EX_ArrayGetByRef.cs
│ │ │ │ ├── EX_Assert.cs
│ │ │ │ ├── EX_BindDelegate.cs
│ │ │ │ ├── EX_BitFieldConst.cs
│ │ │ │ ├── EX_Breakpoint.cs
│ │ │ │ ├── EX_ByteConst.cs
│ │ │ │ ├── EX_CallMath.cs
│ │ │ │ ├── EX_CallMulticastDelegate.cs
│ │ │ │ ├── EX_CastBase.cs
│ │ │ │ ├── EX_ClassContext.cs
│ │ │ │ ├── EX_ClassSparseDataVariable.cs
│ │ │ │ ├── EX_ClearMulticastDelegate.cs
│ │ │ │ ├── EX_ComputedJump.cs
│ │ │ │ ├── EX_Context.cs
│ │ │ │ ├── EX_Context_FailSilent.cs
│ │ │ │ ├── EX_CrossInterfaceCast.cs
│ │ │ │ ├── EX_DefaultVariable.cs
│ │ │ │ ├── EX_DeprecatedOp4A.cs
│ │ │ │ ├── EX_DoubleConst.cs
│ │ │ │ ├── EX_DynamicCast.cs
│ │ │ │ ├── EX_EndArray.cs
│ │ │ │ ├── EX_EndArrayConst.cs
│ │ │ │ ├── EX_EndFunctionParms.cs
│ │ │ │ ├── EX_EndMap.cs
│ │ │ │ ├── EX_EndMapConst.cs
│ │ │ │ ├── EX_EndOfScript.cs
│ │ │ │ ├── EX_EndParmValue.cs
│ │ │ │ ├── EX_EndSet.cs
│ │ │ │ ├── EX_EndSetConst.cs
│ │ │ │ ├── EX_EndStructConst.cs
│ │ │ │ ├── EX_False.cs
│ │ │ │ ├── EX_FieldPathConst.cs
│ │ │ │ ├── EX_FinalFunction.cs
│ │ │ │ ├── EX_FloatConst.cs
│ │ │ │ ├── EX_InstanceDelegate.cs
│ │ │ │ ├── EX_InstanceVariable.cs
│ │ │ │ ├── EX_InstrumentationEvent.cs
│ │ │ │ ├── EX_Int64Const.cs
│ │ │ │ ├── EX_IntConst.cs
│ │ │ │ ├── EX_IntConstByte.cs
│ │ │ │ ├── EX_IntOne.cs
│ │ │ │ ├── EX_IntZero.cs
│ │ │ │ ├── EX_InterfaceContext.cs
│ │ │ │ ├── EX_InterfaceToObjCast.cs
│ │ │ │ ├── EX_Jump.cs
│ │ │ │ ├── EX_JumpIfNot.cs
│ │ │ │ ├── EX_Let.cs
│ │ │ │ ├── EX_LetBase.cs
│ │ │ │ ├── EX_LetBool.cs
│ │ │ │ ├── EX_LetDelegate.cs
│ │ │ │ ├── EX_LetMulticastDelegate.cs
│ │ │ │ ├── EX_LetObj.cs
│ │ │ │ ├── EX_LetValueOnPersistentFrame.cs
│ │ │ │ ├── EX_LetWeakObjPtr.cs
│ │ │ │ ├── EX_LocalFinalFunction.cs
│ │ │ │ ├── EX_LocalOutVariable.cs
│ │ │ │ ├── EX_LocalVariable.cs
│ │ │ │ ├── EX_LocalVirtualFunction.cs
│ │ │ │ ├── EX_MapConst.cs
│ │ │ │ ├── EX_MetaCast.cs
│ │ │ │ ├── EX_NameConst.cs
│ │ │ │ ├── EX_NoInterface.cs
│ │ │ │ ├── EX_NoObject.cs
│ │ │ │ ├── EX_Nothing.cs
│ │ │ │ ├── EX_NothingInt32.cs
│ │ │ │ ├── EX_ObjToInterfaceCast.cs
│ │ │ │ ├── EX_ObjectConst.cs
│ │ │ │ ├── EX_PopExecutionFlow.cs
│ │ │ │ ├── EX_PopExecutionFlowIfNot.cs
│ │ │ │ ├── EX_PrimitiveCast.cs
│ │ │ │ ├── EX_PropertyConst.cs
│ │ │ │ ├── EX_PushExecutionFlow.cs
│ │ │ │ ├── EX_RemoveMulticastDelegate.cs
│ │ │ │ ├── EX_Return.cs
│ │ │ │ ├── EX_RotationConst.cs
│ │ │ │ ├── EX_Self.cs
│ │ │ │ ├── EX_SetArray.cs
│ │ │ │ ├── EX_SetConst.cs
│ │ │ │ ├── EX_SetMap.cs
│ │ │ │ ├── EX_SetSet.cs
│ │ │ │ ├── EX_Skip.cs
│ │ │ │ ├── EX_SkipOffsetConst.cs
│ │ │ │ ├── EX_SoftObjectConst.cs
│ │ │ │ ├── EX_StringConst.cs
│ │ │ │ ├── EX_StructConst.cs
│ │ │ │ ├── EX_StructMemberContext.cs
│ │ │ │ ├── EX_SwitchValue.cs
│ │ │ │ ├── EX_TextConst.cs
│ │ │ │ ├── EX_Tracepoint.cs
│ │ │ │ ├── EX_TransformConst.cs
│ │ │ │ ├── EX_True.cs
│ │ │ │ ├── EX_UInt64Const.cs
│ │ │ │ ├── EX_UnicodeStringConst.cs
│ │ │ │ ├── EX_VariableBase.cs
│ │ │ │ ├── EX_Vector3fConst.cs
│ │ │ │ ├── EX_VectorConst.cs
│ │ │ │ ├── EX_VirtualFunction.cs
│ │ │ │ └── EX_WireTracepoint.cs
│ │ │ ├── FScriptText.cs
│ │ │ ├── KismetExpression.cs
│ │ │ └── KismetPropertyPointer.cs
│ │ └── KismetSerializer.cs
│ ├── MainSerializer.cs
│ ├── Pak/
│ │ ├── Interop.cs
│ │ └── RePak.cs
│ ├── Properties/
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── PropertyTypes/
│ │ ├── Objects/
│ │ │ ├── ArrayPropertyData.cs
│ │ │ ├── BoolPropertyData.cs
│ │ │ ├── BytePropertyData.cs
│ │ │ ├── DelegatePropertyData.cs
│ │ │ ├── DoublePropertyData.cs
│ │ │ ├── EnumPropertyData.cs
│ │ │ ├── FieldPathPropertyData.cs
│ │ │ ├── FloatPropertyData.cs
│ │ │ ├── Int16PropertyData.cs
│ │ │ ├── Int64PropertyData.cs
│ │ │ ├── Int8PropertyData.cs
│ │ │ ├── IntPropertyData.cs
│ │ │ ├── InterfacePropertyData.cs
│ │ │ ├── MapPropertyData.cs
│ │ │ ├── MulticastDelegatePropertyData.cs
│ │ │ ├── NamePropertyData.cs
│ │ │ ├── ObjectPropertyData.cs
│ │ │ ├── PropertyData.cs
│ │ │ ├── SetPropertyData.cs
│ │ │ ├── SoftObjectPropertyData.cs
│ │ │ ├── StrPropertyData.cs
│ │ │ ├── TextHistoryType.cs
│ │ │ ├── TextPropertyData.cs
│ │ │ ├── UInt16PropertyData.cs
│ │ │ ├── UInt32PropertyData.cs
│ │ │ ├── UInt64PropertyData.cs
│ │ │ ├── UnknownPropertyData.cs
│ │ │ └── WeakObjectPropertyData.cs
│ │ └── Structs/
│ │ ├── ClothLODDataPropertyData.cs
│ │ ├── ClothTetherDataPropertyData.cs
│ │ ├── Core/
│ │ │ ├── ColorPropertyData.cs
│ │ │ ├── DateTimePropertyData.cs
│ │ │ ├── GuidPropertyData.cs
│ │ │ └── TimespanPropertyData.cs
│ │ ├── Engine/
│ │ │ ├── FontCharacterPropertyData.cs
│ │ │ ├── KeyHandleMapPropertyData.cs
│ │ │ ├── MaterialInputProperties.cs
│ │ │ ├── MaterialOverrideNanitePropertyData.cs
│ │ │ ├── NavAgentSelectorPropertyData.cs
│ │ │ ├── PerPlatformProperties.cs
│ │ │ ├── PerQualityProperties.cs
│ │ │ ├── RichCurveKeyPropertyData.cs
│ │ │ ├── SkeletalMeshSamplingLODBuiltDataPropertyData.cs
│ │ │ ├── SkeletalMeshSamplingRegionBuiltDataPropertyData.cs
│ │ │ ├── SmartNamePropertyData.cs
│ │ │ ├── StringCurveKeyPropertyData.cs
│ │ │ ├── ViewTargetBlendParamsPropertyData.cs
│ │ │ └── WeightedRandomSamplerPropertyData.cs
│ │ ├── GameplayTagContainerPropertyData.cs
│ │ ├── LevelSequenceObjectReferenceMapPropertyData.cs
│ │ ├── Math/
│ │ │ ├── BoxPropertyData.cs
│ │ │ ├── IntPointPropertyData.cs
│ │ │ ├── IntVector2PropertyData.cs
│ │ │ ├── IntVectorPropertyData.cs
│ │ │ ├── LinearColorPropertyData.cs
│ │ │ ├── MatrixPropertyData.cs
│ │ │ ├── PlanePropertyData.cs
│ │ │ ├── QuatPropertyData.cs
│ │ │ ├── RotatorPropertyData.cs
│ │ │ ├── TwoVectorsPropertyData.cs
│ │ │ ├── Vector2DPropertyData.cs
│ │ │ ├── Vector2fPropertyData.cs
│ │ │ ├── Vector3fPropertyData.cs
│ │ │ ├── Vector4PropertyData.cs
│ │ │ ├── Vector4fPropertyData.cs
│ │ │ ├── VectorNetQuantizePropertyData.cs
│ │ │ └── VectorPropertyData.cs
│ │ ├── Movies/
│ │ │ ├── FrameNumberPropertyData.cs
│ │ │ ├── MovieScene.cs
│ │ │ ├── MovieSceneChannel.cs
│ │ │ ├── MovieSceneDoubleChannelPropertyData.cs
│ │ │ ├── MovieSceneEvalTemplatePtrPropertyData.cs
│ │ │ ├── MovieSceneEvaluationFieldEntityTreePropertyData.cs
│ │ │ ├── MovieSceneEvaluationTree.cs
│ │ │ ├── MovieSceneEvaluationTreeNode.cs
│ │ │ ├── MovieSceneEventParametersPropertyData.cs
│ │ │ ├── MovieSceneFloatChannelPropertyData.cs
│ │ │ ├── MovieSceneFloatValuePropertyData.cs
│ │ │ ├── MovieSceneFrameRangePropertyData.cs
│ │ │ ├── MovieSceneGenerationLedgerPropertyData.cs
│ │ │ ├── MovieSceneSegment.cs
│ │ │ ├── MovieSceneSegmentPropertyData.cs
│ │ │ ├── MovieSceneTrackIdentifierPropertyData.cs
│ │ │ ├── MovieSceneValue.cs
│ │ │ └── NameCurveKeyPropertyData.cs
│ │ ├── Niagara/
│ │ │ ├── NiagaraDataInterfaceGPUParamInfoPropertyData.cs
│ │ │ └── NiagaraVariablePropertyData.cs
│ │ ├── Ranges/
│ │ │ └── FloatRangePropertyData.cs
│ │ ├── RawStructPropertyData.cs
│ │ ├── Slate/
│ │ │ ├── DeprecateSlateVector2DPropertyData.cs
│ │ │ └── FontDataPropertyData.cs
│ │ ├── SoftObjectPathPropertyData.cs
│ │ └── StructPropertyData.cs
│ ├── UAPUtils.cs
│ ├── UAsset.cs
│ ├── UAssetAPI.csproj
│ ├── UnrealTypes/
│ │ ├── EngineVersion.cs
│ │ ├── FFieldPath.cs
│ │ ├── FGatherableTextData.cs
│ │ ├── FLocMetadataObject.cs
│ │ ├── FName.cs
│ │ ├── FObjectDataResource.cs
│ │ ├── FObjectThumbnail.cs
│ │ ├── FPackageIndex.cs
│ │ ├── FPropertyTypeName.cs
│ │ ├── FString.cs
│ │ ├── FTextSourceData.cs
│ │ ├── FTextSourceSiteContext.cs
│ │ ├── FUniversalObjectLocatorFragment.cs
│ │ ├── FWorldTileInfo.cs
│ │ ├── Flags.cs
│ │ ├── ObjectVersion.cs
│ │ ├── Objects/
│ │ │ ├── Core/
│ │ │ │ └── Math/
│ │ │ │ ├── FIntVector.cs
│ │ │ │ ├── FIntVector2.cs
│ │ │ │ ├── FLinearColor.cs
│ │ │ │ ├── FMatrix.cs
│ │ │ │ ├── FPlane.cs
│ │ │ │ ├── FQuat.cs
│ │ │ │ ├── FRotator.cs
│ │ │ │ ├── FTransform.cs
│ │ │ │ ├── FTwoVectors.cs
│ │ │ │ ├── FVector.cs
│ │ │ │ ├── FVector2D.cs
│ │ │ │ ├── FVector2f.cs
│ │ │ │ ├── FVector3f.cs
│ │ │ │ ├── FVector4.cs
│ │ │ │ ├── FVector4f.cs
│ │ │ │ ├── TBox.cs
│ │ │ │ └── TPerQualityLevel.cs
│ │ │ ├── Engine/
│ │ │ │ ├── CoreUObject/
│ │ │ │ │ ├── CoreUObjectEnums.cs
│ │ │ │ │ └── CoreUObjectStructs.cs
│ │ │ │ ├── EngineEnums.cs
│ │ │ │ ├── FFontCharacter.cs
│ │ │ │ ├── FRichCurveKey.cs
│ │ │ │ ├── FSkeletalMeshSamplingRegionBuiltData.cs
│ │ │ │ ├── FWeightedRandomSampler.cs
│ │ │ │ ├── GameFramework/
│ │ │ │ │ └── UniqueNetIdReplPropertyData.cs
│ │ │ │ └── Niagara/
│ │ │ │ └── FNiagaraDataInterfaceGPUParamInfo.cs
│ │ │ └── SlateCore/
│ │ │ └── FFontData.cs
│ │ ├── TMap.cs
│ │ └── UE4VersionToObjectVersion.cs
│ └── Unversioned/
│ ├── FFragment.cs
│ ├── FUnversionedHeader.cs
│ ├── Oodle.cs
│ ├── SaveGame.cs
│ ├── Usmap.cs
│ └── UsmapBinaryReader.cs
├── UAssetAPI.Benchmark/
│ ├── App.config
│ ├── Program.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── TestAssets/
│ │ ├── B_Gamemode.uasset
│ │ ├── Begin_Player.uasset
│ │ ├── HUB_Restaurant.uexp
│ │ ├── HUB_Restaurant.umap
│ │ ├── PlayerBase01.uexp
│ │ ├── PlayerBase01.umap
│ │ ├── Staging_T2.uexp
│ │ ├── Staging_T2.umap
│ │ └── _asset_versions.json
│ └── UAssetAPI.Benchmark.csproj
├── UAssetAPI.Tests/
│ ├── AssetUnitTests.cs
│ ├── CoolPropertyData.cs
│ ├── Properties/
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── TestAssets/
│ │ ├── TestACE7/
│ │ │ ├── ex02_IGC_03_Subtitle.uasset
│ │ │ ├── ex02_IGC_03_Subtitle.uexp
│ │ │ ├── plwp_6aam_a0.uasset
│ │ │ └── plwp_6aam_a0.uexp
│ │ ├── TestCustomProperty/
│ │ │ └── AlternateStartActor.uasset
│ │ ├── TestCustomSerializationStructsInMap/
│ │ │ ├── wtf.uasset
│ │ │ └── wtf.uexp
│ │ ├── TestDuplicateNameMapEntries/
│ │ │ ├── BIOME_AzureWeald.uasset
│ │ │ └── BIOME_AzureWeald.uexp
│ │ ├── TestEditorAssets/
│ │ │ ├── TestActorBP.uasset
│ │ │ ├── TestMaterial.uasset
│ │ │ └── TestSoundClass.uasset
│ │ ├── TestImproperNameMapHashes/
│ │ │ ├── OC_Gatling_DamageB_B.uasset
│ │ │ └── OC_Gatling_DamageB_B.uexp
│ │ ├── TestJson/
│ │ │ ├── ABP_SMG_A.uasset
│ │ │ ├── ABP_SMG_A.uexp
│ │ │ ├── AssetDatabase_AutoGenerated.uasset
│ │ │ ├── AssetDatabase_AutoGenerated.uexp
│ │ │ ├── Atlas_6x4_Semi.uasset
│ │ │ ├── Atlas_6x4_Semi.uexp
│ │ │ ├── BlinkerLight_01.uasset
│ │ │ ├── BlinkerLight_01.uexp
│ │ │ ├── FrontDomeLight_2m.uasset
│ │ │ ├── FrontDomeLight_2m.uexp
│ │ │ ├── Items.uasset
│ │ │ ├── Items.uexp
│ │ │ ├── MGA_HeavyWeapon_Parent.uasset
│ │ │ ├── MGA_HeavyWeapon_Parent.uexp
│ │ │ ├── MTVehicleBaseBP.uasset
│ │ │ ├── MTVehicleBaseBP.uexp
│ │ │ ├── Map_FrontEnd_Hotel_LS_Night.uexp
│ │ │ ├── Map_FrontEnd_Hotel_LS_Night.umap
│ │ │ ├── MotorTown.usmap
│ │ │ ├── Outriders.usmap
│ │ │ ├── RaceSimDataAsset.uasset
│ │ │ ├── RaceSimDataAsset.uexp
│ │ │ ├── ReverseLight_01.uasset
│ │ │ ├── ReverseLight_01.uexp
│ │ │ ├── TaliLight_01.uasset
│ │ │ ├── TaliLight_01.uexp
│ │ │ ├── TurboAcres_Environment.uasset
│ │ │ ├── TurboAcres_Environment.uexp
│ │ │ ├── WPN_LockOnRifle.uasset
│ │ │ └── WPN_LockOnRifle.uexp
│ │ ├── TestManyAssets/
│ │ │ ├── Astroneer/
│ │ │ │ ├── Augment_BroadBrush.uasset
│ │ │ │ ├── DebugMenu.uasset
│ │ │ │ ├── LargeResourceCanister_IT.uasset
│ │ │ │ ├── ResourceProgressCurve.uasset
│ │ │ │ └── Staging_T2.umap
│ │ │ ├── Biodigital/
│ │ │ │ ├── Roboto.uasset
│ │ │ │ └── RobotoTiny.uasset
│ │ │ ├── Bloodstained/
│ │ │ │ ├── PB_DT_ItemMaster.uasset
│ │ │ │ ├── PB_DT_RandomizerRoomCheck.uasset
│ │ │ │ ├── m01SIP_000_BG.umap
│ │ │ │ ├── m01SIP_000_Gimmick.umap
│ │ │ │ ├── m02VIL_004_Gimmick.umap
│ │ │ │ └── m05SAN_000_Gimmick.umap
│ │ │ ├── BurningDaylight/
│ │ │ │ ├── TestMap.uexp
│ │ │ │ └── TestMap.umap
│ │ │ ├── CodeVein/
│ │ │ │ ├── SK_Inner_Female1.uasset
│ │ │ │ └── SK_Inner_Female1.uexp
│ │ │ ├── F1Manager2023/
│ │ │ │ ├── F1Manager2023.usmap
│ │ │ │ ├── FixedStaff.uasset
│ │ │ │ ├── FixedStaff.uexp
│ │ │ │ ├── MI_F1_Driver_LoganSargeant_Visor.uasset
│ │ │ │ ├── MI_F1_Driver_LoganSargeant_Visor.uexp
│ │ │ │ ├── StaffPhotoData.uasset
│ │ │ │ └── StaffPhotoData.uexp
│ │ │ ├── LiesOfP/
│ │ │ │ ├── ItemInfo.uasset
│ │ │ │ ├── ItemInfo.uexp
│ │ │ │ ├── LiesOfP.usmap
│ │ │ │ ├── SkillHitInfo.uasset
│ │ │ │ ├── SkillHitInfo.uexp
│ │ │ │ ├── SkillInfo.uasset
│ │ │ │ └── SkillInfo.uexp
│ │ │ ├── Liminal/
│ │ │ │ ├── FinalCinematic.uasset
│ │ │ │ ├── FinalCinematic.uexp
│ │ │ │ ├── InCathedralCinematic.uasset
│ │ │ │ ├── InCathedralCinematic.uexp
│ │ │ │ ├── InventoryStruct.uasset
│ │ │ │ └── InventoryStruct.uexp
│ │ │ ├── MISC_426/
│ │ │ │ ├── MainChar_BellySlice_BR.uasset
│ │ │ │ ├── MainChar_BellySlice_BR.uexp
│ │ │ │ ├── RaceSimDataAsset.uasset
│ │ │ │ └── RaceSimDataAsset.uexp
│ │ │ ├── MidAir/
│ │ │ │ ├── AM_MedChar_Reload_RingLauncher.uasset
│ │ │ │ ├── AM_MedChar_Reload_RingLauncher.uexp
│ │ │ │ ├── WBP_PartyPlayerRow.uasset
│ │ │ │ └── WBP_PartyPlayerRow.uexp
│ │ │ ├── MutantYearZero/
│ │ │ │ ├── ChroniclerpathCutscene.uasset
│ │ │ │ ├── ChroniclerpathCutscene.uexp
│ │ │ │ ├── MainCut.uasset
│ │ │ │ └── MainCut.uexp
│ │ │ ├── Palia/
│ │ │ │ ├── DT_FishConfigs.uasset
│ │ │ │ ├── DT_FishConfigs.uexp
│ │ │ │ ├── DT_FishingLevelConfigs.uasset
│ │ │ │ ├── DT_FishingLevelConfigs.uexp
│ │ │ │ ├── DT_FishingLevelSegmentConfigs.uasset
│ │ │ │ ├── DT_FishingLevelSegmentConfigs.uexp
│ │ │ │ ├── DT_FishingLootConfigs.uasset
│ │ │ │ ├── DT_FishingLootConfigs.uexp
│ │ │ │ ├── DT_FishingNibbleConfig.uasset
│ │ │ │ ├── DT_FishingNibbleConfig.uexp
│ │ │ │ ├── DT_FishingNibbleLevelConfig.uasset
│ │ │ │ ├── DT_FishingNibbleLevelConfig.uexp
│ │ │ │ ├── DT_ShopConfigs.uasset
│ │ │ │ ├── DT_ShopConfigs.uexp
│ │ │ │ └── Palia.usmap
│ │ │ ├── Palworld/
│ │ │ │ ├── BP_BuildObject_BaseCampWorkHard.uasset
│ │ │ │ ├── BP_BuildObject_BaseCampWorkHard.uexp
│ │ │ │ ├── BP_InteractableBox.uasset
│ │ │ │ ├── BP_InteractableBox.uexp
│ │ │ │ └── Palworld.usmap
│ │ │ ├── SnakePass/
│ │ │ │ ├── MP00_GateTutorial.uasset
│ │ │ │ └── MP00_Intro.uasset
│ │ │ ├── StarlitSeason/
│ │ │ │ ├── CharacterCostume_chr0001_DataTable.uasset
│ │ │ │ └── CharacterCostume_chr0001_DataTable.uexp
│ │ │ ├── Tekken/
│ │ │ │ └── BP_TekkenPlayer_Modular.uasset
│ │ │ ├── TheBeastInside/
│ │ │ │ ├── DV_ItemDescription.uasset
│ │ │ │ ├── DV_ItemDescription.uexp
│ │ │ │ ├── MF_CharacterEffects.uasset
│ │ │ │ └── MF_CharacterEffects.uexp
│ │ │ ├── TheOccupation/
│ │ │ │ ├── LiftStruct.uasset
│ │ │ │ └── RecieverPneumaticTerminals.uasset
│ │ │ ├── ToTheCore/
│ │ │ │ ├── BP_MimicCrate.uasset
│ │ │ │ └── BP_MimicCrate.uexp
│ │ │ └── VERSIONED/
│ │ │ └── Assault_M1A1Thompson_WW2_DrumSuppressor.uasset
│ │ ├── TestMaterials/
│ │ │ ├── M_COM_DetailMaster_B.uasset
│ │ │ ├── as_mt_base.uasset
│ │ │ └── as_mt_base.uexp
│ │ ├── TestUE5_1/
│ │ │ └── UnderlyingEnumTypes/
│ │ │ ├── NewDataTable.uasset
│ │ │ ├── NewDataTable.uexp
│ │ │ └── UnderlyingEnumTypes.usmap
│ │ ├── TestUE5_3/
│ │ │ ├── Engine/
│ │ │ │ ├── DefaultRecorderBoneCompression.uasset
│ │ │ │ ├── DefaultRecorderBoneCompression.uexp
│ │ │ │ ├── Engine.usmap
│ │ │ │ ├── Entry.uexp
│ │ │ │ ├── Entry.umap
│ │ │ │ ├── Entry_MODIFIED_INVALID_ENUM_INDEX.uexp
│ │ │ │ ├── Entry_MODIFIED_INVALID_ENUM_INDEX.umap
│ │ │ │ ├── OpenWorld.uexp
│ │ │ │ └── OpenWorld.umap
│ │ │ └── RON/
│ │ │ ├── AmmoDataTable.uasset
│ │ │ ├── AmmoDataTable.uexp
│ │ │ └── ReadyOrNot.usmap
│ │ ├── TestUE5_4/
│ │ │ ├── Bellwright/
│ │ │ │ ├── Bellwright.usmap
│ │ │ │ └── Content/
│ │ │ │ └── Mist/
│ │ │ │ └── Characters/
│ │ │ │ └── NPC/
│ │ │ │ └── Villager/
│ │ │ │ ├── HighSkill/
│ │ │ │ │ ├── ApprenticeBlacksmithNPCTemplate.uasset
│ │ │ │ │ ├── ApprenticeBlacksmithNPCTemplate.uexp
│ │ │ │ │ ├── ApprenticeCarpenterNPCTemplate.uasset
│ │ │ │ │ ├── ApprenticeCarpenterNPCTemplate.uexp
│ │ │ │ │ ├── ApprenticeEngineerNPCTemplate.uasset
│ │ │ │ │ ├── ApprenticeEngineerNPCTemplate.uexp
│ │ │ │ │ ├── ApprenticeFarmerNPCTemplate.uasset
│ │ │ │ │ ├── ApprenticeFarmerNPCTemplate.uexp
│ │ │ │ │ ├── ApprenticeHealerNPCTemplate.uasset
│ │ │ │ │ ├── ApprenticeHealerNPCTemplate.uexp
│ │ │ │ │ ├── ApprenticeInkeeperNPCTemplate.uasset
│ │ │ │ │ ├── ApprenticeInkeeperNPCTemplate.uexp
│ │ │ │ │ ├── ApprenticeLabourerNPCTemplate.uasset
│ │ │ │ │ ├── ApprenticeLabourerNPCTemplate.uexp
│ │ │ │ │ ├── ApprenticeWeaverNPCTemplate.uasset
│ │ │ │ │ ├── ApprenticeWeaverNPCTemplate.uexp
│ │ │ │ │ ├── ApprenticeWoodsmanNPCTemplate.uasset
│ │ │ │ │ ├── ApprenticeWoodsmanNPCTemplate.uexp
│ │ │ │ │ ├── HighNoTraitsVillagerIdleNPCTemplate.uasset
│ │ │ │ │ ├── HighNoTraitsVillagerIdleNPCTemplate.uexp
│ │ │ │ │ ├── HighVillagerIdleNPCTemplate.uasset
│ │ │ │ │ └── HighVillagerIdleNPCTemplate.uexp
│ │ │ │ ├── LowSkill/
│ │ │ │ │ ├── LowBeggarNPCTemplate.uasset
│ │ │ │ │ ├── LowBeggarNPCTemplate.uexp
│ │ │ │ │ ├── LowVillagerIdleNPCTemplate.uasset
│ │ │ │ │ ├── LowVillagerIdleNPCTemplate.uexp
│ │ │ │ │ ├── LowVillagerIdleNoTraitsNPCTemplate.uasset
│ │ │ │ │ └── LowVillagerIdleNoTraitsNPCTemplate.uexp
│ │ │ │ └── MediumSkill/
│ │ │ │ ├── MediumNoTraitsVillagerIdleNPCTemplate.uasset
│ │ │ │ ├── MediumNoTraitsVillagerIdleNPCTemplate.uexp
│ │ │ │ ├── MediumVillagerIdleNPCTemplate.uasset
│ │ │ │ ├── MediumVillagerIdleNPCTemplate.uexp
│ │ │ │ ├── NoviceBlacksmithNPCTemplate.uasset
│ │ │ │ ├── NoviceBlacksmithNPCTemplate.uexp
│ │ │ │ ├── NoviceCarpenterNPCTemplate.uasset
│ │ │ │ ├── NoviceCarpenterNPCTemplate.uexp
│ │ │ │ ├── NoviceEngineerNPCTemplate.uasset
│ │ │ │ ├── NoviceEngineerNPCTemplate.uexp
│ │ │ │ ├── NoviceFarmerNPCTemplate.uasset
│ │ │ │ ├── NoviceFarmerNPCTemplate.uexp
│ │ │ │ ├── NoviceHealerNPCTemplate.uasset
│ │ │ │ ├── NoviceHealerNPCTemplate.uexp
│ │ │ │ ├── NoviceInkeeperNPCTemplate.uasset
│ │ │ │ ├── NoviceInkeeperNPCTemplate.uexp
│ │ │ │ ├── NoviceLabourerNPCTemplate.uasset
│ │ │ │ ├── NoviceLabourerNPCTemplate.uexp
│ │ │ │ ├── NoviceWeaverNPCTemplate.uasset
│ │ │ │ ├── NoviceWeaverNPCTemplate.uexp
│ │ │ │ ├── NoviceWoodsmanNPCTemplate.uasset
│ │ │ │ └── NoviceWoodsmanNPCTemplate.uexp
│ │ │ ├── Billiards/
│ │ │ │ ├── 5.4.3-34507850+++UE5+Release-5.4-DeepSpace7.usmap
│ │ │ │ ├── BP_Table_Lamp.uasset
│ │ │ │ └── BP_Table_Lamp.uexp
│ │ │ ├── BlankGame/
│ │ │ │ ├── BP_CubePawn.combined
│ │ │ │ ├── BP_CubePawn.uasset
│ │ │ │ ├── BP_CubePawn.uexp
│ │ │ │ ├── BlankGame_Dumper-7.usmap
│ │ │ │ ├── MI_BlueCube.uasset
│ │ │ │ ├── MI_BlueCube.uexp
│ │ │ │ ├── M_Cube.uasset
│ │ │ │ ├── M_Cube.uexp
│ │ │ │ ├── SM_BlueCube.uasset
│ │ │ │ └── SM_BlueCube.uexp
│ │ │ ├── JOY/
│ │ │ │ ├── 5.4.3-34507850+++UE5+Release-5.4-JOY.usmap
│ │ │ │ ├── BP_GameMode_Base.uasset
│ │ │ │ └── BP_GameMode_Base.uexp
│ │ │ └── TheForeverWinter/
│ │ │ ├── DA_DailyGiftList.uasset
│ │ │ ├── DA_DailyGiftList.uexp
│ │ │ └── TheForeverWinter.usmap
│ │ ├── TestUE5_5/
│ │ │ └── BlankGame/
│ │ │ ├── BP_Test.uasset
│ │ │ ├── BP_Test.uexp
│ │ │ ├── BlankUE5_5.usmap
│ │ │ ├── M_Cube_1.uasset
│ │ │ ├── M_Cube_1.uexp
│ │ │ ├── SM_Cube.uasset
│ │ │ ├── SM_Cube.ubulk
│ │ │ ├── SM_Cube.uexp
│ │ │ ├── T_Test.uasset
│ │ │ ├── T_Test.ubulk
│ │ │ ├── T_Test.uexp
│ │ │ ├── T_pl01_001_body_D.uasset
│ │ │ ├── T_pl01_001_body_D.uexp
│ │ │ ├── WBP_Hello.uasset
│ │ │ └── WBP_Hello.uexp
│ │ ├── TestUE5_6/
│ │ │ └── BpThirdPerson/
│ │ │ ├── BP_ThirdPersonCharacter.uasset
│ │ │ ├── BP_ThirdPersonCharacter.uexp
│ │ │ ├── ExplicitEnumValuesExample.usmap
│ │ │ ├── MI_Quinn_01.uasset
│ │ │ ├── MI_Quinn_01.uexp
│ │ │ ├── M_Mannequin.uasset
│ │ │ ├── M_Mannequin.uexp
│ │ │ ├── SKM_Quinn_Simple.uasset
│ │ │ ├── SKM_Quinn_Simple.uexp
│ │ │ ├── SM_Cube.uasset
│ │ │ ├── SM_Cube.ubulk
│ │ │ └── SM_Cube.uexp
│ │ └── TestUnknownProperties/
│ │ ├── BP_DetPack_Charge.uasset
│ │ └── BP_DetPack_Charge.uexp
│ └── UAssetAPI.Tests.csproj
├── UAssetAPI.sln
└── docs/
├── book.toml
├── correct_pages.py
├── correct_summary.py
├── css/
│ └── custom.css
├── generate_docs.bat
├── generate_docs.sh
└── src/
├── README.md
├── SUMMARY.md
├── SUMMARY_header.md
├── api/
│ ├── uassetapi.ac7decrypt.md
│ ├── uassetapi.ac7xorkey.md
│ ├── uassetapi.assetbinaryreader.md
│ ├── uassetapi.assetbinarywriter.md
│ ├── uassetapi.crcgenerator.md
│ ├── uassetapi.customserializationflags.md
│ ├── uassetapi.customversion.md
│ ├── uassetapi.customversions.fanimphysobjectversion.md
│ ├── uassetapi.customversions.fassetregistryversion.md
│ ├── uassetapi.customversions.fcoreobjectversion.md
│ ├── uassetapi.customversions.feditorobjectversion.md
│ ├── uassetapi.customversions.ffortnitemainbranchobjectversion.md
│ ├── uassetapi.customversions.ffortnitereleasebranchcustomobjectversion.md
│ ├── uassetapi.customversions.fframeworkobjectversion.md
│ ├── uassetapi.customversions.fniagaracustomversion.md
│ ├── uassetapi.customversions.fniagaraobjectversion.md
│ ├── uassetapi.customversions.freleaseobjectversion.md
│ ├── uassetapi.customversions.fsequencerobjectversion.md
│ ├── uassetapi.customversions.fue5releasestreamobjectversion.md
│ ├── uassetapi.customversions.introducedattribute.md
│ ├── uassetapi.exporttypes.classexport.md
│ ├── uassetapi.exporttypes.datatableexport.md
│ ├── uassetapi.exporttypes.eclassserializationcontrolextension.md
│ ├── uassetapi.exporttypes.ecppform.md
│ ├── uassetapi.exporttypes.eexportfilterflags.md
│ ├── uassetapi.exporttypes.enumexport.md
│ ├── uassetapi.exporttypes.export.md
│ ├── uassetapi.exporttypes.fieldexport.md
│ ├── uassetapi.exporttypes.fstringtable.md
│ ├── uassetapi.exporttypes.functionexport.md
│ ├── uassetapi.exporttypes.furl.md
│ ├── uassetapi.exporttypes.levelexport.md
│ ├── uassetapi.exporttypes.metadataexport.md
│ ├── uassetapi.exporttypes.normalexport.md
│ ├── uassetapi.exporttypes.objectmetadataentry.md
│ ├── uassetapi.exporttypes.propertyexport.md
│ ├── uassetapi.exporttypes.rawexport.md
│ ├── uassetapi.exporttypes.serializedinterfacereference.md
│ ├── uassetapi.exporttypes.stringtableexport.md
│ ├── uassetapi.exporttypes.structexport.md
│ ├── uassetapi.exporttypes.udatatable.md
│ ├── uassetapi.exporttypes.uenum.md
│ ├── uassetapi.exporttypes.userdefinedstructexport.md
│ ├── uassetapi.fengineversion.md
│ ├── uassetapi.fgenerationinfo.md
│ ├── uassetapi.fieldtypes.earraydim.md
│ ├── uassetapi.fieldtypes.elifetimecondition.md
│ ├── uassetapi.fieldtypes.farrayproperty.md
│ ├── uassetapi.fieldtypes.fboolproperty.md
│ ├── uassetapi.fieldtypes.fbyteproperty.md
│ ├── uassetapi.fieldtypes.fclassproperty.md
│ ├── uassetapi.fieldtypes.fdelegateproperty.md
│ ├── uassetapi.fieldtypes.fenumproperty.md
│ ├── uassetapi.fieldtypes.ffield.md
│ ├── uassetapi.fieldtypes.fgenericproperty.md
│ ├── uassetapi.fieldtypes.finterfaceproperty.md
│ ├── uassetapi.fieldtypes.fmapproperty.md
│ ├── uassetapi.fieldtypes.fmulticastdelegateproperty.md
│ ├── uassetapi.fieldtypes.fmulticastinlinedelegateproperty.md
│ ├── uassetapi.fieldtypes.fnumericproperty.md
│ ├── uassetapi.fieldtypes.fobjectproperty.md
│ ├── uassetapi.fieldtypes.foptionalproperty.md
│ ├── uassetapi.fieldtypes.fproperty.md
│ ├── uassetapi.fieldtypes.fsetproperty.md
│ ├── uassetapi.fieldtypes.fsoftclassproperty.md
│ ├── uassetapi.fieldtypes.fsoftobjectproperty.md
│ ├── uassetapi.fieldtypes.fstructproperty.md
│ ├── uassetapi.fieldtypes.fweakobjectproperty.md
│ ├── uassetapi.fieldtypes.uarrayproperty.md
│ ├── uassetapi.fieldtypes.uassetclassproperty.md
│ ├── uassetapi.fieldtypes.uassetobjectproperty.md
│ ├── uassetapi.fieldtypes.uboolproperty.md
│ ├── uassetapi.fieldtypes.ubyteproperty.md
│ ├── uassetapi.fieldtypes.uclassproperty.md
│ ├── uassetapi.fieldtypes.udelegateproperty.md
│ ├── uassetapi.fieldtypes.udoubleproperty.md
│ ├── uassetapi.fieldtypes.uenumproperty.md
│ ├── uassetapi.fieldtypes.ufield.md
│ ├── uassetapi.fieldtypes.ufloatproperty.md
│ ├── uassetapi.fieldtypes.ugenericproperty.md
│ ├── uassetapi.fieldtypes.uint16property.md
│ ├── uassetapi.fieldtypes.uint64property.md
│ ├── uassetapi.fieldtypes.uint8property.md
│ ├── uassetapi.fieldtypes.uinterfaceproperty.md
│ ├── uassetapi.fieldtypes.uintproperty.md
│ ├── uassetapi.fieldtypes.ulazyobjectproperty.md
│ ├── uassetapi.fieldtypes.umapproperty.md
│ ├── uassetapi.fieldtypes.umulticastdelegateproperty.md
│ ├── uassetapi.fieldtypes.umulticastinlinedelegateproperty.md
│ ├── uassetapi.fieldtypes.umulticastsparsedelegateproperty.md
│ ├── uassetapi.fieldtypes.unameproperty.md
│ ├── uassetapi.fieldtypes.unumericproperty.md
│ ├── uassetapi.fieldtypes.uobjectproperty.md
│ ├── uassetapi.fieldtypes.uproperty.md
│ ├── uassetapi.fieldtypes.usetproperty.md
│ ├── uassetapi.fieldtypes.usoftclassproperty.md
│ ├── uassetapi.fieldtypes.usoftobjectproperty.md
│ ├── uassetapi.fieldtypes.ustrproperty.md
│ ├── uassetapi.fieldtypes.ustructproperty.md
│ ├── uassetapi.fieldtypes.utextproperty.md
│ ├── uassetapi.fieldtypes.uuint16property.md
│ ├── uassetapi.fieldtypes.uuint32property.md
│ ├── uassetapi.fieldtypes.uuint64property.md
│ ├── uassetapi.fieldtypes.uweakobjectproperty.md
│ ├── uassetapi.import.md
│ ├── uassetapi.inamemap.md
│ ├── uassetapi.invalidmappingsexception.md
│ ├── uassetapi.json.bytearrayjsonconverter.md
│ ├── uassetapi.json.fnamejsonconverter.md
│ ├── uassetapi.json.fpackageindexjsonconverter.md
│ ├── uassetapi.json.fsignedzerojsonconverter.md
│ ├── uassetapi.json.fstringjsonconverter.md
│ ├── uassetapi.json.fstringtablejsonconverter.md
│ ├── uassetapi.json.guidjsonconverter.md
│ ├── uassetapi.json.tmapjsonconverter-2.md
│ ├── uassetapi.json.uassetcontractresolver.md
│ ├── uassetapi.kismet.bytecode.eblueprinttextliteraltype.md
│ ├── uassetapi.kismet.bytecode.ecasttoken.md
│ ├── uassetapi.kismet.bytecode.eexprtoken.md
│ ├── uassetapi.kismet.bytecode.escriptinstrumentationtype.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_addmulticastdelegate.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_arrayconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_arraygetbyref.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_assert.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_binddelegate.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_bitfieldconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_breakpoint.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_byteconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_callmath.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_callmulticastdelegate.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_castbase.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_classcontext.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_classsparsedatavariable.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_clearmulticastdelegate.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_computedjump.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_context.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_context_failsilent.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_crossinterfacecast.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_defaultvariable.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_deprecatedop4a.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_doubleconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_dynamiccast.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_endarray.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_endarrayconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_endfunctionparms.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_endmap.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_endmapconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_endofscript.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_endparmvalue.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_endset.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_endsetconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_endstructconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_false.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_fieldpathconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_finalfunction.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_floatconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_instancedelegate.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_instancevariable.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_instrumentationevent.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_int64const.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_intconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_intconstbyte.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_interfacecontext.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_interfacetoobjcast.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_intone.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_intzero.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_jump.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_jumpifnot.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_let.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_letbase.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_letbool.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_letdelegate.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_letmulticastdelegate.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_letobj.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_letvalueonpersistentframe.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_letweakobjptr.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_localfinalfunction.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_localoutvariable.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_localvariable.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_localvirtualfunction.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_mapconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_metacast.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_nameconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_nointerface.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_noobject.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_nothing.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_nothingint32.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_objectconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_objtointerfacecast.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_popexecutionflow.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_popexecutionflowifnot.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_primitivecast.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_propertyconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_pushexecutionflow.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_removemulticastdelegate.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_return.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_rotationconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_self.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_setarray.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_setconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_setmap.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_setset.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_skip.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_skipoffsetconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_softobjectconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_stringconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_structconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_structmembercontext.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_switchvalue.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_textconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_tracepoint.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_transformconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_true.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_uint64const.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_unicodestringconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_variablebase.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_vector3fconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_vectorconst.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_virtualfunction.md
│ ├── uassetapi.kismet.bytecode.expressions.ex_wiretracepoint.md
│ ├── uassetapi.kismet.bytecode.expressions.fkismetswitchcase.md
│ ├── uassetapi.kismet.bytecode.expressionserializer.md
│ ├── uassetapi.kismet.bytecode.fscripttext.md
│ ├── uassetapi.kismet.bytecode.kismetexpression-1.md
│ ├── uassetapi.kismet.bytecode.kismetexpression.md
│ ├── uassetapi.kismet.bytecode.kismetpropertypointer.md
│ ├── uassetapi.kismet.kismetserializer.md
│ ├── uassetapi.mainserializer.md
│ ├── uassetapi.namemapoutofrangeexception.md
│ ├── uassetapi.pakbuilder.md
│ ├── uassetapi.pakcompression.md
│ ├── uassetapi.pakreader.md
│ ├── uassetapi.pakversion.md
│ ├── uassetapi.pakwriter.md
│ ├── uassetapi.propertytypes.objects.ancestryinfo.md
│ ├── uassetapi.propertytypes.objects.arraypropertydata.md
│ ├── uassetapi.propertytypes.objects.assetobjectpropertydata.md
│ ├── uassetapi.propertytypes.objects.boolpropertydata.md
│ ├── uassetapi.propertytypes.objects.bytepropertydata.md
│ ├── uassetapi.propertytypes.objects.bytepropertytype.md
│ ├── uassetapi.propertytypes.objects.delegatepropertydata.md
│ ├── uassetapi.propertytypes.objects.doublepropertydata.md
│ ├── uassetapi.propertytypes.objects.enumpropertydata.md
│ ├── uassetapi.propertytypes.objects.eoverriddenpropertyoperation.md
│ ├── uassetapi.propertytypes.objects.epropertytagextension.md
│ ├── uassetapi.propertytypes.objects.epropertytagflags.md
│ ├── uassetapi.propertytypes.objects.etextflag.md
│ ├── uassetapi.propertytypes.objects.etransformtype.md
│ ├── uassetapi.propertytypes.objects.fdelegate.md
│ ├── uassetapi.propertytypes.objects.fformatargumentdata.md
│ ├── uassetapi.propertytypes.objects.fformatargumentvalue.md
│ ├── uassetapi.propertytypes.objects.fieldpathpropertydata.md
│ ├── uassetapi.propertytypes.objects.floatpropertydata.md
│ ├── uassetapi.propertytypes.objects.fnumberformattingoptions.md
│ ├── uassetapi.propertytypes.objects.fsoftobjectpath.md
│ ├── uassetapi.propertytypes.objects.ftoplevelassetpath.md
│ ├── uassetapi.propertytypes.objects.int16propertydata.md
│ ├── uassetapi.propertytypes.objects.int64propertydata.md
│ ├── uassetapi.propertytypes.objects.int8propertydata.md
│ ├── uassetapi.propertytypes.objects.interfacepropertydata.md
│ ├── uassetapi.propertytypes.objects.intpropertydata.md
│ ├── uassetapi.propertytypes.objects.istruct-1.md
│ ├── uassetapi.propertytypes.objects.mappropertydata.md
│ ├── uassetapi.propertytypes.objects.multicastdelegatepropertydata.md
│ ├── uassetapi.propertytypes.objects.multicastinlinedelegatepropertydata.md
│ ├── uassetapi.propertytypes.objects.multicastsparsedelegatepropertydata.md
│ ├── uassetapi.propertytypes.objects.namepropertydata.md
│ ├── uassetapi.propertytypes.objects.objectpropertydata.md
│ ├── uassetapi.propertytypes.objects.propertydata-1.md
│ ├── uassetapi.propertytypes.objects.propertydata.md
│ ├── uassetapi.propertytypes.objects.propertyserializationcontext.md
│ ├── uassetapi.propertytypes.objects.setpropertydata.md
│ ├── uassetapi.propertytypes.objects.softobjectpropertydata.md
│ ├── uassetapi.propertytypes.objects.strpropertydata.md
│ ├── uassetapi.propertytypes.objects.texthistorytype.md
│ ├── uassetapi.propertytypes.objects.textpropertydata.md
│ ├── uassetapi.propertytypes.objects.uint16propertydata.md
│ ├── uassetapi.propertytypes.objects.uint32propertydata.md
│ ├── uassetapi.propertytypes.objects.uint64propertydata.md
│ ├── uassetapi.propertytypes.objects.unknownpropertydata.md
│ ├── uassetapi.propertytypes.objects.weakobjectpropertydata.md
│ ├── uassetapi.propertytypes.structs.box2dpropertydata.md
│ ├── uassetapi.propertytypes.structs.box2fpropertydata.md
│ ├── uassetapi.propertytypes.structs.boxpropertydata.md
│ ├── uassetapi.propertytypes.structs.clothloddatacommonpropertydata.md
│ ├── uassetapi.propertytypes.structs.clothloddatapropertydata.md
│ ├── uassetapi.propertytypes.structs.clothtetherdatapropertydata.md
│ ├── uassetapi.propertytypes.structs.colormaterialinputpropertydata.md
│ ├── uassetapi.propertytypes.structs.colorpropertydata.md
│ ├── uassetapi.propertytypes.structs.datetimepropertydata.md
│ ├── uassetapi.propertytypes.structs.deprecateslatevector2dpropertydata.md
│ ├── uassetapi.propertytypes.structs.esectionevaluationflags.md
│ ├── uassetapi.propertytypes.structs.expressioninputpropertydata.md
│ ├── uassetapi.propertytypes.structs.fentityandmetadataindex.md
│ ├── uassetapi.propertytypes.structs.fentry.md
│ ├── uassetapi.propertytypes.structs.fevaluationtreeentryhandle.md
│ ├── uassetapi.propertytypes.structs.flevelsequencelegacyobjectreference.md
│ ├── uassetapi.propertytypes.structs.floatrangepropertydata.md
│ ├── uassetapi.propertytypes.structs.fmeshtomeshvertdata.md
│ ├── uassetapi.propertytypes.structs.fmoviescenechannel-1.md
│ ├── uassetapi.propertytypes.structs.fmoviescenedoublechannel.md
│ ├── uassetapi.propertytypes.structs.fmoviescenedoublevalue.md
│ ├── uassetapi.propertytypes.structs.fmoviesceneevaluationfieldentitytree.md
│ ├── uassetapi.propertytypes.structs.fmoviesceneevaluationkey.md
│ ├── uassetapi.propertytypes.structs.fmoviesceneevaluationtree.md
│ ├── uassetapi.propertytypes.structs.fmoviesceneevaluationtreenode.md
│ ├── uassetapi.propertytypes.structs.fmoviesceneevaluationtreenodehandle.md
│ ├── uassetapi.propertytypes.structs.fmoviesceneeventparameters.md
│ ├── uassetapi.propertytypes.structs.fmoviescenefloatchannel.md
│ ├── uassetapi.propertytypes.structs.fmoviescenefloatvalue.md
│ ├── uassetapi.propertytypes.structs.fmoviescenesegment.md
│ ├── uassetapi.propertytypes.structs.fmoviescenesubsectiondata.md
│ ├── uassetapi.propertytypes.structs.fmoviescenesubsectionfielddata.md
│ ├── uassetapi.propertytypes.structs.fmoviescenesubsequencetree.md
│ ├── uassetapi.propertytypes.structs.fmoviescenesubsequencetreeentry.md
│ ├── uassetapi.propertytypes.structs.fmoviescenetangentdata.md
│ ├── uassetapi.propertytypes.structs.fmoviescenetrackfielddata.md
│ ├── uassetapi.propertytypes.structs.fmoviescenevalue-1.md
│ ├── uassetapi.propertytypes.structs.fnamecurvekey.md
│ ├── uassetapi.propertytypes.structs.fnavagentselector.md
│ ├── uassetapi.propertytypes.structs.fontcharacterpropertydata.md
│ ├── uassetapi.propertytypes.structs.fontdatapropertydata.md
│ ├── uassetapi.propertytypes.structs.framenumberpropertydata.md
│ ├── uassetapi.propertytypes.structs.fsectionevaluationdatatree.md
│ ├── uassetapi.propertytypes.structs.fstringcurvekey.md
│ ├── uassetapi.propertytypes.structs.gameplaytagcontainerpropertydata.md
│ ├── uassetapi.propertytypes.structs.guidpropertydata.md
│ ├── uassetapi.propertytypes.structs.intpointpropertydata.md
│ ├── uassetapi.propertytypes.structs.intvector2propertydata.md
│ ├── uassetapi.propertytypes.structs.intvectorpropertydata.md
│ ├── uassetapi.propertytypes.structs.keyhandlemappropertydata.md
│ ├── uassetapi.propertytypes.structs.levelsequenceobjectreferencemappropertydata.md
│ ├── uassetapi.propertytypes.structs.linearcolorpropertydata.md
│ ├── uassetapi.propertytypes.structs.materialattributesinputpropertydata.md
│ ├── uassetapi.propertytypes.structs.materialoverridenanitepropertydata.md
│ ├── uassetapi.propertytypes.structs.matrixpropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenedoublechannelpropertydata.md
│ ├── uassetapi.propertytypes.structs.moviesceneevaltemplateptrpropertydata.md
│ ├── uassetapi.propertytypes.structs.moviesceneevaluationfieldentitytreepropertydata.md
│ ├── uassetapi.propertytypes.structs.moviesceneevaluationkeypropertydata.md
│ ├── uassetapi.propertytypes.structs.moviesceneeventparameterspropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenefloatchannelpropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenefloatvaluepropertydata.md
│ ├── uassetapi.propertytypes.structs.moviesceneframerangepropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenegenerationledgerpropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenesegmentidentifierpropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenesegmentpropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenesequenceidpropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenesequenceinstancedataptrpropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenesubsectionfielddatapropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenesubsequencetreepropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenetemplatepropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenetrackfielddatapropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenetrackidentifierpropertydata.md
│ ├── uassetapi.propertytypes.structs.moviescenetrackimplementationptrpropertydata.md
│ ├── uassetapi.propertytypes.structs.namecurvekeypropertydata.md
│ ├── uassetapi.propertytypes.structs.navagentselectorpropertydata.md
│ ├── uassetapi.propertytypes.structs.niagaradatachannelvariablepropertydata.md
│ ├── uassetapi.propertytypes.structs.niagaradatainterfacegpuparaminfopropertydata.md
│ ├── uassetapi.propertytypes.structs.niagaravariablebasepropertydata.md
│ ├── uassetapi.propertytypes.structs.niagaravariablepropertydata.md
│ ├── uassetapi.propertytypes.structs.niagaravariablewithoffsetpropertydata.md
│ ├── uassetapi.propertytypes.structs.perplatformboolpropertydata.md
│ ├── uassetapi.propertytypes.structs.perplatformfloatpropertydata.md
│ ├── uassetapi.propertytypes.structs.perplatformframeratepropertydata.md
│ ├── uassetapi.propertytypes.structs.perplatformintpropertydata.md
│ ├── uassetapi.propertytypes.structs.perqualitylevelfloatpropertydata.md
│ ├── uassetapi.propertytypes.structs.perqualitylevelintpropertydata.md
│ ├── uassetapi.propertytypes.structs.planepropertydata.md
│ ├── uassetapi.propertytypes.structs.quatpropertydata.md
│ ├── uassetapi.propertytypes.structs.rawstructpropertydata.md
│ ├── uassetapi.propertytypes.structs.richcurvekeypropertydata.md
│ ├── uassetapi.propertytypes.structs.rotatorpropertydata.md
│ ├── uassetapi.propertytypes.structs.scalarmaterialinputpropertydata.md
│ ├── uassetapi.propertytypes.structs.sectionevaluationdatatreepropertydata.md
│ ├── uassetapi.propertytypes.structs.skeletalmeshareaweightedtrianglesamplerpropertydata.md
│ ├── uassetapi.propertytypes.structs.skeletalmeshsamplinglodbuiltdatapropertydata.md
│ ├── uassetapi.propertytypes.structs.smartnamepropertydata.md
│ ├── uassetapi.propertytypes.structs.softassetpathpropertydata.md
│ ├── uassetapi.propertytypes.structs.softclasspathpropertydata.md
│ ├── uassetapi.propertytypes.structs.softobjectpathpropertydata.md
│ ├── uassetapi.propertytypes.structs.stringassetreferencepropertydata.md
│ ├── uassetapi.propertytypes.structs.stringclassreferencepropertydata.md
│ ├── uassetapi.propertytypes.structs.stringcurvekeypropertydata.md
│ ├── uassetapi.propertytypes.structs.structpropertydata.md
│ ├── uassetapi.propertytypes.structs.tevaluationtreeentrycontainer-1.md
│ ├── uassetapi.propertytypes.structs.timespanpropertydata.md
│ ├── uassetapi.propertytypes.structs.tmoviesceneevaluationtree-1.md
│ ├── uassetapi.propertytypes.structs.twovectorspropertydata.md
│ ├── uassetapi.propertytypes.structs.vector2dpropertydata.md
│ ├── uassetapi.propertytypes.structs.vector2fpropertydata.md
│ ├── uassetapi.propertytypes.structs.vector2materialinputpropertydata.md
│ ├── uassetapi.propertytypes.structs.vector3fpropertydata.md
│ ├── uassetapi.propertytypes.structs.vector4fpropertydata.md
│ ├── uassetapi.propertytypes.structs.vector4propertydata.md
│ ├── uassetapi.propertytypes.structs.vectormaterialinputpropertydata.md
│ ├── uassetapi.propertytypes.structs.vectornetquantize100propertydata.md
│ ├── uassetapi.propertytypes.structs.vectornetquantize10propertydata.md
│ ├── uassetapi.propertytypes.structs.vectornetquantizenormalpropertydata.md
│ ├── uassetapi.propertytypes.structs.vectornetquantizepropertydata.md
│ ├── uassetapi.propertytypes.structs.vectorpropertydata.md
│ ├── uassetapi.propertytypes.structs.viewtargetblendfunction.md
│ ├── uassetapi.propertytypes.structs.viewtargetblendparamspropertydata.md
│ ├── uassetapi.propertytypes.structs.weightedrandomsamplerpropertydata.md
│ ├── uassetapi.repakinterop.md
│ ├── uassetapi.streamcallbacks.md
│ ├── uassetapi.structtypes.skeletalmeshsamplingregionbuiltdatapropertydata.md
│ ├── uassetapi.uaputils.md
│ ├── uassetapi.uasset.md
│ ├── uassetapi.unknownengineversionexception.md
│ ├── uassetapi.unrealbinaryreader.md
│ ├── uassetapi.unrealbinarywriter.md
│ ├── uassetapi.unrealtypes.comparer2-1.md
│ ├── uassetapi.unrealtypes.dictionaryenumerator-2.md
│ ├── uassetapi.unrealtypes.eaxis.md
│ ├── uassetapi.unrealtypes.eclassflags.md
│ ├── uassetapi.unrealtypes.efonthinting.md
│ ├── uassetapi.unrealtypes.efontloadingpolicy.md
│ ├── uassetapi.unrealtypes.efunctionflags.md
│ ├── uassetapi.unrealtypes.einterpcurvemode.md
│ ├── uassetapi.unrealtypes.emappednametype.md
│ ├── uassetapi.unrealtypes.engineenums.animationcompressionformat.md
│ ├── uassetapi.unrealtypes.engineenums.animationkeyformat.md
│ ├── uassetapi.unrealtypes.engineenums.animphyscollisiontype.md
│ ├── uassetapi.unrealtypes.engineenums.animphystwistaxis.md
│ ├── uassetapi.unrealtypes.engineenums.beam2sourcetargetmethod.md
│ ├── uassetapi.unrealtypes.engineenums.beam2sourcetargettangentmethod.md
│ ├── uassetapi.unrealtypes.engineenums.beammodifiertype.md
│ ├── uassetapi.unrealtypes.engineenums.cylinderheightaxis.md
│ ├── uassetapi.unrealtypes.engineenums.distributionparammode.md
│ ├── uassetapi.unrealtypes.engineenums.eactorupdateoverlapsmethod.md
│ ├── uassetapi.unrealtypes.engineenums.eadditiveanimationtype.md
│ ├── uassetapi.unrealtypes.engineenums.eadditivebaseposetype.md
│ ├── uassetapi.unrealtypes.engineenums.eadmanagerdelegate.md
│ ├── uassetapi.unrealtypes.engineenums.eairabsorptionmethod.md
│ ├── uassetapi.unrealtypes.engineenums.ealphablendoption.md
│ ├── uassetapi.unrealtypes.engineenums.ealphachannelmode.md
│ ├── uassetapi.unrealtypes.engineenums.eangularconstraintmotion.md
│ ├── uassetapi.unrealtypes.engineenums.eangulardrivemode.md
│ ├── uassetapi.unrealtypes.engineenums.eanimalphainputtype.md
│ ├── uassetapi.unrealtypes.engineenums.eanimassetcurveflags.md
│ ├── uassetapi.unrealtypes.engineenums.eanimationmode.md
│ ├── uassetapi.unrealtypes.engineenums.eanimcurvetype.md
│ ├── uassetapi.unrealtypes.engineenums.eanimgrouprole.md
│ ├── uassetapi.unrealtypes.engineenums.eaniminterpolationtype.md
│ ├── uassetapi.unrealtypes.engineenums.eanimlinkmethod.md
│ ├── uassetapi.unrealtypes.engineenums.eanimnotifyeventtype.md
│ ├── uassetapi.unrealtypes.engineenums.eantialiasingmethod.md
│ ├── uassetapi.unrealtypes.engineenums.eapplicationstate.md
│ ├── uassetapi.unrealtypes.engineenums.easpectratioaxisconstraint.md
│ ├── uassetapi.unrealtypes.engineenums.eattachlocation.md
│ ├── uassetapi.unrealtypes.engineenums.eattachmentrule.md
│ ├── uassetapi.unrealtypes.engineenums.eattenuationdistancemodel.md
│ ├── uassetapi.unrealtypes.engineenums.eattenuationshape.md
│ ├── uassetapi.unrealtypes.engineenums.eattractorparticleselectionmethod.md
│ ├── uassetapi.unrealtypes.engineenums.eaudiocomponentplaystate.md
│ ├── uassetapi.unrealtypes.engineenums.eaudiofadercurve.md
│ ├── uassetapi.unrealtypes.engineenums.eaudiooutputtarget.md
│ ├── uassetapi.unrealtypes.engineenums.eaudiorecordingexporttype.md
│ ├── uassetapi.unrealtypes.engineenums.eautoexposuremethod.md
│ ├── uassetapi.unrealtypes.engineenums.eautoexposuremethodui.md
│ ├── uassetapi.unrealtypes.engineenums.eautopossessai.md
│ ├── uassetapi.unrealtypes.engineenums.eautoreceiveinput.md
│ ├── uassetapi.unrealtypes.engineenums.eaxisoption.md
│ ├── uassetapi.unrealtypes.engineenums.ebeam2method.md
│ ├── uassetapi.unrealtypes.engineenums.ebeamtapermethod.md
│ ├── uassetapi.unrealtypes.engineenums.eblendablelocation.md
│ ├── uassetapi.unrealtypes.engineenums.eblendmode.md
│ ├── uassetapi.unrealtypes.engineenums.eblendspaceaxis.md
│ ├── uassetapi.unrealtypes.engineenums.ebloommethod.md
│ ├── uassetapi.unrealtypes.engineenums.eblueprintcompilemode.md
│ ├── uassetapi.unrealtypes.engineenums.eblueprintnativizationflag.md
│ ├── uassetapi.unrealtypes.engineenums.eblueprintpinstyletype.md
│ ├── uassetapi.unrealtypes.engineenums.eblueprintstatus.md
│ ├── uassetapi.unrealtypes.engineenums.eblueprinttype.md
│ ├── uassetapi.unrealtypes.engineenums.ebodycollisionresponse.md
│ ├── uassetapi.unrealtypes.engineenums.eboneaxis.md
│ ├── uassetapi.unrealtypes.engineenums.ebonecontrolspace.md
│ ├── uassetapi.unrealtypes.engineenums.ebonefilteractionoption.md
│ ├── uassetapi.unrealtypes.engineenums.ebonerotationsource.md
│ ├── uassetapi.unrealtypes.engineenums.ebonespaces.md
│ ├── uassetapi.unrealtypes.engineenums.ebonetranslationretargetingmode.md
│ ├── uassetapi.unrealtypes.engineenums.ebonevisibilitystatus.md
│ ├── uassetapi.unrealtypes.engineenums.ebrushtype.md
│ ├── uassetapi.unrealtypes.engineenums.ecameraalphablendmode.md
│ ├── uassetapi.unrealtypes.engineenums.ecameraanimplayspace.md
│ ├── uassetapi.unrealtypes.engineenums.ecameraprojectionmode.md
│ ├── uassetapi.unrealtypes.engineenums.ecamerashakeattenuation.md
│ ├── uassetapi.unrealtypes.engineenums.ecanbecharacterbase.md
│ ├── uassetapi.unrealtypes.engineenums.ecancreateconnectionresponse.md
│ ├── uassetapi.unrealtypes.engineenums.echannelmaskparametercolor.md
│ ├── uassetapi.unrealtypes.engineenums.eclampmode.md
│ ├── uassetapi.unrealtypes.engineenums.eclearsceneoptions.md
│ ├── uassetapi.unrealtypes.engineenums.eclothmassmode.md
│ ├── uassetapi.unrealtypes.engineenums.ecloudstoragedelegate.md
│ ├── uassetapi.unrealtypes.engineenums.ecollisionchannel.md
│ ├── uassetapi.unrealtypes.engineenums.ecollisionenabled.md
│ ├── uassetapi.unrealtypes.engineenums.ecollisionresponse.md
│ ├── uassetapi.unrealtypes.engineenums.ecollisiontraceflag.md
│ ├── uassetapi.unrealtypes.engineenums.ecomponentcreationmethod.md
│ ├── uassetapi.unrealtypes.engineenums.ecomponentmobility.md
│ ├── uassetapi.unrealtypes.engineenums.ecomponentsockettype.md
│ ├── uassetapi.unrealtypes.engineenums.ecomponenttype.md
│ ├── uassetapi.unrealtypes.engineenums.ecompositetexturemode.md
│ ├── uassetapi.unrealtypes.engineenums.ecompositingsamplecount.md
│ ├── uassetapi.unrealtypes.engineenums.econstraintframe.md
│ ├── uassetapi.unrealtypes.engineenums.econstrainttransform.md
│ ├── uassetapi.unrealtypes.engineenums.econtrolconstraint.md
│ ├── uassetapi.unrealtypes.engineenums.econtrolleranalogstick.md
│ ├── uassetapi.unrealtypes.engineenums.ecopytype.md
│ ├── uassetapi.unrealtypes.engineenums.ecsgoper.md
│ ├── uassetapi.unrealtypes.engineenums.ecurveblendoption.md
│ ├── uassetapi.unrealtypes.engineenums.ecurvetablemode.md
│ ├── uassetapi.unrealtypes.engineenums.ecustomdepthstencil.md
│ ├── uassetapi.unrealtypes.engineenums.ecustommaterialoutputtype.md
│ ├── uassetapi.unrealtypes.engineenums.ecustomtimestepsynchronizationstate.md
│ ├── uassetapi.unrealtypes.engineenums.edecalblendmode.md
│ ├── uassetapi.unrealtypes.engineenums.edecompressiontype.md
│ ├── uassetapi.unrealtypes.engineenums.edefaultbackbufferpixelformat.md
│ ├── uassetapi.unrealtypes.engineenums.edemoplayfailure.md
│ ├── uassetapi.unrealtypes.engineenums.edepthoffieldfunctionvalue.md
│ ├── uassetapi.unrealtypes.engineenums.edepthoffieldmethod.md
│ ├── uassetapi.unrealtypes.engineenums.edetachmentrule.md
│ ├── uassetapi.unrealtypes.engineenums.edetailmode.md
│ ├── uassetapi.unrealtypes.engineenums.edistributionvectorlockflags.md
│ ├── uassetapi.unrealtypes.engineenums.edistributionvectormirrorflags.md
│ ├── uassetapi.unrealtypes.engineenums.edofmode.md
│ ├── uassetapi.unrealtypes.engineenums.edrawdebugitemtype.md
│ ├── uassetapi.unrealtypes.engineenums.edrawdebugtrace.md
│ ├── uassetapi.unrealtypes.engineenums.edynamicforcefeedbackaction.md
│ ├── uassetapi.unrealtypes.engineenums.eearlyzpass.md
│ ├── uassetapi.unrealtypes.engineenums.eeasingfunc.md
│ ├── uassetapi.unrealtypes.engineenums.eedgraphpindirection.md
│ ├── uassetapi.unrealtypes.engineenums.eemitterdynamicparametervalue.md
│ ├── uassetapi.unrealtypes.engineenums.eemitternormalsmode.md
│ ├── uassetapi.unrealtypes.engineenums.eemitterrendermode.md
│ ├── uassetapi.unrealtypes.engineenums.eendplayreason.md
│ ├── uassetapi.unrealtypes.engineenums.eevaluatecurvetableresult.md
│ ├── uassetapi.unrealtypes.engineenums.eevaluatordatasource.md
│ ├── uassetapi.unrealtypes.engineenums.eevaluatormode.md
│ ├── uassetapi.unrealtypes.engineenums.efastarrayserializerdeltaflags.md
│ ├── uassetapi.unrealtypes.engineenums.efilterinterpolationtype.md
│ ├── uassetapi.unrealtypes.engineenums.efontcachetype.md
│ ├── uassetapi.unrealtypes.engineenums.efontimportcharacterset.md
│ ├── uassetapi.unrealtypes.engineenums.eformatargumenttype.md
│ ├── uassetapi.unrealtypes.engineenums.efrictioncombinemode.md
│ ├── uassetapi.unrealtypes.engineenums.efullyloadpackagetype.md
│ ├── uassetapi.unrealtypes.engineenums.efunctioninputtype.md
│ ├── uassetapi.unrealtypes.engineenums.egbufferformat.md
│ ├── uassetapi.unrealtypes.engineenums.egrammaticalgender.md
│ ├── uassetapi.unrealtypes.engineenums.egrammaticalnumber.md
│ ├── uassetapi.unrealtypes.engineenums.egraphaxisstyle.md
│ ├── uassetapi.unrealtypes.engineenums.egraphdatastyle.md
│ ├── uassetapi.unrealtypes.engineenums.egraphtype.md
│ ├── uassetapi.unrealtypes.engineenums.ehascustomnavigablegeometry.md
│ ├── uassetapi.unrealtypes.engineenums.ehitproxypriority.md
│ ├── uassetapi.unrealtypes.engineenums.ehoriztextaligment.md
│ ├── uassetapi.unrealtypes.engineenums.eimportancelevel.md
│ ├── uassetapi.unrealtypes.engineenums.eimportanceweight.md
│ ├── uassetapi.unrealtypes.engineenums.eindirectlightingcachequality.md
│ ├── uassetapi.unrealtypes.engineenums.einertializationbonestate.md
│ ├── uassetapi.unrealtypes.engineenums.einertializationspace.md
│ ├── uassetapi.unrealtypes.engineenums.einertializationstate.md
│ ├── uassetapi.unrealtypes.engineenums.einitialoscillatoroffset.md
│ ├── uassetapi.unrealtypes.engineenums.einputevent.md
│ ├── uassetapi.unrealtypes.engineenums.einterpmoveaxis.md
│ ├── uassetapi.unrealtypes.engineenums.einterptobehaviourtype.md
│ ├── uassetapi.unrealtypes.engineenums.einterptrackmoverotmode.md
│ ├── uassetapi.unrealtypes.engineenums.ekinematicbonesupdatetophysics.md
│ ├── uassetapi.unrealtypes.engineenums.elandscapecullingprecision.md
│ ├── uassetapi.unrealtypes.engineenums.elegendposition.md
│ ├── uassetapi.unrealtypes.engineenums.elerpinterpolationmode.md
│ ├── uassetapi.unrealtypes.engineenums.elightingbuildquality.md
│ ├── uassetapi.unrealtypes.engineenums.elightmappaddingtype.md
│ ├── uassetapi.unrealtypes.engineenums.elightmaptype.md
│ ├── uassetapi.unrealtypes.engineenums.elightunits.md
│ ├── uassetapi.unrealtypes.engineenums.elinearconstraintmotion.md
│ ├── uassetapi.unrealtypes.engineenums.elocationbonesocketselectionmethod.md
│ ├── uassetapi.unrealtypes.engineenums.elocationbonesocketsource.md
│ ├── uassetapi.unrealtypes.engineenums.elocationemitterselectionmethod.md
│ ├── uassetapi.unrealtypes.engineenums.elocationskelvertsurfacesource.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialattributeblend.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialdecalresponse.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialdomain.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialexposedtextureproperty.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialexposedviewproperty.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialfunctionusage.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialmergetype.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialparameterassociation.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialpositiontransformsource.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialproperty.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialsamplertype.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialsceneattributeinputmode.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialshadingmodel.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialstencilcompare.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialtessellationmode.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialusage.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialvectorcoordtransform.md
│ ├── uassetapi.unrealtypes.engineenums.ematerialvectorcoordtransformsource.md
│ ├── uassetapi.unrealtypes.engineenums.ematrixcolumns.md
│ ├── uassetapi.unrealtypes.engineenums.emaxconcurrentresolutionrule.md
│ ├── uassetapi.unrealtypes.engineenums.emeshbufferaccess.md
│ ├── uassetapi.unrealtypes.engineenums.emeshcamerafacingoptions.md
│ ├── uassetapi.unrealtypes.engineenums.emeshcamerafacingupaxis.md
│ ├── uassetapi.unrealtypes.engineenums.emeshfeatureimportance.md
│ ├── uassetapi.unrealtypes.engineenums.emeshinstancingreplacementmethod.md
│ ├── uassetapi.unrealtypes.engineenums.emeshlodselectiontype.md
│ ├── uassetapi.unrealtypes.engineenums.emeshmergetype.md
│ ├── uassetapi.unrealtypes.engineenums.emeshscreenalignment.md
│ ├── uassetapi.unrealtypes.engineenums.emicrotransactiondelegate.md
│ ├── uassetapi.unrealtypes.engineenums.emicrotransactionresult.md
│ ├── uassetapi.unrealtypes.engineenums.emobilemsaasamplecount.md
│ ├── uassetapi.unrealtypes.engineenums.emoduletype.md
│ ├── uassetapi.unrealtypes.engineenums.emonochannelupmixmethod.md
│ ├── uassetapi.unrealtypes.engineenums.emontagenotifyticktype.md
│ ├── uassetapi.unrealtypes.engineenums.emontageplayreturntype.md
│ ├── uassetapi.unrealtypes.engineenums.emontagesubstepresult.md
│ ├── uassetapi.unrealtypes.engineenums.emousecapturemode.md
│ ├── uassetapi.unrealtypes.engineenums.emouselockmode.md
│ ├── uassetapi.unrealtypes.engineenums.emovecomponentaction.md
│ ├── uassetapi.unrealtypes.engineenums.emovementmode.md
│ ├── uassetapi.unrealtypes.engineenums.enaturalsoundfalloffmode.md
│ ├── uassetapi.unrealtypes.engineenums.enavdatagatheringmode.md
│ ├── uassetapi.unrealtypes.engineenums.enavdatagatheringmodeconfig.md
│ ├── uassetapi.unrealtypes.engineenums.enavigationoptionflag.md
│ ├── uassetapi.unrealtypes.engineenums.enavigationqueryresult.md
│ ├── uassetapi.unrealtypes.engineenums.enavlinkdirection.md
│ ├── uassetapi.unrealtypes.engineenums.enavpathevent.md
│ ├── uassetapi.unrealtypes.engineenums.enetdormancy.md
│ ├── uassetapi.unrealtypes.engineenums.enetrole.md
│ ├── uassetapi.unrealtypes.engineenums.enetworkfailure.md
│ ├── uassetapi.unrealtypes.engineenums.enetworklagstate.md
│ ├── uassetapi.unrealtypes.engineenums.enetworksmoothingmode.md
│ ├── uassetapi.unrealtypes.engineenums.enodeadvancedpins.md
│ ├── uassetapi.unrealtypes.engineenums.enodeenabledstate.md
│ ├── uassetapi.unrealtypes.engineenums.enodetitletype.md
│ ├── uassetapi.unrealtypes.engineenums.enoisefunction.md
│ ├── uassetapi.unrealtypes.engineenums.enormalmode.md
│ ├── uassetapi.unrealtypes.engineenums.enotifyfiltertype.md
│ ├── uassetapi.unrealtypes.engineenums.enotifytriggermode.md
│ ├── uassetapi.unrealtypes.engineenums.eobjecttypequery.md
│ ├── uassetapi.unrealtypes.engineenums.eocclusioncombinemode.md
│ ├── uassetapi.unrealtypes.engineenums.eopacitysourcemode.md
│ ├── uassetapi.unrealtypes.engineenums.eoptimizationtype.md
│ ├── uassetapi.unrealtypes.engineenums.eorbitchainmode.md
│ ├── uassetapi.unrealtypes.engineenums.eoscillatorwaveform.md
│ ├── uassetapi.unrealtypes.engineenums.eoverlapfilteroption.md
│ ├── uassetapi.unrealtypes.engineenums.epanningmethod.md
│ ├── uassetapi.unrealtypes.engineenums.eparticleaxislock.md
│ ├── uassetapi.unrealtypes.engineenums.eparticleburstmethod.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlecameraoffsetupdatemethod.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlecollisioncomplete.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlecollisionmode.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlecollisionresponse.md
│ ├── uassetapi.unrealtypes.engineenums.eparticledetailmode.md
│ ├── uassetapi.unrealtypes.engineenums.eparticleeventtype.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlescreenalignment.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlesignificancelevel.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlesortmode.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlesourceselectionmethod.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlesubuvinterpmethod.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlesysparamtype.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlesysteminsignificancereaction.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlesystemocclusionboundsmethod.md
│ ├── uassetapi.unrealtypes.engineenums.eparticlesystemupdatemode.md
│ ├── uassetapi.unrealtypes.engineenums.eparticleuvflipmode.md
│ ├── uassetapi.unrealtypes.engineenums.ephysbodyop.md
│ ├── uassetapi.unrealtypes.engineenums.ephysicalmaterialmaskcolor.md
│ ├── uassetapi.unrealtypes.engineenums.ephysicalsurface.md
│ ├── uassetapi.unrealtypes.engineenums.ephysicstransformupdatemode.md
│ ├── uassetapi.unrealtypes.engineenums.ephysicstype.md
│ ├── uassetapi.unrealtypes.engineenums.epincontainertype.md
│ ├── uassetapi.unrealtypes.engineenums.epinhidingmode.md
│ ├── uassetapi.unrealtypes.engineenums.eplaneconstraintaxissetting.md
│ ├── uassetapi.unrealtypes.engineenums.eplatforminterfacedatatype.md
│ ├── uassetapi.unrealtypes.engineenums.epostcopyoperation.md
│ ├── uassetapi.unrealtypes.engineenums.epreviewanimationblueprintapplicationmethod.md
│ ├── uassetapi.unrealtypes.engineenums.eprimaryassetcookrule.md
│ ├── uassetapi.unrealtypes.engineenums.epriorityattenuationmethod.md
│ ├── uassetapi.unrealtypes.engineenums.eproxynormalcomputationmethod.md
│ ├── uassetapi.unrealtypes.engineenums.epscpoolmethod.md
│ ├── uassetapi.unrealtypes.engineenums.equitpreference.md
│ ├── uassetapi.unrealtypes.engineenums.eradialimpulsefalloff.md
│ ├── uassetapi.unrealtypes.engineenums.erawcurvetracktypes.md
│ ├── uassetapi.unrealtypes.engineenums.eraytracingglobalilluminationtype.md
│ ├── uassetapi.unrealtypes.engineenums.ereflectedandrefractedraytracedshadows.md
│ ├── uassetapi.unrealtypes.engineenums.ereflectionsourcetype.md
│ ├── uassetapi.unrealtypes.engineenums.ereflectionstype.md
│ ├── uassetapi.unrealtypes.engineenums.erefractionmode.md
│ ├── uassetapi.unrealtypes.engineenums.erelativetransformspace.md
│ ├── uassetapi.unrealtypes.engineenums.erendererstencilmask.md
│ ├── uassetapi.unrealtypes.engineenums.erenderfocusrule.md
│ ├── uassetapi.unrealtypes.engineenums.ereporterlinestyle.md
│ ├── uassetapi.unrealtypes.engineenums.ereverbsendmethod.md
│ ├── uassetapi.unrealtypes.engineenums.erichcurvecompressionformat.md
│ ├── uassetapi.unrealtypes.engineenums.erichcurveextrapolation.md
│ ├── uassetapi.unrealtypes.engineenums.erichcurveinterpmode.md
│ ├── uassetapi.unrealtypes.engineenums.erichcurvekeytimecompressionformat.md
│ ├── uassetapi.unrealtypes.engineenums.erichcurvetangentmode.md
│ ├── uassetapi.unrealtypes.engineenums.erichcurvetangentweightmode.md
│ ├── uassetapi.unrealtypes.engineenums.erootmotionaccumulatemode.md
│ ├── uassetapi.unrealtypes.engineenums.erootmotionfinishvelocitymode.md
│ ├── uassetapi.unrealtypes.engineenums.erootmotionmode.md
│ ├── uassetapi.unrealtypes.engineenums.erootmotionrootlock.md
│ ├── uassetapi.unrealtypes.engineenums.erootmotionsourcesettingsflags.md
│ ├── uassetapi.unrealtypes.engineenums.erootmotionsourcestatusflags.md
│ ├── uassetapi.unrealtypes.engineenums.erotatorquantization.md
│ ├── uassetapi.unrealtypes.engineenums.eroundingmode.md
│ ├── uassetapi.unrealtypes.engineenums.eruntimevirtualtexturemainpasstype.md
│ ├── uassetapi.unrealtypes.engineenums.eruntimevirtualtexturematerialtype.md
│ ├── uassetapi.unrealtypes.engineenums.eruntimevirtualtexturemipvaluemode.md
│ ├── uassetapi.unrealtypes.engineenums.esamplersourcemode.md
│ ├── uassetapi.unrealtypes.engineenums.escenecapturecompositemode.md
│ ├── uassetapi.unrealtypes.engineenums.escenecaptureprimitiverendermode.md
│ ├── uassetapi.unrealtypes.engineenums.escenecapturesource.md
│ ├── uassetapi.unrealtypes.engineenums.escenedepthprioritygroup.md
│ ├── uassetapi.unrealtypes.engineenums.escenetextureid.md
│ ├── uassetapi.unrealtypes.engineenums.escreenorientation.md
│ ├── uassetapi.unrealtypes.engineenums.esendlevelcontrolmethod.md
│ ├── uassetapi.unrealtypes.engineenums.esettingsdof.md
│ ├── uassetapi.unrealtypes.engineenums.esettingslockedaxis.md
│ ├── uassetapi.unrealtypes.engineenums.eshadowmapflags.md
│ ├── uassetapi.unrealtypes.engineenums.eskeletalmeshgeoimportversions.md
│ ├── uassetapi.unrealtypes.engineenums.eskeletalmeshskinningimportversions.md
│ ├── uassetapi.unrealtypes.engineenums.eskincachedefaultbehavior.md
│ ├── uassetapi.unrealtypes.engineenums.eskincacheusage.md
│ ├── uassetapi.unrealtypes.engineenums.eskyatmospheretransformmode.md
│ ├── uassetapi.unrealtypes.engineenums.eskylightsourcetype.md
│ ├── uassetapi.unrealtypes.engineenums.eslategesture.md
│ ├── uassetapi.unrealtypes.engineenums.esleepfamily.md
│ ├── uassetapi.unrealtypes.engineenums.esounddistancecalc.md
│ ├── uassetapi.unrealtypes.engineenums.esoundgroup.md
│ ├── uassetapi.unrealtypes.engineenums.esoundspatializationalgorithm.md
│ ├── uassetapi.unrealtypes.engineenums.esoundwavefftsize.md
│ ├── uassetapi.unrealtypes.engineenums.esoundwaveloadingbehavior.md
│ ├── uassetapi.unrealtypes.engineenums.esourcebuschannels.md
│ ├── uassetapi.unrealtypes.engineenums.esourcebussendlevelcontrolmethod.md
│ ├── uassetapi.unrealtypes.engineenums.espawnactorcollisionhandlingmethod.md
│ ├── uassetapi.unrealtypes.engineenums.espeedtreegeometrytype.md
│ ├── uassetapi.unrealtypes.engineenums.espeedtreelodtype.md
│ ├── uassetapi.unrealtypes.engineenums.espeedtreewindtype.md
│ ├── uassetapi.unrealtypes.engineenums.esplinecoordinatespace.md
│ ├── uassetapi.unrealtypes.engineenums.esplinemeshaxis.md
│ ├── uassetapi.unrealtypes.engineenums.esplinepointtype.md
│ ├── uassetapi.unrealtypes.engineenums.estandbytype.md
│ ├── uassetapi.unrealtypes.engineenums.estaticmeshreductionterimationcriterion.md
│ ├── uassetapi.unrealtypes.engineenums.estereolayershape.md
│ ├── uassetapi.unrealtypes.engineenums.estereolayertype.md
│ ├── uassetapi.unrealtypes.engineenums.estreamingvolumeusage.md
│ ├── uassetapi.unrealtypes.engineenums.esubmixsendmethod.md
│ ├── uassetapi.unrealtypes.engineenums.esubuvboundingvertexcount.md
│ ├── uassetapi.unrealtypes.engineenums.esuggestprojvelocitytraceoption.md
│ ├── uassetapi.unrealtypes.engineenums.eteleporttype.md
│ ├── uassetapi.unrealtypes.engineenums.etemperatureseveritytype.md
│ ├── uassetapi.unrealtypes.engineenums.etextgender.md
│ ├── uassetapi.unrealtypes.engineenums.etexturecolorchannel.md
│ ├── uassetapi.unrealtypes.engineenums.etexturecompressionquality.md
│ ├── uassetapi.unrealtypes.engineenums.etexturelossycompressionamount.md
│ ├── uassetapi.unrealtypes.engineenums.etexturemipcount.md
│ ├── uassetapi.unrealtypes.engineenums.etexturemiploadoptions.md
│ ├── uassetapi.unrealtypes.engineenums.etexturemipvaluemode.md
│ ├── uassetapi.unrealtypes.engineenums.etexturepoweroftwosetting.md
│ ├── uassetapi.unrealtypes.engineenums.etexturerendertargetformat.md
│ ├── uassetapi.unrealtypes.engineenums.etexturesamplerfilter.md
│ ├── uassetapi.unrealtypes.engineenums.etexturesizingtype.md
│ ├── uassetapi.unrealtypes.engineenums.etexturesourcearttype.md
│ ├── uassetapi.unrealtypes.engineenums.etexturesourceformat.md
│ ├── uassetapi.unrealtypes.engineenums.etickinggroup.md
│ ├── uassetapi.unrealtypes.engineenums.etimecodeprovidersynchronizationstate.md
│ ├── uassetapi.unrealtypes.engineenums.etimelinedirection.md
│ ├── uassetapi.unrealtypes.engineenums.etimelinelengthmode.md
│ ├── uassetapi.unrealtypes.engineenums.etimelinesigtype.md
│ ├── uassetapi.unrealtypes.engineenums.etimestretchcurvemapping.md
│ ├── uassetapi.unrealtypes.engineenums.etracetypequery.md
│ ├── uassetapi.unrealtypes.engineenums.etrackactivecondition.md
│ ├── uassetapi.unrealtypes.engineenums.etracktoggleaction.md
│ ├── uassetapi.unrealtypes.engineenums.etrail2sourcemethod.md
│ ├── uassetapi.unrealtypes.engineenums.etrailsrenderaxisoption.md
│ ├── uassetapi.unrealtypes.engineenums.etrailwidthmode.md
│ ├── uassetapi.unrealtypes.engineenums.etransitionblendmode.md
│ ├── uassetapi.unrealtypes.engineenums.etransitionlogictype.md
│ ├── uassetapi.unrealtypes.engineenums.etransitiontype.md
│ ├── uassetapi.unrealtypes.engineenums.etranslucencylightingmode.md
│ ├── uassetapi.unrealtypes.engineenums.etranslucencytype.md
│ ├── uassetapi.unrealtypes.engineenums.etranslucentsortpolicy.md
│ ├── uassetapi.unrealtypes.engineenums.etravelfailure.md
│ ├── uassetapi.unrealtypes.engineenums.etraveltype.md
│ ├── uassetapi.unrealtypes.engineenums.etwitterintegrationdelegate.md
│ ├── uassetapi.unrealtypes.engineenums.etwitterrequestmethod.md
│ ├── uassetapi.unrealtypes.engineenums.etypeadvanceanim.md
│ ├── uassetapi.unrealtypes.engineenums.euiscalingrule.md
│ ├── uassetapi.unrealtypes.engineenums.eupdaterateshiftbucket.md
│ ├── uassetapi.unrealtypes.engineenums.euserdefinedstructurestatus.md
│ ├── uassetapi.unrealtypes.engineenums.euvoutput.md
│ ├── uassetapi.unrealtypes.engineenums.evectorfieldconstructionop.md
│ ├── uassetapi.unrealtypes.engineenums.evectornoisefunction.md
│ ├── uassetapi.unrealtypes.engineenums.evectorquantization.md
│ ├── uassetapi.unrealtypes.engineenums.evertexpaintaxis.md
│ ├── uassetapi.unrealtypes.engineenums.everticaltextaligment.md
│ ├── uassetapi.unrealtypes.engineenums.eviewmodeindex.md
│ ├── uassetapi.unrealtypes.engineenums.eviewtargetblendfunction.md
│ ├── uassetapi.unrealtypes.engineenums.evirtualizationmode.md
│ ├── uassetapi.unrealtypes.engineenums.evisibilityaggressiveness.md
│ ├── uassetapi.unrealtypes.engineenums.evisibilitybasedanimtickoption.md
│ ├── uassetapi.unrealtypes.engineenums.evisibilitytrackaction.md
│ ├── uassetapi.unrealtypes.engineenums.evisibilitytrackcondition.md
│ ├── uassetapi.unrealtypes.engineenums.evoicesamplerate.md
│ ├── uassetapi.unrealtypes.engineenums.evolumelightingmethod.md
│ ├── uassetapi.unrealtypes.engineenums.ewalkableslopebehavior.md
│ ├── uassetapi.unrealtypes.engineenums.ewindowmode.md
│ ├── uassetapi.unrealtypes.engineenums.ewindowtitlebarmode.md
│ ├── uassetapi.unrealtypes.engineenums.ewindsourcetype.md
│ ├── uassetapi.unrealtypes.engineenums.eworldpositionincludedoffsets.md
│ ├── uassetapi.unrealtypes.engineenums.fnavigationsystemrunmode.md
│ ├── uassetapi.unrealtypes.engineenums.modulationparammode.md
│ ├── uassetapi.unrealtypes.engineenums.particlereplaystate.md
│ ├── uassetapi.unrealtypes.engineenums.particlesystemlodmethod.md
│ ├── uassetapi.unrealtypes.engineenums.reverbpreset.md
│ ├── uassetapi.unrealtypes.engineenums.skeletalmeshoptimizationimportance.md
│ ├── uassetapi.unrealtypes.engineenums.skeletalmeshoptimizationtype.md
│ ├── uassetapi.unrealtypes.engineenums.skeletalmeshterminationcriterion.md
│ ├── uassetapi.unrealtypes.engineenums.textureaddress.md
│ ├── uassetapi.unrealtypes.engineenums.texturecompressionsettings.md
│ ├── uassetapi.unrealtypes.engineenums.texturefilter.md
│ ├── uassetapi.unrealtypes.engineenums.texturegroup.md
│ ├── uassetapi.unrealtypes.engineenums.texturemipgensettings.md
│ ├── uassetapi.unrealtypes.engineversion.md
│ ├── uassetapi.unrealtypes.eobjectdataresourceflags.md
│ ├── uassetapi.unrealtypes.eobjectdataresourceversion.md
│ ├── uassetapi.unrealtypes.eobjectflags.md
│ ├── uassetapi.unrealtypes.epackageflags.md
│ ├── uassetapi.unrealtypes.epropertyflags.md
│ ├── uassetapi.unrealtypes.erangeboundtypes.md
│ ├── uassetapi.unrealtypes.ffieldpath.md
│ ├── uassetapi.unrealtypes.ffontcharacter.md
│ ├── uassetapi.unrealtypes.ffontdata.md
│ ├── uassetapi.unrealtypes.fframenumber.md
│ ├── uassetapi.unrealtypes.fframerate.md
│ ├── uassetapi.unrealtypes.fframetime.md
│ ├── uassetapi.unrealtypes.fgatherabletextdata.md
│ ├── uassetapi.unrealtypes.fintvector.md
│ ├── uassetapi.unrealtypes.fintvector2.md
│ ├── uassetapi.unrealtypes.flinearcolor.md
│ ├── uassetapi.unrealtypes.flocmetadataobject.md
│ ├── uassetapi.unrealtypes.fmatrix.md
│ ├── uassetapi.unrealtypes.fname.md
│ ├── uassetapi.unrealtypes.fniagaradatainterfacegeneratedfunction.md
│ ├── uassetapi.unrealtypes.fniagaradatainterfacegpuparaminfo.md
│ ├── uassetapi.unrealtypes.fniagaravariablecommonreference.md
│ ├── uassetapi.unrealtypes.fobjectdataresource.md
│ ├── uassetapi.unrealtypes.fobjectthumbnail.md
│ ├── uassetapi.unrealtypes.fpackageindex.md
│ ├── uassetapi.unrealtypes.fplane.md
│ ├── uassetapi.unrealtypes.fpropertytypename.md
│ ├── uassetapi.unrealtypes.fpropertytypenameconverter.md
│ ├── uassetapi.unrealtypes.fpropertytypenamenode.md
│ ├── uassetapi.unrealtypes.fqualifiedframetime.md
│ ├── uassetapi.unrealtypes.fquat.md
│ ├── uassetapi.unrealtypes.frichcurvekey.md
│ ├── uassetapi.unrealtypes.frotator.md
│ ├── uassetapi.unrealtypes.fskeletalmeshareaweightedtrianglesampler.md
│ ├── uassetapi.unrealtypes.fskeletalmeshsamplingregionbuiltdata.md
│ ├── uassetapi.unrealtypes.fstring.md
│ ├── uassetapi.unrealtypes.ftextsourcedata.md
│ ├── uassetapi.unrealtypes.ftextsourcesitecontext.md
│ ├── uassetapi.unrealtypes.ftimecode.md
│ ├── uassetapi.unrealtypes.ftransform.md
│ ├── uassetapi.unrealtypes.ftwovectors.md
│ ├── uassetapi.unrealtypes.funiquenetid.md
│ ├── uassetapi.unrealtypes.fvector.md
│ ├── uassetapi.unrealtypes.fvector2d.md
│ ├── uassetapi.unrealtypes.fvector2f.md
│ ├── uassetapi.unrealtypes.fvector3f.md
│ ├── uassetapi.unrealtypes.fvector4.md
│ ├── uassetapi.unrealtypes.fvector4f.md
│ ├── uassetapi.unrealtypes.fweightedrandomsampler.md
│ ├── uassetapi.unrealtypes.fworldtileinfo.md
│ ├── uassetapi.unrealtypes.fworldtilelayer.md
│ ├── uassetapi.unrealtypes.fworldtilelodinfo.md
│ ├── uassetapi.unrealtypes.iordereddictionary-2.md
│ ├── uassetapi.unrealtypes.linearhelpers.md
│ ├── uassetapi.unrealtypes.objectversion.md
│ ├── uassetapi.unrealtypes.objectversionue5.md
│ ├── uassetapi.unrealtypes.tbox-1.md
│ ├── uassetapi.unrealtypes.tmap-2.md
│ ├── uassetapi.unrealtypes.tperqualitylevel-1.md
│ ├── uassetapi.unrealtypes.trange-1.md
│ ├── uassetapi.unrealtypes.trangebound-1.md
│ ├── uassetapi.unrealtypes.ue4versiontoobjectversion.md
│ ├── uassetapi.unrealtypes.ue5versiontoobjectversion.md
│ ├── uassetapi.unrealtypes.uniquenetidreplpropertydata.md
│ ├── uassetapi.unrealtypes.universalobjectlocatorfragmentpropertydata.md
│ ├── uassetapi.unversioned.ecompressionmethod.md
│ ├── uassetapi.unversioned.ecustomversionserializationformat.md
│ ├── uassetapi.unversioned.epropertytype.md
│ ├── uassetapi.unversioned.esavegamefileversion.md
│ ├── uassetapi.unversioned.ffragment.md
│ ├── uassetapi.unversioned.funversionedheader.md
│ ├── uassetapi.unversioned.oodle.md
│ ├── uassetapi.unversioned.savegame.md
│ ├── uassetapi.unversioned.usmap.md
│ ├── uassetapi.unversioned.usmaparraydata.md
│ ├── uassetapi.unversioned.usmapenum.md
│ ├── uassetapi.unversioned.usmapenumdata.md
│ ├── uassetapi.unversioned.usmapextensionlayoutversion.md
│ ├── uassetapi.unversioned.usmapmapdata.md
│ ├── uassetapi.unversioned.usmapproperty.md
│ ├── uassetapi.unversioned.usmappropertydata.md
│ ├── uassetapi.unversioned.usmapschema.md
│ ├── uassetapi.unversioned.usmapschemapropertiesjsonconverter.md
│ ├── uassetapi.unversioned.usmapstructdata.md
│ ├── uassetapi.unversioned.usmapstructkind.md
│ ├── uassetapi.unversioned.usmapversion.md
│ └── uassetapi.usmapbinaryreader.md
├── guide/
│ ├── basic.md
│ ├── build.md
│ └── extras.md
└── samples/
├── plwp_6aam_a0.uasset
└── plwp_6aam_a0.uexp
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
Please provide a copy of an asset that can be used to reproduce the issue if needed, along with the game's Unreal Engine version. If the asset uses unversioned properties, you should also provide a set of mappings. YOUR ISSUE WILL NOT BE REVIEWED IF YOUR ISSUE CANNOT BE REPLICATED BECAUSE NO TEST ASSET IS PROVIDED.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. Windows 10]
- Version or Commit: [e.g. 1.0.2/c7d9f8d]
- If you encountered this issue on a release version of UAssetGUI, you may find that your issue has already been fixed with the latest experimental release: https://github.com/atenfyr/UAssetGUI/releases/tag/experimental-latest
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/pull_request_template.md
================================================
# Pull Request
## Description
## Type of change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Other (please specify)
## Testing
================================================
FILE: .github/workflows/build.yml
================================================
name: CI
on:
push:
branches:
- master
jobs:
build:
runs-on: windows-latest
steps:
- name: git checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: .NET Setup
uses: actions/setup-dotnet@v2
with:
dotnet-version: '8.0.x'
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Unit tests
run: dotnet test --no-restore --verbosity normal
================================================
FILE: .github/workflows/main.yml
================================================
name: Deploy
on:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install mdbook
run: |
mkdir mdbook
curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.14/mdbook-v0.4.14-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook
echo `pwd`/mdbook >> $GITHUB_PATH
- name: Deploy GitHub Pages
run: |
cd docs
mdbook build
git worktree add gh-pages
git config user.name "Deploy from CI"
git config user.email ""
cd gh-pages
git update-ref -d refs/heads/gh-pages
rm -rf *
mv ../book/* .
git add .
git commit -m "Deploy $GITHUB_SHA to gh-pages"
git push --force --set-upstream origin gh-pages
================================================
FILE: .gitignore
================================================
.vs
docs/book
docs/XMLDoc2Markdown
packages
TestResults
UAssetAPI/git_commit.txt
UAssetAPI/bin
UAssetAPI/obj
UAssetAPI.Benchmark/bin
UAssetAPI.Benchmark/obj
UAssetAPI.Tests/bin
UAssetAPI.Tests/obj
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020 - 2026 atenfyr
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: NOTICE.md
================================================
# Notices
The following is a list of applicable licensing information for all the third-party material used, in whole or in part, within this software.
## repak
https://github.com/trumank/repak
```
MIT License
Copyright 2024 Truman Kilen, spuds
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
## Json.NET
https://github.com/JamesNK/Newtonsoft.Json
```
The MIT License (MIT)
Copyright (c) 2007 James Newton-King
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
```
## dotmore
https://github.com/mattmc3/dotmore
```
The MIT License (MIT)
Copyright (c) 2014 mattmc3
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
## ZstdNet
https://github.com/skbkontur/ZstdNet
```
BSD License
For ZstdNet software
Copyright (c) 2016-present, SKB Kontur. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name SKB Kontur nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```
## zstd
https://github.com/facebook/zstd
```
BSD License
For Zstandard software
Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name Facebook, nor Meta, nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```
## UEAssetToolkitGenerator
https://github.com/LongerWarrior/UEAssetToolkitGenerator
### License
```
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
### Statement of Modification
Major portions of the source code that is adapted from UEAssetToolkitGenerator have been modified for usage in UAssetAPI through changes in code formatting, nomenclature, and serialization specifics in order to improve the effectiveness of the serialization across different engine versions and assets and to improve integration with newer versions of UAssetAPI. The relevant portions of source code have been sufficiently adapted such that no improper serialization or other unexpected behavior should be construed as having originated from any portion of the original work or any of its contributors.
### Original NOTICE text file information
The NOTICE text file bundled with the referenced project is not included in this copyright notice because none of the notices in that file pertain to any part of the work that is adapted for usage in UAssetAPI. Please see the original repository for more detailed copyright information.
================================================
FILE: README.md
================================================
# UAssetAPI
[](https://github.com/atenfyr/UAssetAPI/actions)
[](https://github.com/atenfyr/UAssetAPI/issues)
[](https://github.com/atenfyr/UAssetAPI/blob/master/LICENSE.md)
UAssetAPI is a low-level .NET library for reading and writing Unreal Engine game assets.
## Features
- Low-level read/write capability for a wide variety of cooked and uncooked .uasset files from ~4.13 to 5.3
- Support for more than 100 property types and 12 export types
- Support for JSON export and import to a proprietary format that maintains binary equality
- Support for reading and writing raw Kismet (blueprint) bytecode
- Reading capability for the unofficial .usmap format to parse ambiguous and unversioned properties
- Robust fail-safes for many properties and exports that fail serialization
- Automatic reflection for new property types in other loaded assemblies
## Usage
To get started using UAssetAPI, first build the API using the [Build Instructions guide](https://atenfyr.github.io/UAssetAPI/guide/build.html) and learn how to perform basic operations on your cooked .uasset files using the [Basic Usage guide](https://atenfyr.github.io/UAssetAPI/guide/basic.html).
UAssetGUI, a graphical wrapper around UAssetAPI which allows you to directly view and modify game assets by hand, is also available and can be downloaded for free on GitHub at [https://github.com/atenfyr/UAssetGUI/releases](https://github.com/atenfyr/UAssetGUI/releases).
## Contributing
All contributions, whether through pull requests or issues, that you may make are greatly appreciated.
I am particularly interested in .uasset files that have their `VerifyBinaryEquality()` method return false (or display "failed to maintain binary equality" within [UAssetGUI](https://github.com/atenfyr/UAssetGUI)); if you encounter such an asset, feel free to submit an issue here with a copy of the asset in question along with the name of the game and the Unreal version that it was cooked with.
Please note: Your issue will NOT be reviewed if your issue cannot be replicated due to no test asset being provided.
## License
UAssetAPI and UAssetGUI are distributed under the MIT license, which you can view in detail in the [LICENSE file](LICENSE).
================================================
FILE: UAssetAPI/AC7Decrypt.cs
================================================
using System;
using System.Diagnostics;
using System.IO;
using UAssetAPI.ExportTypes;
namespace UAssetAPI
{
///
/// XOR key for decrypting a particular Ace Combat 7 asset.
///
public class AC7XorKey
{
public int NameKey;
public int Offset;
public int pk1;
public int pk2;
public void SkipCount(int count)
{
int num = count % 217;
pk1 += num;
if (pk1 >= 217)
{
pk1 -= 217;
}
int num2 = count % 1024;
pk2 += num2;
if (pk2 >= 1024)
{
pk2 -= 1024;
}
}
private static int CalcNameKey(string fname)
{
fname = fname.ToUpper();
int num = 0;
for (int i = 0; i < fname.Length; i++)
{
int num2 = (byte)fname[i];
num ^= num2;
num2 = num * 8;
num2 ^= num;
int num3 = num + num;
num2 = ~num2;
num2 = (num2 >> 7) & 1;
num = num2 | num3;
}
return num;
}
private static void CalcPKeyFromNKey(int nkey, int dataoffset, out int pk1, out int pk2)
{
long num = (uint)((long)nkey * 7L);
System.Numerics.BigInteger bigInteger = new System.Numerics.BigInteger(5440514381186227205L);
num += dataoffset;
System.Numerics.BigInteger bigInteger2 = bigInteger * num;
long num2 = (long)(bigInteger2 >> 70);
long num3 = num2 >> 63;
num2 += num3;
num3 = num2 * 217;
num -= num3;
pk1 = (int)(num & 0xFFFFFFFFu);
long num4 = (uint)((long)nkey * 11L);
num4 += dataoffset;
num2 = 0L;
num2 &= 0x3FF;
num4 += num2;
num4 &= 0x3FF;
long num5 = num4 - num2;
pk2 = (int)(num5 & 0xFFFFFFFFu);
}
///
/// Generates an encryption key for a particular asset on disk.
///
/// The name of the asset being encrypted on disk without the extension.
/// An encryption key for the asset.
public AC7XorKey(string fname)
{
NameKey = CalcNameKey(fname); Offset = 4;
CalcPKeyFromNKey(this.NameKey, this.Offset, out this.pk1, out this.pk2);
}
}
///
/// Decryptor for Ace Combat 7 assets.
///
public class AC7Decrypt
{
private static byte[] AC7FullKey = new byte[0];
public AC7Decrypt()
{
if (AC7FullKey.Length == 0) AC7FullKey = Properties.Resources.AC7Key;
}
///
/// Decrypts an Ace Combat 7 encrypted asset on disk.
///
/// The path to an encrypted asset on disk.
/// The path that the decrypted asset should be saved to.
public void Decrypt(string input, string output)
{
AC7XorKey xorKey = new AC7XorKey(Path.GetFileNameWithoutExtension(input));
byte[] doneData = DecryptUAssetBytes(File.ReadAllBytes(input), xorKey);
File.WriteAllBytes(output, doneData);
try
{
byte[] doneData2 = DecryptUexpBytes(File.ReadAllBytes(Path.ChangeExtension(input, "uexp")), xorKey);
File.WriteAllBytes(Path.ChangeExtension(output, "uexp"), doneData2);
}
catch { }
}
///
/// Encrypts an Ace Combat 7 encrypted asset on disk.
///
/// The path to a decrypted asset on disk.
/// The path that the encrypted asset should be saved to.
public void Encrypt(string input, string output)
{
AC7XorKey xorKey = new AC7XorKey(Path.GetFileNameWithoutExtension(output));
byte[] doneData = EncryptUAssetBytes(File.ReadAllBytes(input), xorKey);
File.WriteAllBytes(output, doneData);
try
{
byte[] doneData2 = EncryptUexpBytes(File.ReadAllBytes(Path.ChangeExtension(input, "uexp")), xorKey);
File.WriteAllBytes(Path.ChangeExtension(output, "uexp"), doneData2);
}
catch { }
}
public byte[] DecryptUAssetBytes(byte[] uasset, AC7XorKey xorkey)
{
if (xorkey == null) throw new NullReferenceException("Null key provided");
byte[] array = new byte[uasset.Length];
BitConverter.GetBytes(UAsset.UASSET_MAGIC).CopyTo(array, 0);
for (int i = 4; i < array.Length; i++)
{
array[i] = GetXorByte(uasset[i], ref xorkey);
}
return array;
}
public byte[] EncryptUAssetBytes(byte[] uasset, AC7XorKey xorkey)
{
if (xorkey == null) throw new NullReferenceException("Null key provided");
byte[] array = new byte[uasset.Length];
BitConverter.GetBytes(UAsset.ACE7_MAGIC).CopyTo(array, 0);
for (int i = 4; i < array.Length; i++)
{
array[i] = GetXorByte(uasset[i], ref xorkey);
}
return array;
}
public byte[] DecryptUexpBytes(byte[] uexp, AC7XorKey xorkey)
{
if (xorkey == null) throw new NullReferenceException("Null key provided");
byte[] array = new byte[uexp.Length];
for (int i = 0; i < array.Length; i++)
{
array[i] = GetXorByte(uexp[i], ref xorkey);
}
BitConverter.GetBytes(UAsset.UASSET_MAGIC).CopyTo(array, array.Length - 4);
return array;
}
public byte[] EncryptUexpBytes(byte[] uexp, AC7XorKey xorkey)
{
if (xorkey == null) throw new NullReferenceException("Null key provided");
byte[] array = new byte[uexp.Length];
for (int i = 0; i < uexp.Length; i++)
{
array[i] = GetXorByte(uexp[i], ref xorkey);
}
return array;
}
private static byte GetXorByte(byte tagb, ref AC7XorKey xorkey)
{
if (xorkey == null)
{
return tagb;
}
tagb = (byte)((uint)(tagb ^ AC7FullKey[xorkey.pk1 * 1024 + xorkey.pk2]) ^ 0x77u);
xorkey.pk1++;
xorkey.pk2++;
if (xorkey.pk1 >= 217)
{
xorkey.pk1 = 0;
}
if (xorkey.pk2 >= 1024)
{
xorkey.pk2 = 0;
}
return tagb;
}
}
}
================================================
FILE: UAssetAPI/AssetBinaryReader.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UAssetAPI.CustomVersions;
using UAssetAPI.Kismet.Bytecode;
using UAssetAPI.UnrealTypes;
using UAssetAPI.Unversioned;
namespace UAssetAPI;
///
/// Any binary reader used in the parsing of Unreal file types.
///
public class UnrealBinaryReader : BinaryReader
{
public UnrealBinaryReader(Stream stream) : base(stream) { }
protected byte[] ReverseIfBigEndian(byte[] data)
{
if (!BitConverter.IsLittleEndian) Array.Reverse(data);
return data;
}
public override short ReadInt16()
{
return BitConverter.ToInt16(ReverseIfBigEndian(base.ReadBytes(2)), 0);
}
public override ushort ReadUInt16()
{
return BitConverter.ToUInt16(ReverseIfBigEndian(base.ReadBytes(2)), 0);
}
public override int ReadInt32()
{
return BitConverter.ToInt32(ReverseIfBigEndian(base.ReadBytes(4)), 0);
}
public override uint ReadUInt32()
{
return BitConverter.ToUInt32(ReverseIfBigEndian(base.ReadBytes(4)), 0);
}
public override long ReadInt64()
{
return BitConverter.ToInt64(ReverseIfBigEndian(base.ReadBytes(8)), 0);
}
public override ulong ReadUInt64()
{
return BitConverter.ToUInt64(ReverseIfBigEndian(base.ReadBytes(8)), 0);
}
public override float ReadSingle()
{
return BitConverter.ToSingle(ReverseIfBigEndian(base.ReadBytes(4)), 0);
}
public override double ReadDouble()
{
return BitConverter.ToDouble(ReverseIfBigEndian(base.ReadBytes(8)), 0);
}
public bool ReadBooleanInt()
{
var i = ReadInt32();
return i switch
{
1 => true,
0 => false,
_ => throw new FormatException($"Invalid boolean value {i}")
};
}
public override string ReadString()
{
return ReadFString()?.Value;
}
public virtual FString ReadFString()
{
int length = this.ReadInt32();
switch (length)
{
case < 0:
var len = -length * 2;
Span data = len < 512 ? stackalloc byte[len] : new byte[len];
BaseStream.Read(data);
return new FString(Encoding.Unicode.GetString(data[..^2]), Encoding.Unicode);
case > 0:
data = length < 512 ? stackalloc byte[length] : new byte[length];
BaseStream.Read(data);
return new FString(Encoding.UTF8.GetString(data[..^1]), Encoding.UTF8);
default:
return null;
}
}
public virtual FString ReadUtf8String()
{
int length = this.ReadInt32();
switch (length)
{
case < 0:
throw new FormatException("Invalid UTF-8 string length");
case > 0:
Span data = length < 512 ? stackalloc byte[length] : new byte[length];
BaseStream.Read(data);
return new FString(Encoding.UTF8.GetString(data), Encoding.UTF8);
default:
return null;
}
}
public virtual FString ReadNameMapString(out uint hashes)
{
hashes = 0;
FString str = this.ReadFString();
if (this is AssetBinaryReader abr)
{
if (abr.Asset is UAsset abrUa && abrUa.WillSerializeNameHashes != false && !string.IsNullOrEmpty(str.Value))
{
hashes = this.ReadUInt32();
if (hashes < (1 << 10) && abrUa.ObjectVersion < ObjectVersion.VER_UE4_NAME_HASHES_SERIALIZED) // "i lied, there's actually no hashes"
{
abrUa.WillSerializeNameHashes = false;
hashes = 0;
this.BaseStream.Position -= sizeof(uint);
}
else
{
abrUa.WillSerializeNameHashes = true;
}
}
}
return str;
}
public List ReadCustomVersionContainer(ECustomVersionSerializationFormat format, List oldCustomVersionContainer = null, Usmap Mappings = null)
{
var newCustomVersionContainer = new List();
var existingCustomVersions = new HashSet();
switch (format)
{
case ECustomVersionSerializationFormat.Enums:
throw new NotImplementedException("Custom version serialization format Enums is currently unimplemented");
case ECustomVersionSerializationFormat.Guids:
int numCustomVersions = ReadInt32();
for (int i = 0; i < numCustomVersions; i++)
{
var customVersionID = new Guid(ReadBytes(16));
var customVersionNumber = ReadInt32();
newCustomVersionContainer.Add(new CustomVersion(customVersionID, customVersionNumber) { Name = ReadFString() });
existingCustomVersions.Add(customVersionID);
}
break;
case ECustomVersionSerializationFormat.Optimized:
numCustomVersions = ReadInt32();
for (int i = 0; i < numCustomVersions; i++)
{
var customVersionID = new Guid(ReadBytes(16));
var customVersionNumber = ReadInt32();
newCustomVersionContainer.Add(new CustomVersion(customVersionID, customVersionNumber));
existingCustomVersions.Add(customVersionID);
}
break;
}
if (Mappings != null && Mappings.CustomVersionContainer != null && Mappings.CustomVersionContainer.Count > 0)
{
foreach (CustomVersion entry in Mappings.CustomVersionContainer)
{
if (!existingCustomVersions.Contains(entry.Key)) newCustomVersionContainer.Add(entry.SetIsSerialized(false));
}
}
if (oldCustomVersionContainer != null)
{
foreach (CustomVersion entry in oldCustomVersionContainer)
{
if (!existingCustomVersions.Contains(entry.Key)) newCustomVersionContainer.Add(entry.SetIsSerialized(false));
}
}
return newCustomVersionContainer;
}
}
///
/// Reads primitive data types from Unreal Engine assets.
///
public class AssetBinaryReader : UnrealBinaryReader
{
public UAsset Asset;
public bool LoadUexp = true;
public AssetBinaryReader(Stream stream, UAsset asset = null) : base(stream)
{
Asset = asset;
}
public AssetBinaryReader(Stream stream, bool inLoadUexp, UAsset asset = null) : base(stream)
{
Asset = asset;
LoadUexp = inLoadUexp;
}
public virtual Guid? ReadPropertyGuid()
{
if (Asset.HasUnversionedProperties) return null;
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_PROPERTY_GUID_IN_PROPERTY_TAG)
{
bool hasPropertyGuid = ReadBoolean();
if (hasPropertyGuid) return new Guid(ReadBytes(16));
}
return null;
}
public virtual FName ReadFName()
{
int nameMapPointer = this.ReadInt32();
int number = this.ReadInt32();
return new FName(Asset, nameMapPointer, number);
}
public T[] ReadArray(Func readElement)
{
int arrayLength = ReadInt32();
if (arrayLength == 0) return [];
T[] newData = new T[arrayLength];
for (int i = 0; i < arrayLength; i++)
{
newData[i] = readElement();
}
return newData;
}
public FObjectThumbnail ReadObjectThumbnail()
{
var thumb = new FObjectThumbnail();
thumb.Width = ReadInt32();
thumb.Height = ReadInt32();
var imageBytesCount = ReadInt32();
thumb.CompressedImageData = imageBytesCount > 0 ? ReadBytes(imageBytesCount) : Array.Empty();
return thumb;
}
public FLocMetadataObject ReadLocMetadataObject()
{
var locMetadataObject = new FLocMetadataObject();
var valueCount = ReadInt32();
if (valueCount > 0)
throw new NotImplementedException("TODO: implement ReadLocMetadataObject");
return locMetadataObject;
}
public string XFERSTRING()
{
List readData = new List();
while (true)
{
byte newVal = this.ReadByte();
if (newVal == 0) break;
readData.Add(newVal);
}
return Encoding.UTF8.GetString(readData.ToArray());
}
public string XFERUNICODESTRING()
{
List readData = new List();
while (true)
{
byte newVal1 = this.ReadByte();
byte newVal2 = this.ReadByte();
if (newVal1 == 0 && newVal2 == 0) break;
readData.Add(newVal1);
readData.Add(newVal2);
}
return Encoding.Unicode.GetString(readData.ToArray());
}
public void XFERTEXT()
{
}
public FName XFERNAME()
{
return this.ReadFName();
}
public FName XFER_FUNC_NAME()
{
return this.XFERNAME();
}
public FPackageIndex XFERPTR()
{
return new FPackageIndex(this.ReadInt32());
}
public FPackageIndex XFER_FUNC_POINTER()
{
return this.XFERPTR();
}
public KismetPropertyPointer XFER_PROP_POINTER()
{
if (Asset.GetCustomVersion() >= FReleaseObjectVersion.FFieldPathOwnerSerialization)
{
int numEntries = this.ReadInt32();
FName[] allNames = new FName[numEntries];
for (int i = 0; i < numEntries; i++)
{
allNames[i] = this.ReadFName();
}
FPackageIndex owner = this.XFER_OBJECT_POINTER();
return new KismetPropertyPointer(new FFieldPath(allNames, owner, this.Asset.Exports.Count));
}
else
{
return new KismetPropertyPointer(this.XFERPTR());
}
}
public FPackageIndex XFER_OBJECT_POINTER()
{
return this.XFERPTR();
}
public KismetExpression[] ReadExpressionArray(EExprToken endToken)
{
List newData = new List();
KismetExpression currExpression = null;
while (currExpression == null || currExpression.Token != endToken)
{
if (currExpression != null) newData.Add(currExpression);
currExpression = ExpressionSerializer.ReadExpression(this);
}
return newData.ToArray();
}
}
================================================
FILE: UAssetAPI/AssetBinaryWriter.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UAssetAPI.CustomVersions;
using UAssetAPI.Kismet.Bytecode;
using UAssetAPI.UnrealTypes;
using UAssetAPI.Unversioned;
namespace UAssetAPI
{
///
/// Any binary writer used in the parsing of Unreal file types.
///
public class UnrealBinaryWriter : BinaryWriter
{
public UnrealBinaryWriter() : base()
{
}
public UnrealBinaryWriter(Stream stream) : base(stream)
{
}
public UnrealBinaryWriter(Stream stream, Encoding encoding) : base(stream, encoding)
{
}
public UnrealBinaryWriter(Stream stream, Encoding encoding, bool leaveOpen) : base(stream, encoding, leaveOpen)
{
}
protected byte[] ReverseIfBigEndian(byte[] data)
{
if (!BitConverter.IsLittleEndian) Array.Reverse(data);
return data;
}
public override void Write(short value)
{
this.Write(ReverseIfBigEndian(BitConverter.GetBytes(value)));
}
public override void Write(ushort value)
{
this.Write(ReverseIfBigEndian(BitConverter.GetBytes(value)));
}
public override void Write(int value)
{
this.Write(ReverseIfBigEndian(BitConverter.GetBytes(value)));
}
public override void Write(uint value)
{
this.Write(ReverseIfBigEndian(BitConverter.GetBytes(value)));
}
public override void Write(long value)
{
this.Write(ReverseIfBigEndian(BitConverter.GetBytes(value)));
}
public override void Write(ulong value)
{
this.Write(ReverseIfBigEndian(BitConverter.GetBytes(value)));
}
public override void Write(float value)
{
this.Write(ReverseIfBigEndian(BitConverter.GetBytes(value)));
}
public override void Write(double value)
{
this.Write(ReverseIfBigEndian(BitConverter.GetBytes(value)));
}
public override void Write(string value)
{
Write(new FString(value));
}
public virtual int Write(FString value)
{
switch (value?.Value)
{
case null:
this.Write((int)0);
return sizeof(int);
default:
string nullTerminatedStr = value.Value + "\0";
this.Write(value.Encoding is UnicodeEncoding ? -nullTerminatedStr.Length : nullTerminatedStr.Length);
byte[] actualStrData = value.Encoding.GetBytes(nullTerminatedStr);
this.Write(actualStrData);
return actualStrData.Length + 4;
}
}
public int WriteUtf8String(FString value)
{
switch (value?.Value)
{
case null:
this.Write((int)0);
return sizeof(int);
default:
this.Write(value.Value.Length);
byte[] actualStrData = value.Encoding.GetBytes(value.Value);
this.Write(actualStrData);
return actualStrData.Length + 4;
}
}
public void WriteCustomVersionContainer(ECustomVersionSerializationFormat format, List CustomVersionContainer)
{
// TODO: support for enum-based custom versions
int num = CustomVersionContainer == null ? 0 : CustomVersionContainer.Count;
switch (format)
{
case ECustomVersionSerializationFormat.Enums:
throw new NotImplementedException("Custom version serialization format Enums is currently unimplemented");
case ECustomVersionSerializationFormat.Guids:
long numLoc = this.BaseStream.Position;
Write((int)0);
int realNum = 0;
for (int i = 0; i < num; i++)
{
if (CustomVersionContainer[i].Version <= 0 || !CustomVersionContainer[i].IsSerialized) continue;
realNum++;
Write(CustomVersionContainer[i].Key.ToByteArray());
Write(CustomVersionContainer[i].Version);
Write(CustomVersionContainer[i].Name);
}
long endLoc = this.BaseStream.Position;
this.Seek((int)numLoc, SeekOrigin.Begin);
Write(realNum);
this.Seek((int)endLoc, SeekOrigin.Begin);
break;
case ECustomVersionSerializationFormat.Optimized:
numLoc = this.BaseStream.Position;
Write((int)0);
realNum = 0;
for (int i = 0; i < num; i++)
{
if (CustomVersionContainer[i].Version < 0 || !CustomVersionContainer[i].IsSerialized) continue;
realNum++;
Write(CustomVersionContainer[i].Key.ToByteArray());
Write(CustomVersionContainer[i].Version);
}
endLoc = this.BaseStream.Position;
this.Seek((int)numLoc, SeekOrigin.Begin);
Write(realNum);
this.Seek((int)endLoc, SeekOrigin.Begin);
break;
}
}
}
///
/// Writes primitive data types from Unreal Engine assets.
///
public class AssetBinaryWriter : UnrealBinaryWriter
{
public UAsset Asset;
public AssetBinaryWriter(UAsset asset) : base()
{
Asset = asset;
}
public AssetBinaryWriter(Stream stream, UAsset asset) : base(stream)
{
Asset = asset;
}
public AssetBinaryWriter(Stream stream, Encoding encoding, UAsset asset) : base(stream, encoding)
{
Asset = asset;
}
public AssetBinaryWriter(Stream stream, Encoding encoding, bool leaveOpen, UAsset asset) : base(stream, encoding, leaveOpen)
{
Asset = asset;
}
public virtual void Write(FName name)
{
if (name == null) name = new FName(Asset, 0, 0);
this.Write(name.Index);
this.Write(name.Number);
}
public virtual void WritePropertyGuid(Guid? guid)
{
if (Asset.HasUnversionedProperties) return;
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_PROPERTY_GUID_IN_PROPERTY_TAG)
{
Write(guid != null);
if (guid != null) Write(((Guid)guid).ToByteArray());
}
}
public virtual void Write(FObjectThumbnail thumbnail)
{
Write(thumbnail.Width);
Write(thumbnail.Height);
Write(thumbnail.CompressedImageData.Length);
if (thumbnail.CompressedImageData.Length > 0)
Write(thumbnail.CompressedImageData);
}
public virtual void Write(FLocMetadataObject metadataObject)
{
Write(metadataObject.Values.Count);
if (metadataObject.Values.Count > 0)
throw new NotImplementedException("TODO: implement Write(FLocMetadataObject)");
}
/*
!!!!!
THE FOLLOWING METHODS ARE INTENDED ONLY TO BE USED IN PARSING KISMET BYTECODE; PLEASE DO NOT USE THEM FOR ANY OTHER PURPOSE!
!!!!!
*/
/// This method is intended only to be used in parsing Kismet bytecode; please do not use it for any other purpose!
public int XFERSTRING(string val)
{
long startMetric = this.BaseStream.Position;
this.Write(Encoding.UTF8.GetBytes(val + "\0"));
return (int)(this.BaseStream.Position - startMetric);
}
/// This method is intended only to be used in parsing Kismet bytecode; please do not use it for any other purpose!
public int XFERUNICODESTRING(string val)
{
long startMetric = this.BaseStream.Position;
this.Write(Encoding.Unicode.GetBytes(val + "\0"));
return (int)(this.BaseStream.Position - startMetric);
}
/// This method is intended only to be used in parsing Kismet bytecode; please do not use it for any other purpose!
public int XFERNAME(FName val)
{
this.Write(val);
return 12; // FScriptName's iCode offset is 12 bytes, not 8
}
/// This method is intended only to be used in parsing Kismet bytecode; please do not use it for any other purpose!
public int XFER_FUNC_NAME(FName val)
{
return this.XFERNAME(val);
}
private static readonly int PointerSize = sizeof(ulong);
/// This method is intended only to be used in parsing Kismet bytecode; please do not use it for any other purpose!
public int XFERPTR(FPackageIndex val)
{
this.Write(val?.Index ?? 0);
return PointerSize; // For the iCode offset, we return the size of a pointer in memory rather than the size of an FPackageIndex on disk
}
/// This method is intended only to be used in parsing Kismet bytecode; please do not use it for any other purpose!
public int XFER_FUNC_POINTER(FPackageIndex val)
{
return this.XFERPTR(val);
}
/// This method is intended only to be used in parsing Kismet bytecode; please do not use it for any other purpose!
public int XFER_PROP_POINTER(KismetPropertyPointer val)
{
if (Asset.GetCustomVersion() >= FReleaseObjectVersion.FFieldPathOwnerSerialization)
{
this.Write(val.New.Path.Length);
for (int i = 0; i < val.New.Path.Length; i++)
{
this.XFERNAME(val.New.Path[i]);
}
this.XFER_OBJECT_POINTER(val.New.ResolvedOwner);
}
else
{
this.XFERPTR(val.Old);
}
return PointerSize;
}
/// This method is intended only to be used in parsing Kismet bytecode; please do not use it for any other purpose!
public int XFER_OBJECT_POINTER(FPackageIndex val)
{
return this.XFERPTR(val);
}
}
}
================================================
FILE: UAssetAPI/CRCGenerator.cs
================================================
using System;
using System.Text;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI;
public static class CRCGenerator
{
public static uint GenerateHash(FString text, bool disableCasePreservingHash, bool version420 = false)
{
return GenerateHash(text?.Value, text?.Encoding, disableCasePreservingHash, version420);
}
public static uint GenerateHash(string text, bool disableCasePreservingHash, bool version420 = false)
{
return GenerateHash(text, Encoding.UTF8, disableCasePreservingHash, version420);
}
public static uint GenerateHash(string text, Encoding encoding, bool disableCasePreservingHash, bool version420 = false)
{
uint algor1 = Strihash_DEPRECATED(text, encoding, version420);
uint algor2 = disableCasePreservingHash ? 0 : StrCrc32(text);
return (algor1 & 0xFFFF) | ((algor2 & 0xFFFF) << 16);
}
public static char ToUpper(char input)
{
return (char)((uint)input - ((((uint)input - 'a' < 26u) ? 1 : 0) << 5));
}
public static char ToUpperVersion420(char input)
{
return (char)((input < 256 ? (uint)unchecked((sbyte)input) : (uint)input) - ((((uint)input - 'a' < 26u) ? 1 : 0) << 5));
}
public static string ToUpper(string input)
{
var res = "";
foreach (char x in input) res += ToUpper(x); // todo: revise for better perf if needed
return res;
}
public static char ToLower(char input)
{
return (char)((uint)input + ((((uint)input - 'A' < 26u) ? 1 : 0) << 5));
}
public static string ToLower(string input, bool coalesceToSlash = false)
{
var res = "";
foreach (char x in input)
{
char chosenX = x;
if (coalesceToSlash && (chosenX == '.' || chosenX == ':')) chosenX = '/';
res += ToLower(chosenX); // todo: revise for better perf if needed
}
return res;
}
public static FString ToLower(FString input, bool coalesceToSlash = false)
{
FString output = (FString)input.Clone();
output.Value = ToLower(output.Value, coalesceToSlash);
return output;
}
public static uint Strihash_DEPRECATED(string text, Encoding encoding, bool version420 = false)
{
uint hash = 0;
byte[] rawDataForCharacter;
for (int i = 0; i < text.Length; i++)
{
var next = Math.Min(i + 1, text.Length - 1);
if (char.IsHighSurrogate(text[i]) && next != i && char.IsLowSurrogate(text[next]))
{
rawDataForCharacter = encoding.GetBytes( new [] { text[i], text[++i] });
}
else
{
char B = !version420 ? ToUpper(text[i]) : ToUpperVersion420(text[i]);
rawDataForCharacter = encoding.GetBytes(new [] { B });
}
foreach (byte rawByte in rawDataForCharacter)
{
hash = ((hash >> 8) & 0x00FFFFFF) ^ CRCTable_DEPRECATED[(hash ^ rawByte) & 0x000000FF];
}
}
return hash;
}
// Accurate as-is for both WIDECHAR and ANSICHAR
public static uint StrCrc32(string text, uint CRC = 0)
{
CRC = ~CRC;
for (int i = 0; i < text.Length; i++)
{
char Ch = text[i];
CRC = (CRC >> 8) ^ CRCTablesSB8[0, (CRC ^ Ch) & 0xFF];
Ch >>= 8;
CRC = (CRC >> 8) ^ CRCTablesSB8[0, (CRC ^ Ch) & 0xFF];
Ch >>= 8;
CRC = (CRC >> 8) ^ CRCTablesSB8[0, (CRC ^ Ch) & 0xFF];
Ch >>= 8;
CRC = (CRC >> 8) ^ CRCTablesSB8[0, (CRC ^ Ch) & 0xFF];
}
return ~CRC;
}
public static readonly uint[] CRCTable_DEPRECATED =
[
0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC, 0x5BD4B01B, 0x569796C2, 0x52568B75, 0x6A1936C8, 0x6ED82B7F, 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A, 0x745E66CD,
0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039, 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0xBE2B5B58, 0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033, 0xA4AD16EA, 0xA06C0B5D,
0xD4326D90, 0xD0F37027, 0xDDB056FE, 0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95, 0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4, 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D,
0x34867077, 0x30476DC0, 0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5, 0x2AC12072, 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16, 0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA,
0x7897AB07, 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C, 0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1, 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B, 0xBB60ADFC, 0xB6238B25, 0xB2E29692, 0x8AAD2B2F, 0x8E6C3698, 0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D, 0x94EA7B2A,
0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E, 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, 0xC6BCF05F, 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34, 0xDC3ABDED, 0xD8FBA05A,
0x690CE0EE, 0x6DCDFD59, 0x608EDB80, 0x644FC637, 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB, 0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, 0x5C007B8A, 0x58C1663D, 0x558240E4, 0x51435D53,
0x251D3B9E, 0x21DC2629, 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C, 0x3B5A6B9B, 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF, 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623,
0xF12F560E, 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65, 0xEBA91BBC, 0xEF68060B, 0xD727BBB6, 0xD3E6A601, 0xDEA580D8, 0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3,
0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, 0xAE3AFBA2, 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, 0x9B3660C6, 0x9FF77D71, 0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74, 0x857130C3,
0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640, 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C, 0x7B827D21, 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, 0x6C47164A, 0x61043093, 0x65C52D24,
0x119B4BE9, 0x155A565E, 0x18197087, 0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC, 0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D, 0x2056CD3A, 0x2D15EBE3, 0x29D4F654,
0xC5A92679, 0xC1683BCE, 0xCC2B1D17, 0xC8EA00A0, 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB, 0xDBEE767C, 0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18, 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4,
0x89B8FD09, 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662, 0x933EB0BB, 0x97FFAD0C, 0xAFB010B1, 0xAB710D06, 0xA6322BDF, 0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4
];
public static readonly uint[,] CRCTablesSB8 = new uint[8, 256]
{
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
},
{
0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf,
0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e,
0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d,
0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c,
0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b,
0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768,
0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539,
0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484,
0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026,
0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277,
0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81,
0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0,
0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72
},
{
0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d,
0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d,
0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd,
0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad,
0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d,
0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d,
0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d,
0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd,
0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d,
0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d,
0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d,
0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d,
0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed
},
{
0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056,
0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9,
0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68,
0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7,
0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4,
0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755,
0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca,
0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d,
0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953,
0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc,
0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50,
0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf,
0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1
},
{
0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, 0x825097d1,
0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, 0xdfd029e3, 0xe2b00053,
0xc1c12f04, 0xfca106b4, 0xbb017c64, 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, 0x3951ebb5, 0x7ef19165, 0x4391b8d5,
0xa121b886, 0x9c419136, 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57,
0x58f35849, 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98,
0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, 0xba43581a,
0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, 0x2602c92c, 0x1b62e09c,
0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, 0x0142247e, 0x46e25eae, 0x7b82771e,
0xb1e6b092, 0x8c869922, 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743,
0xd1062710, 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1,
0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, 0xf2770847,
0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, 0xaff7b675, 0x92979fc5,
0xe915e8db, 0xd475c16b, 0x93d5bbbb, 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, 0x11852c6a, 0x562556ba, 0x6b457f0a,
0x89f57f59, 0xb49556e9, 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888,
0x28d4c7df, 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e,
0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, 0xca64c78c
},
{
0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, 0xf156b2d5,
0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, 0x39dc63eb, 0xf280b04e,
0x07ac0536, 0xccf0d693, 0x4a64a43d, 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, 0xbb3216e8, 0x3da66446, 0xf6fab7e3,
0x047a07ad, 0xcf26d408, 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578,
0x0f580a6c, 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9,
0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, 0xfdd8ba22,
0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, 0x32fe6e2a, 0xf9a2bd8f,
0x0b220dc1, 0xc07ede64, 0x46eaacca, 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14,
0x1eb014d8, 0xd5ecc77d, 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d,
0x1d661643, 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496,
0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, 0xe84aa33b,
0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, 0x20c07205, 0xeb9ca1a0,
0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, 0xad760d6a, 0x2be27fc4, 0xe0beac61,
0x123e1c2f, 0xd962cf8a, 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa,
0x16441b82, 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957,
0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, 0xe4c4abcc
},
{
0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, 0xf64870e9,
0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, 0x37e1e793, 0x9196ec27,
0xcfbd399c, 0x69ca3228, 0x582228b5, 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, 0xae6a585c, 0x9f8242c1, 0x39f54975,
0xa863a552, 0x0e14aee6, 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb,
0x440b7579, 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590,
0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, 0xd59d995e,
0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, 0xdb8937b8, 0x7dfe3c0c,
0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2,
0x8816eaf2, 0x2e61e146, 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b,
0xefc8763c, 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5,
0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, 0xb1e3a387,
0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, 0x704a34fd, 0xd63d3f49,
0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62,
0xabc30345, 0x0db408f1, 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac,
0x03a0a617, 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe,
0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, 0x92364a30
},
{
0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, 0xd92012ac,
0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, 0x69312319, 0xa59b2387,
0xf9766256, 0x35dc62c8, 0xbb53652b, 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, 0x62737787, 0xecfc7064, 0x205670fa,
0x85cd537d, 0x496753e3, 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1,
0x299dc2ed, 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041,
0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, 0x8c06e16a,
0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, 0xc561b289, 0x09cbb217,
0xac509190, 0x60fa910e, 0xee7596ed, 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, 0x37558441, 0xb9da83a2, 0x7570833c,
0x533b85da, 0x9f918544, 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776,
0x2f80b4f1, 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d,
0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, 0x736df520,
0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, 0xc37cc495, 0x0fd6c40b,
0x7aa64737, 0xb60c47a9, 0x3883404a, 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, 0xe1a352e6, 0x6f2c5505, 0xa386559b,
0x061d761c, 0xcab77682, 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0,
0x83d02561, 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd,
0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, 0x264b06e6
}
};
}
================================================
FILE: UAssetAPI/CustomVersion.cs
================================================
using System;
using System.Collections.Generic;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI;
///
/// A custom version. Controls more specific serialization than the main engine object version does.
///
public class CustomVersion : ICloneable
{
///
/// Static map of custom version GUIDs to the object or enum that they represent in the Unreal Engine. This list is not necessarily exhaustive, so feel free to add to it if need be.
///
public static readonly Dictionary GuidToCustomVersionStringMap = new Dictionary()
{
{ UnusedCustomVersionKey, "UnusedCustomVersionKey" },
{ UAPUtils.GUID(0xB0D832E4, 0x1F894F0D, 0xACCF7EB7, 0x36FD4AA2), "FBlueprintsObjectVersion" },
{ UAPUtils.GUID(0xE1C64328, 0xA22C4D53, 0xA36C8E86, 0x6417BD8C), "FBuildObjectVersion" },
{ UAPUtils.GUID(0x375EC13C, 0x06E448FB, 0xB50084F0, 0x262A717E), "FCoreObjectVersion" },
{ UAPUtils.GUID(0xE4B068ED, 0xF49442E9, 0xA231DA0B, 0x2E46BB41), "FEditorObjectVersion" },
{ UAPUtils.GUID(0xCFFC743F, 0x43B04480, 0x939114DF, 0x171D2073), "FFrameworkObjectVersion" },
{ UAPUtils.GUID(0xB02B49B5, 0xBB2044E9, 0xA30432B7, 0x52E40360), "FMobileObjectVersion" },
{ UAPUtils.GUID(0xA4E4105C, 0x59A149B5, 0xA7C540C4, 0x547EDFEE), "FNetworkingObjectVersion" },
{ UAPUtils.GUID(0x39C831C9, 0x5AE647DC, 0x9A449C17, 0x3E1C8E7C), "FOnlineObjectVersion" },
{ UAPUtils.GUID(0x78F01B33, 0xEBEA4F98, 0xB9B484EA, 0xCCB95AA2), "FPhysicsObjectVersion" },
{ UAPUtils.GUID(0x6631380F, 0x2D4D43E0, 0x8009CF27, 0x6956A95A), "FPlatformObjectVersion" },
{ UAPUtils.GUID(0x12F88B9F, 0x88754AFC, 0xA67CD90C, 0x383ABD29), "FRenderingObjectVersion" },
{ UAPUtils.GUID(0x7B5AE74C, 0xD2704C10, 0xA9585798, 0x0B212A5A), "FSequencerObjectVersion" },
{ UAPUtils.GUID(0xD7296918, 0x1DD64BDD, 0x9DE264A8, 0x3CC13884), "FVRObjectVersion" },
{ UAPUtils.GUID(0xC2A15278, 0xBFE74AFE, 0x6C1790FF, 0x531DF755), "FLoadTimesObjectVersion" },
{ UAPUtils.GUID(0x6EACA3D4, 0x40EC4CC1, 0xb7868BED, 0x9428FC5), "FGeometryObjectVersion" },
{ UAPUtils.GUID(0x29E575DD, 0xE0A34627, 0x9D10D276, 0x232CDCEA), "FAnimPhysObjectVersion" },
{ UAPUtils.GUID(0xAF43A65D, 0x7FD34947, 0x98733E8E, 0xD9C1BB05), "FAnimObjectVersion" },
{ UAPUtils.GUID(0x6B266CEC, 0x1EC74B8F, 0xA30BE4D9, 0x0942FC07), "FReflectionCaptureObjectVersion" },
{ UAPUtils.GUID(0x0DF73D61, 0xA23F47EA, 0xB72789E9, 0x0C41499A), "FAutomationObjectVersion" },
{ UAPUtils.GUID(0x601D1886, 0xAC644F84, 0xAA16D3DE, 0x0DEAC7D6), "FFortniteMainBranchObjectVersion" },
{ UAPUtils.GUID(0x9DFFBCD6, 0x494F0158, 0xE2211282, 0x3C92A888), "FEnterpriseObjectVersion" },
{ UAPUtils.GUID(0xF2AED0AC, 0x9AFE416F, 0x8664AA7F, 0xFA26D6FC), "FNiagaraObjectVersion" },
{ UAPUtils.GUID(0x174F1F0B, 0xB4C645A5, 0xB13F2EE8, 0xD0FB917D), "FDestructionObjectVersion" },
{ UAPUtils.GUID(0x35F94A83, 0xE258406C, 0xA31809F5, 0x9610247C), "FExternalPhysicsCustomObjectVersion" },
{ UAPUtils.GUID(0xB68FC16E, 0x8B1B42E2, 0xB453215C, 0x058844FE), "FExternalPhysicsMaterialCustomObjectVersion" },
{ UAPUtils.GUID(0xB2E18506, 0x4273CFC2, 0xA54EF4BB, 0x758BBA07), "FCineCameraObjectVersion" },
{ UAPUtils.GUID(0x64F58936, 0xFD1B42BA, 0xBA967289, 0xD5D0FA4E), "FVirtualProductionObjectVersion" },
{ UAPUtils.GUID(0x6f0ed827, 0xa6094895, 0x9c91998d, 0x90180ea4), "FMediaFrameworkObjectVersion" },
{ UAPUtils.GUID(0xAFE08691, 0x3A0D4952, 0xB673673B, 0x7CF22D1E), "FPoseDriverCustomVersion" },
{ UAPUtils.GUID(0xCB8AB0CD, 0xE78C4BDE, 0xA8621393, 0x14E9EF62), "FTempCustomVersion" },
{ UAPUtils.GUID(0x2EB5FDBD, 0x01AC4D10, 0x8136F38F, 0x3393A5DA), "FAnimationCustomVersion" },
{ UAPUtils.GUID(0x717F9EE7, 0xE9B0493A, 0x88B39132, 0x1B388107), "FAssetRegistryVersion" },
{ UAPUtils.GUID(0xFB680AF2, 0x59EF4BA3, 0xBAA819B5, 0x73C8443D), "FClothingAssetCustomVersion" },
{ UAPUtils.GUID(0x9C54D522, 0xA8264FBE, 0x94210746, 0x61B482D0), "FReleaseObjectVersion" },
{ UAPUtils.GUID(0x4A56EB40, 0x10F511DC, 0x92D3347E, 0xB2C96AE7), "FParticleSystemCustomVersion" },
{ UAPUtils.GUID(0xD78A4A00, 0xE8584697, 0xBAA819B5, 0x487D46B4), "FSkeletalMeshCustomVersion" },
{ UAPUtils.GUID(0x5579F886, 0x933A4C1F, 0x83BA087B, 0x6361B92F), "FRecomputeTangentCustomVersion" },
{ UAPUtils.GUID(0x612FBE52, 0xDA53400B, 0x910D4F91, 0x9FB1857C), "FOverlappingVerticesCustomVersion" },
{ UAPUtils.GUID(0x430C4D19, 0x71544970, 0x87699B69, 0xDF90B0E5), "FFoliageCustomVersion" },
{ UAPUtils.GUID(0xaafe32bd, 0x53954c14, 0xb66a5e25, 0x1032d1dd), "FProceduralFoliageCustomVersion" },
{ UAPUtils.GUID(0xab965196, 0x45d808fc, 0xb7d7228d, 0x78ad569e), "FLiveLinkCustomVersion" },
{ UAPUtils.GUID(0xE7086368, 0x6B234C58, 0x84391B70, 0x16265E91), "FFortniteReleaseBranchCustomObjectVersion" },
{ UAPUtils.GUID(0xD89B5E42, 0x24BD4D46, 0x8412ACA8, 0xDF641779), "FUE5ReleaseStreamObjectVersion" },
{ UAPUtils.GUID(0xFCF57AFA, 0x50764283, 0xB9A9E658, 0xFFA02D32), "FNiagaraCustomVersion" },
{ UAPUtils.GUID(0x697DD581, 0xE64f41AB, 0xAA4A51EC, 0xBEB7B628), "FUE5MainStreamObjectVersion" }
// etc.
};
///
/// A GUID that represents an unused custom version.
///
public static readonly Guid UnusedCustomVersionKey = UAPUtils.GUID(0, 0, 0, 0xF99D40C1);
///
/// Returns the name of the object or enum that a custom version GUID represents, as specified in .
///
/// A GUID that represents a custom version.
/// A string that represents the friendly name of the corresponding custom version.
public static string GetCustomVersionFriendlyNameFromGuid(Guid guid)
{
return GuidToCustomVersionStringMap.ContainsKey(guid) ? GuidToCustomVersionStringMap[guid] : null;
}
///
/// Returns the GUID of the custom version that the object or enum name provided represents.
///
/// The name of a custom version object or enum.
/// A GUID that represents the custom version
public static Guid GetCustomVersionGuidFromFriendlyName(string friendlyName)
{
foreach (KeyValuePair entry in GuidToCustomVersionStringMap)
{
if (entry.Value == friendlyName) return entry.Key;
}
return UnusedCustomVersionKey;
}
public FString Name = null;
public Guid Key;
public string FriendlyName = null;
public int Version;
public bool IsSerialized = true;
public CustomVersion SetIsSerialized(bool val)
{
this.IsSerialized = val;
return this;
}
public object Clone()
{
return new CustomVersion(Key, Version)
{
Name = Name,
FriendlyName = FriendlyName,
IsSerialized = IsSerialized
};
}
///
/// Initializes a new instance of the class given an object or enum name and a version number.
///
/// The friendly name to use when initializing this custom version.
/// The version number to use when initializing this custom version.
public CustomVersion(string friendlyName, int version)
{
Key = GetCustomVersionGuidFromFriendlyName(friendlyName);
FriendlyName = friendlyName;
Version = version;
}
///
/// Initializes a new instance of the class given a custom version GUID and a version number.
///
/// The GUID to use when initializing this custom version.
/// The version number to use when initializing this custom version.
public CustomVersion(Guid key, int version)
{
Key = key;
if (GuidToCustomVersionStringMap.ContainsKey(key)) FriendlyName = GuidToCustomVersionStringMap[key];
Version = version;
}
///
/// Initializes a new instance of the class.
///
public CustomVersion()
{
Key = UnusedCustomVersionKey;
Version = 0;
}
}
================================================
FILE: UAssetAPI/CustomVersions/CustomVersions.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.CustomVersions
{
///
/// Represents the engine version at the time that a custom version was implemented.
///
[AttributeUsage(AttributeTargets.Field)]
public class IntroducedAttribute : Attribute
{
public EngineVersion IntroducedVersion;
public IntroducedAttribute(EngineVersion introducedVersion)
{
IntroducedVersion = introducedVersion;
}
}
///
/// Custom serialization version for changes made in the //Fortnite/Main stream.
///
public enum FFortniteMainBranchObjectVersion
{
/// Before any version changes were made
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
BeforeCustomVersionWasAdded = 0,
/// World composition tile offset changed from 2d to 3d
[Introduced(EngineVersion.VER_UE4_20)]
WorldCompositionTile3DOffset,
/// Minor material serialization optimization
[Introduced(EngineVersion.VER_UE4_20)]
MaterialInstanceSerializeOptimization_ShaderFName,
/// Refactored cull distances to account for HLOD, explicit override and globals in priority
[Introduced(EngineVersion.VER_UE4_20)]
CullDistanceRefactor_RemovedDefaultDistance,
[Introduced(EngineVersion.VER_UE4_20)]
CullDistanceRefactor_NeverCullHLODsByDefault,
[Introduced(EngineVersion.VER_UE4_20)]
CullDistanceRefactor_NeverCullALODActorsByDefault,
/// Support to remove morphtarget generated by bRemapMorphtarget
[Introduced(EngineVersion.VER_UE4_20)]
SaveGeneratedMorphTargetByEngine,
/// Convert reduction setting options
[Introduced(EngineVersion.VER_UE4_20)]
ConvertReductionSettingOptions,
/// Serialize the type of blending used for landscape layer weight static params
[Introduced(EngineVersion.VER_UE4_20)]
StaticParameterTerrainLayerWeightBlendType,
/// Fix up None Named animation curve names,
[Introduced(EngineVersion.VER_UE4_20)]
FixUpNoneNameAnimationCurves,
/// Ensure ActiveBoneIndices to have parents even not skinned for old assets
[Introduced(EngineVersion.VER_UE4_20)]
EnsureActiveBoneIndicesToContainParents,
/// Serialize the instanced static mesh render data, to avoid building it at runtime
[Introduced(EngineVersion.VER_UE4_20)]
SerializeInstancedStaticMeshRenderData,
/// Cache material quality node usage
[Introduced(EngineVersion.VER_UE4_20)]
CachedMaterialQualityNodeUsage,
/// Font outlines no longer apply to drop shadows for new objects but we maintain the opposite way for backwards compat
[Introduced(EngineVersion.VER_UE4_21)]
FontOutlineDropShadowFixup,
/// New skeletal mesh import workflow (Geometry only or animation only re-import )
[Introduced(EngineVersion.VER_UE4_21)]
NewSkeletalMeshImporterWorkflow,
/// Migrate data from previous data structure to new one to support materials per LOD on the Landscape
[Introduced(EngineVersion.VER_UE4_21)]
NewLandscapeMaterialPerLOD,
/// New Pose Asset data type
[Introduced(EngineVersion.VER_UE4_21)]
RemoveUnnecessaryTracksFromPose,
/// Migrate Foliage TLazyObjectPtr to TSoftObjectPtr
[Introduced(EngineVersion.VER_UE4_21)]
FoliageLazyObjPtrToSoftObjPtr,
/// TimelineTemplates store their derived names instead of dynamically generating. This code tied to this version was reverted and redone at a later date
[Introduced(EngineVersion.VER_UE4_22)]
REVERTED_StoreTimelineNamesInTemplate,
/// Added BakePoseOverride for LOD setting
[Introduced(EngineVersion.VER_UE4_22)]
AddBakePoseOverrideForSkeletalMeshReductionSetting,
/// TimelineTemplates store their derived names instead of dynamically generating
[Introduced(EngineVersion.VER_UE4_22)]
StoreTimelineNamesInTemplate,
/// New Pose Asset data type
[Introduced(EngineVersion.VER_UE4_22)]
WidgetStopDuplicatingAnimations,
/// Allow reducing of the base LOD, we need to store some imported model data so we can reduce again from the same data.
[Introduced(EngineVersion.VER_UE4_22)]
AllowSkeletalMeshToReduceTheBaseLOD,
/// Curve Table size reduction
[Introduced(EngineVersion.VER_UE4_22)]
ShrinkCurveTableSize,
/// Widgets upgraded with WidgetStopDuplicatingAnimations, may not correctly default-to-self for the widget parameter.
[Introduced(EngineVersion.VER_UE4_22)]
WidgetAnimationDefaultToSelfFail,
/// HUDWidgets now require an element tag
[Introduced(EngineVersion.VER_UE4_22)]
FortHUDElementNowRequiresTag,
/// Animation saved as bulk data when cooked
[Introduced(EngineVersion.VER_UE4_23)]
FortMappedCookedAnimation,
/// Support Virtual Bone in Retarget Manager
[Introduced(EngineVersion.VER_UE4_23)]
SupportVirtualBoneInRetargeting,
/// Fixup bad defaults in water metadata
[Introduced(EngineVersion.VER_UE4_24)]
FixUpWaterMetadata,
/// Move the location of water metadata
[Introduced(EngineVersion.VER_UE4_24)]
MoveWaterMetadataToActor,
/// Replaced lake collision component
[Introduced(EngineVersion.VER_UE4_24)]
ReplaceLakeCollision,
/// Anim layer node names are now conformed by Guid
[Introduced(EngineVersion.VER_UE4_24)]
AnimLayerGuidConformation,
/// Ocean collision component has become dynamic
[Introduced(EngineVersion.VER_UE4_26)]
MakeOceanCollisionTransient,
/// FFieldPath will serialize the owner struct reference and only a short path to its property
[Introduced(EngineVersion.VER_UE4_26)]
FFieldPathOwnerSerialization,
/// Simplified WaterBody post process material handling
[Introduced(EngineVersion.VER_UE4_26)]
FixUpUnderwaterPostProcessMaterial,
/// A single water exclusion volume can now exclude N water bodies
[Introduced(EngineVersion.VER_UE4_26)]
SupportMultipleWaterBodiesPerExclusionVolume,
/// Serialize rigvm operators one by one instead of the full byte code array to ensure determinism
[Introduced(EngineVersion.VER_UE4_26)]
RigVMByteCodeDeterminism,
/// Serialize the physical materials generated by the render material
[Introduced(EngineVersion.VER_UE4_26)]
LandscapePhysicalMaterialRenderData,
/// RuntimeVirtualTextureVolume fix transforms
[Introduced(EngineVersion.VER_UE4_26)]
FixupRuntimeVirtualTextureVolume,
/// Retrieve water body collision components that were lost in cooked builds
[Introduced(EngineVersion.VER_UE4_26)]
FixUpRiverCollisionComponents,
/// Fix duplicate spline mesh components on rivers
[Introduced(EngineVersion.VER_UE4_26)]
FixDuplicateRiverSplineMeshCollisionComponents,
/// Indicates level has stable actor guids
[Introduced(EngineVersion.VER_UE4_26)]
ContainsStableActorGUIDs,
/// Levelset Serialization support for BodySetup.
[Introduced(EngineVersion.VER_UE4_26)]
LevelsetSerializationSupportForBodySetup,
/// Moving Chaos solver properties to allow them to exist in the project physics settings
[Introduced(EngineVersion.VER_UE4_26)]
ChaosSolverPropertiesMoved,
/// Moving some UFortGameFeatureData properties and behaviors into the UGameFeatureAction pattern
[Introduced(EngineVersion.VER_UE4_27)]
GameFeatureData_MovedComponentListAndCheats,
/// Add centrifugal forces for cloth
[Introduced(EngineVersion.VER_UE4_27)]
ChaosClothAddfictitiousforces,
/// Chaos Convex StructureData supports different index sizes based on num verts/planes. Chaos FConvex uses array of FVec3s for vertices instead of particles (Merged from //UE4/Main)
[Introduced(EngineVersion.VER_UE4_27)]
ChaosConvexVariableStructureDataAndVerticesArray,
/// Remove the WaterVelocityHeightTexture dependency on MPC_Landscape and LandscapeWaterIndo
[Introduced(EngineVersion.VER_UE4_27)]
RemoveLandscapeWaterInfo,
// CHANGES BEYOND HERE ARE UE5 ONLY //
/// Added the weighted value property type to store the cloths weight maps' low/high ranges
[Introduced(EngineVersion.VER_UE5_0)]
ChaosClothAddWeightedValue,
/// Added the Long Range Attachment stiffness weight map
[Introduced(EngineVersion.VER_UE5_0)]
ChaosClothAddTetherStiffnessWeightMap,
/// Fix corrupted LOD transition maps
[Introduced(EngineVersion.VER_UE5_0)]
ChaosClothFixLODTransitionMaps,
/// Enable a few more weight maps to better art direct the cloth simulation
[Introduced(EngineVersion.VER_UE5_0)]
ChaosClothAddTetherScaleAndDragLiftWeightMaps,
/// Enable material (edge, bending, and area stiffness) weight maps
[Introduced(EngineVersion.VER_UE5_0)]
ChaosClothAddMaterialWeightMaps,
/// Added bShowCurve for movie scene float channel serialization
[Introduced(EngineVersion.VER_UE5_0)]
SerializeFloatChannelShowCurve,
/// Minimize slack waste by using a single array for grass data
[Introduced(EngineVersion.VER_UE5_0)]
LandscapeGrassSingleArray,
/// Add loop counters to sequencer's compiled sub-sequence data
[Introduced(EngineVersion.VER_UE5_0)]
AddedSubSequenceEntryWarpCounter,
/// Water plugin is now component-based rather than actor based
[Introduced(EngineVersion.VER_UE5_0)]
WaterBodyComponentRefactor,
/// Cooked BPGC storing editor-only asset tags
[Introduced(EngineVersion.VER_UE5_0)]
BPGCCookedEditorTags,
/// Terrain layer weights are no longer considered material parameters
[Introduced(EngineVersion.VER_UE5_0)]
TTerrainLayerWeightsAreNotParameters,
///
/// Anim Dynamics Node Gravity Override vector is now defined in world space, not simulation space.
/// Legacy behavior can be maintained with a flag, which is set false by default for new nodes,
/// true for nodes predating this change.
///
[Introduced(EngineVersion.VER_UE5_0)]
GravityOverrideDefinedInWorldSpace,
/// Anim Dynamics Node Physics parameters for each body in a chain are now stored in an array and can be edited.
[Introduced(EngineVersion.VER_UE5_1)]
AnimDynamicsEditableChainParameters,
/// Decoupled the generation of the water texture from the Water Brush and the landscape
[Introduced(EngineVersion.VER_UE5_1)]
WaterZonesRefactor,
/// Add faster damping calculations to the cloth simulation and rename previous Damping parameter to LocalDamping.
[Introduced(EngineVersion.VER_UE5_1)]
ChaosClothFasterDamping,
/// Migrated function handlers to the CDO/archetype data
[Introduced(EngineVersion.VER_UE5_1)]
MigratedFunctionHandlersToDefaults,
/// Storing inertia tensor as vec3 instead of matrix.
[Introduced(EngineVersion.VER_UE5_1)]
ChaosInertiaConvertedToVec3,
/// Migrated event definitions to the CDO/archetype data
[Introduced(EngineVersion.VER_UE5_1)]
MigratedEventDefinitionToDefaults,
/// Serialize LevelInstanceActorGuid on new ILevelInstanceInterface implementation
[Introduced(EngineVersion.VER_UE5_1)]
LevelInstanceActorGuidSerialize,
/// Single-frame/key AnimDataModel patch-up
[Introduced(EngineVersion.VER_UE5_1)]
SingleFrameAndKeyAnimModel,
/// Remapped bEvaluateWorldPositionOffset to bEvaluateWorldPositionOffsetInRayTracing
[Introduced(EngineVersion.VER_UE5_1)]
RemappedEvaluateWorldPositionOffsetInRayTracing,
/// Water body collision settings are now those of the base UPrimitiveComponent, rather than duplicated in UWaterBodyComponent
[Introduced(EngineVersion.VER_UE5_1)]
WaterBodyComponentCollisionSettingsRefactor,
///
/// Introducing widget inherited named slots. This wouldn't have required a version bump, except in the previous
/// version, users could make NamedSlots and then Seed them with any random widgets, as a sorta 'default' setup.
/// In order to preserve that, we're bumping the version so that we can set a new field on UNamedSlot to control
/// if a widget exposes its named slot to everyone (even if it has content), which by default they wont any longer.
///
[Introduced(EngineVersion.VER_UE5_1)]
WidgetInheritedNamedSlots,
/// Added water HLOD material
[Introduced(EngineVersion.VER_UE5_1)]
WaterHLODSupportAdded,
/// Moved parameters affecting Skeleton pose rendering from the PoseWatch class to the PoseWatchPoseElement class.
[Introduced(EngineVersion.VER_UE5_1)]
PoseWatchMigrateSkeletonDrawParametersToPoseElement,
/// Reset default value for Water exclusion volumes to make them more intuitive and support the "it just works" philosophy.
[Introduced(EngineVersion.VER_UE5_1)]
WaterExclusionVolumeExcludeAllDefault,
/// Added water non-tessellated LOD
[Introduced(EngineVersion.VER_UE5_1)]
WaterNontessellatedLODSupportAdded,
/// Added FHierarchicalSimplification::SimplificationMethod
[Introduced(EngineVersion.VER_UE5_1)]
HierarchicalSimplificationMethodEnumAdded,
/// Changed how world partition streaming cells are named
[Introduced(EngineVersion.VER_UE5_1)]
WorldPartitionStreamingCellsNamingShortened,
/// Serialize ContentBundleGuid in WorldPartitionActorDesc
[Introduced(EngineVersion.VER_UE5_1)]
WorldPartitionActorDescSerializeContentBundleGuid,
/// Serialize IsActorRuntimeOnly in WorldPartitionActorDesc
[Introduced(EngineVersion.VER_UE5_1)]
WorldPartitionActorDescSerializeActorIsRuntimeOnly,
/// Add Nanite Material Override option to materials and material instances.
[Introduced(EngineVersion.VER_UE5_1)]
NaniteMaterialOverride,
/// Serialize HLOD stats in HLODActorDesc
[Introduced(EngineVersion.VER_UE5_1)]
WorldPartitionHLODActorDescSerializeStats,
/// WorldPartitionStreamingSourceComponent property deprecation
[Introduced(EngineVersion.VER_UE5_2)]
WorldPartitionStreamingSourceComponentTargetDeprecation,
/// Fixed localization gathering for external actor packages
[Introduced(EngineVersion.VER_UE5_2)]
FixedLocalizationGatherForExternalActorPackage,
/// Change HLODActors to RuntimeCells mapping to use a GUID instead of the cell name
[Introduced(EngineVersion.VER_UE5_2)]
WorldPartitionHLODActorUseSourceCellGuid,
/// Add an attribute to geometry collection to track internal faces, rather than relying on material ID numbering
[Introduced(EngineVersion.VER_UE5_3)]
ChaosGeometryCollectionInternalFacesAttribute,
/// Dynamic cast nodes use an enumerated pure node state to include a value for the default setting
[Introduced(EngineVersion.VER_UE5_3)]
DynamicCastNodesUsePureStateEnum,
/// Add FWorldPartitionActorFilter to FLevelInstanceActorDesc/FDataLayerInstanceDesc
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionActorFilter,
/// Change the non-spatialized radius to blend to a pure 2D spatialized sound vs omnidirectional
[Introduced(EngineVersion.VER_UE5_3)]
AudioAttenuationNonSpatializedRadiusBlend,
/// Serialize actor class descriptors
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionActorClassDescSerialize,
/// FActorContainerID is now an FGuid instead of a uint64
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionFActorContainerIDu64ToGuid,
/// FDataLayerInstanceDesc support for private data layers
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionPrivateDataLayers,
/// Reduce size and improve behaviour of Chaos::FImplicitObjectUnion
[Introduced(EngineVersion.VER_UE5_3)]
ChaosImplicitObjectUnionBVHRefactor,
/// FLevelInstanceActorDesc DeltaSerialize Filter
[Introduced(EngineVersion.VER_UE5_3)]
LevelInstanceActorDescDeltaSerializeFilter,
/// Fix the Nanite landscape mesh non-deterministic DDC keys
[Introduced(EngineVersion.VER_UE5_3)]
FixNaniteLandscapeMeshDDCKey,
/// Change how connection graphs are stored on Geometry Collections to an edge-array representation
[Introduced(EngineVersion.VER_UE5_3)]
ChaosGeometryCollectionConnectionEdgeGroup,
/// Moved the water info mesh data and static water body meshes into new static mesh components for water bodies.
[Introduced(EngineVersion.VER_UE5_3)]
WaterBodyStaticMeshComponents,
/// Serialize invalid bounds in world partition actor descriptors
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionActorDescSerializeInvalidBounds,
/// Upgrade Navigation Links to use 64 bits for the ID
[Introduced(EngineVersion.VER_UE5_3)]
NavigationLinkID32To64,
/// Serialize editor only references in world partition actor descriptors
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionActorDescSerializeEditorOnlyReferences,
/// Add support for soft object paths in actor descriptors
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionActorDescSerializeSoftObjectPathSupport,
/// Don't serialize class descriptor GUIDs
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionClasDescGuidTransient,
/// Serialize ActorDesc bIsMainWorldOnly
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionActorDescIsMainWorldOnly,
/// FWorldPartitionActorFilter go back to FString serialize of AssetPaths to avoid FArchiveReplaceOrClearExternalReferences clearing CDO references on BP Compile
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionActorFilterStringAssetPath,
/// Add FPackedLevelActorDesc for APackedLevelActor and support for APackedLevelActor Filters
[Introduced(EngineVersion.VER_UE5_3)]
PackedLevelActorDesc,
/// Add customizable values for several UWorldPartitionRuntimeSpatialHash cvars
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionRuntimeSpatialHashCVarOverrides,
/// WorldPartition HLOD now contains a source actors object
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionHLODSourceActorsRefactor,
[Introduced(EngineVersion.VER_UE5_3)]
WaterBodyStaticMeshRename,
/// Geometry Collection now by-default converts vertex colors to sRGB when creating render data
[Introduced(EngineVersion.VER_UE5_3)]
GeometryCollectionConvertVertexColorToSRGB,
/// Water bodies before this version need to update their water zone on load since they won't have been serialized yet.
[Introduced(EngineVersion.VER_UE5_3)]
WaterOwningZonePointerFixup,
/// Set flags on water static meshes to duplicate transient to avoid underlying static mesh duplication issue
[Introduced(EngineVersion.VER_UE5_3)]
WaterBodyStaticMeshDuplicateTransient,
/// Update paths to use the SkeletalClass
[Introduced(EngineVersion.VER_UE5_3)]
MVVMConvertPropertyPathToSkeletalClass,
/// Fixup all flags/outering on static meshes on water bodies by rebuilding them completely
[Introduced(EngineVersion.VER_UE5_3)]
WaterBodyStaticMeshFixup,
/// Binding extensions for anim graph nodes
[Introduced(EngineVersion.VER_UE5_4)]
AnimGraphNodeBindingExtensions,
/// Function data stores a map from work to debug operands
[Introduced(EngineVersion.VER_UE5_4)]
RigVMSaveDebugMapInGraphFunctionData,
/// Fix missing binding extensions for some anim graph nodes
[Introduced(EngineVersion.VER_UE5_4)]
FixMissingAnimGraphNodeBindingExtensions,
/// EditableWhenInherited: Skip custom serialization on non Archetypes
[Introduced(EngineVersion.VER_UE5_4)]
ISMComponentEditableWhenInheritedSkipSerialization,
/// GrassTypes are now per-component, rather than per-landscape proxy :
[Introduced(EngineVersion.VER_UE5_4)]
LandscapeSupportPerComponentGrassTypes,
/// World partition actor data layers activation logic operator support defaults for old maps
[Introduced(EngineVersion.VER_UE5_4)]
WorldPartitionDataLayersLogicOperatorAdded,
/// Started sorting Possessables, Spawnables, and MovieSceneBindings for better search performance.
[Introduced(EngineVersion.VER_UE5_4)]
MovieSceneSortedBindings,
/// Remove the UAnimCurveCompressionCodec::InstanceGuid which causes cook determinism issues
[Introduced(EngineVersion.VER_UE5_4)]
RemoveAnimCurveCompressionCodecInstanceGuid,
/// Serialize the source HLOD Layer for HLOD actor descriptors.
[Introduced(EngineVersion.VER_UE5_4)]
WorldPartitionHLODActorDescSerializeSourceHLODLayer,
/// Serialize custom editor bounds for HLOD actor descriptors.
[Introduced(EngineVersion.VER_UE5_4)]
WorldPartitionHLODActorDescSerializeEditorBounds,
/// Changed default Local Exposure Contrast from 1.0 to 0.8 (reverted)
[Introduced(EngineVersion.VER_UE5_4)]
LocalExposureDefaultChangeFrom1_Reverted,
/// Added support of external packaging of Data Layer Instances
[Introduced(EngineVersion.VER_UE5_4)]
AddDataLayerInstanceExternalPackage,
/// Update paths to keep a flag if they are the widget BP
[Introduced(EngineVersion.VER_UE5_4)]
MVVMPropertyPathSelf,
/// Enabled ObjectPtr property serialization for Dataflow nodes
[Introduced(EngineVersion.VER_UE5_4)]
AddDataflowObjectSerialization,
/// Add anim notify rate scaling, defaults to on for new content, off for old content
[Introduced(EngineVersion.VER_UE5_4)]
AnimNotifyAddRateScale,
/// Fix tangents for non-uniform build scales, and add a flag to optionally match the previous (incorrect) tangents
[Introduced(EngineVersion.VER_UE5_4)]
FixedTangentTransformForNonuniformBuildScale,
/// AnimNode Layers will now start in a Shared Group, instead of being each one on a different group at runtime
[Introduced(EngineVersion.VER_UE5_4)]
AnimNodeRootDefaultGroupChange,
/// Move AnimNext graphs to sub-entries of assets
[Introduced(EngineVersion.VER_UE5_4)]
AnimNextMoveGraphsToEntries,
/// Removed debug information containing compressed data author, time etc. from animation DDC data as it introduces indeterminism
[Introduced(EngineVersion.VER_UE5_4)]
AnimationSequenceCompressedDataRemoveDebugData,
/// Changes to Orthographic Camera default settings
[Introduced(EngineVersion.VER_UE5_4)]
OrthographicCameraDefaultSettings,
/// Added settings to Landscape HLODs
[Introduced(EngineVersion.VER_UE5_4)]
LandscapeAddedHLODSettings,
/// Skeletal Mesh uses Mesh Description to store mesh bulk data.
[Introduced(EngineVersion.VER_UE5_4)]
MeshDescriptionForSkeletalMesh,
/// Skeletal Mesh optionally cooks half edge data per lod
[Introduced(EngineVersion.VER_UE5_4)]
SkeletalHalfEdgeData,
/// Combine graph contexts for AnimNext graphs
[Introduced(EngineVersion.VER_UE5_5)]
AnimNextCombineGraphContexts,
/// Combine parameter blocks and graphs
[Introduced(EngineVersion.VER_UE5_5)]
AnimNextCombineParameterBlocksAndGraphs,
/// Move workspaces to a seperate plugin
[Introduced(EngineVersion.VER_UE5_5)]
AnimNextMoveWorkspaces,
/// Level Instance Property overrides
[Introduced(EngineVersion.VER_UE5_5)]
LevelInstancePropertyOverrides,
/// Added FVolumetricLightMapGridDesc in MapBuildData
[Introduced(EngineVersion.VER_UE5_5)]
VolumetricLightMapGridDescSupport,
/// Introduce new structure for customizing the landscape edit layer behavior
[Introduced(EngineVersion.VER_UE5_5)]
IntroduceLandscapeEditLayerClass,
/// Change workspaces to store asset references as external objects
[Introduced(EngineVersion.VER_UE5_5)]
AnimNextWorkspaceEntryConversion,
/// Add support for anytype in dataflow
[Introduced(EngineVersion.VER_UE5_5)]
DataflowAnyTypeSupport,
/// Adding a new flag in RBAN Solver Setting to be able to use manifolds
[Introduced(EngineVersion.VER_UE5_5)]
PhysicsAssetUseManifoldFlags,
/// Added support for to record sim and query data of Shape Instance data in CVD
[Introduced(EngineVersion.VER_UE5_5)]
SimAndQueryDataSupportInChaosVisualDebugger,
/// Add the imported asset dependencies to the Cloth Asset USD Import node
[Introduced(EngineVersion.VER_UE5_5)]
ChaosClothAssetUSDImportNodeAddAssetDependencies,
/// Changed HitLighting to HitLightingForReflections, and HitLighting now means hit lighting for entire Lumen
[Introduced(EngineVersion.VER_UE5_5)]
LumenRayLightingModeOverrideEnum,
/// PCGPartitionActorDesc
[Introduced(EngineVersion.VER_UE5_5)]
PCGPartitionActorDesc,
/// Target layers are now defined in the Landscape actor and not continuously synced from the assigned material.
[Introduced(EngineVersion.VER_UE5_5)]
LandscapeTargetLayersInLandscapeActor,
/// Fix to get full name of templated type ( Tarray > TArray{Float} for example )
[Introduced(EngineVersion.VER_UE5_5)]
DataflowTemplatedTypeFix,
/// Changes for LevelInstance support in StaticLighting
[Introduced(EngineVersion.VER_UE5_5)]
LevelInstanceStaticLightingSupport,
/// PCGGridDescriptor
[Introduced(EngineVersion.VER_UE5_5)]
PCGGridDescriptor,
/// AnimNext graphs now have public/private state
[Introduced(EngineVersion.VER_UE5_5)]
AnimNextGraphAccessSpecifiers,
/// Added a more stable pixel depth offset mode.
[Introduced(EngineVersion.VER_UE5_5)]
MaterialPixelDepthOffsetMode,
/// Added hideable pins to dataflow
[Introduced(EngineVersion.VER_UE5_5)]
DataflowHideablePins,
/// Added multiple section import to the cloth asset skeletal mesh import node
[Introduced(EngineVersion.VER_UE5_5)]
ClothAssetSkeletalMeshMultiSectionImport,
/// Serialize EditorBounds in WorldPartitionActorDesc
[Introduced(EngineVersion.VER_UE5_5)]
WorldPartitionActorDescSerializeEditorBounds,
/// Fixup for the data that has been damaged by LandscapeTargetLayersInLandscapeActor (loss of landscape layer info object assignments)
[Introduced(EngineVersion.VER_UE5_5)]
FixupLandscapeTargetLayersInLandscapeActor,
//Allow custom import of morph target
[Introduced(EngineVersion.VER_UE5_5)]
MorphTargetCustomImport,
/// Fix chaos cloth buckling stiffness parameter bug
[Introduced(EngineVersion.VER_UE5_5)]
ChaosClothAllowZeroBucklingStiffness,
/// LevelSequenceUpgradeDynamicBindings was removed but was intended for this position. Putting this here to make sure versioning of subsequent assets remains the same
[Introduced(EngineVersion.VER_UE5_5)]
LevelSequenceUpgradeDynamicBindings_NoOp,
/// AddToFrontend GFA now defaults to unload plugin on exit frontend
[Introduced(EngineVersion.VER_UE5_5)]
GameFeatureDataActionAddToFrontendDefaultToUnload,
/// Upgraded movie scene 'dynamic bindings' to use the new Custom Bindings system
[Introduced(EngineVersion.VER_UE5_5)]
LevelSequenceUpgradeDynamicBindings,
/// Changed the precision for the stored rotation on kinematic targets to match the precision used in particles
[Introduced(EngineVersion.VER_UE5_5)]
ChaosStoreKinematicTargetRotationAsSinglePrecision,
/// PCG changes around the ApplyOnActor node, where we collapsed the TargetActor to the input pin.
[Introduced(EngineVersion.VER_UE5_5)]
PCGApplyOnActorNodeMoveTargetActorEdgeToInput,
///
/// Deprecation of the bPlaying flag on FTimeline struct types in favor of a better
/// PlayingStateTracker type to improve replication reliability
///
[Introduced(EngineVersion.VER_UE5_5)]
TimelinePlayingStateTrackerDeprecation,
/// Enable SkipOnlyEditorOnly style cooking of UStaticMeshComponent::MeshPaintTexture
[Introduced(EngineVersion.VER_UE5_5)]
MeshPaintTextureUsesEditorOnly,
/// Fixup and synchronize some landscape properties that have moved to the property sharing/overriding system :
[Introduced(EngineVersion.VER_UE5_5)]
LandscapeBodyInstanceAsSharedProperty,
/// Multiple changes to AnimNext modules, variables etc.
[Introduced(EngineVersion.VER_UE5_5)]
AnimNextModuleRefactor,
/// Subsurface profile now has a guid to be able to select one of many in a Substrate material.
[Introduced(EngineVersion.VER_UE5_5)]
SubsurfaceProfileGuid,
/// Added support for to record the new solver iteration settings in CVD
[Introduced(EngineVersion.VER_UE5_5)]
SolverIterationsDataSupportInChaosVisualDebugger,
/// Updated FColorMaterialInput to use FLinearColor instead of FColor
[Introduced(EngineVersion.VER_UE5_6)]
MaterialInputUsesLinearColor,
/// Updated editor only AFunctionalTest running logic to run tests editor world if the actors don't support PIE
[Introduced(EngineVersion.VER_UE5_6)]
FunctionalTestCanRunInEditorWorld,
/// Added support for display name in the Visual Logger
[Introduced(EngineVersion.VER_UE5_6)]
VisualLoggerSupportDisplayName,
/// Added support for the GyroscopicTorque flag in CVD
[Introduced(EngineVersion.VER_UE5_6)]
GyroscopicTorquesSupportInChaosVisualDebugger,
/// Added managed array property serialization
[Introduced(EngineVersion.VER_UE5_6)]
AddManagedArrayCollectionPropertySerialization,
/// Landscape texture patches in Texture Asset source mode now use proper resolution when calculating transform
[Introduced(EngineVersion.VER_UE5_6)]
LandscapeTexturePatchUsesTextureAssetResolution,
/// Added support for relative transform in WorldPartitionActorDesc
[Introduced(EngineVersion.VER_UE5_6)]
WorldPartitionActorDescSerializeRelativeTransform,
/// Make sure scene graph entities are not public by default
[Introduced(EngineVersion.VER_UE5_6)]
SceneGraphEntitiesPrivateByDefault,
/// Added debug color for physical materials
[Introduced(EngineVersion.VER_UE5_6)]
DebugColorForPhysicalMaterials,
/// Added PreprocessedFontGeometry to FFontFaceData
[Introduced(EngineVersion.VER_UE5_6)]
AddedPreprocessedFontGeometry,
/// Added Dynamic Mesh Sculpt Layer serialization
[Introduced(EngineVersion.VER_UE5_6)]
DynamicMeshSerializeSculptLayers,
/// Fix reachable garbage object warnings from some legacy ASpatialHashRuntimeGridInfo actors
[Introduced(EngineVersion.VER_UE5_6)]
SpatialHashRuntimeGridInfoSpriteFixup,
/// Removed UAnimSequence::bUseRawDataOnly flag alongside compression refactor
[Introduced(EngineVersion.VER_UE5_6)]
AnimSequenceRawDataOnlyFlagRemoval,
/// HLOD relevancy of Level Instances was previously ignored, now taken into account. Reset to the default behavior.
[Introduced(EngineVersion.VER_UE5_6)]
ResetLevelInstanceHLODRelevancy,
/// Updated default scene capture post-processing settings to reflect the underlying implementation overrides
[Introduced(EngineVersion.VER_UE5_6)]
SceneCaptureDefaultSettings,
/// Add Cloth Asset Base class serialization
[Introduced(EngineVersion.VER_UE5_6)]
AddClothAssetBase,
/// Add inline constant default values to the PCG graph nodes.
[Introduced(EngineVersion.VER_UE5_6)]
PCGInlineConstantDefaultValues,
/// Add MaterialSubstrateSubsurfaceType type to UMaterialExpressionSubstrateSlabBSDF for replacing bUseSSSDifffusion
[Introduced(EngineVersion.VER_UE5_6)]
AddMaterialSubstrateSubsurfaceType,
/// Added option to visualize runtime virtual textures' streamed mips only in PIE
[Introduced(EngineVersion.VER_UE5_6)]
AddedRuntimeVirtualTextureUseStreamingMipsInEditorMode,
/// Media plate holdout composite components have been replaced by a checkbox
[Introduced(EngineVersion.VER_UE5_6)]
MediaPlateHoldoutComponentRemoval,
/// Changed PCG landscape cache default from "serialize at cook" to "never serialize"
[Introduced(EngineVersion.VER_UE5_6)]
PCGLandscapeCacheDefaultSerializationChanged,
/// FSoftObjectPath::SubPathString changed to FUtf8String
[Introduced(EngineVersion.VER_UE5_6)]
SoftObjectPathUtf8SubPaths,
/// FSoftObjectPath::SubPathString could be saved with trailing NULs and need truncating
[Introduced(EngineVersion.VER_UE5_6)]
SoftObjectPathTrailingNULsMaintained,
/// Water body components no longer need to maintain their own PhysicalMaterial property since they are primitive components. After this version, leverage that one instead.
[Introduced(EngineVersion.VER_UE5_6)]
WaterBodyPhysicalMaterialPropertyRemoval,
/// PCG fixed attribute set -> point conversion passing through empty point data as-is and violating output pin type.
[Introduced(EngineVersion.VER_UE5_6)]
PCGAttributeSetToPointAlwaysConverts,
//Add per material slot overlay material data
[Introduced(EngineVersion.VER_UE5_6)]
MeshMaterialSlotOverlayMaterialAdded,
/// Convert Sustrate glint density properly
[Introduced(EngineVersion.VER_UE5_6)]
ConvertGlintDensity,
/// Introduced skinweight validation to avoid render crashes and disappearing simulation meshes
[Introduced(EngineVersion.VER_UE5_6)]
ClothAssetSkinweightsValidation,
/// Switching verse from right handed to left handed
[Introduced(EngineVersion.VER_UE5_6)]
VerseRightToLeftHandedness,
/// Added additional data required to record and represent particle data from the game thread (Kinematic targets, and SQ rejection reasons)
[Introduced(EngineVersion.VER_UE5_6)]
AdditionalGameThreadDataSupportInChaosVisualDebugger,
/// Upgrade UMG widget blueprints using legacy animation API
[Introduced(EngineVersion.VER_UE5_6)]
UpgradeWidgetBlueprintLegacySequencePlayer,
/// Changed clockwise detection algorithm for PCGSplineDirection node with the correct one, but add a version to not break previous nodes.
[Introduced(EngineVersion.VER_UE5_6)]
PCGSplineDirectionClockwiseFix,
/// Rect Lights set in EV units had the wrong intensity (older files need a flag set to keep the old look)
[Introduced(EngineVersion.VER_UE5_6)]
RectLightFixedEVUnitConversion,
/// Add particle bounds to data exported to CVD
[Introduced(EngineVersion.VER_UE5_6)]
ParticleInflatedBoundsInChaosVisualDebugger,
/// Migrate properties from FLandscapeLayer to ULandscapeEditLayer
[Introduced(EngineVersion.VER_UE5_6)]
MigrateLandscapeEditLayerProperties,
/// Added more context data to CVD's traced shapes so we can play it back at the solver stage level (not just game thread frames)
[Introduced(EngineVersion.VER_UE5_6)]
ThreadContextDataInChaosVisualDebuggerDebugDrawData,
/// Changed default grid mode in surface sampler to a version that's more intuitive and less error-prone
[Introduced(EngineVersion.VER_UE5_6)]
PCGChangedSurfaceSamplerDefaultGridCreationMode,
/// Media plate overlay composite technique replacement with holdout composite
[Introduced(EngineVersion.VER_UE5_7)]
MediaPlateOverlayTechniqueRemoval,
/// Added particle flag to allow/disallow partial island sleeping in the island the particle is in
[Introduced(EngineVersion.VER_UE5_7)]
PerParticleFlagToAllowPartialIslandSleepInConnectedIsland,
/// Material Function Blend Deserialize Top/Bottom input nodes with clearer enum marker.
[Introduced(EngineVersion.VER_UE5_7)]
MaterialFunctionBlendTopBottomInputEnum,
/// Cooked CPU-side morph target points are now stored internally in the same compressed format as the GPU morph data.
[Introduced(EngineVersion.VER_UE5_7)]
MorphTargetCookedCPUDataCompressed,
/// AnimNext variables converted to references
[Introduced(EngineVersion.VER_UE5_7)]
AnimNextVariableReferences,
/// The default distortion rendering mode used by the Lens Component is now the Lens Distortion Scene View Extension
[Introduced(EngineVersion.VER_UE5_7)]
LensComponentDefaultToDistortionSVE,
/// Animation default blend option changed from Linear to HermiteCubic (aka SmoothStep, ease in / ease out)
[Introduced(EngineVersion.VER_UE5_7)]
ChangeDefaultAlphaBlendType,
/// Moved Position/Velocity/Projection Iteration Counts from FChaosVDFRigidParticleControlFlags to FChaosVDParticleDynamicMisc
[Introduced(EngineVersion.VER_UE5_7)]
PerParticleIterationCountMovedToDynamicMisc,
/// Added missing custom serialization for some properties in the ParticleDynamicMisc structure used by the Chaos Visual Debugger
[Introduced(EngineVersion.VER_UE5_7)]
AddedMissingSerializationForPropertiesInDynamicMisc,
/// Change default value for deprecated bEnableWorldPartitionGenerationSources
[Introduced(EngineVersion.VER_UE5_7)]
PCGDeprecateWorldPartitionGenerationSources,
/// Refactored the composite (plugin) actor scene capture management.
[Introduced(EngineVersion.VER_UE5_7)]
CompositeActorSceneCaptureRefactor,
/// Moved HLOD Layer properties to an editor only optional object
[Introduced(EngineVersion.VER_UE5_7)]
HLODLayerEditorOnlyObject,
/// Deduplicated particle debug names serialization in the Chaos Visual Debugger
[Introduced(EngineVersion.VER_UE5_7)]
DeduplicatedDebugNameSerializationInCVD,
/// Add BloomGaussianIntensity and BloomConvolutionIntensity
[Introduced(EngineVersion.VER_UE5_7)]
SpecializeBloomIntensity,
/// Add support for world partition actor component descriptors
[Introduced(EngineVersion.VER_UE5_7)]
WorldPartitionActorComponentDesc,
/// Migrate Non-Edit layer landscapes to use the edit layer (ULandscapeEditLayer) system
[Introduced(EngineVersion.VER_UE5_7)]
MigrateLandscapeNonEditLayerToEditLayer,
/// FDynamicMeshAttributeSet has Morph Targets.
[Introduced(EngineVersion.VER_UE5_7)]
DynamicMeshAttributesMorphTargets,
/// Introduce landscape advanced weight blending
[Introduced(EngineVersion.VER_UE5_7)]
LandscapeAdvancedWeightBlending,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION_PLUS_ONE)]
VersionPlusOne,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION)]
LatestVersion = VersionPlusOne - 1
};
///
/// Custom serialization version for changes made in Dev-Framework stream.
///
public enum FFrameworkObjectVersion
{
/// Before any version changes were made
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
BeforeCustomVersionWasAdded = 0,
/// BodySetup's default instance collision profile is used by default when creating a new instance.
[Introduced(EngineVersion.VER_UE4_12)]
UseBodySetupCollisionProfile,
/// Regenerate subgraph arrays correctly in animation blueprints to remove duplicates and add missing graphs that appear read only when edited
[Introduced(EngineVersion.VER_UE4_12)]
AnimBlueprintSubgraphFix,
/// Static and skeletal mesh sockets now use the specified scale
[Introduced(EngineVersion.VER_UE4_12)]
MeshSocketScaleUtilization,
/// Attachment rules are now explicit in how they affect location, rotation and scale
[Introduced(EngineVersion.VER_UE4_12)]
ExplicitAttachmentRules,
/// Moved compressed anim data from uasset to the DDC
[Introduced(EngineVersion.VER_UE4_12)]
MoveCompressedAnimDataToTheDDC,
/// Some graph pins created using legacy code seem to have lost the RF_Transactional flag, which causes issues with undo. Restore the flag at this version
[Introduced(EngineVersion.VER_UE4_12)]
FixNonTransactionalPins,
/// Create new struct for SmartName, and use that for CurveName
[Introduced(EngineVersion.VER_UE4_13)]
SmartNameRefactor,
/// Add Reference Skeleton to Rig
[Introduced(EngineVersion.VER_UE4_13)]
AddSourceReferenceSkeletonToRig,
/// Refactor ConstraintInstance so that we have an easy way to swap behavior paramters
[Introduced(EngineVersion.VER_UE4_13)]
ConstraintInstanceBehaviorParameters,
/// Pose Asset support mask per bone
[Introduced(EngineVersion.VER_UE4_13)]
PoseAssetSupportPerBoneMask,
/// Physics Assets now use SkeletalBodySetup instead of BodySetup
[Introduced(EngineVersion.VER_UE4_13)]
PhysAssetUseSkeletalBodySetup,
/// Remove SoundWave CompressionName
[Introduced(EngineVersion.VER_UE4_13)]
RemoveSoundWaveCompressionName,
/// Switched render data for clothing over to unreal data, reskinned to the simulation mesh
[Introduced(EngineVersion.VER_UE4_14)]
AddInternalClothingGraphicalSkinning,
/// Wheel force offset is now applied at the wheel instead of vehicle COM
[Introduced(EngineVersion.VER_UE4_14)]
WheelOffsetIsFromWheel,
/// Move curve metadata to be saved in skeleton. Individual asset still saves some flag - i.e. disabled curve and editable or not, but major flag - i.e. material types - moves to skeleton and handle in one place
[Introduced(EngineVersion.VER_UE4_14)]
MoveCurveTypesToSkeleton,
/// Cache destructible overlaps on save
[Introduced(EngineVersion.VER_UE4_14)]
CacheDestructibleOverlaps,
/// Added serialization of materials applied to geometry cache objects
[Introduced(EngineVersion.VER_UE4_14)]
GeometryCacheMissingMaterials,
/// Switch static and skeletal meshes to calculate LODs based on resolution-independent screen size
[Introduced(EngineVersion.VER_UE4_15)]
LODsUseResolutionIndependentScreenSize,
/// Blend space post load verification
[Introduced(EngineVersion.VER_UE4_15)]
BlendSpacePostLoadSnapToGrid,
/// Addition of rate scales to blend space samples
[Introduced(EngineVersion.VER_UE4_15)]
SupportBlendSpaceRateScale,
/// LOD hysteresis also needs conversion from the LODsUseResolutionIndependentScreenSize version
[Introduced(EngineVersion.VER_UE4_15)]
LODHysteresisUseResolutionIndependentScreenSize,
/// AudioComponent override subtitle priority default change
[Introduced(EngineVersion.VER_UE4_15)]
ChangeAudioComponentOverrideSubtitlePriorityDefault,
/// Serialize hard references to sound files when possible
[Introduced(EngineVersion.VER_UE4_16)]
HardSoundReferences,
/// Enforce const correctness in Animation Blueprint function graphs
[Introduced(EngineVersion.VER_UE4_17)]
EnforceConstInAnimBlueprintFunctionGraphs,
/// Upgrade the InputKeySelector to use a text style
[Introduced(EngineVersion.VER_UE4_17)]
InputKeySelectorTextStyle,
/// Represent a pins container type as an enum not 3 independent booleans
[Introduced(EngineVersion.VER_UE4_17)]
EdGraphPinContainerType,
/// Switch asset pins to store as string instead of hard object reference
[Introduced(EngineVersion.VER_UE4_17)]
ChangeAssetPinsToString,
/// Fix Local Variables so that the properties are correctly flagged as blueprint visible
[Introduced(EngineVersion.VER_UE4_17)]
LocalVariablesBlueprintVisible,
/// Stopped serializing UField_Next so that UFunctions could be serialized in dependently of a UClass in order to allow us to do all UFunction loading in a single pass (after classes and CDOs are created)
[Introduced(EngineVersion.VER_UE4_18)]
RemoveUField_Next,
/// Fix User Defined structs so that all members are correct flagged blueprint visible
[Introduced(EngineVersion.VER_UE4_18)]
UserDefinedStructsBlueprintVisible,
/// FMaterialInput and FEdGraphPin store their name as FName instead of FString
[Introduced(EngineVersion.VER_UE4_19)]
PinsStoreFName,
/// User defined structs store their default instance, which is used for initializing instances
[Introduced(EngineVersion.VER_UE4_19)]
UserDefinedStructsStoreDefaultInstance,
/// Function terminator nodes serialize an FMemberReference rather than a name/class pair
[Introduced(EngineVersion.VER_UE4_19)]
FunctionTerminatorNodesUseMemberReference,
/// Custom event and non-native interface event implementations add 'const' to reference parameters
[Introduced(EngineVersion.VER_UE4_20)]
EditableEventsUseConstRefParameters,
/// No longer serialize the legacy flag that indicates this state, as it is now implied since we don't serialize the skeleton CDO
[Introduced(EngineVersion.VER_UE4_22)]
BlueprintGeneratedClassIsAlwaysAuthoritative,
/// Enforce visibility of blueprint functions - e.g. raise an error if calling a private function from another blueprint:
[Introduced(EngineVersion.VER_UE4_24)]
EnforceBlueprintFunctionVisibility,
/// ActorComponents now store their serialization index
[Introduced(EngineVersion.VER_UE4_25)]
StoringUCSSerializationIndex,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION_PLUS_ONE)]
VersionPlusOne,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION)]
LatestVersion = VersionPlusOne - 1
};
///
/// Custom serialization version for changes made in Dev-Core stream.
///
public enum FCoreObjectVersion
{
/// Before any version changes were made
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
BeforeCustomVersionWasAdded = 0,
[Introduced(EngineVersion.VER_UE4_12)]
MaterialInputNativeSerialize,
[Introduced(EngineVersion.VER_UE4_15)]
EnumProperties,
[Introduced(EngineVersion.VER_UE4_22)]
SkeletalMaterialEditorDataStripping,
[Introduced(EngineVersion.VER_UE4_25)]
FProperties,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION_PLUS_ONE)]
VersionPlusOne,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION)]
LatestVersion = VersionPlusOne - 1
};
///
/// Custom serialization version for changes made in Dev-Editor stream.
///
public enum FEditorObjectVersion
{
/// Before any version changes were made
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
BeforeCustomVersionWasAdded = 0,
/// Localizable text gathered and stored in packages is now flagged with a localizable text gathering process version
[Introduced(EngineVersion.VER_UE4_12)]
GatheredTextProcessVersionFlagging,
/// Fixed several issues with the gathered text cache stored in package headers
[Introduced(EngineVersion.VER_UE4_12)]
GatheredTextPackageCacheFixesV1,
/// Added support for "root" meta-data (meta-data not associated with a particular object in a package)
[Introduced(EngineVersion.VER_UE4_13)]
RootMetaDataSupport,
/// Fixed issues with how Blueprint bytecode was cached
[Introduced(EngineVersion.VER_UE4_13)]
GatheredTextPackageCacheFixesV2,
/// Updated FFormatArgumentData to allow variant data to be marshaled from a BP into C++
[Introduced(EngineVersion.VER_UE4_13)]
TextFormatArgumentDataIsVariant,
/// Changes to SplineComponent
[Introduced(EngineVersion.VER_UE4_13)]
SplineComponentCurvesInStruct,
/// Updated ComboBox to support toggling the menu open, better controller support
[Introduced(EngineVersion.VER_UE4_14)]
ComboBoxControllerSupportUpdate,
/// Refactor mesh editor materials
[Introduced(EngineVersion.VER_UE4_14)]
RefactorMeshEditorMaterials,
/// Added UFontFace assets
[Introduced(EngineVersion.VER_UE4_15)]
AddedFontFaceAssets,
/// Add UPROPERTY for TMap of Mesh section, so the serialize will be done normally (and export to text will work correctly)
[Introduced(EngineVersion.VER_UE4_15)]
UPropertryForMeshSection,
/// Update the schema of all widget blueprints to use the WidgetGraphSchema
[Introduced(EngineVersion.VER_UE4_15)]
WidgetGraphSchema,
/// Added a specialized content slot to the background blur widget
[Introduced(EngineVersion.VER_UE4_15)]
AddedBackgroundBlurContentSlot,
/// Updated UserDefinedEnums to have stable keyed display names
[Introduced(EngineVersion.VER_UE4_15)]
StableUserDefinedEnumDisplayNames,
/// Added "Inline" option to UFontFace assets
[Introduced(EngineVersion.VER_UE4_15)]
AddedInlineFontFaceAssets,
/// Fix a serialization issue with static mesh FMeshSectionInfoMap FProperty
[Introduced(EngineVersion.VER_UE4_16)]
UPropertryForMeshSectionSerialize,
/// Adding a version bump for the new fast widget construction in case of problems.
[Introduced(EngineVersion.VER_UE4_16)]
FastWidgetTemplates,
/// Update material thumbnails to be more intelligent on default primitive shape for certain material types
[Introduced(EngineVersion.VER_UE4_16)]
MaterialThumbnailRenderingChanges,
/// Introducing a new clipping system for Slate/UMG
[Introduced(EngineVersion.VER_UE4_17)]
NewSlateClippingSystem,
/// MovieScene Meta Data added as native Serialization
[Introduced(EngineVersion.VER_UE4_17)]
MovieSceneMetaDataSerialization,
/// Text gathered from properties now adds two variants: a version without the package localization ID (for use at runtime), and a version with it (which is editor-only)
[Introduced(EngineVersion.VER_UE4_17)]
GatheredTextEditorOnlyPackageLocId,
/// Added AlwaysSign to FNumberFormattingOptions
[Introduced(EngineVersion.VER_UE4_19)]
AddedAlwaysSignNumberFormattingOption,
/// Added additional objects that must be serialized as part of this new material feature
[Introduced(EngineVersion.VER_UE4_19)]
AddedMaterialSharedInputs,
/// Added morph target section indices
[Introduced(EngineVersion.VER_UE4_19)]
AddedMorphTargetSectionIndices,
/// Serialize the instanced static mesh render data, to avoid building it at runtime
[Introduced(EngineVersion.VER_UE4_20)]
SerializeInstancedStaticMeshRenderData,
/// Change to MeshDescription serialization (moved to release)
[Introduced(EngineVersion.VER_UE4_21)]
MeshDescriptionNewSerialization_MovedToRelease,
/// New format for mesh description attributes
[Introduced(EngineVersion.VER_UE4_21)]
MeshDescriptionNewAttributeFormat,
/// Switch root component of SceneCapture actors from MeshComponent to SceneComponent
[Introduced(EngineVersion.VER_UE4_22)]
ChangeSceneCaptureRootComponent,
/// StaticMesh serializes MeshDescription instead of RawMesh
[Introduced(EngineVersion.VER_UE4_22)]
StaticMeshDeprecatedRawMesh,
/// MeshDescriptionBulkData contains a Guid used as a DDC key
[Introduced(EngineVersion.VER_UE4_22)]
MeshDescriptionBulkDataGuid,
/// Change to MeshDescription serialization (removed FMeshPolygon::HoleContours)
[Introduced(EngineVersion.VER_UE4_22)]
MeshDescriptionRemovedHoles,
/// Change to the WidgetCompoent WindowVisibilty default value
[Introduced(EngineVersion.VER_UE4_23)]
ChangedWidgetComponentWindowVisibilityDefault,
/// Avoid keying culture invariant display strings during serialization to avoid non-deterministic cooking issues
[Introduced(EngineVersion.VER_UE4_23)]
CultureInvariantTextSerializationKeyStability,
/// Change to UScrollBar and UScrollBox thickness property (removed implicit padding of 2, so thickness value must be incremented by 4).
[Introduced(EngineVersion.VER_UE4_23)]
ScrollBarThicknessChange,
/// Deprecated LandscapeHoleMaterial
[Introduced(EngineVersion.VER_UE4_23)]
RemoveLandscapeHoleMaterial,
/// MeshDescription defined by triangles instead of arbitrary polygons
[Introduced(EngineVersion.VER_UE4_24)]
MeshDescriptionTriangles,
/// Add weighted area and angle when computing the normals
[Introduced(EngineVersion.VER_UE4_24)]
ComputeWeightedNormals,
/// SkeletalMesh now can be rebuild in editor, no more need to re-import
[Introduced(EngineVersion.VER_UE4_24)]
SkeletalMeshBuildRefactor,
/// Move all SkeletalMesh source data into a private uasset in the same package has the skeletalmesh
[Introduced(EngineVersion.VER_UE4_25)]
SkeletalMeshMoveEditorSourceDataToPrivateAsset,
/// Parse text only if the number is inside the limits of its type
[Introduced(EngineVersion.VER_UE4_26)]
NumberParsingOptionsNumberLimitsAndClamping,
/// Make sure we can have more then 255 material in the skeletal mesh source data
[Introduced(EngineVersion.VER_UE4_26)]
SkeletalMeshSourceDataSupport16bitOfMaterialNumber,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION_PLUS_ONE)]
VersionPlusOne,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION)]
LatestVersion = VersionPlusOne - 1
};
///
/// Custom serialization version for changes made in Dev-AnimPhys stream
///
public enum FAnimPhysObjectVersion
{
/// Before any version changes were made
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
BeforeCustomVersionWasAdded,
/// convert animnode look at to use just default axis instead of enum, which doesn't do much
[Introduced(EngineVersion.VER_UE4_16)]
ConvertAnimNodeLookAtAxis,
/// Change FKSphylElem and FKBoxElem to use Rotators not Quats for easier editing
[Introduced(EngineVersion.VER_UE4_16)]
BoxSphylElemsUseRotators,
/// Change thumbnail scene info and asset import data to be transactional
[Introduced(EngineVersion.VER_UE4_16)]
ThumbnailSceneInfoAndAssetImportDataAreTransactional,
/// Enabled clothing masks rather than painting parameters directly
[Introduced(EngineVersion.VER_UE4_17)]
AddedClothingMaskWorkflow,
/// Remove UID from smart name serialize, it just breaks determinism
[Introduced(EngineVersion.VER_UE4_17)]
RemoveUIDFromSmartNameSerialize,
/// Convert FName Socket to FSocketReference and added TargetReference that support bone and socket
[Introduced(EngineVersion.VER_UE4_17)]
CreateTargetReference,
/// Tune soft limit stiffness and damping coefficients
[Introduced(EngineVersion.VER_UE4_17)]
TuneSoftLimitStiffnessAndDamping,
/// Fix possible inf/nans in clothing particle masses
[Introduced(EngineVersion.VER_UE4_18)]
FixInvalidClothParticleMasses,
/// Moved influence count to cached data
[Introduced(EngineVersion.VER_UE4_18)]
CacheClothMeshInfluences,
/// Remove GUID from Smart Names entirely + remove automatic name fixup
[Introduced(EngineVersion.VER_UE4_18)]
SmartNameRefactorForDeterministicCooking,
/// rename the variable and allow individual curves to be set
[Introduced(EngineVersion.VER_UE4_18)]
RenameDisableAnimCurvesToAllowAnimCurveEvaluation,
/// link curve to LOD, so curve metadata has to include LODIndex
[Introduced(EngineVersion.VER_UE4_18)]
AddLODToCurveMetaData,
/// Fixed blend profile references persisting after paste when they aren't compatible
[Introduced(EngineVersion.VER_UE4_19)]
FixupBadBlendProfileReferences,
/// Allowing multiple audio plugin settings
[Introduced(EngineVersion.VER_UE4_19)]
AllowMultipleAudioPluginSettings,
/// Change RetargetSource reference to SoftObjectPtr
[Introduced(EngineVersion.VER_UE4_19)]
ChangeRetargetSourceReferenceToSoftObjectPtr,
/// Save editor only full pose for pose asset
[Introduced(EngineVersion.VER_UE4_19)]
SaveEditorOnlyFullPoseForPoseAsset,
/// Asset change and cleanup to facilitate new streaming system
[Introduced(EngineVersion.VER_UE4_20)]
GeometryCacheAssetDeprecation,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION_PLUS_ONE)]
VersionPlusOne,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION)]
LatestVersion = VersionPlusOne - 1
}
///
/// Custom serialization version for changes made in Release streams.
///
public enum FReleaseObjectVersion
{
/// Before any version changes were made
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
BeforeCustomVersionWasAdded = 0,
/// Static Mesh extended bounds radius fix
[Introduced(EngineVersion.VER_UE4_11)]
StaticMeshExtendedBoundsFix,
/// Physics asset bodies are either in the sync scene or the async scene, but not both
[Introduced(EngineVersion.VER_UE4_13)]
NoSyncAsyncPhysAsset,
/// ULevel was using TTransArray incorrectly (serializing the entire array in addition to individual mutations). converted to a TArray
[Introduced(EngineVersion.VER_UE4_13)]
LevelTransArrayConvertedToTArray,
/// Add Component node templates now use their own unique naming scheme to ensure more reliable archetype lookups.
[Introduced(EngineVersion.VER_UE4_14)]
AddComponentNodeTemplateUniqueNames,
/// Fix a serialization issue with static mesh FMeshSectionInfoMap FProperty
[Introduced(EngineVersion.VER_UE4_15)]
UPropertryForMeshSectionSerialize,
/// Existing HLOD settings screen size to screen area conversion
[Introduced(EngineVersion.VER_UE4_15)]
ConvertHLODScreenSize,
/// Adding mesh section info data for existing billboard LOD models
[Introduced(EngineVersion.VER_UE4_15)]
SpeedTreeBillboardSectionInfoFixup,
/// Change FMovieSceneEventParameters::StructType to be a string asset reference from a TWeakObjectPtr UScriptStruct
[Introduced(EngineVersion.VER_UE4_16)]
EventSectionParameterStringAssetRef,
/// Remove serialized irradiance map data from skylight.
[Introduced(EngineVersion.VER_UE4_16)]
SkyLightRemoveMobileIrradianceMap,
/// rename bNoTwist to bAllowTwist
[Introduced(EngineVersion.VER_UE4_17)]
RenameNoTwistToAllowTwistInTwoBoneIK,
/// Material layers serialization refactor
[Introduced(EngineVersion.VER_UE4_19)]
MaterialLayersParameterSerializationRefactor,
/// Added disable flag to skeletal mesh data
[Introduced(EngineVersion.VER_UE4_19)]
AddSkeletalMeshSectionDisable,
/// Removed objects that were serialized as part of this material feature
[Introduced(EngineVersion.VER_UE4_19)]
RemovedMaterialSharedInputCollection,
/// HISMC Cluster Tree migration to add new data
[Introduced(EngineVersion.VER_UE4_20)]
HISMCClusterTreeMigration,
/// Default values on pins in blueprints could be saved incoherently
[Introduced(EngineVersion.VER_UE4_20)]
PinDefaultValuesVerified,
/// During copy and paste transition getters could end up with broken state machine references
[Introduced(EngineVersion.VER_UE4_20)]
FixBrokenStateMachineReferencesInTransitionGetters,
/// Change to MeshDescription serialization
[Introduced(EngineVersion.VER_UE4_20)]
MeshDescriptionNewSerialization,
/// Change to not clamp RGB values > 1 on linear color curves
[Introduced(EngineVersion.VER_UE4_21)]
UnclampRGBColorCurves,
/// BugFix for FAnimObjectVersion::LinkTimeAnimBlueprintRootDiscovery.
[Introduced(EngineVersion.VER_UE4_21)]
LinkTimeAnimBlueprintRootDiscoveryBugFix,
/// Change trail anim node variable deprecation
[Introduced(EngineVersion.VER_UE4_21)]
TrailNodeBlendVariableNameChange,
/// Make sure the Blueprint Replicated Property Conditions are actually serialized properly.
[Introduced(EngineVersion.VER_UE4_23)]
PropertiesSerializeRepCondition,
/// DepthOfFieldFocalDistance at 0 now disables DOF instead of DepthOfFieldFstop at 0.
[Introduced(EngineVersion.VER_UE4_23)]
FocalDistanceDisablesDOF,
/// Removed versioning, but version entry must still exist to keep assets saved with this version loadable
[Introduced(EngineVersion.VER_UE4_23)]
Unused_SoundClass2DReverbSend,
/// Groom asset version
[Introduced(EngineVersion.VER_UE4_24)]
GroomAssetVersion1,
/// Groom asset version
[Introduced(EngineVersion.VER_UE4_24)]
GroomAssetVersion2,
/// Store applied version of Animation Modifier to use when reverting
[Introduced(EngineVersion.VER_UE4_24)]
SerializeAnimModifierState,
/// Groom asset version
[Introduced(EngineVersion.VER_UE4_24)]
GroomAssetVersion3,
/// Upgrade filmback
[Introduced(EngineVersion.VER_UE4_24)]
DeprecateFilmbackSettings,
/// custom collision type
[Introduced(EngineVersion.VER_UE4_25)]
CustomImplicitCollisionType,
/// FFieldPath will serialize the owner struct reference and only a short path to its property
[Introduced(EngineVersion.VER_UE4_25)]
FFieldPathOwnerSerialization,
/// Dummy version to allow us to Fix up the fact that ReleaseObjectVersion was changed elsewhere
[Introduced(EngineVersion.VER_UE4_26)]
ReleaseUE4VersionFixup,
/// Pin types include a flag that propagates the 'CPF_UObjectWrapper' flag to generated properties
[Introduced(EngineVersion.VER_UE4_26)]
PinTypeIncludesUObjectWrapperFlag,
/// Added Weight member to FMeshToMeshVertData
[Introduced(EngineVersion.VER_UE4_26)]
WeightFMeshToMeshVertData,
/// Animation graph node bindings displayed as pins
[Introduced(EngineVersion.VER_UE4_26)]
AnimationGraphNodeBindingsDisplayedAsPins,
/// Serialized rigvm offset segment paths
[Introduced(EngineVersion.VER_UE4_26)]
SerializeRigVMOffsetSegmentPaths,
/// Upgrade AbcGeomCacheImportSettings for velocities
[Introduced(EngineVersion.VER_UE4_26)]
AbcVelocitiesSupport,
/// Add margin support to Chaos Convex
[Introduced(EngineVersion.VER_UE4_26)]
MarginAddedToConvexAndBox,
/// Add structure data to Chaos Convex
[Introduced(EngineVersion.VER_UE4_26)]
StructureDataAddedToConvex,
/// Changed axis UI for LiveLink AxisSwitch Pre Processor
[Introduced(EngineVersion.VER_UE4_27)]
AddedFrontRightUpAxesToLiveLinkPreProcessor,
/// Some sequencer event sections that were copy-pasted left broken links to the director BP
[Introduced(EngineVersion.VER_UE4_27)]
FixupCopiedEventSections,
/// Serialize the number of bytes written when serializing function arguments
[Introduced(EngineVersion.VER_UE4_27)]
RemoteControlSerializeFunctionArgumentsSize,
/// Add loop counters to sequencer's compiled sub-sequence data
[Introduced(EngineVersion.VER_UE4_27)]
AddedSubSequenceEntryWarpCounter,
/// Remove default resolution limit of 512 pixels for cubemaps generated from long-lat sources
[Introduced(EngineVersion.VER_UE4_27)]
LonglatTextureCubeDefaultMaxResolution,
// bake center of mass into chaos cache
[Introduced(EngineVersion.VER_UE5_0)]
GeometryCollectionCacheRemovesMassToLocal,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION_PLUS_ONE)]
VersionPlusOne,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION)]
LatestVersion = VersionPlusOne - 1
}
///
/// Version used for serializing asset registry caches, both runtime and editor
///
public enum FAssetRegistryVersion
{
/// From before file versioning was implemented
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
PreVersioning = 0,
/// The first version of the runtime asset registry to include file versioning.
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
HardSoftDependencies,
/// Added FAssetRegistryState and support for piecemeal serialization
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
AddAssetRegistryState,
/// AssetData serialization format changed, versions before this are not readable
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
ChangedAssetData,
/// Removed MD5 hash from package data
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
RemovedMD5Hash,
/// Added hard/soft manage references
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
AddedHardManage,
/// Added MD5 hash of cooked package to package data
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
AddedCookedMD5Hash,
/// Added UE::AssetRegistry::EDependencyProperty to each dependency
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
AddedDependencyFlags,
/// Major tag format change that replaces USE_COMPACT_ASSET_REGISTRY:
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
FixedTags,
/// Added Version information to AssetPackageData
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
WorkspaceDomain,
/// Added ImportedClasses to AssetPackageData
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
PackageImportedClasses,
/// A new version number of UE5 was added to FPackageFileSummary
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
PackageFileSummaryVersionChange,
/// Change to linker export/import resource serializationn
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
ObjectResourceOptionalVersionChange,
/// Added FIoHash for each FIoChunkId in the package to the AssetPackageData.
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
AddedChunkHashes,
/// Classes are serialized as path names rather than short object names, e.g. /Script/Engine.StaticMesh
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
ClassPaths,
/// Asset bundles are serialized as FTopLevelAssetPath instead of FSoftObjectPath, deprecated FAssetData::ObjectPath
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
RemoveAssetPathFNames,
/// Added header with bFilterEditorOnlyData flag
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
AddedHeader,
/// Added Extension to AssetPackageData.
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
AssetPackageDataHasExtension,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION_PLUS_ONE)]
VersionPlusOne,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION)]
LatestVersion = VersionPlusOne - 1
}
public enum FSequencerObjectVersion
{
/// Before any version changes were made
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
BeforeCustomVersionWasAdded = 0,
/// Per-platform overrides player overrides for media sources changed name and type.
[Introduced(EngineVersion.VER_UE4_14)]
RenameMediaSourcePlatformPlayers,
/// Enable root motion isn't the right flag to use, but force root lock
[Introduced(EngineVersion.VER_UE4_15)]
ConvertEnableRootMotionToForceRootLock,
/// Convert multiple rows to tracks
[Introduced(EngineVersion.VER_UE4_15)]
ConvertMultipleRowsToTracks,
/// When finished now defaults to restore state
[Introduced(EngineVersion.VER_UE4_16)]
WhenFinishedDefaultsToRestoreState,
/// EvaluationTree added
[Introduced(EngineVersion.VER_UE4_19)]
EvaluationTree,
/// When finished now defaults to project default
[Introduced(EngineVersion.VER_UE4_19)]
WhenFinishedDefaultsToProjectDefault,
/// Use int range rather than float range in FMovieSceneSegment
[Introduced(EngineVersion.VER_UE4_20)]
FloatToIntConversion,
/// Purged old spawnable blueprint classes from level sequence assets
[Introduced(EngineVersion.VER_UE4_20)]
PurgeSpawnableBlueprints,
/// Finish UMG evaluation on end
[Introduced(EngineVersion.VER_UE4_20)]
FinishUMGEvaluation,
/// Manual serialization of float channel
[Introduced(EngineVersion.VER_UE4_22)]
SerializeFloatChannel,
/// Change the linear keys so they act the old way and interpolate always.
[Introduced(EngineVersion.VER_UE4_22)]
ModifyLinearKeysForOldInterp,
/// Full Manual serialization of float channel
[Introduced(EngineVersion.VER_UE4_25)]
SerializeFloatChannelCompletely,
/// Set ContinuouslyRespawn to false by default, added FMovieSceneSpawnable::bNetAddressableName
[Introduced(EngineVersion.VER_UE4_27)]
SpawnableImprovements,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION_PLUS_ONE)]
VersionPlusOne,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION)]
LatestVersion = VersionPlusOne - 1
}
public enum FFortniteReleaseBranchCustomObjectVersion
{
/// Before any version changes were made
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
BeforeCustomVersionWasAdded = 0,
/// Custom 14.10 File Object Version
[Introduced(EngineVersion.VER_UE4_26)]
DisableLevelset_v14_10,
/// Add the long range attachment tethers to the cloth asset to avoid a large hitch during the cloth's initialization.
[Introduced(EngineVersion.VER_UE5_0)]
ChaosClothAddTethersToCachedData,
/// Chaos::TKinematicTarget no longer stores a full transform, only position/rotation.
[Introduced(EngineVersion.VER_UE5_0)]
ChaosKinematicTargetRemoveScale,
/// Move UCSModifiedProperties out of ActorComponent and in to sparse storage
[Introduced(EngineVersion.VER_UE5_1)]
ActorComponentUCSModifiedPropertiesSparseStorage,
/// Fixup Nanite meshes which were using the wrong material and didn't have proper UVs :
[Introduced(EngineVersion.VER_UE5_2)]
FixupNaniteLandscapeMeshes,
/// Remove any cooked collision data from nanite landscape / editor spline meshes since collisions are not needed there :
[Introduced(EngineVersion.VER_UE5_2)]
RemoveUselessLandscapeMeshesCookedCollisionData,
/// Serialize out UAnimCurveCompressionCodec::InstanceGUID to maintain deterministic DDC key generation in cooked-editor
[Introduced(EngineVersion.VER_UE5_3)]
SerializeAnimCurveCompressionCodecGuidOnCook,
/// Fix the Nanite landscape mesh being reused because of a bad name
[Introduced(EngineVersion.VER_UE5_3)]
FixNaniteLandscapeMeshNames,
/// Fixup and synchronize shared properties modified before the synchronicity enforcement
[Introduced(EngineVersion.VER_UE5_3)]
LandscapeSharedPropertiesEnforcement,
/// Include the cell size when computing the cell guid
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionRuntimeCellGuidWithCellSize,
/// Enable SkipOnlyEditorOnly style cooking of NaniteOverrideMaterial
[Introduced(EngineVersion.VER_UE5_3)]
NaniteMaterialOverrideUsesEditorOnly,
/// Store game thread particles data in single precision
[Introduced(EngineVersion.VER_UE5_4)]
SinglePrecisonParticleData,
/// UPCGPoint custom serialization
[Introduced(EngineVersion.VER_UE5_4)]
PCGPointStructuredSerializer,
/// Deprecation of Nav Movement Properties and moving them to a new struct
[Introduced(EngineVersion.VER_UE5_4)]
NavMovementComponentMovingPropertiesToStruct,
/// Add bone serialization for dynamic mesh attributes
[Introduced(EngineVersion.VER_UE5_4)]
DynamicMeshAttributesSerializeBones,
/// -----new versions can be added above this line-------------------------------------------------
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION_PLUS_ONE)]
VersionPlusOne,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION)]
LatestVersion = VersionPlusOne - 1
}
public enum FUE5ReleaseStreamObjectVersion
{
/// Before any version changes were made
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
BeforeCustomVersionWasAdded = 0,
/// Added Lumen reflections to new reflection enum, changed defaults
[Introduced(EngineVersion.VER_UE5_0EA)]
ReflectionMethodEnum,
/// Serialize HLOD info in WorldPartitionActorDesc
[Introduced(EngineVersion.VER_UE5_0EA)]
WorldPartitionActorDescSerializeHLODInfo,
/// Removing Tessellation from materials and meshes.
[Introduced(EngineVersion.VER_UE5_0EA)]
RemovingTessellation,
/// LevelInstance serialize runtime behavior
[Introduced(EngineVersion.VER_UE5_0EA)]
LevelInstanceSerializeRuntimeBehavior,
/// Refactoring Pose Asset runtime data structures
[Introduced(EngineVersion.VER_UE5_0EA)]
PoseAssetRuntimeRefactor,
/// Serialize the folder path of actor descs
[Introduced(EngineVersion.VER_UE5_0EA)]
WorldPartitionActorDescSerializeActorFolderPath,
/// Change hair strands vertex format
[Introduced(EngineVersion.VER_UE5_0EA)]
HairStrandsVertexFormatChange,
/// Added max linear and angular speed to Chaos bodies
[Introduced(EngineVersion.VER_UE5_0EA)]
AddChaosMaxLinearAngularSpeed,
/// PackedLevelInstance version
[Introduced(EngineVersion.VER_UE5_0EA)]
PackedLevelInstanceVersion,
/// PackedLevelInstance bounds fix
[Introduced(EngineVersion.VER_UE5_0EA)]
PackedLevelInstanceBoundsFix,
/// Custom property anim graph nodes (linked anim graphs, control rig etc.) now use optional pin manager
[Introduced(EngineVersion.VER_UE5_0)]
CustomPropertyAnimGraphNodesUseOptionalPinManager,
/// Add native double and int64 support to FFormatArgumentData
[Introduced(EngineVersion.VER_UE5_0)]
TextFormatArgumentData64bitSupport,
/// Material layer stacks are no longer considered 'static parameters'
[Introduced(EngineVersion.VER_UE5_0)]
MaterialLayerStacksAreNotParameters,
/// CachedExpressionData is moved from UMaterial to UMaterialInterface
[Introduced(EngineVersion.VER_UE5_0)]
MaterialInterfaceSavedCachedData,
/// Add support for multiple cloth deformer LODs to be able to raytrace cloth with a different LOD than the one it is rendered with
[Introduced(EngineVersion.VER_UE5_0)]
AddClothMappingLODBias,
/// Add support for different external actor packaging schemes
[Introduced(EngineVersion.VER_UE5_0)]
AddLevelActorPackagingScheme,
/// Add support for linking to the attached parent actor in WorldPartitionActorDesc
[Introduced(EngineVersion.VER_UE5_0)]
WorldPartitionActorDescSerializeAttachParent,
/// Converted AActor GridPlacement to bIsSpatiallyLoaded flag
[Introduced(EngineVersion.VER_UE5_0)]
ConvertedActorGridPlacementToSpatiallyLoadedFlag,
/// Fixup for bad default value for GridPlacement_DEPRECATED
[Introduced(EngineVersion.VER_UE5_0)]
ActorGridPlacementDeprecateDefaultValueFixup,
/// PackedLevelActor started using FWorldPartitionActorDesc (not currently checked against but added as a security)
[Introduced(EngineVersion.VER_UE5_0)]
PackedLevelActorUseWorldPartitionActorDesc,
/// Add support for actor folder objects
[Introduced(EngineVersion.VER_UE5_0)]
AddLevelActorFolders,
/// Remove FSkeletalMeshLODModel bulk datas
[Introduced(EngineVersion.VER_UE5_0)]
RemoveSkeletalMeshLODModelBulkDatas,
/// Exclude brightness from the EncodedHDRCubemap,
[Introduced(EngineVersion.VER_UE5_0)]
ExcludeBrightnessFromEncodedHDRCubemap,
/// Unified volumetric cloud component quality sample count slider between main and reflection views for consistency
[Introduced(EngineVersion.VER_UE5_0)]
VolumetricCloudSampleCountUnification,
/// Pose asset GUID generated from source AnimationSequence
[Introduced(EngineVersion.VER_UE5_0)]
PoseAssetRawDataGUID,
/// Convolution bloom now take into account FPostProcessSettings::BloomIntensity for scatter dispersion.
[Introduced(EngineVersion.VER_UE5_0)]
ConvolutionBloomIntensity,
/// Serialize FHLODSubActors instead of FGuids in WorldPartition HLODActorDesc
[Introduced(EngineVersion.VER_UE5_0)]
WorldPartitionHLODActorDescSerializeHLODSubActors,
/// Large Worlds - serialize double types as doubles
[Introduced(EngineVersion.VER_UE5_0)]
LargeWorldCoordinates,
/// Deserialize old BP float and double types as real numbers for pins
[Introduced(EngineVersion.VER_UE5_0)]
BlueprintPinsUseRealNumbers,
/// Changed shadow defaults for directional light components, version needed to not affect old things
[Introduced(EngineVersion.VER_UE5_0)]
UpdatedDirectionalLightShadowDefaults,
/// Refresh geometry collections that had not already generated convex bodies.
[Introduced(EngineVersion.VER_UE5_0)]
GeometryCollectionConvexDefaults,
/// Add faster damping calculations to the cloth simulation and rename previous Damping parameter to LocalDamping.
[Introduced(EngineVersion.VER_UE5_0)]
ChaosClothFasterDamping,
/// Serialize LandscapeActorGuid in FLandscapeActorDesc sub class.
[Introduced(EngineVersion.VER_UE5_0)]
WorldPartitionLandscapeActorDescSerializeLandscapeActorGuid,
/// add inertia tensor and rotation of mass to convex
[Introduced(EngineVersion.VER_UE5_0)]
AddedInertiaTensorAndRotationOfMassAddedToConvex,
/// Storing inertia tensor as vec3 instead of matrix.
[Introduced(EngineVersion.VER_UE5_0)]
ChaosInertiaConvertedToVec3,
/// For Blueprint real numbers, ensure that legacy float data is serialized as single-precision
[Introduced(EngineVersion.VER_UE5_0)]
SerializeFloatPinDefaultValuesAsSinglePrecision,
/// Upgrade the BlendMasks array in existing LayeredBoneBlend nodes
[Introduced(EngineVersion.VER_UE5_1)]
AnimLayeredBoneBlendMasks,
/// Uses RG11B10 format to store the encoded reflection capture data on mobile
[Introduced(EngineVersion.VER_UE5_1)]
StoreReflectionCaptureEncodedHDRDataInRG11B10Format,
/// Add WithSerializer type trait and implementation for FRawAnimSequenceTrack
[Introduced(EngineVersion.VER_UE5_1)]
RawAnimSequenceTrackSerializer,
/// Removed font from FEditableTextBoxStyle, and added FTextBlockStyle instead.
[Introduced(EngineVersion.VER_UE5_1)]
RemoveDuplicatedStyleInfo,
/// Added member reference to linked anim graphs
[Introduced(EngineVersion.VER_UE5_1)]
LinkedAnimGraphMemberReference,
/// Changed default tangent behavior for new dynamic mesh components
[Introduced(EngineVersion.VER_UE5_3)]
DynamicMeshComponentsDefaultUseExternalTangents,
/// Added resize methods to media capture
[Introduced(EngineVersion.VER_UE5_3)]
MediaCaptureNewResizeMethods,
/// Function data stores a map from work to debug operands
[Introduced(EngineVersion.VER_UE5_3)]
RigVMSaveDebugMapInGraphFunctionData,
/// Changed default Local Exposure Contrast Scale from 1.0 to 0.8
[Introduced(EngineVersion.VER_UE5_3)]
LocalExposureDefaultChangeFrom1,
/// Serialize bActorIsListedInSceneOutliner in WorldPartitionActorDesc
[Introduced(EngineVersion.VER_UE5_3)]
WorldPartitionActorDescSerializeActorIsListedInSceneOutliner,
/// Disabled opencolorio display configuration by default
[Introduced(EngineVersion.VER_UE5_3)]
OpenColorIODisabledDisplayConfigurationDefault,
/// Serialize ExternalDataLayerAsset in WorldPartitionActorDesc
[Introduced(EngineVersion.VER_UE5_4)]
WorldPartitionExternalDataLayers,
/// Fix Chaos Cloth fictitious angular scale bug that requires existing parameter rescaling.
[Introduced(EngineVersion.VER_UE5_4)]
ChaosClothFictitiousAngularVelocitySubframeFix,
/// Store physics thread particles data in single precision
[Introduced(EngineVersion.VER_UE5_4)]
SinglePrecisonParticleDataPT,
/// Orthographic Near and Far Plane Auto-resolve enabled by default
[Introduced(EngineVersion.VER_UE5_4)]
OrthographicAutoNearFarPlane,
/// -----new versions can be added above this line-------------------------------------------------
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION_PLUS_ONE)]
VersionPlusOne,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION)]
LatestVersion = VersionPlusOne - 1
}
public enum FNiagaraObjectVersion
{
/// Before any version changes were made
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
BeforeCustomVersionWasAdded = 0,
[Introduced(EngineVersion.VER_UE4_21)]
SkeletalMeshVertexSampling = 1,
/// -----new versions can be added above this line-------------------------------------------------
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION_PLUS_ONE)]
VersionPlusOne,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION)]
LatestVersion = VersionPlusOne - 1
}
public enum FNiagaraCustomVersion
{
/// Before any version changes were made in niagara
[Introduced(EngineVersion.VER_UE4_OLDEST_LOADABLE_PACKAGE)]
BeforeCustomVersionWasAdded = 0,
/// Reworked vm external function binding to be more robust.
[Introduced(EngineVersion.VER_UE4_16)]
VMExternalFunctionBindingRework,
/// Making all Niagara files reference the version number, allowing post loading recompilation if necessary.
[Introduced(EngineVersion.VER_UE4_16)]
PostLoadCompilationEnabled,
/// Moved some runtime cost from external functions into the binding step and used variadic templates to neaten that code greatly.
[Introduced(EngineVersion.VER_UE4_16)]
VMExternalFunctionBindingReworkPartDeux,
/// Moved per instance data needed for certain data interfaces out to it's own struct.
[Introduced(EngineVersion.VER_UE4_18)]
DataInterfacePerInstanceRework,
/// Added shader maps and corresponding infrastructure
[Introduced(EngineVersion.VER_UE4_18)]
NiagaraShaderMaps,
/// Combined Spawn, Update, and Event scripts into one graph.
[Introduced(EngineVersion.VER_UE4_18)]
UpdateSpawnEventGraphCombination,
/// Reworked data layout to store float and int data separately.
[Introduced(EngineVersion.VER_UE4_18)]
DataSetLayoutRework,
/// Reworked scripts to support emitter and system scripts
[Introduced(EngineVersion.VER_UE4_18)]
AddedEmitterAndSystemScripts,
/// Rework of script execution contexts to allow better reuse and reduce overhead of parameter handling.
[Introduced(EngineVersion.VER_UE4_18)]
ScriptExecutionContextRework,
/// Removed the Niagara variable ID's making hookup impossible until next compile
[Introduced(EngineVersion.VER_UE4_18)]
RemovalOfNiagaraVariableIDs,
/// System and emitter script simulations.
[Introduced(EngineVersion.VER_UE4_18)]
SystemEmitterScriptSimulations,
/// Adding integer random to VM. TODO: The vm really needs its own versioning system that will force a recompile when changes.
[Introduced(EngineVersion.VER_UE4_18)]
IntegerRandom,
/// Added emitter spawn attributes
[Introduced(EngineVersion.VER_UE4_18)]
AddedEmitterSpawnAttributes,
/// cooking of shader maps and corresponding infrastructure
[Introduced(EngineVersion.VER_UE4_18)]
NiagaraShaderMapCooking,
/// don't serialize shader maps for system scripts
[Introduced(EngineVersion.VER_UE4_18)]
NiagaraShaderMapCooking2,
/// Added script rapid iteration variables, usually top-level module parameters...
[Introduced(EngineVersion.VER_UE4_19)]
AddedScriptRapidIterationVariables,
/// Added type to data interface infos
[Introduced(EngineVersion.VER_UE4_19)]
AddedTypeToDataInterfaceInfos,
/// Hooked up autogenerated default values for function call nodes.
[Introduced(EngineVersion.VER_UE4_19)]
EnabledAutogeneratedDefaultValuesForFunctionCallNodes,
/// Now curve data interfaces have look-up tables on by default.
[Introduced(EngineVersion.VER_UE4_19)]
CurveLUTNowOnByDefault,
/// Scripts now use a guid for identification instead of an index when there are more than one with the same usage.
[Introduced(EngineVersion.VER_UE4_19)]
ScriptsNowUseAGuidForIdentificationInsteadOfAnIndex,
/// don't serialize shader maps for update scripts
[Introduced(EngineVersion.VER_UE4_19)]
NiagaraCombinedGPUSpawnUpdate,
/// don't serialize shader maps for emitters that don't run on gpu.
[Introduced(EngineVersion.VER_UE4_19)]
DontCompileGPUWhenNotNeeded,
[Introduced(EngineVersion.VER_UE4_19)]
LifeCycleRework,
/// We weren't serializing event data sets previously.
[Introduced(EngineVersion.VER_UE4_19)]
NowSerializingReadWriteDataSets,
/// Forcing the internal parameter map vars to be reset between emitter calls.
[Introduced(EngineVersion.VER_UE4_19)]
TranslatorClearOutBetweenEmitters,
/// added sampler shader params based on DI buffer descriptors
[Introduced(EngineVersion.VER_UE4_20)]
AddSamplerDataInterfaceParams,
/// Need to force the GPU shaders to recompile
[Introduced(EngineVersion.VER_UE4_20)]
GPUShadersForceRecompileNeeded,
/// The playback range for the timeline is now stored in the system editor data.
[Introduced(EngineVersion.VER_UE4_20)]
PlaybackRangeStoredOnSystem,
/// All cached values will auto-recompile.
[Introduced(EngineVersion.VER_UE4_20)]
MovedToDerivedDataCache,
/// Data interfaces are preallocated
[Introduced(EngineVersion.VER_UE4_20)]
DataInterfacesNotAllocated,
/// emitter scripts are built using "Emitter." instead of the full name.
[Introduced(EngineVersion.VER_UE4_20)]
EmittersHaveGenericUniqueNames,
/// no longer have compiler version enum value in this list, instead moved to a guid, which works better for the DDC
[Introduced(EngineVersion.VER_UE4_20)]
MovingTranslatorVersionToGuid,
/// adding a parameter map in/out to the data set base node
[Introduced(EngineVersion.VER_UE4_20)]
AddingParamMapToDataSetBaseNode,
/// refactor of CS parameters allowing regular params as well as buffers.
[Introduced(EngineVersion.VER_UE4_20)]
DataInterfaceComputeShaderParamRefactor,
/// bumping version and forcing curves to regen their LUT on version change.
[Introduced(EngineVersion.VER_UE4_20)]
CurveLUTRegen,
/// Changing the graph generation for assignment nodes so that it uses a "Begin Defaults" node where appropriate.
[Introduced(EngineVersion.VER_UE4_20)]
AssignmentNodeUsesBeginDefaults,
/// Updating the usage flage bitmask for assignment nodes to match the part of the stack it's used in.
[Introduced(EngineVersion.VER_UE4_20)]
AssignmentNodeHasCorrectUsageBitmask,
/// Emitter local space is compiled into the hlsl as a literal constant to expose it to emitter scripts and allow for some better optimization of particle transforms.
[Introduced(EngineVersion.VER_UE4_20)]
EmitterLocalSpaceLiteralConstant,
/// The cpu cache of the texture is now directly serialized instead of using array property serialization.
[Introduced(EngineVersion.VER_UE4_21)]
TextureDataInterfaceUsesCustomSerialize,
/// The texture data interface now streams size info
[Introduced(EngineVersion.VER_UE4_21)]
TextureDataInterfaceSizeSerialize,
/// API to skeletal mesh interface was improved but requires a recompile and some graph fixup.
[Introduced(EngineVersion.VER_UE4_21)]
SkelMeshInterfaceAPIImprovements,
/// Only do op add pin fixup on existing nodes which are before this version
[Introduced(EngineVersion.VER_UE4_23)]
ImproveLoadTimeFixupOfOpAddPins,
/// Moved commonly used input metadata out of the strin/string property metadata map to actual properties on the metadata struct.
[Introduced(EngineVersion.VER_UE4_23)]
MoveCommonInputMetadataToProperties,
/// Move to using the traversed graph hash and the base script id for the FNiagaraVMExecutableDataId instead of the change id guid to prevent invalidating the DDC.
[Introduced(EngineVersion.VER_UE4_23)]
UseHashesToIdentifyCompileStateOfTopLevelScripts,
/// Reworked how the metadata is stored in NiagaraGraph from storing a Map of FNiagaraVariableMetaData to storing a map of UNiagaraScriptVariable* to be used with the Details panel.
[Introduced(EngineVersion.VER_UE4_23)]
MetaDataAndParametersUpdate,
/// Moved the emitter inheritance data from the emitter handle to the emitter to allow for chained emitter inheritance.
[Introduced(EngineVersion.VER_UE4_23)]
MoveInheritanceDataFromTheEmitterHandleToTheEmitter,
/// Add property to all Niagara scripts indicating whether or not they belong to the library
[Introduced(EngineVersion.VER_UE4_23)]
AddLibraryAssetProperty,
/// Addding additional defines to the GPU script
[Introduced(EngineVersion.VER_UE4_24)]
AddAdditionalDefinesProperty,
/// Remove the random compile id guids from the cached script usage and from the compile and script ids since the hashes serve the same purpose and are deterministic.
[Introduced(EngineVersion.VER_UE4_24)]
RemoveGraphUsageCompileIds,
/// Adding UseRapidIterationParams and DetailLevelMask to the GPU script
[Introduced(EngineVersion.VER_UE4_24)]
AddRIAndDetailLevel,
/// Changing the system and emitter compiled data to shared pointers to deal with lifetime issues in the editor. They now are handled directly in system serialize.
[Introduced(EngineVersion.VER_UE4_24)]
ChangeEmitterCompiledDataToSharedRefs,
/// Sorting on Renderers is disabled by default, we add a version to maintain existing systems that expected sorting to be enabled
[Introduced(EngineVersion.VER_UE4_24)]
DisableSortingByDefault,
/// Convert TMap into TArray to save memory, TMap contains an inline allocator which pushes the size to 80 bytes
[Introduced(EngineVersion.VER_UE4_25)]
MemorySaving,
/// Added a new value to the script usage enum, and we need a custom version to fix the existing bitfields.
[Introduced(EngineVersion.VER_UE4_25)]
AddSimulationStageUsageEnum,
/// Save the functions generated by a GPU data interface inside FNiagaraDataInterfaceGPUParamInfo
[Introduced(EngineVersion.VER_UE4_25)]
AddGeneratedFunctionsToGPUParamInfo,
/// Removed DetailLevel in favor of FNiagaraPlatfomSet based selection of per platform settings.
[Introduced(EngineVersion.VER_UE4_25)]
PlatformScalingRefactor,
/// Promote parameters used across script executions to the Dataset, and Demote unused parameters.
[Introduced(EngineVersion.VER_UE4_25)]
PrecompileNamespaceFixup,
/// Postload fixup in UNiagaraGraph to fixup VariableToScriptVariable map entries being null.
[Introduced(EngineVersion.VER_UE4_25)]
FixNullScriptVariables,
/// Move FNiagaraVariableMetaData from storing scope enum to storing registered scope name.
[Introduced(EngineVersion.VER_UE4_25)]
PrecompileNamespaceFixup2,
/// Enable the simulation stage flag by default in the usage bitmask of modules and functions
[Introduced(EngineVersion.VER_UE4_25)]
SimulationStageInUsageBitmask,
/// Fix graph parameter map parameters on post load so that they all have a consisten parsable format and update the UI to show and filter based on these formats.
[Introduced(EngineVersion.VER_UE4_25)]
StandardizeParameterNames,
/// Make sure that UNiagaraComponents only have override maps for User variables.
[Introduced(EngineVersion.VER_UE4_26)]
ComponentsOnlyHaveUserVariables,
/// Refactor the options for UV settings on the ribbon renderer.
[Introduced(EngineVersion.VER_UE4_26)]
RibbonRendererUVRefactor,
/// Replace the TypeDefinition in VariableBase with an index into the type registry
[Introduced(EngineVersion.VER_UE4_26)]
VariablesUseTypeDefRegistry,
/// Expand the visibility options of the scripts to be able to hide a script completely from the user
[Introduced(EngineVersion.VER_UE4_26)]
AddLibraryVisibilityProperty,
[Introduced(EngineVersion.VER_UE4_26)]
SignificanceHandlers,
/// Added support for multiple versions of script data
[Introduced(EngineVersion.VER_UE4_27)]
ModuleVersioning,
[Introduced(EngineVersion.VER_UE4_27)]
MoveDefaultValueFromFNiagaraVariableMetaDataToUNiagaraScriptVariable,
/// Changed the default mode from deterministic to non-deterministic which matches emitters
[Introduced(EngineVersion.VER_UE5_0)]
ChangeSystemDeterministicDefault,
/// Update static switch pins to use the PersistentId from their script variable so that when they're renamed their values aren't lost when reallocating pins.
[Introduced(EngineVersion.VER_UE5_0)]
StaticSwitchFunctionPinsUsePersistentGuids,
/// Extended visibility culling options and moved properties into their own struct.
[Introduced(EngineVersion.VER_UE5_1)]
VisibilityCullingImprovements,
[Introduced(EngineVersion.VER_UE5_1)]
AddBakerCameraBookmarks,
/// Function call node refresh from external changes has been refactored so that they don't need to populate their name bindings every load.
[Introduced(EngineVersion.VER_UE5_1)]
PopulateFunctionCallNodePinNameBindings,
/// Changed the default value for the component renderer's OnlyCreateComponentsOnParticleSpawn property
[Introduced(EngineVersion.VER_UE5_1)]
ComponentRendererSpawnProperty,
/// Previous repopulate didn't handle module attributes like Particles.Module.Name so they need to be repopulated for renaming to work correctly.
[Introduced(EngineVersion.VER_UE5_1)]
RepopulateFunctionCallNodePinNameBindings,
/// Event spawns now optionally update Initial. attribute values. New default is true but old data is kept false to maintain existing behavior.
[Introduced(EngineVersion.VER_UE5_1)]
EventSpawnsUpdateInitialAttributeValues,
/// Adds list of variadic parameters to the information about GPU functions.
[Introduced(EngineVersion.VER_UE5_2)]
AddVariadicParametersToGPUFunctionInfo,
/// Some data fixup for NiagaraNodeWithDynamicPins.
[Introduced(EngineVersion.VER_UE5_2)]
DynamicPinNodeFixup,
/// Ribbon renderer will default to unique ID rather than normalized age to make more things 'just work'
[Introduced(EngineVersion.VER_UE5_3)]
RibbonRendererLinkOrderDefaultIsUniqueID,
/// Renderer SubImage Blends are enabled by default
[Introduced(EngineVersion.VER_UE5_4)]
SubImageBlendEnabledByDefault,
/// Ribbon renderer will use geometry normals by default rather than screen / facing aligned normals
[Introduced(EngineVersion.VER_UE5_4)]
RibbonPlaneUseGeometryNormals,
/// Actors velocity is used for the initial velocity before the component has any tracking, old assets use the old zero velocity
[Introduced(EngineVersion.VER_UE5_4)]
InitialOwnerVelocityFromActor,
/// FNiagaraParameterBindingWithValue wouldn't necessarily have the appropriate ResolvedParameter namespace when it comes to emitter merging
[Introduced(EngineVersion.VER_UE5_4)]
ParameterBindingWithValueRenameFixup,
/// Sim Cache moved to bulk data by default
[Introduced(EngineVersion.VER_UE5_4)]
SimCache_BulkDataVersion1,
/// Decoupling of 'Template' and 'Inheritance'
[Introduced(EngineVersion.VER_UE5_4)]
InheritanceUxRefactor,
/// NDC Read DIs will not override spawn group by default when spawning particles. Old content will remain unchanged.
[Introduced(EngineVersion.VER_UE5_4)]
NDCSpawnGroupOverrideDisabledByDefault,
/// Before it was normalized age which can introduce flickering with sorting and random lifetimes
[Introduced(EngineVersion.VER_UE5_5)]
CustomSortingBindingToAge,
/// Update Initial Mesh Orientation Module
[Introduced(EngineVersion.VER_UE5_5)]
StatelessInitialMeshOrientationV1,
/// Hierarchy Editor was implemented
[Introduced(EngineVersion.VER_UE5_5)]
HierarchyEditorScriptSupport,
/// Added loop delay enabled to emitter state
[Introduced(EngineVersion.VER_UE5_5)]
EmitterStateAddLoopDelayEnabled,
/// Make sure that we serialize the UsageBitMask with the GPUFunctionInfo
[Introduced(EngineVersion.VER_UE5_6)]
SerializeUsageBitMaskToGPUFunctionInfo,
/// Changed the interpolated spawn property into an enum
[Introduced(EngineVersion.VER_UE5_6)]
AddedNewInterpolatedSpawnMode,
/// Adding user asset tag storage in UMetaData for all UPackages
[Introduced(EngineVersion.VER_UE5_7)]
UserAssetTagStorageInMetaData,
///
/// DO NOT ADD A NEW VERSION UNLESS YOU HAVE TALKED TO THE NIAGARA LEAD. Mismanagement of these versions can lead to data loss if it is adjusted in multiple streams simultaneously.
/// -----new versions can be added above this line-------------------------------------------------
///
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION_PLUS_ONE)]
VersionPlusOne,
[Introduced(EngineVersion.VER_UE4_AUTOMATIC_VERSION)]
LatestVersion = VersionPlusOne - 1
}
}
================================================
FILE: UAssetAPI/ExportTypes/AssetImportDataExport.cs
================================================
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.ExportTypes
{
public class AssetImportDataExport : NormalExport
{
public FString Json;
public AssetImportDataExport(Export super) : base(super)
{
}
public AssetImportDataExport(UAsset asset, byte[] extras) : base(asset, extras)
{
}
public AssetImportDataExport()
{
}
public override void Read(AssetBinaryReader reader, int nextStarting)
{
Json = reader.ReadFString();
base.Read(reader, nextStarting);
}
public override void Write(AssetBinaryWriter writer)
{
writer.Write(Json);
base.Write(writer);
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/ClassExport.cs
================================================
using Newtonsoft.Json;
using System.IO;
using System.Linq;
using UAssetAPI.JSON;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.ExportTypes
{
///
/// Represents an interface that a UClass () implements.
///
public struct SerializedInterfaceReference
{
public int Class;
public int PointerOffset;
public bool bImplementedByK2;
public SerializedInterfaceReference(int @class, int pointerOffset, bool bImplementedByK2)
{
Class = @class;
PointerOffset = pointerOffset;
this.bImplementedByK2 = bImplementedByK2;
}
}
///
/// Represents an object class.
///
public class ClassExport : StructExport
{
///
/// Map of all functions by name contained in this class
///
[JsonConverter(typeof(TMapJsonConverter))]
public TMap FuncMap;
///
/// Class flags; See for more information
///
public EClassFlags ClassFlags;
///
/// The required type for the outer of instances of this class
///
public FPackageIndex ClassWithin;
///
/// Which Name.ini file to load Config variables out of
///
public FName ClassConfigName;
///
/// The list of interfaces which this class implements, along with the pointer property that is located at the offset of the interface's vtable.
/// If the interface class isn't native, the property will be empty.
///
public SerializedInterfaceReference[] Interfaces;
///
/// This is the blueprint that caused the generation of this class, or null if it is a native compiled-in class
///
public FPackageIndex ClassGeneratedBy;
///
/// Does this class use deprecated script order?
///
public bool bDeprecatedForceScriptOrder;
///
/// Used to check if the class was cooked or not
///
public bool bCooked;
///
/// The class default object; used for delta serialization and object initialization
///
public FPackageIndex ClassDefaultObject;
public ClassExport(Export super) : base(super)
{
}
public ClassExport(UAsset asset, byte[] extras) : base(asset, extras)
{
}
public ClassExport()
{
}
public override void Read(AssetBinaryReader reader, int nextStarting)
{
base.Read(reader, nextStarting);
int numFuncIndexEntries = reader.ReadInt32();
FuncMap = new TMap();
for (int i = 0; i < numFuncIndexEntries; i++)
{
FName functionName = reader.ReadFName();
FPackageIndex functionExport = FPackageIndex.FromRawIndex(reader.ReadInt32());
FuncMap.Add(functionName, functionExport);
}
ClassFlags = (EClassFlags)reader.ReadUInt32();
if (Asset.ObjectVersion < ObjectVersion.VER_UE4_CLASS_NOTPLACEABLE_ADDED)
{
ClassFlags ^= EClassFlags.CLASS_NotPlaceable;
}
ClassWithin = new FPackageIndex(reader.ReadInt32());
ClassConfigName = reader.ReadFName();
Asset.AddNameReference(ClassConfigName.Value);
int numInterfaces = 0;
long interfacesStart = 0;
if (Asset.ObjectVersion < ObjectVersion.VER_UE4_UCLASS_SERIALIZE_INTERFACES_AFTER_LINKING)
{
interfacesStart = reader.BaseStream.Position;
numInterfaces = reader.ReadInt32();
reader.BaseStream.Seek(interfacesStart + sizeof(int) + numInterfaces * (sizeof(int) * 3), SeekOrigin.Begin);
}
// Linking procedure here; I don't think anything is really serialized during this
ClassGeneratedBy = new FPackageIndex(reader.ReadInt32());
long currentOffset = reader.BaseStream.Position;
if (Asset.ObjectVersion < ObjectVersion.VER_UE4_UCLASS_SERIALIZE_INTERFACES_AFTER_LINKING)
{
reader.BaseStream.Seek(interfacesStart, SeekOrigin.Begin);
}
numInterfaces = reader.ReadInt32();
Interfaces = new SerializedInterfaceReference[numInterfaces];
for (int i = 0; i < numInterfaces; i++)
{
Interfaces[i] = new SerializedInterfaceReference(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32() == 1);
}
if (Asset.ObjectVersion < ObjectVersion.VER_UE4_UCLASS_SERIALIZE_INTERFACES_AFTER_LINKING)
{
reader.BaseStream.Seek(currentOffset, SeekOrigin.Begin);
}
bDeprecatedForceScriptOrder = reader.ReadInt32() == 1;
reader.ReadInt64(); // None
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_ADD_COOKED_TO_UCLASS)
{
bCooked = reader.ReadInt32() == 1;
}
ClassDefaultObject = new FPackageIndex(reader.ReadInt32());
// CDO serialization usually comes after this export has finished serializing
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(FuncMap.Count);
for (int i = 0; i < FuncMap.Count; i++)
{
writer.Write(FuncMap.Keys.ElementAt(i));
writer.Write(FuncMap[i].Index);
}
EClassFlags serializingClassFlags = ClassFlags;
if (Asset.ObjectVersion < ObjectVersion.VER_UE4_CLASS_NOTPLACEABLE_ADDED)
{
serializingClassFlags ^= EClassFlags.CLASS_NotPlaceable;
}
writer.Write((uint)serializingClassFlags);
writer.Write(ClassWithin.Index);
writer.Write(ClassConfigName);
if (Asset.ObjectVersion < ObjectVersion.VER_UE4_UCLASS_SERIALIZE_INTERFACES_AFTER_LINKING)
{
SerializeInterfaces(writer);
}
// Linking procedure here; I don't think anything is really serialized during this
writer.Write(ClassGeneratedBy.Index);
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_UCLASS_SERIALIZE_INTERFACES_AFTER_LINKING)
{
SerializeInterfaces(writer);
}
writer.Write(bDeprecatedForceScriptOrder ? 1 : 0);
writer.Write(new FName(writer.Asset, "None"));
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_ADD_COOKED_TO_UCLASS)
{
writer.Write(bCooked ? 1 : 0);
}
writer.Write(ClassDefaultObject.Index);
}
private void SerializeInterfaces(BinaryWriter writer)
{
writer.Write(Interfaces.Length);
for (int i = 0; i < Interfaces.Length; i++)
{
writer.Write(Interfaces[i].Class);
writer.Write(Interfaces[i].PointerOffset);
writer.Write(Interfaces[i].bImplementedByK2 ? 1 : 0);
}
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/DataTableExport.cs
================================================
using System.Collections.Generic;
using UAssetAPI.PropertyTypes.Objects;
using UAssetAPI.PropertyTypes.Structs;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
using System.Reflection.PortableExecutable;
namespace UAssetAPI.ExportTypes
{
///
/// Imported spreadsheet table.
///
public class UDataTable
{
public List Data;
public UDataTable()
{
Data = new List();
}
public UDataTable(List data)
{
Data = data;
}
}
///
/// Export for an imported spreadsheet table. See .
///
public class DataTableExport : NormalExport
{
///
/// Gets or sets the value associated with the specified key. This operation loops linearly, so it may not be suitable for high-performance environments.
///
/// The key associated with the value to get or set.
public override PropertyData this[FName key]
{
get
{
for (int i = 0; i < Data.Count; i++)
{
if (Data[i].Name == key) return Data[i];
}
for (int i = 0; i < Table.Data.Count; i++)
{
if (Table.Data[i].Name == key) return Table.Data[i];
}
return null;
}
set
{
value.Name = key;
for (int i = 0; i < Data.Count; i++)
{
if (Data[i].Name == key)
{
Data[i] = value;
return;
}
}
if (value is StructPropertyData)
{
for (int i = 0; i < Table.Data.Count; i++)
{
if (Table.Data[i].Name == key)
{
Table.Data[i] = (StructPropertyData)value;
return;
}
}
Table.Data.Add((StructPropertyData)value);
}
else
{
Data.Add(value);
}
}
}
///
/// Gets or sets the value associated with the specified key. This operation loops linearly, so it may not be suitable for high-performance environments.
///
/// The key associated with the value to get or set.
public override PropertyData this[string key]
{
get
{
return this[FName.FromString(Asset, key)];
}
set
{
this[FName.FromString(Asset, key)] = value;
}
}
public UDataTable Table;
public DataTableExport(Export super) : base(super)
{
}
public DataTableExport(UDataTable data, UAsset asset, byte[] extras) : base(asset, extras)
{
Table = data;
}
public DataTableExport()
{
}
public override void Read(AssetBinaryReader reader, int nextStarting)
{
base.Read(reader, nextStarting);
// Find an ObjectProperty named RowStruct
FName decidedStructType = FName.DefineDummy(reader.Asset, "Generic");
foreach (PropertyData thisData in Data)
{
if (thisData.Name.Value.Value == "RowStruct" && thisData is ObjectPropertyData thisObjData && thisObjData.Value.IsImport())
{
decidedStructType = thisObjData.ToImport(reader.Asset).ObjectName;
break;
}
}
if (decidedStructType.ToString() == "Generic")
{
// overrides here...
FName exportClassTypeName = this.GetExportClassType();
string exportClassType = exportClassTypeName.Value.Value;
switch(exportClassType)
{
case "CommonGenericInputActionDataTable":
decidedStructType = FName.DefineDummy(reader.Asset, "CommonInputActionDataBase");
break;
}
}
Table = new UDataTable();
int numEntries = reader.ReadInt32();
FName pcen = reader.Asset.GetParentClassExportName(out FName pcen2);
for (int i = 0; i < numEntries; i++)
{
FName rowName = reader.ReadFName();
var nextStruct = new StructPropertyData(rowName)
{
StructType = decidedStructType
};
nextStruct.Ancestry.Initialize(null, pcen, pcen2);
nextStruct.Read(reader, false, 1);
Table.Data.Add(nextStruct);
}
}
public override void ResolveAncestries(UAsset asset, AncestryInfo ancestrySoFar)
{
var ancestryNew = (AncestryInfo)ancestrySoFar.Clone();
FName pcen = asset.GetParentClassExportName(out FName pcen2);
ancestryNew.SetAsParent(pcen, pcen2);
if (Data != null)
{
for (int i = 0; i < Data.Count; i++) Data[i]?.ResolveAncestries(asset, ancestryNew);
}
if (Table?.Data != null)
{
for (int i = 0; i < Table.Data.Count; i++) Table.Data[i]?.ResolveAncestries(asset, ancestryNew);
}
base.ResolveAncestries(asset, ancestrySoFar);
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
// Find an ObjectProperty named RowStruct
FName decidedStructType = FName.DefineDummy(writer.Asset, "Generic");
foreach (PropertyData thisData in Data)
{
if (thisData.Name.Value.Value == "RowStruct" && thisData is ObjectPropertyData thisObjData)
{
decidedStructType = thisObjData.ToImport(writer.Asset).ObjectName;
break;
}
}
if (decidedStructType.ToString() == "Generic")
{
// overrides here...
FName exportClassTypeName = this.GetExportClassType();
string exportClassType = exportClassTypeName.Value.Value;
switch (exportClassType)
{
case "CommonGenericInputActionDataTable":
decidedStructType = FName.DefineDummy(writer.Asset, "CommonInputActionDataBase");
break;
}
}
writer.Write(Table.Data.Count);
for (int i = 0; i < Table.Data.Count; i++)
{
var thisDataTableEntry = Table.Data[i];
thisDataTableEntry.StructType = decidedStructType;
writer.Write(thisDataTableEntry.Name);
thisDataTableEntry.Write(writer, false);
}
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/EnumExport.cs
================================================
using System;
using System.Collections.Generic;
using UAssetAPI.CustomVersions;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.ExportTypes
{
/// How this enum is declared in C++. Affects the internal naming of enum values.
public enum ECppForm
{
Regular,
Namespaced,
EnumClass
}
///
/// Reflection data for an enumeration.
///
public class UEnum
{
/// List of pairs of all enum names and values.
public List> Names;
/// How the enum was originally defined.
public ECppForm CppForm = ECppForm.Regular;
public void Read(AssetBinaryReader reader, UAsset asset)
{
if (asset.ObjectVersion < ObjectVersion.VER_UE4_TIGHTLY_PACKED_ENUMS)
{
int numEntries = reader.ReadInt32();
for (int i = 0; i < numEntries; i++)
{
FName tempName = reader.ReadFName();
Names.Add(new Tuple(tempName, i));
}
}
else if (asset.GetCustomVersion() < FCoreObjectVersion.EnumProperties)
{
int numEntries = reader.ReadInt32();
for (int i = 0; i < numEntries; i++)
{
FName tempName = reader.ReadFName();
byte tempVal = reader.ReadByte();
Names.Add(new Tuple(tempName, tempVal));
}
}
else
{
int numEntries = reader.ReadInt32();
for (int i = 0; i < numEntries; i++)
{
FName tempName = reader.ReadFName();
long tempVal = reader.ReadInt64();
Names.Add(new Tuple(tempName, tempVal));
}
}
if (asset.ObjectVersion < ObjectVersion.VER_UE4_ENUM_CLASS_SUPPORT)
{
bool bIsNamespace = reader.ReadInt32() == 1;
CppForm = bIsNamespace ? ECppForm.Namespaced : ECppForm.Regular;
}
else
{
CppForm = (ECppForm)reader.ReadByte();
}
}
public void Write(AssetBinaryWriter writer, UAsset asset)
{
writer.Write(Names.Count);
if (asset.ObjectVersion < ObjectVersion.VER_UE4_TIGHTLY_PACKED_ENUMS)
{
var namesForSerialization = new Dictionary();
for (int i = 0; i < Names.Count; i++) namesForSerialization.Add(Names[i].Item2, Names[i].Item1);
for (int i = 0; i < Names.Count; i++)
{
if (namesForSerialization.ContainsKey(i)) writer.Write(namesForSerialization[i]);
}
}
else if (asset.GetCustomVersion() < FCoreObjectVersion.EnumProperties)
{
for (int i = 0; i < Names.Count; i++)
{
writer.Write(Names[i].Item1);
writer.Write((byte)Names[i].Item2);
}
}
else
{
for (int i = 0; i < Names.Count; i++)
{
writer.Write(Names[i].Item1);
writer.Write(Names[i].Item2);
}
}
if (asset.ObjectVersion < ObjectVersion.VER_UE4_ENUM_CLASS_SUPPORT)
{
writer.Write(CppForm == ECppForm.Namespaced ? 1 : 0);
}
else
{
writer.Write((byte)CppForm);
}
}
public UEnum()
{
Names = new List>();
}
}
///
/// Export data for an enumeration. See .
///
public class EnumExport : NormalExport
{
/// The enum that is stored in this export.
public UEnum Enum;
public EnumExport(Export super) : base(super)
{
}
public EnumExport(UAsset asset, byte[] extras) : base(asset, extras)
{
}
public EnumExport()
{
}
public override void Read(AssetBinaryReader reader, int nextStarting)
{
base.Read(reader, nextStarting);
Enum = new UEnum();
Enum.Read(reader, Asset);
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
Enum.Write(writer, Asset);
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/Export.cs
================================================
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using UAssetAPI.PropertyTypes.Objects;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.ExportTypes
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
internal class DisplayIndexOrderAttribute : Attribute
{
internal int DisplayingIndex = 0;
internal bool IsIoStore = false;
internal bool IsTraditional = true;
internal DisplayIndexOrderAttribute(int displayingIndex, bool isIoStore = false, bool isTraditional = true)
{
DisplayingIndex = displayingIndex;
IsIoStore = isIoStore;
IsTraditional = isTraditional;
}
}
///
/// Enum used to determine whether an export should be loaded or not on the client/server. Not actually a bitflag.
///
public enum EExportFilterFlags : byte
{
None,
NotForClient,
NotForServer
}
///
/// UObject resource type for objects that are contained within this package and can be referenced by other packages.
///
[JsonObject(MemberSerialization.OptOut)]
public class Export : ICloneable
{
///The name of the UObject represented by this resource.
[DisplayIndexOrder(0, true)]
public FName ObjectName;
///Location of the resource for this resource's Outer (import/other export). 0 = this resource is a top-level UPackage
[DisplayIndexOrder(1)]
public FPackageIndex OuterIndex;
///Location of this export's class (import/other export). 0 = this export is a UClass
[DisplayIndexOrder(2)]
public FPackageIndex ClassIndex;
///Location of this export's parent class (import/other export). 0 = this export is not derived from UStruct
[DisplayIndexOrder(3)]
public FPackageIndex SuperIndex;
///Location of this export's template (import/other export). 0 = there is some problem
[DisplayIndexOrder(4)]
public FPackageIndex TemplateIndex;
///The object flags for the UObject represented by this resource. Only flags that match the RF_Load combination mask will be loaded from disk and applied to the UObject.
[DisplayIndexOrder(5, true)]
public EObjectFlags ObjectFlags;
///The number of bytes to serialize when saving/loading this export's UObject.
[DisplayIndexOrder(6, true)]
public long SerialSize;
///The location (into the FLinker's underlying file reader archive) of the beginning of the data for this export's UObject. Used for verification only.
[DisplayIndexOrder(7, true)]
public long SerialOffset;
///
/// The location (relative to SerialOffset) of the beginning of the portion of this export's data that is serialized using tagged property serialization.
/// Serialized into packages using tagged property serialization as of (5.4).
///
[DisplayIndexOrder(8)]
public long ScriptSerializationStartOffset;
///
/// The location (relative to SerialOffset) of the end of the portion of this export's data that is serialized using tagged property serialization.
/// Serialized into packages using tagged property serialization as of (5.4)
///
[DisplayIndexOrder(9)]
public long ScriptSerializationEndOffset;
///Was this export forced into the export table via OBJECTMARK_ForceTagExp?
[DisplayIndexOrder(10)]
public bool bForcedExport;
///Should this export not be loaded on clients?
[DisplayIndexOrder(11, true)]
public bool bNotForClient;
///Should this export not be loaded on servers?
[DisplayIndexOrder(12, true)]
public bool bNotForServer;
///If this object is a top level package (which must have been forced into the export table via OBJECTMARK_ForceTagExp), this is the GUID for the original package file. Deprecated
[DisplayIndexOrder(13)]
public Guid PackageGuid;
///
[DisplayIndexOrder(14)]
public bool IsInheritedInstance;
///If this export is a top-level package, this is the flags for the original package
[DisplayIndexOrder(15)]
public EPackageFlags PackageFlags;
///Should this export be always loaded in editor game?
[DisplayIndexOrder(16)]
public bool bNotAlwaysLoadedForEditorGame;
///Is this export an asset?
[DisplayIndexOrder(17)]
public bool bIsAsset;
///
[DisplayIndexOrder(18)]
public bool GeneratePublicHash;
///
/// The export table must serialize as a fixed size, this is used to index into a long list, which is later loaded into the array. -1 means dependencies are not present. These are contiguous blocks, so CreateBeforeSerializationDependencies starts at FirstExportDependency + SerializationBeforeSerializationDependencies.
///
internal int FirstExportDependencyOffset;
internal int SerializationBeforeSerializationDependenciesSize;
internal int CreateBeforeSerializationDependenciesSize;
internal int SerializationBeforeCreateDependenciesSize;
internal int CreateBeforeCreateDependenciesSize;
[DisplayIndexOrder(19)]
public List SerializationBeforeSerializationDependencies = new List();
[DisplayIndexOrder(20)]
public List CreateBeforeSerializationDependencies = new List();
[DisplayIndexOrder(21)]
public List SerializationBeforeCreateDependencies = new List();
[DisplayIndexOrder(22)]
public List CreateBeforeCreateDependencies = new List();
///
/// Miscellaneous, unparsed export data, stored as a byte array.
///
public byte[] Extras;
///
/// The asset that this export is parsed with.
///
[JsonIgnore]
public UAsset Asset;
[JsonIgnore]
internal bool alreadySerialized = false;
public Export(UAsset asset, byte[] extras)
{
Asset = asset;
Extras = extras;
}
public Export()
{
}
public virtual void Read(AssetBinaryReader reader, int nextStarting = 0)
{
}
///
/// Resolves the ancestry of all child properties of this export.
///
public virtual void ResolveAncestries(UAsset asset, AncestryInfo ancestrySoFar)
{
}
public virtual void Write(AssetBinaryWriter writer)
{
}
// https://github.com/EpicGames/UnrealEngine/commit/1952a8b65290bc5b492f87d57fce87c809e231a0
// this commit doesn't seem to actually make any changes to how bools are serialized
private bool ReadBit(AssetBinaryReader reader)
{
return reader.ReadInt32() == 1;
}
private void WriteBit(AssetBinaryWriter writer, bool b)
{
writer.Write(b ? 1 : 0);
}
public void ReadExportMapEntry(AssetBinaryReader reader)
{
Asset = reader.Asset;
this.ClassIndex = new FPackageIndex(reader.ReadInt32());
this.SuperIndex = new FPackageIndex(reader.ReadInt32());
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_TemplateIndex_IN_COOKED_EXPORTS)
{
this.TemplateIndex = new FPackageIndex(reader.ReadInt32());
}
this.OuterIndex = new FPackageIndex(reader.ReadInt32());
this.ObjectName = reader.ReadFName();
this.ObjectFlags = (EObjectFlags)reader.ReadUInt32();
if (Asset.ObjectVersion < ObjectVersion.VER_UE4_64BIT_EXPORTMAP_SERIALSIZES)
{
this.SerialSize = reader.ReadInt32();
this.SerialOffset = reader.ReadInt32();
}
else
{
this.SerialSize = reader.ReadInt64();
this.SerialOffset = reader.ReadInt64();
}
this.bForcedExport = ReadBit(reader);
this.bNotForClient = ReadBit(reader);
this.bNotForServer = ReadBit(reader);
if (Asset.ObjectVersionUE5 < ObjectVersionUE5.REMOVE_OBJECT_EXPORT_PACKAGE_GUID) this.PackageGuid = new Guid(reader.ReadBytes(16));
if (Asset.ObjectVersionUE5 >= ObjectVersionUE5.TRACK_OBJECT_EXPORT_IS_INHERITED) this.IsInheritedInstance = ReadBit(reader);
this.PackageFlags = (EPackageFlags)reader.ReadUInt32();
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_LOAD_FOR_EDITOR_GAME)
{
this.bNotAlwaysLoadedForEditorGame = ReadBit(reader);
}
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_COOKED_ASSETS_IN_EDITOR_SUPPORT)
{
this.bIsAsset = ReadBit(reader);
}
if (Asset.ObjectVersionUE5 >= ObjectVersionUE5.OPTIONAL_RESOURCES)
{
this.GeneratePublicHash = ReadBit(reader);
}
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_PRELOAD_DEPENDENCIES_IN_COOKED_EXPORTS)
{
this.FirstExportDependencyOffset = reader.ReadInt32();
this.SerializationBeforeSerializationDependenciesSize = reader.ReadInt32();
this.CreateBeforeSerializationDependenciesSize = reader.ReadInt32();
this.SerializationBeforeCreateDependenciesSize = reader.ReadInt32();
this.CreateBeforeCreateDependenciesSize = reader.ReadInt32();
}
if (!Asset.HasUnversionedProperties && Asset.ObjectVersionUE5 >= ObjectVersionUE5.SCRIPT_SERIALIZATION_OFFSET)
{
this.ScriptSerializationStartOffset = reader.ReadInt64();
this.ScriptSerializationEndOffset = reader.ReadInt64();
}
}
public static long GetExportMapEntrySize(UAsset asset)
{
AssetBinaryWriter testWriter = new AssetBinaryWriter(new MemoryStream(127), asset);
new Export().WriteExportMapEntry(testWriter);
long res = testWriter.BaseStream.Position;
testWriter.Dispose();
return res;
}
public void WriteExportMapEntry(AssetBinaryWriter writer)
{
Asset = writer.Asset;
writer.Write(ClassIndex?.Index ?? 0);
writer.Write(SuperIndex?.Index ?? 0);
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_TemplateIndex_IN_COOKED_EXPORTS)
{
writer.Write(TemplateIndex?.Index ?? 0);
}
writer.Write(OuterIndex?.Index ?? 0);
writer.Write(ObjectName);
writer.Write((uint)ObjectFlags);
if (Asset.ObjectVersion < ObjectVersion.VER_UE4_64BIT_EXPORTMAP_SERIALSIZES)
{
writer.Write((int)SerialSize);
writer.Write((int)SerialOffset);
}
else
{
writer.Write(SerialSize);
writer.Write(SerialOffset);
}
WriteBit(writer, bForcedExport);
WriteBit(writer, bNotForClient);
WriteBit(writer, bNotForServer);
if (Asset.ObjectVersionUE5 < ObjectVersionUE5.REMOVE_OBJECT_EXPORT_PACKAGE_GUID) writer.Write(PackageGuid.ToByteArray());
if (Asset.ObjectVersionUE5 >= ObjectVersionUE5.TRACK_OBJECT_EXPORT_IS_INHERITED) WriteBit(writer, IsInheritedInstance);
writer.Write((uint)PackageFlags);
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_LOAD_FOR_EDITOR_GAME)
{
WriteBit(writer, bNotAlwaysLoadedForEditorGame);
}
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_COOKED_ASSETS_IN_EDITOR_SUPPORT)
{
WriteBit(writer, bIsAsset);
}
if (Asset.ObjectVersionUE5 >= ObjectVersionUE5.OPTIONAL_RESOURCES)
{
WriteBit(writer, GeneratePublicHash);
}
if (Asset.ObjectVersion >= ObjectVersion.VER_UE4_PRELOAD_DEPENDENCIES_IN_COOKED_EXPORTS)
{
writer.Write(FirstExportDependencyOffset);
writer.Write(SerializationBeforeSerializationDependenciesSize);
writer.Write(CreateBeforeSerializationDependenciesSize);
writer.Write(SerializationBeforeCreateDependenciesSize);
writer.Write(CreateBeforeCreateDependenciesSize);
}
if (!Asset.HasUnversionedProperties && Asset.ObjectVersionUE5 >= ObjectVersionUE5.SCRIPT_SERIALIZATION_OFFSET)
{
writer.Write(ScriptSerializationStartOffset);
writer.Write(ScriptSerializationEndOffset);
}
}
private static MemberInfo[] _allFields = null;
private static void InitAllFields()
{
if (_allFields != null) return;
_allFields = UAPUtils.GetOrderedMembers();
}
public static MemberInfo[] GetAllObjectExportFields(UAsset asset)
{
InitAllFields();
var finalFields = new List();
for (int i = 0; i < _allFields.Length; i++)
{
if (_allFields[i] == null) continue;
DisplayIndexOrderAttribute attr = ((DisplayIndexOrderAttribute[])_allFields[i]?.GetCustomAttributes(typeof(DisplayIndexOrderAttribute), true))?[0];
if (attr == null) continue;
if (asset is UAsset && !attr.IsTraditional) continue;
finalFields.Add(_allFields[i]);
}
return finalFields.ToArray();
}
public static string[] GetAllFieldNames(UAsset asset)
{
InitAllFields();
MemberInfo[] relevantFields = GetAllObjectExportFields(asset);
string[] allFieldNames = new string[relevantFields.Length];
for (int i = 0; i < relevantFields.Length; i++)
{
allFieldNames[i] = relevantFields[i].Name;
}
return allFieldNames;
}
public FName GetExportClassType()
{
return this.ClassIndex.IsImport() ? this.ClassIndex.ToImport(Asset).ObjectName : FName.DefineDummy(Asset, this.ClassIndex.Index.ToString());
}
public FName GetClassTypeForAncestry(UAsset asset, out FName modulePath)
{
if (asset == null) asset = Asset;
return GetClassTypeForAncestry(this.ClassIndex, asset, out modulePath);
}
public static FName GetClassTypeForAncestry(FPackageIndex classIndex, UAsset asset, out FName modulePath)
{
modulePath = null;
if (classIndex.IsNull()) return null;
if (classIndex.IsExport()) return classIndex.ToExport(asset).ObjectName;
var imp = classIndex.ToImport(asset);
if (imp.OuterIndex.IsImport()) modulePath = imp.OuterIndex.ToImport(asset).ObjectName;
return imp.ObjectName;
}
public override string ToString()
{
InitAllFields();
var sb = new StringBuilder();
foreach (var info in _allFields)
{
DisplayIndexOrderAttribute attr = ((DisplayIndexOrderAttribute[])info?.GetCustomAttributes(typeof(DisplayIndexOrderAttribute), true))?[0];
if (attr == null) continue;
if (Asset is UAsset && !attr.IsTraditional) continue;
var value = info.GetValue(this) ?? "(null)";
sb.AppendLine(info.Name + ": " + value.ToString());
}
return sb.ToString();
}
public object Clone()
{
var res = (Export)MemberwiseClone();
res.SerializationBeforeSerializationDependencies = this.SerializationBeforeSerializationDependencies.ToList();
res.CreateBeforeSerializationDependencies = this.CreateBeforeSerializationDependencies.ToList();
res.SerializationBeforeCreateDependencies = this.SerializationBeforeCreateDependencies.ToList();
res.CreateBeforeCreateDependencies = this.CreateBeforeCreateDependencies.ToList();
res.Extras = (byte[])this.Extras.Clone();
res.PackageGuid = new Guid(this.PackageGuid.ToByteArray());
return res;
}
///
/// Creates a child export instance with the same export details as the current export.
///
/// The type of child export to create.
/// An instance of the child export type provided with the export details copied over.
public T ConvertToChildExport() where T : Export, new()
{
InitAllFields();
Export res = new T();
res.SerializationBeforeSerializationDependencies = this.SerializationBeforeSerializationDependencies.ToList();
res.CreateBeforeSerializationDependencies = this.CreateBeforeSerializationDependencies.ToList();
res.SerializationBeforeCreateDependencies = this.SerializationBeforeCreateDependencies.ToList();
res.CreateBeforeCreateDependencies = this.CreateBeforeCreateDependencies.ToList();
res.Asset = this.Asset;
res.Extras = this.Extras;
foreach (var info in _allFields)
{
info.SetValue(res, info.GetValue(this));
}
return (T)res;
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/FieldExport.cs
================================================
using UAssetAPI.FieldTypes;
namespace UAssetAPI.ExportTypes
{
///
/// Export data for a .
///
public class FieldExport : NormalExport
{
public UField Field;
public FieldExport(Export super) : base(super)
{
}
public FieldExport(UAsset asset, byte[] extras) : base(asset, extras)
{
}
public FieldExport()
{
}
public override void Read(AssetBinaryReader reader, int nextStarting)
{
base.Read(reader, nextStarting);
Field = new UField();
Field.Read(reader);
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
Field.Write(writer);
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/FunctionExport.cs
================================================
using System.IO;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.ExportTypes
{
///
/// Export data for a blueprint function.
///
public class FunctionExport : StructExport
{
public EFunctionFlags FunctionFlags;
public FunctionExport(Export super) : base(super)
{
Asset = super.Asset;
Extras = super.Extras;
}
public FunctionExport(UAsset asset, byte[] extras) : base(asset, extras)
{
}
public FunctionExport()
{
}
public override void Read(AssetBinaryReader reader, int nextStarting)
{
base.Read(reader, nextStarting);
FunctionFlags = (EFunctionFlags)reader.ReadUInt32();
// TODO
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write((uint)FunctionFlags);
// TODO
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/LevelExport.cs
================================================
using System.Collections.Generic;
using UAssetAPI.CustomVersions;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.ExportTypes;
///
/// URL structure.
///
public struct FURL
{
// Protocol, i.e. "unreal" or "http".
public FString Protocol;
// Optional hostname, i.e. "204.157.115.40" or "unreal.epicgames.com", blank if local.
public FString Host;
// Optional host port.
public int Port;
public int Valid;
// Map name, i.e. "SkyCity", default is "Entry".
public FString Map;
// Options.
public List Op;
// Portal to enter through, default is "".
public FString Portal;
public FURL(AssetBinaryReader reader)
{
Protocol = reader.ReadFString();
Host = reader.ReadFString();
Map = reader.ReadFString();
Portal = reader.ReadFString();
var len = reader.ReadInt32();
Op = new List(len);
for (int i = 0; i < len; i++)
{
Op.Add(reader.ReadFString());
}
Port = reader.ReadInt32();
Valid = reader.ReadInt32();
}
public int Write(AssetBinaryWriter writer){
var offset = writer.BaseStream.Position;
writer.Write(Protocol);
writer.Write(Host);
writer.Write(Map);
writer.Write(Portal);
writer.Write(Op.Count);
for (int i = 0; i < Op.Count; i++)
{
writer.Write(Op[i]);
}
writer.Write(Port);
writer.Write(Valid);
return (int)(writer.BaseStream.Position-offset);
}
}
public class LevelExport : NormalExport
{
// Owner of TTransArray Actors
public FPackageIndex Owner;
public List Actors;
public FURL URL;
public FPackageIndex Model;
public List ModelComponents;
public FPackageIndex LevelScriptActor;
public FPackageIndex NavListStart;
public FPackageIndex NavListEnd;
//public FPrecomputedVisibilityHandler PrecomputedVisibilityHandler;
//public FPrecomputedVolumeDistanceField PrecomputedVolumeDistanceField;
public LevelExport(Export super) : base(super) { }
public LevelExport(UAsset asset, byte[] extras) : base(asset, extras) { }
public LevelExport(){ }
public override void Read(AssetBinaryReader reader, int nextStarting)
{
base.Read(reader, nextStarting);
if (reader.Asset.GetCustomVersion() < FReleaseObjectVersion.LevelTransArrayConvertedToTArray)
Owner = new FPackageIndex(reader);
int numIndexEntries = reader.ReadInt32();
Actors = new List(numIndexEntries);
for (int i = 0; i < numIndexEntries; i++) {
Actors.Add(new FPackageIndex(reader));
}
URL = new FURL(reader);
Model = new FPackageIndex(reader);
int numModelEntries = reader.ReadInt32();
ModelComponents = new List(numModelEntries);
for (int i = 0; i < numModelEntries; i++)
{
ModelComponents.Add(new FPackageIndex(reader));
}
LevelScriptActor = new FPackageIndex(reader);
NavListStart = new FPackageIndex(reader);
NavListEnd = new FPackageIndex(reader);
// TODO: Implement the rest of the properties
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
if (writer.Asset.GetCustomVersion() < FReleaseObjectVersion.LevelTransArrayConvertedToTArray)
Owner.Write(writer);
writer.Write(Actors.Count);
for (int i = 0; i < Actors.Count; i++)
{
Actors[i].Write(writer);
}
URL.Write(writer);
Model.Write(writer);
writer.Write(ModelComponents.Count);
for (int i = 0; i < ModelComponents.Count; i++)
{
ModelComponents[i].Write(writer);
}
LevelScriptActor.Write(writer);
NavListStart.Write(writer);
NavListEnd.Write(writer);
}
}
================================================
FILE: UAssetAPI/ExportTypes/MetaDataExport.cs
================================================
using Newtonsoft.Json;
using System.Collections.Generic;
using UAssetAPI.CustomVersions;
using UAssetAPI.JSON;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.ExportTypes
{
public struct ObjectMetaDataEntry
{
public int Import;
[JsonConverter(typeof(TMapJsonConverter))]
public TMap MetaData;
public ObjectMetaDataEntry(int import, TMap metaData)
{
Import = import;
MetaData = metaData;
}
}
public class MetaDataExport : NormalExport
{
public List ObjectMetaData;
[JsonConverter(typeof(TMapJsonConverter))]
public TMap RootMetaData;
public MetaDataExport(Export super) : base(super)
{
}
public MetaDataExport(UAsset asset, byte[] extras) : base(asset, extras)
{
}
public MetaDataExport()
{
}
public override void Read(AssetBinaryReader reader, int nextStarting)
{
base.Read(reader, nextStarting);
{
ObjectMetaData = [];
var objectMetaDataMapCount = reader.ReadInt32();
for (var i = 0; i < objectMetaDataMapCount; i++)
{
var import = reader.ReadInt32();
var metaDataCount = reader.ReadInt32();
var metaData = new TMap();
for (var j = 0; j < metaDataCount; j++)
{
var key = reader.ReadFName();
var value = reader.ReadFString();
metaData.Add(key, value);
}
ObjectMetaData.Add(new ObjectMetaDataEntry(import, metaData));
}
}
if (reader.Asset.GetCustomVersion() >= FEditorObjectVersion.RootMetaDataSupport)
{
RootMetaData = [];
var rootMetaDataMapCount = reader.ReadInt32();
for (var i = 0; i < rootMetaDataMapCount; i++)
{
var key = reader.ReadFName();
var value = reader.ReadFString();
RootMetaData.Add(key, value);
}
}
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(ObjectMetaData.Count);
foreach (var entry in ObjectMetaData)
{
writer.Write(entry.Import);
writer.Write(entry.MetaData.Count);
foreach (var entry2 in entry.MetaData)
{
writer.Write(entry2.Key);
writer.Write(entry2.Value);
}
}
if (writer.Asset.GetCustomVersion() >= FEditorObjectVersion.RootMetaDataSupport)
{
writer.Write(RootMetaData.Count);
foreach ((var key, var value) in RootMetaData)
{
writer.Write(key);
writer.Write(value);
}
}
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/NormalExport.cs
================================================
using System;
using System.Collections.Generic;
using UAssetAPI.PropertyTypes.Objects;
using UAssetAPI.UnrealTypes;
using UAssetAPI.Unversioned;
namespace UAssetAPI.ExportTypes
{
///
/// Enum flags that indicate that additional data may be serialized prior to actual tagged property serialization
/// Those extensions are used to store additional function to control how TPS will resolved. e.g. use overridable serialization
///
public enum EClassSerializationControlExtension
{
NoExtension = 0x00,
ReserveForFutureUse = 0x01, // Can be use to add a next group of extension
////////////////////////////////////////////////
// First extension group
OverridableSerializationInformation = 0x02,
//
// Add more extension for the first group here
//
}
///
/// A regular export representing a UObject, with no special serialization.
///
public class NormalExport : Export
{
public List Data;
public Guid? ObjectGuid;
public EClassSerializationControlExtension SerializationControl;
public EOverriddenPropertyOperation Operation;
public bool HasLeadingFourNullBytes = false;
///
/// Gets or sets the value associated with the specified key. This operation loops linearly, so it may not be suitable for high-performance environments.
///
/// The key associated with the value to get or set.
public virtual PropertyData this[FName key]
{
get
{
for (int i = 0; i < Data.Count; i++)
{
if (Data[i].Name == key) return Data[i];
}
return null;
}
set
{
value.Name = key;
for (int i = 0; i < Data.Count; i++)
{
if (Data[i].Name == key)
{
Data[i] = value;
return;
}
}
Data.Add(value);
}
}
///
/// Gets or sets the value associated with the specified key. This operation loops linearly, so it may not be suitable for high-performance environments.
///
/// The key associated with the value to get or set.
public virtual PropertyData this[string key]
{
get
{
return this[FName.FromString(Asset, key)];
}
set
{
this[FName.FromString(Asset, key)] = value;
}
}
///
/// Gets or sets the value at the specified index.
///
/// The index of the value to get or set.
public PropertyData this[int index]
{
get
{
return Data[index];
}
set
{
Data[index] = value;
}
}
public NormalExport(Export super)
{
Asset = super.Asset;
Extras = super.Extras;
}
public NormalExport(UAsset asset, byte[] extras) : base(asset, extras)
{
}
public NormalExport(List data, UAsset asset, byte[] extras) : base(asset, extras)
{
Data = data;
}
public NormalExport()
{
}
public override void Read(AssetBinaryReader reader, int nextStarting = 0)
{
// 5.4-specific problem; unclear why this occurs
if (reader.Asset.ObjectVersionUE5 > ObjectVersionUE5.DATA_RESOURCES && reader.Asset.ObjectVersionUE5 < ObjectVersionUE5.ASSETREGISTRY_PACKAGEBUILDDEPENDENCIES && !ObjectFlags.HasFlag(EObjectFlags.RF_ClassDefaultObject))
{
int dummy = reader.ReadInt32();
if (dummy == 0)
{
HasLeadingFourNullBytes = true;
}
else
{
HasLeadingFourNullBytes = false;
reader.BaseStream.Seek(-4, System.IO.SeekOrigin.Current);
}
}
Data = new List();
PropertyData bit;
var unversionedHeader = new FUnversionedHeader(reader);
if (!reader.Asset.HasUnversionedProperties && reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_EXTENSION_AND_OVERRIDABLE_SERIALIZATION)
{
SerializationControl = (EClassSerializationControlExtension)reader.ReadByte();
if (SerializationControl.HasFlag(EClassSerializationControlExtension.OverridableSerializationInformation))
{
Operation = (EOverriddenPropertyOperation)reader.ReadByte();
}
}
FName parentName = GetClassTypeForAncestry(reader.Asset, out FName parentModulePath);
while ((bit = MainSerializer.Read(reader, null, parentName, parentModulePath, unversionedHeader, true)) != null)
{
Data.Add(bit);
}
ObjectGuid = null;
if (!this.ObjectFlags.HasFlag(EObjectFlags.RF_ClassDefaultObject) && reader.ReadBooleanInt()) ObjectGuid = new Guid(reader.ReadBytes(16));
}
public override void ResolveAncestries(UAsset asset, AncestryInfo ancestrySoFar)
{
var ancestryNew = (AncestryInfo)ancestrySoFar.Clone();
ancestryNew.SetAsParent(GetClassTypeForAncestry(asset, out FName modulePath), modulePath);
if (Data != null)
{
for (int i = 0; i < Data.Count; i++) Data[i]?.ResolveAncestries(asset, ancestryNew);
}
base.ResolveAncestries(asset, ancestrySoFar);
}
public override void Write(AssetBinaryWriter writer)
{
// 5.4-specific problem; unclear why this occurs
if (HasLeadingFourNullBytes && writer.Asset.ObjectVersionUE5 > ObjectVersionUE5.DATA_RESOURCES && writer.Asset.ObjectVersionUE5 < ObjectVersionUE5.ASSETREGISTRY_PACKAGEBUILDDEPENDENCIES && !ObjectFlags.HasFlag(EObjectFlags.RF_ClassDefaultObject))
{
writer.Write((int)0); // "false" bool?
}
FName parentName = GetClassTypeForAncestry(writer.Asset, out FName parentModulePath);
MainSerializer.GenerateUnversionedHeader(ref Data, parentName, parentModulePath, writer.Asset)?.Write(writer);
if (!writer.Asset.HasUnversionedProperties && writer.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_EXTENSION_AND_OVERRIDABLE_SERIALIZATION)
{
writer.Write((byte)SerializationControl);
if (SerializationControl.HasFlag(EClassSerializationControlExtension.OverridableSerializationInformation))
{
writer.Write((byte)Operation);
}
}
for (int j = 0; j < Data.Count; j++)
{
PropertyData current = Data[j];
MainSerializer.Write(current, writer, true);
}
if (!writer.Asset.HasUnversionedProperties) writer.Write(new FName(writer.Asset, "None"));
if (this.ObjectFlags.HasFlag(EObjectFlags.RF_ClassDefaultObject)) return;
if (ObjectGuid == null)
{
writer.Write((int)0);
}
else
{
writer.Write((int)1);
writer.Write(((Guid)ObjectGuid).ToByteArray());
}
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/PropertyExport.cs
================================================
using System.Linq;
using UAssetAPI.FieldTypes;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.ExportTypes
{
///
/// Export data for a .
///
public class PropertyExport : NormalExport
{
public UProperty Property;
public PropertyExport(Export super) : base(super)
{
}
public PropertyExport(UAsset asset, byte[] extras) : base(asset, extras)
{
}
public PropertyExport()
{
}
public override void Read(AssetBinaryReader reader, int nextStarting)
{
base.Read(reader, nextStarting);
FName exportClassType = this.GetExportClassType();
Property = MainSerializer.ReadUProperty(reader, exportClassType);
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
MainSerializer.WriteUProperty(Property, writer);
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/RawExport.cs
================================================
using System.IO;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.ExportTypes
{
///
/// An export that could not be properly parsed by UAssetAPI, and is instead represented as an array of bytes as a fallback.
///
public class RawExport : Export
{
public byte[] Data;
public RawExport(Export super)
{
Asset = super.Asset;
Extras = super.Extras;
}
public RawExport(byte[] data, UAsset asset, byte[] extras) : base(asset, extras)
{
Data = data;
}
public RawExport()
{
}
public override void Write(AssetBinaryWriter writer)
{
writer.Write(Data);
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/StringTableExport.cs
================================================
using Newtonsoft.Json;
using System.Linq;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.ExportTypes
{
///
/// A string table. Holds Key->SourceString pairs of text.
///
public class FStringTable : TMap
{
[JsonProperty]
public FString TableNamespace;
public FStringTable(FString tableNamespace) : base()
{
TableNamespace = tableNamespace;
}
public FStringTable() : base()
{
}
}
///
/// Export data for a string table. See .
///
public class StringTableExport : NormalExport
{
[JsonProperty]
public FStringTable Table;
public StringTableExport(Export super) : base(super)
{
}
public StringTableExport(FStringTable data, UAsset asset, byte[] extras) : base(asset, extras)
{
Table = data;
}
public StringTableExport()
{
}
public override void Read(AssetBinaryReader reader, int nextStarting)
{
base.Read(reader, nextStarting);
Table = new FStringTable(reader.ReadFString());
int numEntries = reader.ReadInt32();
for (int i = 0; i < numEntries; i++)
{
Table.Add(reader.ReadFString(), reader.ReadFString());
}
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(Table.TableNamespace);
writer.Write(Table.Count);
for (int i = 0; i < Table.Count; i++)
{
writer.Write(Table.Keys.ElementAt(i));
writer.Write(Table[i]);
}
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/StructExport.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using UAssetAPI.CustomVersions;
using UAssetAPI.FieldTypes;
using UAssetAPI.Kismet.Bytecode;
using UAssetAPI.UnrealTypes;
#if DEBUGVERBOSE
using System.Diagnostics;
#endif
namespace UAssetAPI.ExportTypes
{
///
/// Base export for all UObject types that contain fields.
///
public class StructExport : FieldExport
{
///
/// Struct this inherits from, may be null
///
public FPackageIndex SuperStruct;
///
/// List of child fields
///
public FPackageIndex[] Children;
///
/// Properties serialized with this struct definition
///
public FProperty[] LoadedProperties;
///
/// The bytecode instructions contained within this struct.
///
public KismetExpression[] ScriptBytecode;
///
/// Bytecode size in total in deserialized memory. Filled out in lieu of if an error occurs during bytecode parsing.
///
public int ScriptBytecodeSize;
///
/// Raw binary bytecode data. Filled out in lieu of if an error occurs during bytecode parsing.
///
public byte[] ScriptBytecodeRaw;
public StructExport(Export super) : base(super)
{
}
public StructExport(UAsset asset, byte[] extras) : base(asset, extras)
{
}
public StructExport()
{
}
public override void Read(AssetBinaryReader reader, int nextStarting)
{
base.Read(reader, nextStarting);
SuperStruct = new FPackageIndex(reader.ReadInt32());
if (Asset.GetCustomVersion() < FFrameworkObjectVersion.RemoveUField_Next)
{
var firstChild = new FPackageIndex(reader.ReadInt32());
Children = firstChild.IsNull() ? Array.Empty() : new[] { firstChild };
}
else
{
int numIndexEntries = reader.ReadInt32();
Children = new FPackageIndex[numIndexEntries];
for (int i = 0; i < numIndexEntries; i++)
{
Children[i] = new FPackageIndex(reader.ReadInt32());
}
}
if (Asset.GetCustomVersion() >= FCoreObjectVersion.FProperties)
{
int numProps = reader.ReadInt32();
LoadedProperties = new FProperty[numProps];
for (int i = 0; i < numProps; i++)
{
LoadedProperties[i] = MainSerializer.ReadFProperty(reader);
}
}
else
{
LoadedProperties = [];
}
ScriptBytecodeSize = reader.ReadInt32(); // # of bytes in total in deserialized memory
int scriptStorageSize = reader.ReadInt32(); // # of bytes in total
long startedReading = reader.BaseStream.Position;
bool willParseRaw = true;
#pragma warning disable CS0168 // Variable is declared but never used
try
{
if (!Asset.CustomSerializationFlags.HasFlag(CustomSerializationFlags.SkipParsingBytecode))
{
var tempCode = new List();
while ((reader.BaseStream.Position - startedReading) < scriptStorageSize)
{
tempCode.Add(ExpressionSerializer.ReadExpression(reader));
}
ScriptBytecode = tempCode.ToArray();
willParseRaw = false;
}
}
catch (Exception ex)
{
#if DEBUGVERBOSE
Debug.WriteLine(ex.StackTrace);
#endif
}
#pragma warning restore CS0168 // Variable is declared but never used
if (willParseRaw)
{
reader.BaseStream.Seek(startedReading, SeekOrigin.Begin);
ScriptBytecode = null;
ScriptBytecodeRaw = reader.ReadBytes(scriptStorageSize);
}
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(SuperStruct.Index);
if (Asset.GetCustomVersion() < FFrameworkObjectVersion.RemoveUField_Next)
{
if (Children.Length == 0)
{
writer.Write(0);
}
else
{
writer.Write(Children[0].Index);
}
}
else
{
writer.Write(Children.Length);
for (int i = 0; i < Children.Length; i++)
{
writer.Write(Children[i].Index);
}
}
if (Asset.GetCustomVersion() >= FCoreObjectVersion.FProperties)
{
writer.Write(LoadedProperties.Length);
for (int i = 0; i < LoadedProperties.Length; i++)
{
MainSerializer.WriteFProperty(LoadedProperties[i], writer);
}
}
if (ScriptBytecode == null)
{
writer.Write(ScriptBytecodeSize);
writer.Write(ScriptBytecodeRaw.Length);
writer.Write(ScriptBytecodeRaw);
}
else
{
long lengthOffset1 = writer.BaseStream.Position;
writer.Write((int)0); // total iCode offset; to be filled out after serialization
long lengthOffset2 = writer.BaseStream.Position;
writer.Write((int)0); // size on disk; to be filled out after serialization
int totalICodeOffset = 0;
long startMetric = writer.BaseStream.Position;
for (int i = 0; i < ScriptBytecode.Length; i++)
{
totalICodeOffset += ExpressionSerializer.WriteExpression(ScriptBytecode[i], writer);
}
long endMetric = writer.BaseStream.Position;
// Write out total size in bytes
long totalLength = endMetric - startMetric;
long here = writer.BaseStream.Position;
writer.Seek((int)lengthOffset1, SeekOrigin.Begin);
writer.Write(totalICodeOffset);
writer.Seek((int)lengthOffset2, SeekOrigin.Begin);
writer.Write((int)totalLength);
writer.Seek((int)here, SeekOrigin.Begin);
}
}
}
}
================================================
FILE: UAssetAPI/ExportTypes/UserDefinedStructExport.cs
================================================
using System.Collections.Generic;
using System.Linq;
using UAssetAPI.CustomVersions;
using UAssetAPI.PropertyTypes.Objects;
using UAssetAPI.UnrealTypes;
using UAssetAPI.Unversioned;
namespace UAssetAPI.ExportTypes;
public class UserDefinedStructExport : StructExport
{
public uint StructFlags;
public List StructData = [];
public EClassSerializationControlExtension SerializationControl2;
public EOverriddenPropertyOperation Operation2;
public UserDefinedStructExport(Export super) : base(super) { }
public UserDefinedStructExport(UAsset asset, byte[] extras) : base(asset, extras) { }
public UserDefinedStructExport() { }
public override void Read(AssetBinaryReader reader, int nextStarting)
{
base.Read(reader, nextStarting);
if (reader.Asset.Mappings?.Schemas != null && this.ObjectName?.Value?.Value != null)
{
UsmapSchema newSchema = Usmap.GetSchemaFromStructExport(this, reader.Asset.Mappings?.AreFNamesCaseInsensitive ?? true);
reader.Asset.Mappings.Schemas[this.ObjectName.Value.Value] = newSchema;
}
if (reader.Asset.GetCustomVersion() < FFrameworkObjectVersion.UserDefinedStructsStoreDefaultInstance
|| (Data.FirstOrDefault(x => x.Name.Value.Value == "Status") is BytePropertyData byteprop && byteprop.EnumValue?.Value.Value != "UDSS_UpToDate"))
return;
if (this.ObjectFlags.HasFlag(EObjectFlags.RF_ClassDefaultObject)) return;
StructFlags = reader.ReadUInt32();
PropertyData bit;
var unversionedHeader = new FUnversionedHeader(reader);
while ((bit = MainSerializer.Read(reader, null, this.ObjectName, FName.DefineDummy(reader.Asset, reader.Asset.InternalAssetPath), unversionedHeader, true)) != null)
{
StructData.Add(bit);
}
}
public override void ResolveAncestries(UAsset asset, AncestryInfo ancestrySoFar)
{
var ancestryNew = (AncestryInfo)ancestrySoFar.Clone();
ancestryNew.SetAsParent(this.ObjectName, null);
if (StructData != null)
{
for (int i = 0; i < StructData.Count; i++) StructData[i]?.ResolveAncestries(asset, ancestryNew);
}
base.ResolveAncestries(asset, ancestrySoFar);
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
if (writer.Asset.GetCustomVersion() < FFrameworkObjectVersion.UserDefinedStructsStoreDefaultInstance
|| (Data.FirstOrDefault(x => x.Name.Value.Value == "Status") is BytePropertyData byteprop && byteprop.EnumValue?.Value.Value != "UDSS_UpToDate"))
return;
if (this.ObjectFlags.HasFlag(EObjectFlags.RF_ClassDefaultObject)) return;
writer.Write(StructFlags);
MainSerializer.GenerateUnversionedHeader(ref StructData, this.ObjectName, FName.DefineDummy(writer.Asset, writer.Asset.InternalAssetPath), writer.Asset)?.Write(writer);
for (int j = 0; j < StructData.Count; j++)
{
PropertyData current = StructData[j];
MainSerializer.Write(current, writer, true);
}
if (!writer.Asset.HasUnversionedProperties) writer.Write(new FName(writer.Asset, "None"));
}
}
================================================
FILE: UAssetAPI/FieldTypes/EArrayDim.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.FieldTypes
{
///
/// The type of array that this property represents. This is represented an integer in the engine.
///
public enum EArrayDim : int
{
NotAnArray = 0,
TArray = 1,
CArray = 2
}
}
================================================
FILE: UAssetAPI/FieldTypes/ELifetimeCondition.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.FieldTypes
{
/// Secondary condition to check before considering the replication of a lifetime property.
public enum ELifetimeCondition : byte
{
/// This property has no condition, and will send anytime it changes
COND_None = 0,
/// This property will only attempt to send on the initial bunch
COND_InitialOnly = 1,
/// This property will only send to the actor's owner
COND_OwnerOnly = 2,
/// This property send to every connection EXCEPT the owner
COND_SkipOwner = 3,
/// This property will only send to simulated actors
COND_SimulatedOnly = 4,
/// This property will only send to autonomous actors
COND_AutonomousOnly = 5,
/// This property will send to simulated OR bRepPhysics actors
COND_SimulatedOrPhysics = 6,
/// This property will send on the initial packet, or to the actors owner
COND_InitialOrOwner = 7,
/// This property has no particular condition, but wants the ability to toggle on/off via SetCustomIsActiveOverride
COND_Custom = 8,
/// This property will only send to the replay connection, or to the actors owner
COND_ReplayOrOwner = 9,
/// This property will only send to the replay connection
COND_ReplayOnly = 10,
/// This property will send to actors only, but not to replay connections
COND_SimulatedOnlyNoReplay = 11,
/// This property will send to simulated Or bRepPhysics actors, but not to replay connections
COND_SimulatedOrPhysicsNoReplay = 12,
/// This property will not send to the replay connection
COND_SkipReplay = 13,
/// This property will never be replicated
COND_Never = 15,
COND_Max = 16
};
}
================================================
FILE: UAssetAPI/FieldTypes/FField.cs
================================================
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using UAssetAPI.UnrealTypes;
using UAssetAPI.Unversioned;
namespace UAssetAPI.FieldTypes
{
///
/// Base class of reflection data objects.
///
public class FField
{
public FName SerializedType;
public FName Name;
public EObjectFlags Flags;
public TMap MetaDataMap;
public virtual void Read(AssetBinaryReader reader)
{
Name = reader.ReadFName();
Flags = (EObjectFlags)reader.ReadUInt32();
if (!reader.Asset.IsFilterEditorOnly && !reader.Asset.PackageFlags.HasFlag(EPackageFlags.PKG_Cooked))
{
bool bHasMetaData = reader.ReadBooleanInt();
if (bHasMetaData)
{
MetaDataMap = new TMap();
int leng = reader.ReadInt32();
for (int i = 0; i < leng; i++)
{
FName key = reader.ReadFName();
FString val = reader.ReadFString();
MetaDataMap.Add(key, val);
}
}
}
}
public virtual void Write(AssetBinaryWriter writer)
{
writer.Write(Name);
writer.Write((uint)Flags);
if (!writer.Asset.IsFilterEditorOnly && !writer.Asset.PackageFlags.HasFlag(EPackageFlags.PKG_Cooked))
{
writer.Write(MetaDataMap is not null ? 1 : 0); // int32
if (MetaDataMap is not null && MetaDataMap.Count > 0)
{
writer.Write(MetaDataMap.Count); // int32
for (int i = 0; i < MetaDataMap.Count; i++)
{
var pair = MetaDataMap.GetItem(i);
writer.Write(pair.Key);
writer.Write(pair.Value);
}
}
}
}
public FField()
{
}
}
///
/// An UnrealScript variable.
///
public abstract class FProperty : FField
{
public EArrayDim ArrayDim;
public int ElementSize;
public EPropertyFlags PropertyFlags;
public ushort RepIndex;
public FName RepNotifyFunc;
public ELifetimeCondition BlueprintReplicationCondition;
public object RawValue;
public void SetObject(object value)
{
RawValue = value;
}
public T GetObject()
{
return (T)RawValue;
}
[JsonIgnore]
public IDictionary UsmapPropertyTypeOverrides = new Dictionary()
{
{ "MulticastInlineDelegateProperty", EPropertyType.MulticastDelegateProperty },
{ "ClassProperty", EPropertyType.ObjectProperty },
{ "SoftClassProperty", EPropertyType.SoftObjectProperty }
};
public EPropertyType GetUsmapPropertyType()
{
EPropertyType res = EPropertyType.Unknown;
if (UsmapPropertyTypeOverrides.TryGetValue(SerializedType.Value.Value, out res)) return res;
if (Enum.TryParse(SerializedType.Value.Value, out res)) return res;
return res;
}
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
ArrayDim = (EArrayDim)reader.ReadInt32();
ElementSize = reader.ReadInt32();
PropertyFlags = (EPropertyFlags)reader.ReadUInt64();
RepIndex = reader.ReadUInt16();
RepNotifyFunc = reader.ReadFName();
BlueprintReplicationCondition = (ELifetimeCondition)reader.ReadByte();
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write((int)ArrayDim);
writer.Write(ElementSize);
writer.Write((ulong)PropertyFlags);
writer.Write(RepIndex);
writer.Write(RepNotifyFunc);
writer.Write((byte)BlueprintReplicationCondition);
}
public FProperty()
{
}
}
public class FEnumProperty : FProperty
{
///A pointer to the UEnum represented by this property
public FPackageIndex Enum;
///The FNumericProperty which represents the underlying type of the enum
public FProperty UnderlyingProp;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
Enum = new FPackageIndex(reader.ReadInt32());
UnderlyingProp = MainSerializer.ReadFProperty(reader);
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(Enum.Index);
MainSerializer.WriteFProperty(UnderlyingProp, writer);
}
}
public class FArrayProperty : FProperty
{
public FProperty Inner;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
Inner = MainSerializer.ReadFProperty(reader);
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
MainSerializer.WriteFProperty(Inner, writer);
}
}
public class FSetProperty : FProperty
{
public FProperty ElementProp;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
ElementProp = MainSerializer.ReadFProperty(reader);
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
MainSerializer.WriteFProperty(ElementProp, writer);
}
}
public class FObjectProperty : FProperty
{
// UClass*
public FPackageIndex PropertyClass;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
PropertyClass = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(PropertyClass.Index);
}
}
public class FSoftObjectProperty : FObjectProperty
{
}
public class FWeakObjectProperty : FObjectProperty
{
}
public class FClassProperty : FObjectProperty
{
// UClass*
public FPackageIndex MetaClass;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
MetaClass = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(MetaClass.Index);
}
}
public class FSoftClassProperty : FObjectProperty
{
// UClass*
public FPackageIndex MetaClass;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
MetaClass = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(MetaClass.Index);
}
}
public class FDelegateProperty : FProperty
{
// UFunction*
public FPackageIndex SignatureFunction;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
SignatureFunction = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(SignatureFunction.Index);
}
}
public class FMulticastDelegateProperty : FDelegateProperty
{
}
public class FMulticastInlineDelegateProperty : FMulticastDelegateProperty
{
}
public class FInterfaceProperty : FProperty
{
// UFunction*
public FPackageIndex InterfaceClass;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
InterfaceClass = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(InterfaceClass.Index);
}
}
public class FMapProperty : FProperty
{
public FProperty KeyProp;
public FProperty ValueProp;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
KeyProp = MainSerializer.ReadFProperty(reader);
ValueProp = MainSerializer.ReadFProperty(reader);
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
MainSerializer.WriteFProperty(KeyProp, writer);
MainSerializer.WriteFProperty(ValueProp, writer);
}
}
public class FBoolProperty : FProperty
{
/// Size of the bitfield/bool property. Equal to ElementSize but used to check if the property has been properly initialized (0-8, where 0 means uninitialized).
public byte FieldSize;
/// Offset from the memeber variable to the byte of the property (0-7).
public byte ByteOffset;
/// Mask of the byte with the property value.
public byte ByteMask;
/// Mask of the field with the property value. Either equal to ByteMask or 255 in case of 'bool' type.
public byte FieldMask;
public bool NativeBool;
public bool Value;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
byte BoolSize = (byte)ElementSize;
FieldSize = reader.ReadByte();
ByteOffset = reader.ReadByte();
ByteMask = reader.ReadByte();
FieldMask = reader.ReadByte();
NativeBool = reader.ReadBoolean();
Value = reader.ReadBoolean();
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(FieldSize);
writer.Write(ByteOffset);
writer.Write(ByteMask);
writer.Write(FieldMask);
writer.Write(NativeBool);
writer.Write(Value);
}
}
public class FByteProperty : FProperty
{
/// A pointer to the UEnum represented by this property
public FPackageIndex Enum;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
Enum = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(Enum.Index);
}
}
public class FStructProperty : FProperty
{
// UScriptStruct*
public FPackageIndex Struct;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
Struct = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(Struct.Index);
}
}
public class FNumericProperty : FProperty
{
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
}
}
///
/// This is a UAssetAPI-specific property that represents anything that we don't have special serialization for
///
public class FGenericProperty : FProperty
{
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
}
}
public class FOptionalProperty : FProperty
{
public FProperty ValueProperty;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
ValueProperty = MainSerializer.ReadFProperty(reader);
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
MainSerializer.WriteFProperty(ValueProperty, writer);
}
}
}
================================================
FILE: UAssetAPI/FieldTypes/UField.cs
================================================
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
using UAssetAPI.CustomVersions;
using UAssetAPI.Unversioned;
namespace UAssetAPI.FieldTypes;
///
/// Base class of reflection data objects.
///
public class UField
{
///
/// Next Field in the linked list. Removed entirely in the custom version FFrameworkObjectVersion::RemoveUField_Next in favor of a regular array
///
[DisplayIndexOrder(0)]
public FPackageIndex Next;
public virtual void Read(AssetBinaryReader reader)
{
if (reader.Asset.GetCustomVersion() < FFrameworkObjectVersion.RemoveUField_Next)
{
Next = new FPackageIndex(reader.ReadInt32());
}
}
public virtual void Write(AssetBinaryWriter writer)
{
if (writer.Asset.GetCustomVersion() < FFrameworkObjectVersion.RemoveUField_Next)
{
writer.Write(Next.Index);
}
}
public UField() { }
}
///
/// An UnrealScript variable.
///
public abstract class UProperty : UField
{
[DisplayIndexOrder(1)]
public EArrayDim ArrayDim;
[DisplayIndexOrder(2)]
public int ElementSize;
[DisplayIndexOrder(3)]
public EPropertyFlags PropertyFlags;
[DisplayIndexOrder(4)]
public FName RepNotifyFunc;
[DisplayIndexOrder(5)]
public ELifetimeCondition BlueprintReplicationCondition;
public object RawValue;
public void SetObject(object value)
{
RawValue = value;
}
public T GetObject()
{
return (T)RawValue;
}
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
ArrayDim = (EArrayDim)reader.ReadInt32();
PropertyFlags = (EPropertyFlags)reader.ReadUInt64();
RepNotifyFunc = reader.ReadFName();
if (reader.Asset.GetCustomVersion() >= FReleaseObjectVersion.PropertiesSerializeRepCondition)
{
BlueprintReplicationCondition = (ELifetimeCondition)reader.ReadByte();
}
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write((int)ArrayDim);
writer.Write((ulong)PropertyFlags);
writer.Write(RepNotifyFunc);
if (writer.Asset.GetCustomVersion() >= FReleaseObjectVersion.PropertiesSerializeRepCondition)
{
writer.Write((byte)BlueprintReplicationCondition);
}
}
public UProperty() { }
public EPropertyType GetUsmapPropertyType()
{
return this switch
{
UEnumProperty => EPropertyType.EnumProperty,
UByteProperty => EPropertyType.ByteProperty,
UBoolProperty => EPropertyType.BoolProperty,
UInt8Property => EPropertyType.Int8Property,
UInt16Property => EPropertyType.Int16Property,
UIntProperty => EPropertyType.IntProperty,
UInt64Property => EPropertyType.Int64Property,
UUInt16Property => EPropertyType.UInt16Property,
UUInt32Property => EPropertyType.UInt32Property,
UUInt64Property => EPropertyType.UInt64Property,
UFloatProperty => EPropertyType.FloatProperty,
UDoubleProperty => EPropertyType.DoubleProperty,
UAssetClassProperty => EPropertyType.SoftObjectProperty,
USoftClassProperty => EPropertyType.SoftObjectProperty,
UClassProperty => EPropertyType.ObjectProperty,
UAssetObjectProperty => EPropertyType.AssetObjectProperty,
UWeakObjectProperty => EPropertyType.WeakObjectProperty,
ULazyObjectProperty => EPropertyType.LazyObjectProperty,
USoftObjectProperty => EPropertyType.SoftObjectProperty,
UObjectProperty => EPropertyType.ObjectProperty,
UNameProperty => EPropertyType.NameProperty,
UStrProperty => EPropertyType.StrProperty,
UTextProperty => EPropertyType.TextProperty,
UInterfaceProperty => EPropertyType.InterfaceProperty,
UMulticastDelegateProperty => EPropertyType.MulticastDelegateProperty,
UDelegateProperty => EPropertyType.DelegateProperty,
UMapProperty => EPropertyType.MapProperty,
USetProperty => EPropertyType.SetProperty,
UArrayProperty => EPropertyType.ArrayProperty,
UStructProperty => EPropertyType.StructProperty,
_ => EPropertyType.Unknown,
};
}
}
public class UEnumProperty : UProperty
{
///A pointer to the UEnum represented by this property
[DisplayIndexOrder(6)]
public FPackageIndex Enum;
///The FNumericProperty which represents the underlying type of the enum
[DisplayIndexOrder(7)]
public FPackageIndex UnderlyingProp;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
Enum = new FPackageIndex(reader.ReadInt32());
UnderlyingProp = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(Enum.Index);
writer.Write(UnderlyingProp.Index);
}
}
public class UArrayProperty : UProperty
{
[DisplayIndexOrder(6)]
public FPackageIndex Inner;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
Inner = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(Inner.Index);
}
}
public class USetProperty : UProperty
{
[DisplayIndexOrder(6)]
public FPackageIndex ElementProp;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
ElementProp = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(ElementProp.Index);
}
}
public class UObjectProperty : UProperty
{
// UClass*
[DisplayIndexOrder(6)]
public FPackageIndex PropertyClass;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
PropertyClass = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(PropertyClass.Index);
}
}
public class UWeakObjectProperty : UObjectProperty { }
public class USoftObjectProperty : UObjectProperty { }
public class ULazyObjectProperty : UObjectProperty { }
public class UAssetObjectProperty : UObjectProperty { }
public class UClassProperty : UObjectProperty
{
// UClass*
[DisplayIndexOrder(7)]
public FPackageIndex MetaClass;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
MetaClass = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(MetaClass.Index);
}
}
public class UAssetClassProperty : UObjectProperty
{
// UClass*
[DisplayIndexOrder(7)]
public FPackageIndex MetaClass;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
MetaClass = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(MetaClass.Index);
}
}
public class USoftClassProperty : UObjectProperty
{
// UClass*
[DisplayIndexOrder(7)]
public FPackageIndex MetaClass;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
MetaClass = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(MetaClass.Index);
}
}
public class UDelegateProperty : UProperty
{
// UFunction*
[DisplayIndexOrder(6)]
public FPackageIndex SignatureFunction;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
SignatureFunction = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(SignatureFunction.Index);
}
}
public class UMulticastDelegateProperty : UDelegateProperty { }
public class UMulticastInlineDelegateProperty : UMulticastDelegateProperty { }
public class UMulticastSparseDelegateProperty : UMulticastDelegateProperty { }
public class UInterfaceProperty : UProperty
{
// UFunction*
[DisplayIndexOrder(6)]
public FPackageIndex InterfaceClass;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
InterfaceClass = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(InterfaceClass.Index);
}
}
public class UMapProperty : UProperty
{
[DisplayIndexOrder(6)]
public FPackageIndex KeyProp;
[DisplayIndexOrder(7)]
public FPackageIndex ValueProp;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
KeyProp = new FPackageIndex(reader.ReadInt32());
ValueProp = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(KeyProp.Index);
writer.Write(ValueProp.Index);
}
}
public class UBoolProperty : UProperty
{
[DisplayIndexOrder(6)]
public bool NativeBool;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
ElementSize = reader.ReadByte();
NativeBool = reader.ReadBoolean();
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write((byte)ElementSize);
writer.Write(NativeBool);
}
}
public class UByteProperty : UProperty
{
/// A pointer to the UEnum represented by this property
[DisplayIndexOrder(6)]
public FPackageIndex Enum;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
Enum = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(Enum.Index);
}
}
public class UStructProperty : UProperty
{
// UScriptStruct*
[DisplayIndexOrder(6)]
public FPackageIndex Struct;
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
Struct = new FPackageIndex(reader.ReadInt32());
}
public override void Write(AssetBinaryWriter writer)
{
base.Write(writer);
writer.Write(Struct.Index);
}
}
public class UNameProperty : UProperty { }
public class UStrProperty : UProperty { }
public class UTextProperty : UProperty { }
public class UNumericProperty : UProperty { }
public class UDoubleProperty : UNumericProperty { }
public class UFloatProperty : UNumericProperty { }
public class UIntProperty : UNumericProperty { }
public class UInt8Property : UNumericProperty { }
public class UInt16Property : UNumericProperty { }
public class UInt64Property : UNumericProperty { }
public class UUInt16Property : UNumericProperty { }
public class UUInt32Property : UNumericProperty { }
public class UUInt64Property : UNumericProperty { }
///
/// This is a UAssetAPI-specific property that represents anything that we don't have special serialization for
///
public class UGenericProperty : UProperty { }
================================================
FILE: UAssetAPI/Import.cs
================================================
using UAssetAPI.UnrealTypes;
namespace UAssetAPI
{
///
/// UObject resource type for objects that are referenced by this package, but contained within another package.
///
public class Import
{
///The name of the UObject represented by this resource.
public FName ObjectName;
///Location of the resource for this resource's Outer (import/other export). 0 = this resource is a top-level UPackage
public FPackageIndex OuterIndex;
public FName ClassPackage;
public FName ClassName;
///
/// Package Name this import belongs to. Can be none, in that case follow the outer chain
/// until a set PackageName is found or until OuterIndex is null
///
public FName PackageName;
public bool bImportOptional;
public Import(string classPackage, string className, FPackageIndex outerIndex, string objectName, bool importOptional, UAsset asset)
{
ObjectName = new FName(asset, objectName);
OuterIndex = outerIndex;
ClassPackage = new FName(asset, classPackage);
ClassName = new FName(asset, className);
bImportOptional = importOptional;
}
public Import(FName classPackage, FName className, FPackageIndex outerIndex, FName objectName, bool importOptional)
{
ObjectName = objectName;
OuterIndex = outerIndex;
ClassPackage = classPackage;
ClassName = className;
bImportOptional = importOptional;
}
public Import(AssetBinaryReader reader)
{
ClassPackage = reader.ReadFName();
ClassName = reader.ReadFName();
OuterIndex = new FPackageIndex(reader.ReadInt32());
ObjectName = reader.ReadFName();
if (reader.Asset.ObjectVersion >= ObjectVersion.VER_UE4_NON_OUTER_PACKAGE_IMPORT
&& !reader.Asset.IsFilterEditorOnly)
PackageName = reader.ReadFName();
if (reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.OPTIONAL_RESOURCES) bImportOptional = reader.ReadInt32() == 1;
}
public Import()
{
}
}
}
================================================
FILE: UAssetAPI/JSON/ByteArrayJsonConverter.cs
================================================
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace UAssetAPI.JSON
{
public class ByteArrayJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(byte[]);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(Convert.ToBase64String((byte[])value));
}
public override bool CanRead
{
get { return true; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
string val = reader.Value as string;
// backwards compatibility for fun
if (reader.TokenType == JsonToken.StartObject)
{
reader.Read();
while (reader.TokenType != JsonToken.EndObject)
{
if (reader.TokenType != JsonToken.PropertyName) throw new FormatException("Expected PropertyName, got " + reader.TokenType);
string propertyName = reader.Value.ToString();
reader.Read();
object propertyValue = reader.Value;
reader.Read();
if (propertyName == "$value")
{
val = propertyValue as string;
}
}
}
if (val == null) return null;
return Convert.FromBase64String(val);
}
}
}
================================================
FILE: UAssetAPI/JSON/FNameJsonConverter.cs
================================================
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.JSON
{
public class FNameJsonConverter : JsonConverter
{
public Dictionary ToBeFilled;
public int currentI = 0;
public override bool CanConvert(Type objectType)
{
return objectType == typeof(FName);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var realVal = (FName)value;
writer.WriteValue(realVal.DummyValue == null ? (realVal is null ? "null" : realVal.ToString()) : realVal.DummyValue.ToString());
}
public override bool CanRead
{
get { return true; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null) return null;
var res = FName.DefineDummy(null, "temp", ++currentI);
ToBeFilled[res] = Convert.ToString(reader.Value);
return res;
}
public FNameJsonConverter(Dictionary dict) : base()
{
ToBeFilled = dict;
}
}
}
================================================
FILE: UAssetAPI/JSON/FPackageIndexJsonConverter.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.JSON
{
public class FPackageIndexJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(FPackageIndex);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue((value as FPackageIndex).Index);
}
public override bool CanRead
{
get { return true; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return new FPackageIndex(Convert.ToInt32(reader.Value));
}
}
}
================================================
FILE: UAssetAPI/JSON/FSignedZeroJsonConverter.cs
================================================
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.JSON
{
public class FSignedZeroJsonConverter : JsonConverter
{
private static readonly decimal negativeZero = decimal.Negate(decimal.Zero);
private static bool IsNegativeZero(double x)
{
return x == 0.0 && double.IsNegativeInfinity(1.0 / x);
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(decimal) || objectType == typeof(float) || objectType == typeof(double);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
double us = Convert.ToDouble(value);
if (us == 0)
{
writer.WriteValue(IsNegativeZero(us) ? "-0" : "+0");
}
else
{
writer.WriteValue(us);
}
}
public override bool CanRead
{
get { return true; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value is null) return 0;
if (reader.Value is string)
{
if (reader.Value == null || reader.Value.Equals("+0")) return Convert.ChangeType(0.0, objectType);
if (reader.Value.Equals("-0")) return Convert.ChangeType(negativeZero, objectType);
}
object res = Convert.ChangeType(reader.Value, objectType);
if (res is null) return 0;
return res;
}
}
}
================================================
FILE: UAssetAPI/JSON/FStringJsonConverter.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.JSON
{
public class FStringJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(FString);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue((value as FString)?.Value);
}
public override bool CanRead
{
get { return true; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value == null) return null;
return new FString(Convert.ToString(reader.Value));
}
}
}
================================================
FILE: UAssetAPI/JSON/FStringTableJsonConverter.cs
================================================
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Specialized;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.JSON
{
public class FStringTableJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(FStringTable);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var realVal = (FStringTable)value;
ICollection keys = ((IOrderedDictionary)value).Keys;
ICollection values = ((IOrderedDictionary)value).Values;
IEnumerator valueEnumerator = values.GetEnumerator();
writer.WriteStartObject();
writer.WritePropertyName("TableNamespace");
writer.WriteValue(realVal.TableNamespace?.Value);
writer.WritePropertyName("Value");
writer.WriteStartArray();
foreach (object key in keys)
{
valueEnumerator.MoveNext();
writer.WriteStartArray();
serializer.Serialize(writer, key);
serializer.Serialize(writer, valueEnumerator.Current);
writer.WriteEndArray();
}
writer.WriteEndArray();
writer.WriteEndObject();
}
public override bool CanRead
{
get { return true; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var dictionary = new FStringTable();
JObject tableJson = JObject.Load(reader);
dictionary.TableNamespace = new FString(tableJson["TableNamespace"].ToObject());
JArray tokens = (JArray)tableJson["Value"];
foreach (var eachToken in tokens)
{
FString key = eachToken[0].ToObject(serializer);
FString value = eachToken[1].ToObject(serializer);
dictionary.Add(key, value);
}
return dictionary;
}
}
}
================================================
FILE: UAssetAPI/JSON/GuidJsonConverter.cs
================================================
using Newtonsoft.Json;
using System;
namespace UAssetAPI.JSON
{
public class GuidJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Guid);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(((Guid) value).ConvertToString());
}
public override bool CanRead
{
get { return true; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return Convert.ToString(reader.Value).ConvertToGUID();
}
}
}
================================================
FILE: UAssetAPI/JSON/TMapJsonConverter.cs
================================================
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Specialized;
/*
The code in this file is modified from mattmc3's dotmore @ https://github.com/mattmc3/dotmore/tree/b032bbf871d46bffd698c9b7a233c533d9d2f0ebs for usage in UAssetAPI.
The MIT License (MIT)
Copyright (c) 2014 mattmc3
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.JSON
{
public class TMapJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(IOrderedDictionary).IsAssignableFrom(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
ICollection keys = ((IOrderedDictionary)value).Keys;
ICollection values = ((IOrderedDictionary)value).Values;
IEnumerator valueEnumerator = values.GetEnumerator();
writer.WriteStartArray();
foreach (object key in keys)
{
valueEnumerator.MoveNext();
writer.WriteStartArray();
serializer.Serialize(writer, key);
serializer.Serialize(writer, valueEnumerator.Current);
writer.WriteEndArray();
}
writer.WriteEndArray();
}
public override bool CanRead
{
get { return true; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var dictionary = new TMap();
JToken tokens = JToken.Load(reader);
foreach (var eachToken in tokens)
{
TKey key = eachToken[0].ToObject(serializer);
TValue value = eachToken[1].ToObject(serializer);
dictionary.Add(key, value);
}
return dictionary;
}
}
}
================================================
FILE: UAssetAPI/JSON/UAssetContractResolver.cs
================================================
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.JSON
{
public class UAssetContractResolver : DefaultContractResolver
{
public Dictionary ToBeFilled;
protected override JsonConverter ResolveContractConverter(Type objectType)
{
if (typeof(FName).IsAssignableFrom(objectType))
{
return new FNameJsonConverter(ToBeFilled);
}
return base.ResolveContractConverter(objectType);
}
public UAssetContractResolver(Dictionary toBeFilled) : base()
{
ToBeFilled = toBeFilled;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/EBlueprintTextLiteralType.cs
================================================
namespace UAssetAPI.Kismet.Bytecode
{
///
/// Kinds of text literals
///
public enum EBlueprintTextLiteralType : byte
{
///
/// Text is an empty string. The bytecode contains no strings, and you should use FText::GetEmpty() to initialize the FText instance.
///
Empty,
///
/// Text is localized. The bytecode will contain three strings - source, key, and namespace - and should be loaded via FInternationalization
///
LocalizedText,
///
/// Text is culture invariant. The bytecode will contain one string, and you should use FText::AsCultureInvariant to initialize the FText instance.
///
InvariantText,
///
/// Text is a literal FString. The bytecode will contain one string, and you should use FText::FromString to initialize the FText instance.
///
LiteralString,
///
/// Text is from a string table. The bytecode will contain an object pointer (not used) and two strings - the table ID, and key - and should be found via FText::FromStringTable
///
StringTableEntry
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/EExprToken.cs
================================================
namespace UAssetAPI.Kismet.Bytecode
{
///
/// Evaluatable expression item types.
///
public enum EExprToken
{
/// A local variable.
EX_LocalVariable = 0x00,
/// An object variable.
EX_InstanceVariable = 0x01,
/// Default variable for a class context.
EX_DefaultVariable = 0x02,
/// Return from function.
EX_Return = 0x04,
/// Goto a local address in code.
EX_Jump = 0x06,
/// Goto if not expression.
EX_JumpIfNot = 0x07,
/// Assertion.
EX_Assert = 0x09,
/// No operation.
EX_Nothing = 0x0B,
/// No operation with an int32 argument (useful for debugging script disassembly).
EX_NothingInt32 = 0x0C,
/// Assign an arbitrary size value to a variable.
EX_Let = 0x0F,
/// Assign to a single bit, defined by an FProperty.
EX_BitFieldConst = 0x11,
/// Class default object context.
EX_ClassContext = 0x12,
/// Metaclass cast.
EX_MetaCast = 0x13,
/// Let boolean variable.
EX_LetBool = 0x14,
/// end of default value for optional function parameter
EX_EndParmValue = 0x15,
/// End of function call parameters.
EX_EndFunctionParms = 0x16,
/// Self object.
EX_Self = 0x17,
/// Skippable expression.
EX_Skip = 0x18,
/// Call a function through an object context.
EX_Context = 0x19,
/// Call a function through an object context (can fail silently if the context is NULL; only generated for functions that don't have output or return values).
EX_Context_FailSilent = 0x1A,
/// A function call with parameters.
EX_VirtualFunction = 0x1B,
/// A prebound function call with parameters.
EX_FinalFunction = 0x1C,
/// Int constant.
EX_IntConst = 0x1D,
/// Floating point constant.
EX_FloatConst = 0x1E,
/// String constant.
EX_StringConst = 0x1F,
/// An object constant.
EX_ObjectConst = 0x20,
/// A name constant.
EX_NameConst = 0x21,
/// A rotation constant.
EX_RotationConst = 0x22,
/// A vector constant.
EX_VectorConst = 0x23,
/// A byte constant.
EX_ByteConst = 0x24,
/// Zero.
EX_IntZero = 0x25,
/// One.
EX_IntOne = 0x26,
/// Bool True.
EX_True = 0x27,
/// Bool False.
EX_False = 0x28,
/// FText constant
EX_TextConst = 0x29,
/// NoObject.
EX_NoObject = 0x2A,
/// A transform constant
EX_TransformConst = 0x2B,
/// Int constant that requires 1 byte.
EX_IntConstByte = 0x2C,
/// A null interface (similar to EX_NoObject, but for interfaces)
EX_NoInterface = 0x2D,
/// Safe dynamic class casting.
EX_DynamicCast = 0x2E,
/// An arbitrary UStruct constant
EX_StructConst = 0x2F,
/// End of UStruct constant
EX_EndStructConst = 0x30,
/// Set the value of arbitrary array
EX_SetArray = 0x31,
EX_EndArray = 0x32,
/// FProperty constant.
EX_PropertyConst = 0x33,
/// Unicode string constant.
EX_UnicodeStringConst = 0x34,
/// 64-bit integer constant.
EX_Int64Const = 0x35,
/// 64-bit unsigned integer constant.
EX_UInt64Const = 0x36,
/// Double-precision floating point constant.
EX_DoubleConst = 0x37,
/// A casting operator for primitives which reads the type as the subsequent byte
EX_PrimitiveCast = 0x38,
EX_SetSet = 0x39,
EX_EndSet = 0x3A,
EX_SetMap = 0x3B,
EX_EndMap = 0x3C,
EX_SetConst = 0x3D,
EX_EndSetConst = 0x3E,
EX_MapConst = 0x3F,
EX_EndMapConst = 0x40,
/// A float vector constant.
EX_Vector3fConst = 0x41,
/// Context expression to address a property within a struct
EX_StructMemberContext = 0x42,
/// Assignment to a multi-cast delegate
EX_LetMulticastDelegate = 0x43,
/// Assignment to a delegate
EX_LetDelegate = 0x44,
/// Special instructions to quickly call a virtual function that we know is going to run only locally
EX_LocalVirtualFunction = 0x45,
/// Special instructions to quickly call a final function that we know is going to run only locally
EX_LocalFinalFunction = 0x46,
/// local out (pass by reference) function parameter
EX_LocalOutVariable = 0x48,
EX_DeprecatedOp4A = 0x4A,
/// const reference to a delegate or normal function object
EX_InstanceDelegate = 0x4B,
/// push an address on to the execution flow stack for future execution when a EX_PopExecutionFlow is executed. Execution continues on normally and doesn't change to the pushed address.
EX_PushExecutionFlow = 0x4C,
/// continue execution at the last address previously pushed onto the execution flow stack.
EX_PopExecutionFlow = 0x4D,
/// Goto a local address in code, specified by an integer value.
EX_ComputedJump = 0x4E,
/// continue execution at the last address previously pushed onto the execution flow stack, if the condition is not true.
EX_PopExecutionFlowIfNot = 0x4F,
/// Breakpoint. Only observed in the editor, otherwise it behaves like EX_Nothing.
EX_Breakpoint = 0x50,
/// Call a function through a native interface variable
EX_InterfaceContext = 0x51,
/// Converting an object reference to native interface variable
EX_ObjToInterfaceCast = 0x52,
/// Last byte in script code
EX_EndOfScript = 0x53,
/// Converting an interface variable reference to native interface variable
EX_CrossInterfaceCast = 0x54,
/// Converting an interface variable reference to an object
EX_InterfaceToObjCast = 0x55,
/// Trace point. Only observed in the editor, otherwise it behaves like EX_Nothing.
EX_WireTracepoint = 0x5A,
/// A CodeSizeSkipOffset constant
EX_SkipOffsetConst = 0x5B,
/// Adds a delegate to a multicast delegate's targets
EX_AddMulticastDelegate = 0x5C,
/// Clears all delegates in a multicast target
EX_ClearMulticastDelegate = 0x5D,
/// Trace point. Only observed in the editor, otherwise it behaves like EX_Nothing.
EX_Tracepoint = 0x5E,
/// assign to any object ref pointer
EX_LetObj = 0x5F,
/// assign to a weak object pointer
EX_LetWeakObjPtr = 0x60,
/// bind object and name to delegate
EX_BindDelegate = 0x61,
/// Remove a delegate from a multicast delegate's targets
EX_RemoveMulticastDelegate = 0x62,
/// Call multicast delegate
EX_CallMulticastDelegate = 0x63,
EX_LetValueOnPersistentFrame = 0x64,
EX_ArrayConst = 0x65,
EX_EndArrayConst = 0x66,
EX_SoftObjectConst = 0x67,
/// static pure function from on local call space
EX_CallMath = 0x68,
EX_SwitchValue = 0x69,
/// Instrumentation event
EX_InstrumentationEvent = 0x6A,
EX_ArrayGetByRef = 0x6B,
/// Sparse data variable
EX_ClassSparseDataVariable = 0x6C,
EX_FieldPathConst = 0x6D,
///
/// AutoRTFM: run following code in a transaction
///
EX_AutoRtfmTransact = 0x70,
///
/// AutoRTFM: if in a transaction, abort or break, otherwise no operation
///
EX_AutoRtfmStopTransact = 0x71,
///
/// AutoRTFM: evaluate bool condition, abort transaction on false
///
EX_AutoRtfmAbortIfNot = 0x72,
EX_Max = 0xFF
};
public enum ECastToken {
ObjectToInterface = 0x46,
ObjectToBool = 0x47,
InterfaceToBool = 0x49,
Max = 0xFF,
};
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/EScriptInstrumentationType.cs
================================================
namespace UAssetAPI.Kismet.Bytecode
{
public enum EScriptInstrumentationType : byte {
Class = 0,
ClassScope,
Instance,
Event,
InlineEvent,
ResumeEvent,
PureNodeEntry,
NodeDebugSite,
NodeEntry,
NodeExit,
PushState,
RestoreState,
ResetState,
SuspendState,
PopState,
TunnelEndOfThread,
Stop
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/ExpressionSerializer.cs
================================================
using System;
using UAssetAPI.Kismet.Bytecode.Expressions;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode
{
public static class ExpressionSerializer
{
public static KismetExpression ReadExpression(AssetBinaryReader reader)
{
KismetExpression res = null;
EExprToken token = (EExprToken)reader.ReadByte();
switch (token)
{
case EExprToken.EX_LocalVariable:
res = new EX_LocalVariable();
break;
case EExprToken.EX_InstanceVariable:
res = new EX_InstanceVariable();
break;
case EExprToken.EX_DefaultVariable:
res = new EX_DefaultVariable();
break;
case EExprToken.EX_Return:
res = new EX_Return();
break;
case EExprToken.EX_Jump:
res = new EX_Jump();
break;
case EExprToken.EX_JumpIfNot:
res = new EX_JumpIfNot();
break;
case EExprToken.EX_Assert:
res = new EX_Assert();
break;
case EExprToken.EX_Nothing:
res = new EX_Nothing();
break;
case EExprToken.EX_NothingInt32:
res = new EX_NothingInt32();
break;
case EExprToken.EX_Let:
res = new EX_Let();
break;
case EExprToken.EX_BitFieldConst:
res = new EX_BitFieldConst();
break;
case EExprToken.EX_ClassContext:
res = new EX_ClassContext();
break;
case EExprToken.EX_MetaCast:
res = new EX_MetaCast();
break;
case EExprToken.EX_LetBool:
res = new EX_LetBool();
break;
case EExprToken.EX_EndParmValue:
res = new EX_EndParmValue();
break;
case EExprToken.EX_EndFunctionParms:
res = new EX_EndFunctionParms();
break;
case EExprToken.EX_Self:
res = new EX_Self();
break;
case EExprToken.EX_Skip:
res = new EX_Skip();
break;
case EExprToken.EX_Context:
res = new EX_Context();
break;
case EExprToken.EX_Context_FailSilent:
res = new EX_Context_FailSilent();
break;
case EExprToken.EX_VirtualFunction:
res = new EX_VirtualFunction();
break;
case EExprToken.EX_FinalFunction:
res = new EX_FinalFunction();
break;
case EExprToken.EX_IntConst:
res = new EX_IntConst();
break;
case EExprToken.EX_FloatConst:
res = new EX_FloatConst();
break;
case EExprToken.EX_DoubleConst:
res = new EX_DoubleConst();
break;
case EExprToken.EX_StringConst:
res = new EX_StringConst();
break;
case EExprToken.EX_ObjectConst:
res = new EX_ObjectConst();
break;
case EExprToken.EX_NameConst:
res = new EX_NameConst();
break;
case EExprToken.EX_RotationConst:
res = new EX_RotationConst();
break;
case EExprToken.EX_VectorConst:
res = new EX_VectorConst();
break;
case EExprToken.EX_ByteConst:
res = new EX_ByteConst();
break;
case EExprToken.EX_IntZero:
res = new EX_IntZero();
break;
case EExprToken.EX_IntOne:
res = new EX_IntOne();
break;
case EExprToken.EX_True:
res = new EX_True();
break;
case EExprToken.EX_False:
res = new EX_False();
break;
case EExprToken.EX_TextConst:
res = new EX_TextConst();
break;
case EExprToken.EX_NoObject:
res = new EX_NoObject();
break;
case EExprToken.EX_TransformConst:
res = new EX_TransformConst();
break;
case EExprToken.EX_IntConstByte:
res = new EX_IntConstByte();
break;
case EExprToken.EX_NoInterface:
res = new EX_NoInterface();
break;
case EExprToken.EX_DynamicCast:
res = new EX_DynamicCast();
break;
case EExprToken.EX_StructConst:
res = new EX_StructConst();
break;
case EExprToken.EX_EndStructConst:
res = new EX_EndStructConst();
break;
case EExprToken.EX_SetArray:
res = new EX_SetArray();
break;
case EExprToken.EX_EndArray:
res = new EX_EndArray();
break;
case EExprToken.EX_PropertyConst:
res = new EX_PropertyConst();
break;
case EExprToken.EX_UnicodeStringConst:
res = new EX_UnicodeStringConst();
break;
case EExprToken.EX_Int64Const:
res = new EX_Int64Const();
break;
case EExprToken.EX_UInt64Const:
res = new EX_UInt64Const();
break;
case EExprToken.EX_PrimitiveCast:
res = new EX_PrimitiveCast();
break;
case EExprToken.EX_SetSet:
res = new EX_SetSet();
break;
case EExprToken.EX_EndSet:
res = new EX_EndSet();
break;
case EExprToken.EX_SetMap:
res = new EX_SetMap();
break;
case EExprToken.EX_EndMap:
res = new EX_EndMap();
break;
case EExprToken.EX_SetConst:
res = new EX_SetConst();
break;
case EExprToken.EX_EndSetConst:
res = new EX_EndSetConst();
break;
case EExprToken.EX_MapConst:
res = new EX_MapConst();
break;
case EExprToken.EX_EndMapConst:
res = new EX_EndMapConst();
break;
case EExprToken.EX_Vector3fConst:
res = new EX_Vector3fConst();
break;
case EExprToken.EX_StructMemberContext:
res = new EX_StructMemberContext();
break;
case EExprToken.EX_LetMulticastDelegate:
res = new EX_LetMulticastDelegate();
break;
case EExprToken.EX_LetDelegate:
res = new EX_LetDelegate();
break;
case EExprToken.EX_LocalVirtualFunction:
res = new EX_LocalVirtualFunction();
break;
case EExprToken.EX_LocalFinalFunction:
res = new EX_LocalFinalFunction();
break;
case EExprToken.EX_LocalOutVariable:
res = new EX_LocalOutVariable();
break;
case EExprToken.EX_DeprecatedOp4A:
res = new EX_DeprecatedOp4A();
break;
case EExprToken.EX_InstanceDelegate:
res = new EX_InstanceDelegate();
break;
case EExprToken.EX_PushExecutionFlow:
res = new EX_PushExecutionFlow();
break;
case EExprToken.EX_PopExecutionFlow:
res = new EX_PopExecutionFlow();
break;
case EExprToken.EX_ComputedJump:
res = new EX_ComputedJump();
break;
case EExprToken.EX_PopExecutionFlowIfNot:
res = new EX_PopExecutionFlowIfNot();
break;
case EExprToken.EX_Breakpoint:
res = new EX_Breakpoint();
break;
case EExprToken.EX_InterfaceContext:
res = new EX_InterfaceContext();
break;
case EExprToken.EX_ObjToInterfaceCast:
res = new EX_ObjToInterfaceCast();
break;
case EExprToken.EX_EndOfScript:
res = new EX_EndOfScript();
break;
case EExprToken.EX_CrossInterfaceCast:
res = new EX_CrossInterfaceCast();
break;
case EExprToken.EX_InterfaceToObjCast:
res = new EX_InterfaceToObjCast();
break;
case EExprToken.EX_WireTracepoint:
res = new EX_WireTracepoint();
break;
case EExprToken.EX_SkipOffsetConst:
res = new EX_SkipOffsetConst();
break;
case EExprToken.EX_AddMulticastDelegate:
res = new EX_AddMulticastDelegate();
break;
case EExprToken.EX_ClearMulticastDelegate:
res = new EX_ClearMulticastDelegate();
break;
case EExprToken.EX_Tracepoint:
res = new EX_Tracepoint();
break;
case EExprToken.EX_LetObj:
res = new EX_LetObj();
break;
case EExprToken.EX_LetWeakObjPtr:
res = new EX_LetWeakObjPtr();
break;
case EExprToken.EX_BindDelegate:
res = new EX_BindDelegate();
break;
case EExprToken.EX_RemoveMulticastDelegate:
res = new EX_RemoveMulticastDelegate();
break;
case EExprToken.EX_CallMulticastDelegate:
res = new EX_CallMulticastDelegate();
break;
case EExprToken.EX_LetValueOnPersistentFrame:
res = new EX_LetValueOnPersistentFrame();
break;
case EExprToken.EX_ArrayConst:
res = new EX_ArrayConst();
break;
case EExprToken.EX_EndArrayConst:
res = new EX_EndArrayConst();
break;
case EExprToken.EX_SoftObjectConst:
res = new EX_SoftObjectConst();
break;
case EExprToken.EX_CallMath:
res = new EX_CallMath();
break;
case EExprToken.EX_SwitchValue:
res = new EX_SwitchValue();
break;
case EExprToken.EX_InstrumentationEvent:
res = new EX_InstrumentationEvent();
break;
case EExprToken.EX_ArrayGetByRef:
res = new EX_ArrayGetByRef();
break;
case EExprToken.EX_ClassSparseDataVariable:
res = new EX_ClassSparseDataVariable();
break;
case EExprToken.EX_FieldPathConst:
res = new EX_FieldPathConst();
break;
default:
throw new NotImplementedException("Unimplemented token " + token);
}
if (res != null)
{
res.Read(reader);
}
return res;
}
public static int WriteExpression(KismetExpression expr, AssetBinaryWriter writer)
{
writer.Write((byte)expr.Token);
return expr.Write(writer) + sizeof(byte);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_AddMulticastDelegate.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_AddMulticastDelegate : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_AddMulticastDelegate; } }
///
/// Delegate property to assign to.
///
[JsonProperty]
public KismetExpression Delegate;
///
/// Delegate to add to the MC delegate for broadcast.
///
[JsonProperty]
public KismetExpression DelegateToAdd;
public EX_AddMulticastDelegate()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Delegate = ExpressionSerializer.ReadExpression(reader);
DelegateToAdd = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += ExpressionSerializer.WriteExpression(Delegate, writer);
offset += ExpressionSerializer.WriteExpression(DelegateToAdd, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
Delegate.Visit(asset, ref offset, visitor);
DelegateToAdd.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_ArrayConst.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_ArrayConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_ArrayConst; } }
///
/// Pointer to this constant's inner property (FProperty*).
///
[JsonProperty]
public KismetPropertyPointer InnerProperty;
///
/// Array constant entries.
///
[JsonProperty]
public KismetExpression[] Elements;
public EX_ArrayConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
InnerProperty = reader.XFER_PROP_POINTER();
int numEntries = reader.ReadInt32(); // Number of elements
Elements = reader.ReadExpressionArray(EExprToken.EX_EndArrayConst);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += writer.XFER_PROP_POINTER(InnerProperty);
writer.Write(Elements.Length); offset += sizeof(int);
for (int i = 0; i < Elements.Length; i++)
{
offset += ExpressionSerializer.WriteExpression(Elements[i], writer);
}
offset += ExpressionSerializer.WriteExpression(new EX_EndArrayConst(), writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 12; // InnerProperty (8) + NumElements (4)
foreach (var element in Elements)
{
element.Visit(asset, ref offset, visitor);
}
offset += 1; // EX_EndArrayConst
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_ArrayGetByRef.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_ArrayGetByRef : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_ArrayGetByRef; } }
///
/// The array variable.
///
[JsonProperty]
public KismetExpression ArrayVariable;
///
/// The index to access in the array.
///
[JsonProperty]
public KismetExpression ArrayIndex;
public EX_ArrayGetByRef()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
ArrayVariable = ExpressionSerializer.ReadExpression(reader);
ArrayIndex = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += ExpressionSerializer.WriteExpression(ArrayVariable, writer);
offset += ExpressionSerializer.WriteExpression(ArrayIndex, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
ArrayVariable.Visit(asset, ref offset, visitor);
ArrayIndex.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Assert.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_Assert : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Assert; } }
///
/// Line number.
///
[JsonProperty]
public ushort LineNumber;
///
/// Whether or not this assertion is in debug mode.
///
[JsonProperty]
public bool DebugMode;
///
/// Expression to assert.
///
[JsonProperty]
public KismetExpression AssertExpression;
public EX_Assert()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
LineNumber = reader.ReadUInt16();
DebugMode = reader.ReadBoolean();
AssertExpression = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
writer.Write(LineNumber); offset += sizeof(ushort);
writer.Write(DebugMode); offset += sizeof(bool);
offset += ExpressionSerializer.WriteExpression(AssertExpression, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 3; // LineNumber (2) + DebugMode (1)
AssertExpression.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_BindDelegate.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_BindDelegate : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_BindDelegate; } }
///
/// The name of the function assigned to the delegate.
///
[JsonProperty]
public FName FunctionName;
///
/// Delegate property to assign to.
///
[JsonProperty]
public KismetExpression Delegate;
///
/// Object to bind.
///
[JsonProperty]
public KismetExpression ObjectTerm;
public EX_BindDelegate()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
FunctionName = reader.XFER_FUNC_NAME();
Delegate = ExpressionSerializer.ReadExpression(reader);
ObjectTerm = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += writer.XFER_FUNC_NAME(FunctionName);
offset += ExpressionSerializer.WriteExpression(Delegate, writer);
offset += ExpressionSerializer.WriteExpression(ObjectTerm, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 12; // FunctionName (12)
Delegate.Visit(asset, ref offset, visitor);
ObjectTerm.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_BitFieldConst.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
/// Assigns to a single bit, defined by an FProperty.
///
public class EX_BitFieldConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_BitFieldConst; } }
///
/// A pointer to the bit property.
///
[JsonProperty]
public KismetPropertyPointer Property;
///
/// The bit value.
///
[JsonProperty]
public byte Value;
public EX_BitFieldConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Property = reader.XFER_PROP_POINTER();
Value = reader.ReadByte();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = writer.XFER_PROP_POINTER(Property);
writer.Write(Value);
return offset + sizeof(byte);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 9; // Property (8) + Value (1)
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Breakpoint.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_Breakpoint : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Breakpoint; } }
public EX_Breakpoint()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_ByteConst.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_ByteConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_ByteConst; } }
public EX_ByteConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.ReadByte();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write(Value);
return sizeof(byte);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 1; // Value
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_CallMath.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_CallMath : EX_FinalFunction
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_CallMath; } }
public EX_CallMath() : base()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return base.Write(writer);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_CallMulticastDelegate.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_CallMulticastDelegate : EX_FinalFunction
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_CallMulticastDelegate; } }
///
/// Delegate property.
///
[JsonProperty]
public KismetExpression Delegate;
public EX_CallMulticastDelegate()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
StackNode = reader.XFER_FUNC_POINTER();
Delegate = ExpressionSerializer.ReadExpression(reader);
Parameters = reader.ReadExpressionArray(EExprToken.EX_EndFunctionParms);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += writer.XFER_FUNC_POINTER(StackNode);
offset += ExpressionSerializer.WriteExpression(Delegate, writer);
for (int i = 0; i < Parameters.Length; i++)
{
offset += ExpressionSerializer.WriteExpression(Parameters[i], writer);
}
offset += ExpressionSerializer.WriteExpression(new EX_EndFunctionParms(), writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
visitor(this, offset);
offset++;
offset += 8; // StackNode (8)
Delegate.Visit(asset, ref offset, visitor);
foreach (var param in Parameters)
{
param.Visit(asset, ref offset, visitor);
}
offset += 1; // EX_EndFunctionParms
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_CastBase.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// Base class for several type cast expressions
///
public abstract class EX_CastBase : KismetExpression
{
///
/// The interface class to convert to.
///
[JsonProperty]
public FPackageIndex ClassPtr;
///
/// The target of this expression.
///
[JsonProperty]
public KismetExpression Target;
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
ClassPtr = reader.XFER_OBJECT_POINTER();
Target = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += writer.XFER_OBJECT_POINTER(ClassPtr);
offset += ExpressionSerializer.WriteExpression(Target, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 8; // ClassPtr (8)
Target.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_ClassContext.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_ClassContext : EX_Context
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_ClassContext; } }
public EX_ClassContext()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return base.Write(writer);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_ClassSparseDataVariable.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_ClassSparseDataVariable : EX_VariableBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_ClassSparseDataVariable; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_ClearMulticastDelegate.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_ClearMulticastDelegate : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_ClearMulticastDelegate; } }
///
/// Delegate property to clear.
///
[JsonProperty]
public KismetExpression DelegateToClear;
public EX_ClearMulticastDelegate()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
DelegateToClear = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return ExpressionSerializer.WriteExpression(DelegateToClear, writer);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
DelegateToClear.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_ComputedJump.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_ComputedJump : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_ComputedJump; } }
///
/// An integer expression corresponding to the offset to jump to.
///
[JsonProperty]
public KismetExpression CodeOffsetExpression;
public EX_ComputedJump()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
CodeOffsetExpression = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return ExpressionSerializer.WriteExpression(CodeOffsetExpression, writer);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
CodeOffsetExpression.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Context.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_Context : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Context; } }
///
/// Object expression.
///
[JsonProperty]
public KismetExpression ObjectExpression;
///
/// Code offset for NULL expressions.
///
[JsonProperty]
public uint Offset;
///
/// Old property type.
///
[JsonProperty]
public byte PropertyType;
///
/// Property corresponding to the r-value data, in case the l-value needs to be mem-zero'd. FField*
///
[JsonProperty]
public KismetPropertyPointer RValuePointer;
///
/// Context expression.
///
[JsonProperty]
public KismetExpression ContextExpression;
public EX_Context()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
ObjectExpression = ExpressionSerializer.ReadExpression(reader);
Offset = reader.ReadUInt32();
RValuePointer = reader.XFER_PROP_POINTER();
if (reader.Asset.ObjectVersion <= ObjectVersion.VER_UE4_SERIALIZE_BLUEPRINT_EVENTGRAPH_FASTCALLS_IN_UFUNCTION)
{
PropertyType = reader.ReadByte();
}
ContextExpression = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += ExpressionSerializer.WriteExpression(ObjectExpression, writer);
writer.Write(Offset); offset += sizeof(uint);
offset += writer.XFER_PROP_POINTER(RValuePointer);
if (writer.Asset.ObjectVersion <= ObjectVersion.VER_UE4_SERIALIZE_BLUEPRINT_EVENTGRAPH_FASTCALLS_IN_UFUNCTION)
{
writer.Write(PropertyType);
offset += sizeof(byte);
}
offset += ExpressionSerializer.WriteExpression(ContextExpression, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
ObjectExpression.Visit(asset, ref offset, visitor);
offset += 12; // Offset (4) + RValuePointer (8)
ContextExpression.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Context_FailSilent.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_Context_FailSilent : EX_Context
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Context_FailSilent; } }
public EX_Context_FailSilent()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return base.Write(writer);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_CrossInterfaceCast.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_CrossInterfaceCast : EX_CastBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_CrossInterfaceCast; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_DefaultVariable.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_DefaultVariable : EX_VariableBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_DefaultVariable; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_DeprecatedOp4A.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_DeprecatedOp4A : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_DeprecatedOp4A; } }
public EX_DeprecatedOp4A()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_DoubleConst.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.JSON;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_DoubleConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_DoubleConst; } }
///
/// The value of this double constant expression.
///
[JsonProperty]
[JsonConverter(typeof(FSignedZeroJsonConverter))]
public double Value;
public EX_DoubleConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.ReadDouble();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write(Value);
return sizeof(double);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 8; // Value
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_DynamicCast.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_DynamicCast : EX_CastBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_DynamicCast; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_EndArray.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_EndArray : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_EndArray; } }
public EX_EndArray()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_EndArrayConst.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_EndArrayConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_EndArrayConst; } }
public EX_EndArrayConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_EndFunctionParms.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_EndFunctionParms : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_EndFunctionParms; } }
public EX_EndFunctionParms()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_EndMap.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_EndMap : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_EndMap; } }
public EX_EndMap()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_EndMapConst.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_EndMapConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_EndMapConst; } }
public EX_EndMapConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_EndOfScript.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_EndOfScript : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_EndOfScript; } }
public EX_EndOfScript()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_EndParmValue.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_EndParmValue : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_EndParmValue; } }
public EX_EndParmValue()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_EndSet.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_EndSet : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_EndSet; } }
public EX_EndSet()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_EndSetConst.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_EndSetConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_EndSetConst; } }
public EX_EndSetConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_EndStructConst.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_EndStructConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_EndStructConst; } }
public EX_EndStructConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_False.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_False : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_False; } }
public EX_False()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_FieldPathConst.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_FieldPathConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_FieldPathConst; } }
public EX_FieldPathConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return ExpressionSerializer.WriteExpression(Value, writer);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
Value.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_FinalFunction.cs
================================================
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_FinalFunction : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_FinalFunction; } }
///
/// Stack node.
///
[JsonProperty]
public FPackageIndex StackNode;
///
/// List of parameters for this function.
///
[JsonProperty]
public KismetExpression[] Parameters;
public EX_FinalFunction()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
StackNode = reader.XFER_FUNC_POINTER();
Parameters = reader.ReadExpressionArray(EExprToken.EX_EndFunctionParms);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += writer.XFER_FUNC_POINTER(StackNode);
for (int i = 0; i < Parameters.Length; i++)
{
offset += ExpressionSerializer.WriteExpression(Parameters[i], writer);
}
offset += ExpressionSerializer.WriteExpression(new EX_EndFunctionParms(), writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 8; // StackNode (8)
foreach (var param in Parameters)
{
param.Visit(asset, ref offset, visitor);
}
offset += 1; // EX_EndFunctionParms
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_FloatConst.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.JSON;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_FloatConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_FloatConst; } }
///
/// The value of this float constant expression.
///
[JsonProperty]
[JsonConverter(typeof(FSignedZeroJsonConverter))]
public float Value;
public EX_FloatConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.ReadSingle();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write(Value);
return sizeof(float);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 4; // Value
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_InstanceDelegate.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_InstanceDelegate : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_InstanceDelegate; } }
///
/// The name of the function assigned to the delegate.
///
[JsonProperty]
public FName FunctionName;
public EX_InstanceDelegate()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
FunctionName = reader.XFER_FUNC_NAME();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return writer.XFER_FUNC_NAME(FunctionName);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 12; // FunctionName (FName)
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_InstanceVariable.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_InstanceVariable : EX_VariableBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_InstanceVariable; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_InstrumentationEvent.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_InstrumentationEvent : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_InstrumentationEvent; } }
[JsonProperty]
public EScriptInstrumentationType EventType;
[JsonProperty]
public FName EventName;
public EX_InstrumentationEvent()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
EventType = (EScriptInstrumentationType)reader.ReadByte();
if (EventType.Equals(EScriptInstrumentationType.InlineEvent))
{
EventName = reader.XFER_FUNC_NAME();
}
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write((byte)EventType);
if (EventType.Equals(EScriptInstrumentationType.InlineEvent)) {
writer.XFER_FUNC_NAME(EventName);
return 1 + 2 * sizeof(int);
} else {
return 1;
}
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 1; // EventType
if (EventType.Equals(EScriptInstrumentationType.InlineEvent))
{
offset += 12; // EventName (FName)
}
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Int64Const.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_Int64Const : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Int64Const; } }
public EX_Int64Const()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.ReadInt64();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write(Value);
return sizeof(long);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 8; // Value
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_IntConst.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_IntConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_IntConst; } }
public EX_IntConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.ReadInt32();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write(Value);
return sizeof(int);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 4; // Value
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_IntConstByte.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_IntConstByte : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_IntConstByte; } }
public EX_IntConstByte()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.ReadByte();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write(Value);
return sizeof(byte);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_IntOne.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_IntOne : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_IntOne; } }
public EX_IntOne()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_IntZero.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_IntZero : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_IntZero; } }
public EX_IntZero()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_InterfaceContext.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_InterfaceContext : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_InterfaceContext; } }
///
/// Interface value.
///
[JsonProperty]
public KismetExpression InterfaceValue;
public EX_InterfaceContext()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
InterfaceValue = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return ExpressionSerializer.WriteExpression(InterfaceValue, writer);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
InterfaceValue.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_InterfaceToObjCast.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_InterfaceToObjCast : EX_CastBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_InterfaceToObjCast; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Jump.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_Jump : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Jump; } }
///
/// The offset to jump to.
///
[JsonProperty]
public uint CodeOffset;
public EX_Jump()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
CodeOffset = reader.ReadUInt32();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write(CodeOffset);
return sizeof(uint);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 4; // CodeOffset
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_JumpIfNot.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
/// Conditional equivalent of the expression.
///
public class EX_JumpIfNot : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_JumpIfNot; } }
///
/// The offset to jump to if the provided expression evaluates to false.
///
[JsonProperty]
public uint CodeOffset;
///
/// Expression to evaluate to determine whether or not a jump should be performed.
///
[JsonProperty]
public KismetExpression BooleanExpression;
public EX_JumpIfNot()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
CodeOffset = reader.ReadUInt32();
BooleanExpression = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
writer.Write(CodeOffset); offset += sizeof(uint);
offset += ExpressionSerializer.WriteExpression(BooleanExpression, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 4; // CodeOffset (4)
BooleanExpression.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Let.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_Let : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Let; } }
///
/// A pointer to the variable.
///
[JsonProperty]
public KismetPropertyPointer Value;
[JsonProperty]
public KismetExpression Variable;
[JsonProperty]
public KismetExpression Expression;
public EX_Let()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
if (reader.Asset.ObjectVersion > ObjectVersion.VER_UE4_SERIALIZE_BLUEPRINT_EVENTGRAPH_FASTCALLS_IN_UFUNCTION)
{
Value = reader.XFER_PROP_POINTER();
}
Variable = ExpressionSerializer.ReadExpression(reader);
Expression = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
if (writer.Asset.ObjectVersion > ObjectVersion.VER_UE4_SERIALIZE_BLUEPRINT_EVENTGRAPH_FASTCALLS_IN_UFUNCTION)
{
offset += writer.XFER_PROP_POINTER(Value);
}
offset += ExpressionSerializer.WriteExpression(Variable, writer);
offset += ExpressionSerializer.WriteExpression(Expression, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 8; // Value (8)
Variable.Visit(asset, ref offset, visitor);
Expression.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_LetBase.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// Base class for several Let (assignment) expressions
///
public abstract class EX_LetBase : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_LetDelegate; } }
///
/// Variable expression.
///
[JsonProperty]
public KismetExpression VariableExpression;
///
/// Assignment expression.
///
[JsonProperty]
public KismetExpression AssignmentExpression;
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
VariableExpression = ExpressionSerializer.ReadExpression(reader);
AssignmentExpression = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += ExpressionSerializer.WriteExpression(VariableExpression, writer);
offset += ExpressionSerializer.WriteExpression(AssignmentExpression, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
VariableExpression.Visit(asset, ref offset, visitor);
AssignmentExpression.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_LetBool.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_LetBool : EX_LetBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_LetBool; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_LetDelegate.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_LetDelegate : EX_LetBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_LetDelegate; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_LetMulticastDelegate.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_LetMulticastDelegate : EX_LetBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_LetMulticastDelegate; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_LetObj.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_LetObj : EX_LetBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_LetObj; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_LetValueOnPersistentFrame.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_LetValueOnPersistentFrame : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_LetValueOnPersistentFrame; } }
///
/// Destination property pointer.
///
[JsonProperty]
public KismetPropertyPointer DestinationProperty;
///
/// Assignment expression.
///
[JsonProperty]
public KismetExpression AssignmentExpression;
public EX_LetValueOnPersistentFrame()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
DestinationProperty = reader.XFER_PROP_POINTER();
AssignmentExpression = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += writer.XFER_PROP_POINTER(DestinationProperty);
offset += ExpressionSerializer.WriteExpression(AssignmentExpression, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 8; // DestinationProperty (8)
AssignmentExpression.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_LetWeakObjPtr.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_LetWeakObjPtr : EX_LetBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_LetWeakObjPtr; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_LocalFinalFunction.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_LocalFinalFunction : EX_FinalFunction
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_LocalFinalFunction; } }
public EX_LocalFinalFunction() : base()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return base.Write(writer);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_LocalOutVariable.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_LocalOutVariable : EX_VariableBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_LocalOutVariable; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_LocalVariable.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_LocalVariable : EX_VariableBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_LocalVariable; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_LocalVirtualFunction.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_LocalVirtualFunction : EX_VirtualFunction
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_LocalVirtualFunction; } }
public EX_LocalVirtualFunction() : base()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
base.Read(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return base.Write(writer);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_MapConst.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_MapConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_MapConst; } }
///
/// Pointer to this constant's key property (FProperty*).
///
[JsonProperty]
public KismetPropertyPointer KeyProperty;
///
/// Pointer to this constant's value property (FProperty*).
///
[JsonProperty]
public KismetPropertyPointer ValueProperty;
///
/// Set constant entries.
///
[JsonProperty]
public KismetExpression[] Elements;
public EX_MapConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
KeyProperty = reader.XFER_PROP_POINTER();
ValueProperty = reader.XFER_PROP_POINTER();
int numEntries = reader.ReadInt32(); // Number of elements
Elements = reader.ReadExpressionArray(EExprToken.EX_EndMapConst);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += writer.XFER_PROP_POINTER(KeyProperty);
offset += writer.XFER_PROP_POINTER(ValueProperty);
writer.Write(Elements.Length / 2); offset += sizeof(int);
for (int i = 0; i < Elements.Length; i++)
{
offset += ExpressionSerializer.WriteExpression(Elements[i], writer);
}
offset += ExpressionSerializer.WriteExpression(new EX_EndMapConst(), writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 20; // KeyProperty (8) + ValueProperty (8) + NumElements (4)
foreach (var element in Elements)
{
element.Visit(asset, ref offset, visitor);
}
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_MetaCast.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_MetaCast : EX_CastBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_MetaCast; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_NameConst.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_NameConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_NameConst; } }
public EX_NameConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.XFERNAME();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return writer.XFERNAME(Value);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 12; // FName (Index + Number + ?)
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_NoInterface.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_NoInterface : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_NoInterface; } }
public EX_NoInterface()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_NoObject.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_NoObject : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_NoObject; } }
public EX_NoObject()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Nothing.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
/// Represents a no-op.
///
public class EX_Nothing : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Nothing; } }
public EX_Nothing()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_NothingInt32.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
/// No operation with an int32 argument (useful for debugging script disassembly).
///
public class EX_NothingInt32 : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_NothingInt32; } }
public EX_NothingInt32()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.ReadInt32();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write(Value);
return sizeof(int);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 4; // Value
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_ObjToInterfaceCast.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
/// A conversion from an object or interface variable to a native interface variable.
///
public class EX_ObjToInterfaceCast : EX_CastBase
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_ObjToInterfaceCast; } }
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_ObjectConst.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_ObjectConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_ObjectConst; } }
public EX_ObjectConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.XFER_OBJECT_POINTER();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return writer.XFER_OBJECT_POINTER(Value);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 8; // Value (FPackageIndex)
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_PopExecutionFlow.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_PopExecutionFlow : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_PopExecutionFlow; } }
public EX_PopExecutionFlow()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_PopExecutionFlowIfNot.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
/// Conditional equivalent of the expression.
///
public class EX_PopExecutionFlowIfNot : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_PopExecutionFlowIfNot; } }
///
/// Expression to evaluate to determine whether or not a pop should be performed.
///
[JsonProperty]
public KismetExpression BooleanExpression;
public EX_PopExecutionFlowIfNot()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
BooleanExpression = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return ExpressionSerializer.WriteExpression(BooleanExpression, writer);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
BooleanExpression.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_PrimitiveCast.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_PrimitiveCast : KismetExpression
{
///
/// The type to cast to.
///
[JsonProperty]
public ECastToken ConversionType;
///
/// The target of this expression.
///
[JsonProperty]
public KismetExpression Target;
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_PrimitiveCast; } }
public EX_PrimitiveCast()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
ConversionType = (ECastToken)reader.ReadByte();
Target = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
writer.Write((byte)ConversionType); offset += sizeof(byte);
offset += ExpressionSerializer.WriteExpression(Target, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 1; // ConversionType (1)
if (ConversionType == ECastToken.ObjectToInterface)
{
offset += 8; // InterfaceClass
}
Target.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_PropertyConst.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_PropertyConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_PropertyConst; } }
///
/// A pointer to the property in question.
///
[JsonProperty]
public KismetPropertyPointer Property;
public EX_PropertyConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Property = reader.XFER_PROP_POINTER();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return writer.XFER_PROP_POINTER(Property);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 8; // Property (KismetPropertyPointer)
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_PushExecutionFlow.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_PushExecutionFlow : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_PushExecutionFlow; } }
///
/// The address to push onto the execution flow stack.
///
[JsonProperty]
public uint PushingAddress;
public EX_PushExecutionFlow()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
PushingAddress = reader.ReadUInt32();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write(PushingAddress);
return sizeof(uint);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 4; // PushingAddress
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_RemoveMulticastDelegate.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_RemoveMulticastDelegate : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_RemoveMulticastDelegate; } }
///
/// Delegate property to assign to.
///
[JsonProperty]
public KismetExpression Delegate;
///
/// Delegate to add to the MC delegate for broadcast.
///
[JsonProperty]
public KismetExpression DelegateToAdd;
public EX_RemoveMulticastDelegate()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Delegate = ExpressionSerializer.ReadExpression(reader);
DelegateToAdd = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += ExpressionSerializer.WriteExpression(Delegate, writer);
offset += ExpressionSerializer.WriteExpression(DelegateToAdd, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
Delegate.Visit(asset, ref offset, visitor);
DelegateToAdd.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Return.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_Return : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Return; } }
///
/// The return expression.
///
[JsonProperty]
public KismetExpression ReturnExpression;
public EX_Return()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
ReturnExpression = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return ExpressionSerializer.WriteExpression(ReturnExpression, writer);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
ReturnExpression.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_RotationConst.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_RotationConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_RotationConst; } }
[JsonProperty]
public FRotator Value;
public EX_RotationConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
if (reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.LARGE_WORLD_COORDINATES)
{
Value = new FRotator(reader.ReadDouble(), reader.ReadDouble(), reader.ReadDouble());
}
else
{
Value = new FRotator(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
if (writer.Asset.ObjectVersionUE5 >= ObjectVersionUE5.LARGE_WORLD_COORDINATES)
{
writer.Write(Value.Pitch);
writer.Write(Value.Yaw);
writer.Write(Value.Roll);
return sizeof(double) * 3;
}
else
{
writer.Write(Value.PitchFloat);
writer.Write(Value.YawFloat);
writer.Write(Value.RollFloat);
return sizeof(float) * 3;
}
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += asset.ObjectVersionUE5 >= ObjectVersionUE5.LARGE_WORLD_COORDINATES ? 24U : 12U;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Self.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_Self : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Self; } }
public EX_Self()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_SetArray.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_SetArray : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_SetArray; } }
///
/// Array property to assign to
///
[JsonProperty]
public KismetExpression AssigningProperty;
///
/// Pointer to the array inner property (FProperty*).
/// Only used in engine versions prior to .
///
[JsonProperty]
public FPackageIndex ArrayInnerProp;
///
/// Array items.
///
[JsonProperty]
public KismetExpression[] Elements;
public EX_SetArray()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
if (reader.Asset.ObjectVersion >= ObjectVersion.VER_UE4_CHANGE_SETARRAY_BYTECODE)
{
AssigningProperty = ExpressionSerializer.ReadExpression(reader);
}
else
{
ArrayInnerProp = reader.XFERPTR();
}
Elements = reader.ReadExpressionArray(EExprToken.EX_EndArray);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
if (writer.Asset.ObjectVersion >= ObjectVersion.VER_UE4_CHANGE_SETARRAY_BYTECODE)
{
offset += ExpressionSerializer.WriteExpression(AssigningProperty, writer);
}
else
{
offset += writer.XFERPTR(ArrayInnerProp);
}
for (int i = 0; i < Elements.Length; i++)
{
offset += ExpressionSerializer.WriteExpression(Elements[i], writer);
}
offset += ExpressionSerializer.WriteExpression(new EX_EndArray(), writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
AssigningProperty.Visit(asset, ref offset, visitor);
foreach (var element in Elements)
{
element.Visit(asset, ref offset, visitor);
}
offset += 1; // EX_EndArray
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_SetConst.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_SetConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_SetConst; } }
///
/// Pointer to this constant's inner property (FProperty*).
///
[JsonProperty]
public KismetPropertyPointer InnerProperty;
///
/// Set constant entries.
///
[JsonProperty]
public KismetExpression[] Elements;
public EX_SetConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
InnerProperty = reader.XFER_PROP_POINTER();
int numEntries = reader.ReadInt32(); // Number of elements
Elements = reader.ReadExpressionArray(EExprToken.EX_EndSetConst);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += writer.XFER_PROP_POINTER(InnerProperty);
writer.Write(Elements.Length); offset += sizeof(int);
for (int i = 0; i < Elements.Length; i++)
{
offset += ExpressionSerializer.WriteExpression(Elements[i], writer);
}
offset += ExpressionSerializer.WriteExpression(new EX_EndSetConst(), writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 12; // InnerProperty (8) + NumElements (4)
foreach (var e in Elements)
{
e.Visit(asset, ref offset, visitor);
}
offset += 1; // EX_EndSetConst
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_SetMap.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_SetMap : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_SetMap; } }
///
/// Map property.
///
[JsonProperty]
public KismetExpression MapProperty;
///
/// Set entries.
///
[JsonProperty]
public KismetExpression[] Elements;
public EX_SetMap()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
MapProperty = ExpressionSerializer.ReadExpression(reader);
int numEntries = reader.ReadInt32(); // Number of elements
Elements = reader.ReadExpressionArray(EExprToken.EX_EndMap);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += ExpressionSerializer.WriteExpression(MapProperty, writer);
// count is number if pairs so is half the number of elements
writer.Write(Elements.Length / 2); offset += sizeof(int);
for (int i = 0; i < Elements.Length; i++)
{
offset += ExpressionSerializer.WriteExpression(Elements[i], writer);
}
offset += ExpressionSerializer.WriteExpression(new EX_EndMap(), writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
MapProperty.Visit(asset, ref offset, visitor);
offset += 4; // NumElements
foreach (var e in Elements)
{
e.Visit(asset, ref offset, visitor);
}
offset += 1; // EX_EndMap
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_SetSet.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_SetSet : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_SetSet; } }
///
/// Set property.
///
[JsonProperty]
public KismetExpression SetProperty;
///
/// Set entries.
///
[JsonProperty]
public KismetExpression[] Elements;
public EX_SetSet()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
SetProperty = ExpressionSerializer.ReadExpression(reader);
int numEntries = reader.ReadInt32(); // Number of elements
Elements = reader.ReadExpressionArray(EExprToken.EX_EndSet);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += ExpressionSerializer.WriteExpression(SetProperty, writer);
writer.Write(Elements.Length); offset += sizeof(int);
for (int i = 0; i < Elements.Length; i++)
{
offset += ExpressionSerializer.WriteExpression(Elements[i], writer);
}
offset += ExpressionSerializer.WriteExpression(new EX_EndSet(), writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
SetProperty.Visit(asset, ref offset, visitor);
offset += 4; // NumElements
foreach (var e in Elements)
{
e.Visit(asset, ref offset, visitor);
}
offset += 1; // EX_EndSet
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Skip.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_Skip : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Skip; } }
///
/// The offset to skip to.
///
[JsonProperty]
public uint CodeOffset;
///
/// An expression to possibly skip.
///
[JsonProperty]
public KismetExpression SkipExpression;
public EX_Skip()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
CodeOffset = reader.ReadUInt32();
SkipExpression = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
writer.Write(CodeOffset); offset += sizeof(uint);
offset += ExpressionSerializer.WriteExpression(SkipExpression, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 4; // CodeOffset
SkipExpression.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_SkipOffsetConst.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
/// Represents a code offset constant.
///
public class EX_SkipOffsetConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_SkipOffsetConst; } }
public EX_SkipOffsetConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.ReadUInt32();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write(Value);
return sizeof(uint);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 4; // Value
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_SoftObjectConst.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_SoftObjectConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_SoftObjectConst; } }
public EX_SoftObjectConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return ExpressionSerializer.WriteExpression(Value, writer);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
Value.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_StringConst.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_StringConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_StringConst; } }
public EX_StringConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.XFERSTRING();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return writer.XFERSTRING(Value);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += (uint)Value.Length + 1; // String + null terminator
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_StructConst.cs
================================================
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_StructConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_StructConst; } }
///
/// Pointer to the UScriptStruct in question.
///
[JsonProperty]
public FPackageIndex Struct;
///
/// The size of the struct that this constant represents in memory in bytes.
///
[JsonProperty]
public int StructSize;
public EX_StructConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Struct = reader.XFERPTR();
StructSize = reader.ReadInt32();
Value = reader.ReadExpressionArray(EExprToken.EX_EndStructConst);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += writer.XFERPTR(Struct);
writer.Write(StructSize); offset += sizeof(int);
for (int i = 0; i < Value.Length; i++)
{
offset += ExpressionSerializer.WriteExpression(Value[i], writer);
}
// Write end expression
offset += ExpressionSerializer.WriteExpression(new EX_EndStructConst(), writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 12; // Struct (8) + StructSize (4)
foreach (var v in Value)
{
v.Visit(asset, ref offset, visitor);
}
offset += 1; // EX_EndStructConst
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_StructMemberContext.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_StructMemberContext : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_StructMemberContext; } }
///
/// A pointer to the struct member expression (FProperty*).
///
[JsonProperty]
public KismetPropertyPointer StructMemberExpression;
///
/// Struct expression.
///
[JsonProperty]
public KismetExpression StructExpression;
public EX_StructMemberContext()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
StructMemberExpression = reader.XFER_PROP_POINTER();
StructExpression = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += writer.XFER_PROP_POINTER(StructMemberExpression);
offset += ExpressionSerializer.WriteExpression(StructExpression, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 8; // StructMemberExpression (8)
StructExpression.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_SwitchValue.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// Represents a case in a Kismet bytecode switch statement.
///
[JsonObject(MemberSerialization.OptIn)]
public struct FKismetSwitchCase
{
///
/// The index value term of this case.
///
[JsonProperty]
public KismetExpression CaseIndexValueTerm;
///
/// Code offset to the next case.
///
[JsonProperty]
public uint NextOffset;
///
/// The main case term.
///
[JsonProperty]
public KismetExpression CaseTerm;
public FKismetSwitchCase(KismetExpression caseIndexValueTerm, uint nextOffset, KismetExpression caseTerm)
{
CaseIndexValueTerm = caseIndexValueTerm;
NextOffset = nextOffset;
CaseTerm = caseTerm;
}
}
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_SwitchValue : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_SwitchValue; } }
///
/// Code offset to jump to when finished.
///
[JsonProperty]
public uint EndGotoOffset;
///
/// The index term of this switch statement.
///
[JsonProperty]
public KismetExpression IndexTerm;
///
/// The default term of this switch statement.
///
[JsonProperty]
public KismetExpression DefaultTerm;
///
/// All the cases in this switch statement.
///
[JsonProperty]
public FKismetSwitchCase[] Cases;
public EX_SwitchValue()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
ushort numCases = reader.ReadUInt16(); // number of cases, without default one
EndGotoOffset = reader.ReadUInt32();
IndexTerm = ExpressionSerializer.ReadExpression(reader);
Cases = new FKismetSwitchCase[numCases];
for (int i = 0; i < numCases; i++)
{
KismetExpression termA = ExpressionSerializer.ReadExpression(reader);
uint termB = reader.ReadUInt32();
KismetExpression termC = ExpressionSerializer.ReadExpression(reader);
Cases[i] = new FKismetSwitchCase(termA, termB, termC);
}
DefaultTerm = ExpressionSerializer.ReadExpression(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
writer.Write((ushort)Cases.Length); offset += sizeof(ushort);
writer.Write(EndGotoOffset); offset += sizeof(uint);
offset += ExpressionSerializer.WriteExpression(IndexTerm, writer);
for (int i = 0; i < Cases.Length; i++)
{
offset += ExpressionSerializer.WriteExpression(Cases[i].CaseIndexValueTerm, writer);
writer.Write(Cases[i].NextOffset); offset += sizeof(uint);
offset += ExpressionSerializer.WriteExpression(Cases[i].CaseTerm, writer);
}
offset += ExpressionSerializer.WriteExpression(DefaultTerm, writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 6; // NumCases (2) + EndGotoOffset (4)
IndexTerm.Visit(asset, ref offset, visitor);
foreach (var c in Cases)
{
c.CaseIndexValueTerm.Visit(asset, ref offset, visitor);
offset += 4; // NextOffset
c.CaseTerm.Visit(asset, ref offset, visitor);
}
DefaultTerm.Visit(asset, ref offset, visitor);
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_TextConst.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_TextConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_TextConst; } }
public EX_TextConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = new FScriptText();
Value.Read(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return Value.Write(writer);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 1; // TextLiteralType
switch (Value.TextLiteralType)
{
case EBlueprintTextLiteralType.Empty:
break;
case EBlueprintTextLiteralType.LocalizedText:
Value.LocalizedSource.Visit(asset, ref offset, visitor);
Value.LocalizedKey.Visit(asset, ref offset, visitor);
Value.LocalizedNamespace.Visit(asset, ref offset, visitor);
break;
case EBlueprintTextLiteralType.InvariantText:
Value.InvariantLiteralString.Visit(asset, ref offset, visitor);
break;
case EBlueprintTextLiteralType.LiteralString:
Value.LiteralString.Visit(asset, ref offset, visitor);
break;
case EBlueprintTextLiteralType.StringTableEntry:
offset += 8; // StringTableAsset
Value.StringTableId.Visit(asset, ref offset, visitor);
Value.StringTableKey.Visit(asset, ref offset, visitor);
break;
}
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Tracepoint.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_Tracepoint : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Tracepoint; } }
public EX_Tracepoint()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_TransformConst.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions;
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_TransformConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_TransformConst; } }
public EX_TransformConst() { Value = new(); }
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = new FTransform(reader);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return Value.Write(writer);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += asset.ObjectVersionUE5 >= ObjectVersionUE5.LARGE_WORLD_COORDINATES ? 80U : 40U;
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_True.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_True : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_True; } }
public EX_True()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_UInt64Const.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_UInt64Const : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_UInt64Const; } }
public EX_UInt64Const()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.ReadUInt64();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write(Value);
return sizeof(ulong);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 8; // Value
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_UnicodeStringConst.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_UnicodeStringConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_UnicodeStringConst; } }
public EX_UnicodeStringConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Value = reader.XFERUNICODESTRING();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return writer.XFERUNICODESTRING(Value);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 2 * ((uint)Value.Length + 1); // Unicode string + null terminator (2 bytes per char)
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_VariableBase.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// Base class for Kismet Variable expressions
///
public abstract class EX_VariableBase : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_ClassSparseDataVariable; } }
///
/// A pointer to the variable in question.
///
[JsonProperty]
public KismetPropertyPointer Variable;
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
Variable = reader.XFER_PROP_POINTER();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return writer.XFER_PROP_POINTER(Variable);
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 8; // Variable (KismetPropertyPointer)
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_Vector3fConst.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
/// A float vector constant (always 3 floats, regardless of LWC).
///
public class EX_Vector3fConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_Vector3fConst; } }
[JsonProperty]
public float X;
[JsonProperty]
public float Y;
[JsonProperty]
public float Z;
public EX_Vector3fConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
X = reader.ReadSingle();
Y = reader.ReadSingle();
Z = reader.ReadSingle();
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
writer.Write(X);
writer.Write(Y);
writer.Write(Z);
return sizeof(float) * 3;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 12; // 3 floats
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_VectorConst.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_VectorConst : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_VectorConst; } }
[JsonProperty]
public FVector Value;
public EX_VectorConst()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
if (reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.LARGE_WORLD_COORDINATES)
{
Value = new FVector(reader.ReadDouble(), reader.ReadDouble(), reader.ReadDouble());
}
else
{
Value = new FVector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
if (writer.Asset.ObjectVersionUE5 >= ObjectVersionUE5.LARGE_WORLD_COORDINATES)
{
writer.Write(Value.X);
writer.Write(Value.Y);
writer.Write(Value.Z);
return sizeof(double) * 3;
}
else
{
writer.Write(Value.XFloat);
writer.Write(Value.YFloat);
writer.Write(Value.ZFloat);
return sizeof(float) * 3;
}
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += asset.ObjectVersionUE5 >= ObjectVersionUE5.LARGE_WORLD_COORDINATES ? 24U : 12U;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_VirtualFunction.cs
================================================
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_VirtualFunction : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_VirtualFunction; } }
///
/// Virtual function name.
///
[JsonProperty]
public FName VirtualFunctionName;
///
/// List of parameters for this function.
///
[JsonProperty]
public KismetExpression[] Parameters;
public EX_VirtualFunction()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
VirtualFunctionName = reader.XFER_FUNC_NAME();
Parameters = reader.ReadExpressionArray(EExprToken.EX_EndFunctionParms);
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
int offset = 0;
offset += writer.XFER_FUNC_NAME(VirtualFunctionName);
for (int i = 0; i < Parameters.Length; i++)
{
offset += ExpressionSerializer.WriteExpression(Parameters[i], writer);
}
offset += ExpressionSerializer.WriteExpression(new EX_EndFunctionParms(), writer);
return offset;
}
public override void Visit(UAsset asset, ref uint offset, Action visitor)
{
base.Visit(asset, ref offset, visitor);
offset += 12; // VirtualFunctionName (12)
foreach (var param in Parameters)
{
param.Visit(asset, ref offset, visitor);
}
offset += 1; // EX_EndFunctionParms
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/Expressions/EX_WireTracepoint.cs
================================================
namespace UAssetAPI.Kismet.Bytecode.Expressions
{
///
/// A single Kismet bytecode instruction, corresponding to the instruction.
///
public class EX_WireTracepoint : KismetExpression
{
///
/// The token of this expression.
///
public override EExprToken Token { get { return EExprToken.EX_WireTracepoint; } }
public EX_WireTracepoint()
{
}
///
/// Reads out the expression from a BinaryReader.
///
/// The BinaryReader to read from.
public override void Read(AssetBinaryReader reader)
{
}
///
/// Writes the expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public override int Write(AssetBinaryWriter writer)
{
return 0;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/FScriptText.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode
{
///
/// Represents an FText as serialized in Kismet bytecode.
///
[JsonObject(MemberSerialization.OptIn)]
public class FScriptText
{
[JsonProperty]
public EBlueprintTextLiteralType TextLiteralType;
///
/// Source of this text if it is localized text. Used when is .
///
[JsonProperty]
public KismetExpression LocalizedSource;
///
/// Key of this text if it is localized text. Used when is .
///
[JsonProperty]
public KismetExpression LocalizedKey;
///
/// Namespace of this text if it is localized text. Used when is .
///
[JsonProperty]
public KismetExpression LocalizedNamespace;
///
/// Value of this text if it is an invariant string literal. Used when is .
///
[JsonProperty]
public KismetExpression InvariantLiteralString;
///
/// Value of this text if it is a string literal. Used when is .
///
[JsonProperty]
public KismetExpression LiteralString;
///
/// Pointer to this text's UStringTable. Not used at runtime, but exists for asset dependency gathering. Used when is .
///
[JsonProperty]
public FPackageIndex StringTableAsset;
///
/// Table ID string literal (namespace). Used when is .
///
[JsonProperty]
public KismetExpression StringTableId;
///
/// String table key string literal. Used when is .
///
[JsonProperty]
public KismetExpression StringTableKey;
///
/// Reads out an FBlueprintText from a BinaryReader.
///
/// The BinaryReader to read from.
public virtual void Read(AssetBinaryReader reader)
{
TextLiteralType = (EBlueprintTextLiteralType)reader.ReadByte();
switch (TextLiteralType)
{
case EBlueprintTextLiteralType.Empty:
break;
case EBlueprintTextLiteralType.LocalizedText:
LocalizedSource = ExpressionSerializer.ReadExpression(reader);
LocalizedKey = ExpressionSerializer.ReadExpression(reader);
LocalizedNamespace = ExpressionSerializer.ReadExpression(reader);
break;
case EBlueprintTextLiteralType.InvariantText: // IsCultureInvariant
InvariantLiteralString = ExpressionSerializer.ReadExpression(reader);
break;
case EBlueprintTextLiteralType.LiteralString:
LiteralString = ExpressionSerializer.ReadExpression(reader);
break;
case EBlueprintTextLiteralType.StringTableEntry:
StringTableAsset = reader.XFER_OBJECT_POINTER();
StringTableId = ExpressionSerializer.ReadExpression(reader);
StringTableKey = ExpressionSerializer.ReadExpression(reader);
break;
default:
throw new NotImplementedException("Unimplemented blueprint text literal type " + TextLiteralType);
}
}
///
/// Writes an FBlueprintText to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public virtual int Write(AssetBinaryWriter writer)
{
int offset = 0;
writer.Write((byte)TextLiteralType); offset += sizeof(byte);
switch (TextLiteralType)
{
case EBlueprintTextLiteralType.Empty:
break;
case EBlueprintTextLiteralType.LocalizedText:
offset += ExpressionSerializer.WriteExpression(LocalizedSource, writer);
offset += ExpressionSerializer.WriteExpression(LocalizedKey, writer);
offset += ExpressionSerializer.WriteExpression(LocalizedNamespace, writer);
break;
case EBlueprintTextLiteralType.InvariantText: // IsCultureInvariant
offset += ExpressionSerializer.WriteExpression(InvariantLiteralString, writer);
break;
case EBlueprintTextLiteralType.LiteralString:
offset += ExpressionSerializer.WriteExpression(LiteralString, writer);
break;
case EBlueprintTextLiteralType.StringTableEntry:
offset += writer.XFER_OBJECT_POINTER(StringTableAsset);
offset += ExpressionSerializer.WriteExpression(StringTableId, writer);
offset += ExpressionSerializer.WriteExpression(StringTableKey, writer);
break;
default:
throw new NotImplementedException("Unimplemented blueprint text literal type " + TextLiteralType);
}
return offset;
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/KismetExpression.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Kismet.Bytecode
{
///
/// A Kismet bytecode instruction.
///
[JsonObject(MemberSerialization.OptIn)]
public class KismetExpression
{
///
/// The token of this expression.
///
public virtual EExprToken Token { get { return EExprToken.EX_Nothing; } }
///
/// The token of this instruction expressed as a string.
///
public string Inst { get { return Token.ToString().Substring(3, Token.ToString().Length - 3); } }
///
/// An optional tag which can be set on any expression in memory. This is for the user only, and has no bearing in the API itself.
///
public object Tag;
public object RawValue;
public void SetObject(object value)
{
RawValue = value;
}
public T GetObject()
{
return (T)RawValue;
}
public KismetExpression()
{
}
///
/// Reads out an expression from a BinaryReader.
///
/// The BinaryReader to read from.
public virtual void Read(AssetBinaryReader reader)
{
}
///
/// Writes an expression to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// The iCode offset of the data that was written.
public virtual int Write(AssetBinaryWriter writer)
{
return 0;
}
///
/// Visits this expression and all child expressions, calling the visitor function for each with the in-memory offset.
/// Note: The offset is the in-memory offset, not the serialization offset.
///
/// The asset containing this expression.
/// Reference to the current in-memory offset, which is incremented as expressions are visited.
/// The visitor function to call for each expression with the expression and its offset.
public virtual void Visit(UAsset asset, ref uint offset, Action visitor)
{
visitor(this, offset);
offset++;
}
///
/// Gets the in-memory size of this expression and all child expressions.
///
/// The asset containing this expression.
/// The size in bytes of this expression.
public uint GetSize(UAsset asset)
{
uint offset = 0;
Visit(asset, ref offset, (_, __) => { });
return offset;
}
}
public abstract class KismetExpression : KismetExpression
{
///
/// The value of this expression if it is a constant.
///
[JsonProperty]
public T Value
{
get => GetObject();
set => SetObject(value);
}
public KismetExpression() : base()
{
}
}
}
================================================
FILE: UAssetAPI/Kismet/Bytecode/KismetPropertyPointer.cs
================================================
using Newtonsoft.Json;
using System.ComponentModel;
using UAssetAPI.UnrealTypes;
using UAssetAPI.CustomVersions;
namespace UAssetAPI.Kismet.Bytecode;
///
/// Represents a Kismet bytecode pointer to an FProperty or FField.
///
[JsonObject(MemberSerialization.OptIn)]
public class KismetPropertyPointer
{
///
/// The pointer serialized as an FPackageIndex. Used in versions older than .
///
[JsonProperty]
[DefaultValue(null)]
public FPackageIndex Old;
///
/// The pointer serialized as an FFieldPath. Used in versions newer than .
///
[JsonProperty]
[DefaultValue(null)]
public FFieldPath New;
public bool ShouldSerializeOld()
{
return Old != null;
}
public bool ShouldSerializeNew()
{
return New != null;
}
public KismetPropertyPointer(FPackageIndex older)
{
Old = older;
}
public KismetPropertyPointer(FFieldPath newer)
{
New = newer;
}
public KismetPropertyPointer()
{
}
}
================================================
FILE: UAssetAPI/Kismet/KismetSerializer.cs
================================================
using Newtonsoft.Json.Linq;
using UAssetAPI.FieldTypes;
using UAssetAPI.Kismet.Bytecode.Expressions;
using UAssetAPI.Kismet.Bytecode;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
using UAssetAPI.CustomVersions;
namespace UAssetAPI.Kismet
{
public static class KismetSerializer
{
public static UAsset asset;
public struct FSimpleMemberReference
{
public string MemberParent;
public string MemberName;
public Guid MemberGuid;
}
public struct FEdGraphTerminalType
{
public string TerminalCategory;
public string TerminalSubCategory;
public string TerminalSubCategoryObject;
public bool bTerminalIsConst;
public bool bTerminalIsWeakPointer;
public bool bTerminalIsUObjectWrapper;
}
public struct FEdGraphPinType
{
public string PinCategory;
public string PinSubCategory;
public string PinSubCategoryObject;
public FSimpleMemberReference PinSubCategoryMemberReference;
public FEdGraphTerminalType PinValueType;
public EPinContainerType ContainerType;
public bool bIsReference;
public bool bIsConst;
public bool bIsWeakPointer;
public bool bIsUObjectWrapper;
}
public enum EPinContainerType : byte
{
None,
Array,
Set,
Map
};
const string PC_Boolean = "Bool";
const string PC_Byte = "Byte";
const string PC_Class = "Class";
const string PC_Int = "Int";
const string PC_Int64 = "Int64";
const string PC_Float = "Float";
const string PC_Double = "Double";
const string PC_Name = "Name";
const string PC_Delegate = "Delegate";
const string PC_MCDelegate = "mcdelegate";
const string PC_Object = "Object";
const string PC_Interface = "Interface";
const string PC_String = "String";
const string PC_Text = "Text";
const string PC_Struct = "Struct";
const string PC_Enum = "Enum";
const string PC_SoftObject = "Softobject";
const string PC_SoftClass = "Softclass";
const string PC_None = "None";
public static JArray SerializeScript(KismetExpression[] code)
{
JArray jscript = new JArray();
int index = 0;
foreach (KismetExpression instruction in code)
{
jscript.Add(SerializeExpression(instruction, ref index, true));
}
return jscript;
}
public static string GetName(int index)
{
if (index > 0)
{
return asset.Exports[index - 1].ObjectName.ToString();
}
else if (index < 0)
{
return asset.Imports[-index - 1].ObjectName.ToString();
}
else
{
return "";
}
}
public static int GetClassIndex()
{
for (int i = 1; i <= asset.Exports.Count; i++)
{
if (asset.Exports[i - 1] is ClassExport)
{
return i;
}
}
return 0;
}
public static string GetFullName(int index, bool alt = false)
{
if (index > 0 && index < asset.Exports.Count)
{
if (asset.Exports[index - 1].OuterIndex.Index != 0)
{
string parent = GetFullName(asset.Exports[index - 1].OuterIndex.Index);
return parent + "." + asset.Exports[index - 1].ObjectName.ToString();
}
else
{
return asset.Exports[index - 1].ObjectName.ToString();
}
}
else if (index < 0)
{
if (asset.Imports[-index - 1].OuterIndex.Index != 0)
{
string parent = GetFullName(asset.Imports[-index - 1].OuterIndex.Index);
return parent + "." + asset.Imports[-index - 1].ObjectName.ToString();
}
else
{
return asset.Imports[-index - 1].ObjectName.ToString();
}
}
else
{
return "";
}
}
public static string GetParentName(int index)
{
if (index > 0)
{
if (asset.Exports[index - 1].OuterIndex.Index != 0)
{
string parent = GetFullName(asset.Exports[index - 1].OuterIndex.Index);
return parent;
}
else
{
return "";
}
}
else if (index < 0)
{
if (asset.Imports[-index - 1].OuterIndex.Index != 0)
{
string parent = GetFullName(asset.Imports[-index - 1].OuterIndex.Index);
return parent;
}
else
{
return "";
}
}
else
{
return "";
}
}
public static bool FindProperty(int index, FName propname, out FProperty property)
{
if (index < 0)
{
property = new FObjectProperty();
return false;
}
Export export = asset.Exports[index - 1];
if (export is StructExport)
{
foreach (FProperty prop in (export as StructExport).LoadedProperties)
{
if (prop.Name == propname)
{
property = prop;
return true;
}
}
}
property = new FObjectProperty();
return false;
}
public static FEdGraphPinType GetPropertyCategoryInfo(FProperty prop)
{
FEdGraphPinType pin = new FEdGraphPinType();
switch (prop)
{
case FInterfaceProperty finterface:
{
pin.PinCategory = PC_Interface;
pin.PinSubCategoryObject = GetFullName(finterface.InterfaceClass.Index);
break;
};
case FClassProperty fclassprop:
{
pin.PinCategory = PC_Class;
pin.PinSubCategoryObject = GetFullName(fclassprop.MetaClass.Index);
break;
};
case FSoftClassProperty fsoftclassprop:
{
pin.PinCategory = PC_SoftClass;
pin.PinSubCategoryObject = GetFullName(fsoftclassprop.MetaClass.Index);
break;
};
case FSoftObjectProperty fsoftobjprop:
{
pin.PinCategory = PC_SoftObject;
pin.PinSubCategoryObject = GetFullName(fsoftobjprop.PropertyClass.Index);
break;
};
case FObjectProperty fobjprop:
{
pin.PinCategory = PC_Object;
pin.PinSubCategoryObject = GetFullName(fobjprop.PropertyClass.Index);
if (fobjprop.PropertyFlags.HasFlag(EPropertyFlags.CPF_AutoWeak))
{
pin.bIsWeakPointer = true;
}
break;
};
case FStructProperty fstruct:
{
pin.PinCategory = PC_Struct;
pin.PinSubCategoryObject = GetFullName(fstruct.Struct.Index);
break;
};
case FByteProperty fbyte:
{
pin.PinCategory = PC_Byte;
pin.PinSubCategoryObject = GetFullName(fbyte.Enum.Index);
break;
};
case FEnumProperty fenum:
{
if (!(fenum.UnderlyingProp is FByteProperty))
{
break;
}
pin.PinCategory = PC_Byte;
pin.PinSubCategoryObject = GetFullName(fenum.Enum.Index);
break;
}
case FBoolProperty fbool:
{
pin.PinCategory = PC_Boolean;
break;
};
case FGenericProperty fgeneric:
{
switch (fgeneric.SerializedType.ToString())
{
case "FloatProperty":
{
pin.PinCategory = PC_Float;
break;
}
case "DoubleProperty":
{
pin.PinCategory = PC_Double;
break;
}
case "Int64Property":
{
pin.PinCategory = PC_Int64;
break;
}
case "IntProperty":
{
pin.PinCategory = PC_Int;
break;
}
case "NameProperty":
{
pin.PinCategory = PC_Name;
break;
}
case "StrProperty":
{
pin.PinCategory = PC_String;
break;
}
case "TextProperty":
{
pin.PinCategory = PC_Text;
break;
}
default: break;
};
break;
}
default: break;
}
return pin;
}
public static FSimpleMemberReference FillSimpleMemberReference(int index)
{
FSimpleMemberReference member = new FSimpleMemberReference();
if (index > 0)
{
member.MemberName = asset.Exports[index - 1].ObjectName.ToString();
member.MemberParent = GetName(asset.Exports[index - 1].OuterIndex.Index);
member.MemberGuid = asset.Exports[index - 1].PackageGuid;
}
else if (index < 0)
{
member.MemberName = asset.Imports[-index - 1].ObjectName.ToString();
member.MemberParent = asset.Imports[-index - 1].ClassPackage.ToString();
member.MemberGuid = new Guid("00000000000000000000000000000000");
}
return member;
}
public static JObject SerializeGraphPinType(FEdGraphPinType pin)
{
JObject jpin = new JObject();
jpin.Add("PinCategory", pin.PinCategory);
jpin.Add("PinSubCategory", pin.PinCategory);
if (pin.PinSubCategoryObject == "" || pin.PinSubCategoryObject == null)
{
}
else { jpin.Add("PinSubCategoryObject", pin.PinSubCategoryObject); }
if (pin.PinSubCategoryMemberReference.MemberName != null)
{
FSimpleMemberReference member = pin.PinSubCategoryMemberReference;
if (member.MemberGuid.Equals(new Guid("00000000000000000000000000000000")))
{
}
else
{
JObject jmember = new JObject();
if (member.MemberParent != "" || member.MemberParent != null)
{
jmember.Add("MemberParent", member.MemberParent);
}
jmember.Add("MemberName", member.MemberName);
jmember.Add("MemberGuid", member.MemberGuid);
jpin.Add("PinSubCategoryMemberReference", jmember);
}
}
if (pin.ContainerType == EPinContainerType.Map)
{
FEdGraphTerminalType valuetype = pin.PinValueType;
JObject jvaluetype = new JObject();
jvaluetype.Add("TerminalCategory", valuetype.TerminalCategory);
if (valuetype.TerminalSubCategory == null || valuetype.TerminalSubCategory == "")
{
jvaluetype.Add("TerminalSubCategory", "None");
}
else
{
jvaluetype.Add("TerminalSubCategory", valuetype.TerminalSubCategory);
}
if (valuetype.TerminalSubCategoryObject != "" && valuetype.TerminalSubCategoryObject != null)
{
jvaluetype.Add("TerminalSubCategoryObject", valuetype.TerminalSubCategoryObject);
}
jvaluetype.Add("TerminalIsConst", valuetype.bTerminalIsConst);
jvaluetype.Add("TerminalIsWeakPointer", valuetype.bTerminalIsWeakPointer);
jpin.Add("PinValueType", jvaluetype);
}
if (pin.ContainerType != EPinContainerType.None)
{
jpin.Add("ContainerType", (int)pin.ContainerType);
}
if (pin.bIsReference)
{
jpin.Add("IsReference", pin.bIsReference);
}
if (pin.bIsConst)
{
jpin.Add("IsConst", pin.bIsConst);
}
if (pin.bIsWeakPointer)
{
jpin.Add("IsWeakPointer", pin.bIsWeakPointer);
}
return jpin;
}
public static FEdGraphPinType ConvertPropertyToPinType(FProperty property)
{
FEdGraphPinType pin = new FEdGraphPinType();
FProperty prop = property;
if (property is FMapProperty)
{
prop = (property as FMapProperty).KeyProp;
pin.ContainerType = EPinContainerType.Map;
pin.bIsWeakPointer = false;
FEdGraphPinType temppin = GetPropertyCategoryInfo((property as FMapProperty).ValueProp);
pin.PinValueType.TerminalCategory = temppin.PinCategory;
pin.PinValueType.TerminalSubCategory = temppin.PinSubCategory;
pin.PinValueType.TerminalSubCategoryObject = temppin.PinSubCategoryObject;
pin.PinValueType.bTerminalIsConst = temppin.bIsConst;
pin.PinValueType.bTerminalIsWeakPointer = temppin.bIsWeakPointer;
}
else if (property is FSetProperty)
{
prop = (property as FSetProperty).ElementProp;
pin.ContainerType = EPinContainerType.Set;
}
else if (property is FArrayProperty)
{
prop = (property as FArrayProperty).Inner;
pin.ContainerType = EPinContainerType.Array;
}
pin.bIsReference = property.PropertyFlags.HasFlag(EPropertyFlags.CPF_OutParm) && property.PropertyFlags.HasFlag(EPropertyFlags.CPF_ReferenceParm);
pin.bIsConst = property.PropertyFlags.HasFlag(EPropertyFlags.CPF_ConstParm);
if (prop is FMulticastDelegateProperty)
{
pin.PinCategory = PC_MCDelegate;
pin.PinSubCategoryMemberReference = FillSimpleMemberReference((prop as FMulticastDelegateProperty).SignatureFunction.Index);
}
else if (prop is FDelegateProperty)
{
pin.PinCategory = PC_Delegate;
pin.PinSubCategoryMemberReference = FillSimpleMemberReference((prop as FDelegateProperty).SignatureFunction.Index);
}
else
{
FEdGraphPinType temppin = GetPropertyCategoryInfo(prop);
pin.PinCategory = temppin.PinCategory;
pin.PinSubCategory = temppin.PinSubCategory;
pin.PinSubCategoryObject = temppin.PinSubCategoryObject;
pin.bIsWeakPointer = temppin.bIsWeakPointer;
}
return pin;
}
public static JProperty[] SerializePropertyPointer(KismetPropertyPointer pointer, string[] names)
{
JProperty[] jproparray = new JProperty[names.Length];
FProperty property;
if (asset.GetCustomVersion() >= FReleaseObjectVersion.FFieldPathOwnerSerialization)
{
if (pointer != null && pointer.New.ResolvedOwner.Index != 0)
{
if (FindProperty(pointer.New.ResolvedOwner.Index, pointer.New.Path[0], out property))
{
FEdGraphPinType PropertyType = ConvertPropertyToPinType(property);
jproparray[0] = new JProperty(names[0], SerializeGraphPinType(PropertyType));
}
else
{
jproparray[0] = new JProperty(names[0], "##NOT SERIALIZED##");
}
if (names.Length > 1)
{
jproparray[1] = new JProperty(names[1], pointer.New.Path[0].ToString());
}
return jproparray;
}
}
if (pointer != null && pointer.Old != null && pointer.Old.Index != 0)
{
if (names.Length > 1)
{
string[] split = GetFullName(pointer.Old.Index).Split('.');
jproparray[0] = new JProperty(names[0], split[0]);
string path = "";
for (int i = 1; i < split.Length; i++)
{
path += split[i] + ".";
}
if (path.EndsWith("."))
{
path = path.Substring(0, path.Length - 1);
}
jproparray[1] = new JProperty(names[1], path);
}
else
{
jproparray[0] = new JProperty(names[0], GetFullName(pointer.Old.Index));
}
}
else
{
jproparray[0] = new JProperty(names[0], "#Pointer Error#");
if (names.Length > 1)
{
jproparray[1] = new JProperty(names[1], "^^^^^");
}
}
return jproparray;
}
private static bool FindProperty(int index, FPackageIndex old, out FProperty property)
{
throw new NotImplementedException();
}
public static JObject SerializeExpression(KismetExpression expression, ref int index, bool addindex = false)
{
int savedindex = index;
JObject jexp = new JObject();
index++;
switch (expression)
{
case EX_PrimitiveCast exp:
{
jexp.Add("Inst", exp.Inst);
index++;
switch (exp.ConversionType)
{
case ECastToken.InterfaceToBool:
{
jexp.Add("CastType", "InterfaceToBool");
break;
}
case ECastToken.ObjectToBool:
{
jexp.Add("CastType", "ObjectToBool");
break;
}
case ECastToken.ObjectToInterface:
{
jexp.Add("CastType", "ObjectToInterface");
index += 8;
jexp.Add("InterfaceClass", "##NOT SERIALIZED##");
break;
}
default: break;
}
jexp.Add("Expression", SerializeExpression(exp.Target, ref index));
break;
}
case EX_SetSet exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("LeftSideExpression", SerializeExpression(exp.SetProperty, ref index));
JArray jparams = new JArray();
index += 4;
foreach (KismetExpression param in exp.Elements)
{
jparams.Add(SerializeExpression(param, ref index));
}
index++;
jexp.Add("Values", jparams);
break;
}
case EX_SetConst exp:
{
index += 8;
jexp.Add("Inst", exp.Inst);
jexp.Add(SerializePropertyPointer(exp.InnerProperty, new[] { "InnerProperty" }));
index += 4;
JArray jparams = new JArray();
foreach (KismetExpression param in exp.Elements)
{
jparams.Add(SerializeExpression(param, ref index));
}
index++;
jexp.Add("Values", jparams);
break;
}
case EX_SetMap exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("LeftSideExpression", SerializeExpression(exp.MapProperty, ref index));
index += 4;
JArray jparams = new JArray();
for (var j = 1; j <= exp.Elements.Length / 2; j++)
{
JObject jobject = new JObject();
jobject.Add("Key", SerializeExpression(exp.Elements[2 * (j - 1)], ref index));
jobject.Add("Value", SerializeExpression(exp.Elements[2 * (j - 1) + 1], ref index));
jparams.Add(jobject);
}
index++;
jexp.Add("Values", jparams);
break;
}
case EX_MapConst exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add(SerializePropertyPointer(exp.KeyProperty, new[] { "KeyProperty" }));
jexp.Add(SerializePropertyPointer(exp.ValueProperty, new[] { "ValueProperty" }));
index += 4;
JArray jparams = new JArray();
for (var j = 1; j <= exp.Elements.Length / 2; j++)
{
JObject jobject = new JObject();
jobject.Add("Key", SerializeExpression(exp.Elements[2 * (j - 1)], ref index));
jobject.Add("Value", SerializeExpression(exp.Elements[2 * (j - 1) + 1], ref index));
jparams.Add(jobject);
}
index++;
jexp.Add("Values", jparams);
break;
}
case EX_ObjToInterfaceCast exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add("InterfaceClass", GetFullName(exp.ClassPtr.Index));
jexp.Add("Expression", SerializeExpression(exp.Target, ref index));
break;
}
case EX_CrossInterfaceCast exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add("InterfaceClass", GetFullName(exp.ClassPtr.Index));
jexp.Add("Expression", SerializeExpression(exp.Target, ref index));
break;
}
case EX_InterfaceToObjCast exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add("ObjectClass", GetFullName(exp.ClassPtr.Index));
jexp.Add("Expression", SerializeExpression(exp.Target, ref index));
break;
}
case EX_Let exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add("Variable", SerializeExpression(exp.Variable, ref index));
jexp.Add("Expression", SerializeExpression(exp.Expression, ref index));
break;
}
case EX_LetObj exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("Variable", SerializeExpression(exp.VariableExpression, ref index));
jexp.Add("Expression", SerializeExpression(exp.AssignmentExpression, ref index));
break;
}
case EX_LetWeakObjPtr exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("Variable", SerializeExpression(exp.VariableExpression, ref index));
jexp.Add("Expression", SerializeExpression(exp.AssignmentExpression, ref index));
break;
}
case EX_LetBool exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("Variable", SerializeExpression(exp.VariableExpression, ref index));
jexp.Add("Expression", SerializeExpression(exp.AssignmentExpression, ref index));
break;
}
case EX_LetValueOnPersistentFrame exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add(SerializePropertyPointer(exp.DestinationProperty, new[] { "Property Outer", "Property Name" }));
jexp.Add("Expression", SerializeExpression(exp.AssignmentExpression, ref index));
break;
}
case EX_StructMemberContext exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add(SerializePropertyPointer(exp.StructMemberExpression, new[] { "Property Outer", "Property Name" }));
jexp.Add("StructExpression", SerializeExpression(exp.StructExpression, ref index));
break;
}
case EX_LetDelegate exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("Variable", SerializeExpression(exp.VariableExpression, ref index));
jexp.Add("Expression", SerializeExpression(exp.AssignmentExpression, ref index));
break;
}
case EX_LocalVirtualFunction exp:
{
jexp.Add("Inst", exp.Inst);
index += 12;
jexp.Add("FunctionName", exp.VirtualFunctionName.ToString());
JArray jparams = new JArray();
foreach (KismetExpression param in exp.Parameters)
{
jparams.Add(SerializeExpression(param, ref index));
}
index++;
jexp.Add("Parameters", jparams);
break;
}
case EX_LocalFinalFunction exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("Function", GetName(exp.StackNode.Index));
index += 8;
JArray jparams = new JArray();
foreach (KismetExpression param in exp.Parameters)
{
jparams.Add(SerializeExpression(param, ref index));
}
index++;
jexp.Add("Parameters", jparams);
break;
}
case EX_LetMulticastDelegate exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("Variable", SerializeExpression(exp.VariableExpression, ref index));
jexp.Add("Expression", SerializeExpression(exp.AssignmentExpression, ref index));
break;
}
case EX_ComputedJump exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("OffsetExpression", SerializeExpression(exp.CodeOffsetExpression, ref index));
break;
}
case EX_Jump exp:
{
jexp.Add("Inst", exp.Inst);
index += 4;
jexp.Add("Offset", exp.CodeOffset);
break;
}
case EX_LocalVariable exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add(SerializePropertyPointer(exp.Variable, new[] { "Variable Outer", "Variable Name" }));
break;
}
case EX_DefaultVariable exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add(SerializePropertyPointer(exp.Variable, new[] { "Variable Outer", "Variable Name" }));
break;
}
case EX_InstanceVariable exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add(SerializePropertyPointer(exp.Variable, new[] { "Variable Outer", "Variable Name" }));
break;
}
case EX_LocalOutVariable exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add(SerializePropertyPointer(exp.Variable, new[] { "Variable Outer", "Variable Name" }));
break;
}
case EX_InterfaceContext exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("Expression", SerializeExpression(exp.InterfaceValue, ref index));
break;
}
case EX_DeprecatedOp4A exp1:
case EX_Nothing exp2:
case EX_EndOfScript exp3:
case EX_IntZero exp4:
case EX_IntOne exp5:
case EX_True exp6:
case EX_False exp7:
case EX_NoObject exp8:
case EX_NoInterface exp9:
case EX_Self exp10:
{
jexp.Add("Inst", expression.Inst);
break;
}
case EX_Return exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("Expression", SerializeExpression(exp.ReturnExpression, ref index));
break;
}
case EX_CallMath exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add("Function", GetName(exp.StackNode.Index));
jexp.Add("ContextClass", GetParentName(exp.StackNode.Index));
JArray jparams = new JArray();
foreach (KismetExpression param in exp.Parameters)
{
jparams.Add(SerializeExpression(param, ref index));
}
index++;
jexp.Add("Parameters", jparams);
break;
}
case EX_CallMulticastDelegate exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
JObject jsign = new JObject();
bool bIsSelfContext = GetClassIndex() == exp.StackNode.Index;
jsign.Add("IsSelfContext", bIsSelfContext);
jsign.Add("MemberParent", GetFullName(exp.StackNode.Index));
jsign.Add("MemberName", GetName(exp.StackNode.Index));
jexp.Add("DelegateSignatureFunction", jsign);
jexp.Add("Delegate", SerializeExpression(exp.Delegate, ref index));
JArray jparams = new JArray();
foreach (KismetExpression param in exp.Parameters)
{
jparams.Add(SerializeExpression(param, ref index));
}
index++;
jexp.Add("Parameters", jparams);
break;
}
case EX_FinalFunction exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add("Function", GetName(exp.StackNode.Index));
JArray jparams = new JArray();
foreach (KismetExpression param in exp.Parameters)
{
jparams.Add(SerializeExpression(param, ref index));
}
index++;
jexp.Add("Parameters", jparams);
break;
}
case EX_VirtualFunction exp:
{
jexp.Add("Inst", exp.Inst);
index += 12;
jexp.Add("Function", exp.VirtualFunctionName.ToString());
JArray jparams = new JArray();
foreach (KismetExpression param in exp.Parameters)
{
jparams.Add(SerializeExpression(param, ref index));
}
index++;
jexp.Add("Parameters", jparams);
break;
}
//case EX_ClassContext:
//case EX_Context_FailSilent: {
case EX_Context exp:
{
if (exp is EX_Context_FailSilent)
{
exp = exp as EX_Context_FailSilent;
}
else if (exp is EX_ClassContext)
{
exp = exp as EX_ClassContext;
}
else
{
}
jexp.Add("Inst", exp.Inst);
jexp.Add("Context", SerializeExpression(exp.ObjectExpression, ref index));
index += 4;
jexp.Add("SkipOffsetForNull", exp.Offset);
index += 8;
jexp.Add(SerializePropertyPointer(exp.RValuePointer, new[] { "RValuePropertyOuter", "RValuePropertyName" }));
jexp.Add("Expression", SerializeExpression(exp.ContextExpression, ref index));
break;
}
case EX_IntConst exp:
{
index += 4;
jexp.Add("Inst", exp.Inst);
jexp.Add("Value", exp.Value);
break;
}
case EX_SkipOffsetConst exp:
{
index += 4;
jexp.Add("Inst", exp.Inst);
jexp.Add("Value", exp.Value);
break;
}
case EX_FloatConst exp:
{
index += 4;
jexp.Add("Inst", exp.Inst);
jexp.Add("Value", exp.Value);
break;
}
case EX_DoubleConst exp:
{
index += 8;
jexp.Add("Inst", exp.Inst);
jexp.Add("Value", exp.Value);
break;
}
case EX_StringConst exp:
{
jexp.Add("Inst", exp.Inst);
index += exp.Value.Length + 1;
jexp.Add("Value", exp.Value);
break;
}
case EX_UnicodeStringConst exp:
{
jexp.Add("Inst", exp.Inst);
index += 2 * (exp.Value.Length + 1);
jexp.Add("Value", exp.Value);
break;
}
case EX_TextConst exp:
{
jexp.Add("Inst", exp.Inst);
index++;
switch (exp.Value.TextLiteralType)
{
case EBlueprintTextLiteralType.Empty:
{
jexp.Add("TextLiteralType", "Empty");
break;
}
case EBlueprintTextLiteralType.LocalizedText:
{
jexp.Add("TextLiteralType", "LocalizedText");
jexp.Add("SourceString", ReadString(exp.Value.LocalizedSource, ref index));
jexp.Add("LocalizationKey", ReadString(exp.Value.LocalizedKey, ref index));
jexp.Add("LocalizationNamespace", ReadString(exp.Value.LocalizedNamespace, ref index));
break;
}
case EBlueprintTextLiteralType.InvariantText:
{
jexp.Add("TextLiteralType", "InvariantText");
jexp.Add("SourceString", ReadString(exp.Value.InvariantLiteralString, ref index));
break;
}
case EBlueprintTextLiteralType.LiteralString:
{
jexp.Add("TextLiteralType", "LiteralString");
jexp.Add("SourceString", ReadString(exp.Value.LiteralString, ref index));
break;
}
case EBlueprintTextLiteralType.StringTableEntry:
{
jexp.Add("TextLiteralType", "StringTableEntry");
index += 8;
jexp.Add("TableId", ReadString(exp.Value.StringTableId, ref index));
jexp.Add("TableKey", ReadString(exp.Value.StringTableKey, ref index));
break;
}
default:
break;
}
break;
}
case EX_ObjectConst exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add("Object", GetFullName(exp.Value.Index));
break;
}
case EX_SoftObjectConst exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("Value", SerializeExpression(exp.Value, ref index));
break;
}
case EX_NameConst exp:
{
jexp.Add("Inst", exp.Inst);
index += 12;
jexp.Add("Value", exp.Value.ToString());
break;
}
case EX_RotationConst exp:
{
jexp.Add("Inst", exp.Inst);
index += ((asset.ObjectVersionUE5 >= ObjectVersionUE5.LARGE_WORLD_COORDINATES) ? sizeof(double) : sizeof(float)) * 3;
jexp.Add("Pitch", exp.Value.Pitch);
jexp.Add("Yaw", exp.Value.Yaw);
jexp.Add("Roll", exp.Value.Roll);
break;
}
case EX_VectorConst exp:
{
jexp.Add("Inst", exp.Inst);
index += ((asset.ObjectVersionUE5 >= ObjectVersionUE5.LARGE_WORLD_COORDINATES) ? sizeof(double) : sizeof(float)) * 3;
jexp.Add("X", exp.Value.X);
jexp.Add("Y", exp.Value.Y);
jexp.Add("Z", exp.Value.Z);
break;
}
case EX_TransformConst exp:
{
jexp.Add("Inst", exp.Inst);
index += ((asset.ObjectVersionUE5 >= ObjectVersionUE5.LARGE_WORLD_COORDINATES) ? sizeof(double) : sizeof(float)) * 10;
JObject jrot = new JObject();
JObject jtrans = new JObject();
JObject jscale = new JObject();
jrot.Add("X", exp.Value.Rotation.X);
jrot.Add("Y", exp.Value.Rotation.Y);
jrot.Add("Z", exp.Value.Rotation.Z);
jrot.Add("W", exp.Value.Rotation.W);
jtrans.Add("X", exp.Value.Translation.X);
jtrans.Add("Y", exp.Value.Translation.Y);
jtrans.Add("Z", exp.Value.Translation.Z);
jscale.Add("X", exp.Value.Scale3D.X);
jscale.Add("Y", exp.Value.Scale3D.Y);
jscale.Add("Z", exp.Value.Scale3D.Z);
jexp.Add("Rotation", jrot);
jexp.Add("Translation", jtrans);
jexp.Add("Scale", jscale);
break;
}
case EX_StructConst exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add("Struct", GetFullName(exp.Struct.Index));
index += 4;
JObject jstruct = new JObject();
int tempindex = 0;
foreach (KismetExpression param in exp.Value)
{
JArray jstructpart = new JArray();
jstructpart.Add(SerializeExpression(param, ref index));
jstruct.Add("Missing property name" + tempindex, jstructpart);
tempindex++;
}
index++;
jexp.Add("Properties", jstruct);
break;
}
case EX_SetArray exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("LeftSideExpression", SerializeExpression(exp.AssigningProperty, ref index));
JArray jparams = new JArray();
foreach (KismetExpression param in exp.Elements)
{
jparams.Add(SerializeExpression(param, ref index));
}
index++;
jexp.Add("Values", jparams);
break;
}
case EX_ArrayConst exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add(SerializePropertyPointer(exp.InnerProperty, new[] { "Variable Outer" }));
index += 4;
JArray jparams = new JArray();
foreach (KismetExpression param in exp.Elements)
{
jparams.Add(SerializeExpression(param, ref index));
}
index++;
jexp.Add("Values", jparams);
break;
}
case EX_ByteConst exp:
{
jexp.Add("Inst", exp.Inst);
index++;
jexp.Add("Value", exp.Value);
break;
}
case EX_IntConstByte exp:
{
jexp.Add("Inst", exp.Inst);
index++;
jexp.Add("Value", exp.Value);
break;
}
case EX_Int64Const exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add("Value", exp.Value);
break;
}
case EX_UInt64Const exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add("Value", exp.Value);
break;
}
case EX_FieldPathConst exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("Expression", SerializeExpression(exp.Value, ref index));
break;
}
case EX_MetaCast exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add("Class", GetFullName(exp.ClassPtr.Index));
jexp.Add("Expression", SerializeExpression(exp.Target, ref index));
break;
}
case EX_DynamicCast exp:
{
jexp.Add("Inst", exp.Inst);
index += 8;
jexp.Add("Class", GetFullName(exp.ClassPtr.Index));
jexp.Add("Expression", SerializeExpression(exp.Target, ref index));
break;
}
case EX_JumpIfNot exp:
{
jexp.Add("Inst", exp.Inst);
index += 4;
jexp.Add("Offset", exp.CodeOffset);
jexp.Add("Condition", SerializeExpression(exp.BooleanExpression, ref index));
break;
}
case EX_Assert exp:
{
jexp.Add("Inst", exp.Inst);
index += 3;
jexp.Add("LineNumber", exp.LineNumber);
jexp.Add("Debug", exp.DebugMode);
jexp.Add("Expression", SerializeExpression(exp.AssertExpression, ref index));
break;
}
case EX_InstanceDelegate exp:
{
jexp.Add("Inst", exp.Inst);
index += 12;
jexp.Add("FunctionName", exp.FunctionName.ToString());
break;
}
case EX_AddMulticastDelegate exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("MulticastDelegate", SerializeExpression(exp.Delegate, ref index));
jexp.Add("Delegate", SerializeExpression(exp.DelegateToAdd, ref index));
break;
}
case EX_RemoveMulticastDelegate exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("MulticastDelegate", SerializeExpression(exp.Delegate, ref index));
jexp.Add("Delegate", SerializeExpression(exp.DelegateToAdd, ref index));
break;
}
case EX_ClearMulticastDelegate exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("MulticastDelegate", SerializeExpression(exp.DelegateToClear, ref index));
break;
}
case EX_BindDelegate exp:
{
jexp.Add("Inst", exp.Inst);
index += 12;
jexp.Add("FunctionName", exp.FunctionName.ToString());
jexp.Add("Delegate", SerializeExpression(exp.Delegate, ref index));
jexp.Add("Object", SerializeExpression(exp.ObjectTerm, ref index));
break;
}
case EX_PushExecutionFlow exp:
{
jexp.Add("Inst", exp.Inst);
index += 4;
jexp.Add("Offset", exp.PushingAddress);
break;
}
case EX_PopExecutionFlow exp:
{
jexp.Add("Inst", exp.Inst);
break;
}
case EX_PopExecutionFlowIfNot exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("Condition", SerializeExpression(exp.BooleanExpression, ref index));
break;
}
case EX_Breakpoint exp:
{
jexp.Add("Inst", exp.Inst);
break;
}
case EX_WireTracepoint exp:
{
jexp.Add("Inst", exp.Inst);
break;
}
case EX_InstrumentationEvent exp:
{
jexp.Add("Inst", exp.Inst);
index++;
switch (exp.EventType)
{
case EScriptInstrumentationType.Class:
jexp.Add("EventType", "Class");
break;
case EScriptInstrumentationType.ClassScope:
jexp.Add("EventType", "ClassScope");
break;
case EScriptInstrumentationType.Instance:
jexp.Add("EventType", "Instance");
break;
case EScriptInstrumentationType.Event:
jexp.Add("EventType", "Event");
break;
case EScriptInstrumentationType.InlineEvent:
{
index += 12;
jexp.Add("EventType", "InlineEvent");
jexp.Add("EventName", exp.EventName.ToString());
break;
}
case EScriptInstrumentationType.ResumeEvent:
jexp.Add("EventType", "ResumeEvent");
break;
case EScriptInstrumentationType.PureNodeEntry:
jexp.Add("EventType", "PureNodeEntry");
break;
case EScriptInstrumentationType.NodeDebugSite:
jexp.Add("EventType", "NodeDebugSite");
break;
case EScriptInstrumentationType.NodeEntry:
jexp.Add("EventType", "NodeEntry");
break;
case EScriptInstrumentationType.NodeExit:
jexp.Add("EventType", "NodeExit");
break;
case EScriptInstrumentationType.PushState:
jexp.Add("EventType", "PushState");
break;
case EScriptInstrumentationType.RestoreState:
jexp.Add("EventType", "RestoreState");
break;
case EScriptInstrumentationType.ResetState:
jexp.Add("EventType", "ResetState");
break;
case EScriptInstrumentationType.SuspendState:
jexp.Add("EventType", "SuspendState");
break;
case EScriptInstrumentationType.PopState:
jexp.Add("EventType", "PopState");
break;
case EScriptInstrumentationType.TunnelEndOfThread:
jexp.Add("EventType", "TunnelEndOfThread");
break;
case EScriptInstrumentationType.Stop:
jexp.Add("EventType", "Stop");
break;
default:
break;
}
break;
}
case EX_Tracepoint exp:
{
jexp.Add("Inst", exp.Inst);
break;
}
case EX_SwitchValue exp:
{
jexp.Add("Inst", exp.Inst);
index += 6;
jexp.Add("Expression", SerializeExpression(exp.IndexTerm, ref index));
jexp.Add("OffsetToSwitchEnd", exp.EndGotoOffset);
JArray jcases = new JArray();
for (var j = 0; j < exp.Cases.Length; j++)
{
JObject jcase = new JObject();
jcase.Add("CaseValue", SerializeExpression(exp.Cases[j].CaseIndexValueTerm, ref index));
index += 4;
jcase.Add("OffsetToNextCase", exp.Cases[j].NextOffset);
jcase.Add("CaseResult", SerializeExpression(exp.Cases[j].CaseTerm, ref index));
jcases.Add(jcase);
}
jexp.Add("Cases", jcases);
jexp.Add("DefaultResult", SerializeExpression(exp.DefaultTerm, ref index));
break;
}
case EX_ArrayGetByRef exp:
{
jexp.Add("Inst", exp.Inst);
jexp.Add("ArrayExpression", SerializeExpression(exp.ArrayVariable, ref index));
jexp.Add("IndexExpression", SerializeExpression(exp.ArrayIndex, ref index));
break;
}
default:
{
// This should never occur.
//checkf(0, TEXT("Unknown bytecode 0x%02X"), (uint8)Opcode);
break;
}
}
if (addindex) { jexp.Add("StatementIndex", savedindex); }
return jexp;
}
public static string ReadString(KismetExpression expr, ref int index)
{
string result = "";
index++;
switch (expr)
{
case EX_StringConst exp:
{
result = exp.Value;
index += result.Length + 1;
break;
}
case EX_UnicodeStringConst exp:
{
result = exp.Value;
index += 2 * (result.Length + 1);
break;
}
default:
break;
}
return result;
}
}
}
================================================
FILE: UAssetAPI/MainSerializer.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text.RegularExpressions;
using UAssetAPI.ExportTypes;
using UAssetAPI.FieldTypes;
using UAssetAPI.PropertyTypes.Objects;
using UAssetAPI.PropertyTypes.Structs;
using UAssetAPI.UnrealTypes;
using UAssetAPI.Unversioned;
#if DEBUGVERBOSE
using System.Diagnostics;
#endif
namespace UAssetAPI
{
///
/// An entry in the property type registry. Contains the class Type used for standard and struct property serialization.
///
internal class RegistryEntry
{
internal Type PropertyType;
internal bool HasCustomStructSerialization;
internal Func Creator;
public RegistryEntry()
{
}
}
///
/// The main serializer for most property types in UAssetAPI.
///
public static class MainSerializer
{
#if DEBUGVERBOSE
private static PropertyData lastType;
#endif
public static string[] AdditionalPropertyRegistry = ["ClassProperty", "SoftClassProperty", "AssetClassProperty"];
private static IDictionary _propertyTypeRegistry;
///
/// The property type registry. Maps serialized property names to their types.
///
internal static IDictionary PropertyTypeRegistry
{
get => _propertyTypeRegistry;
set => _propertyTypeRegistry = value; // I hope you know what you're doing!
}
static MainSerializer()
{
InitializePropertyTypeRegistry();
}
private static IEnumerable GetDependentAssemblies(Assembly analyzedAssembly)
{
return AppDomain.CurrentDomain.GetAssemblies().Where(a => GetNamesOfAssembliesReferencedBy(a).Contains(analyzedAssembly.FullName));
}
public static IEnumerable GetNamesOfAssembliesReferencedBy(Assembly assembly)
{
return assembly.GetReferencedAssemblies().Select(assemblyName => assemblyName.FullName);
}
private static Type registryParentDataType = typeof(PropertyData);
///
/// Initializes the property type registry.
///
private static void InitializePropertyTypeRegistry()
{
if (_propertyTypeRegistry != null) return;
_propertyTypeRegistry = new Dictionary();
Assembly[] allDependentAssemblies = GetDependentAssemblies(registryParentDataType.Assembly).ToArray();
Assembly[] allAssemblies = new Assembly[allDependentAssemblies.Length + 1];
allAssemblies[0] = registryParentDataType.Assembly;
Array.Copy(allDependentAssemblies, 0, allAssemblies, 1, allDependentAssemblies.Length);
for (int i = 0; i < allAssemblies.Length; i++)
{
Type[] allPropertyDataTypes = allAssemblies[i].GetTypes().Where(t => t.IsSubclassOf(registryParentDataType)).ToArray();
for (int j = 0; j < allPropertyDataTypes.Length; j++)
{
Type currentPropertyDataType = allPropertyDataTypes[j];
if (currentPropertyDataType == null || currentPropertyDataType.ContainsGenericParameters) continue;
var testInstance = Activator.CreateInstance(currentPropertyDataType);
FString returnedPropType = currentPropertyDataType.GetProperty("PropertyType")?.GetValue(testInstance, null) as FString;
if (returnedPropType == null) continue;
bool? returnedHasCustomStructSerialization = currentPropertyDataType.GetProperty("HasCustomStructSerialization")?.GetValue(testInstance, null) as bool?;
if (returnedHasCustomStructSerialization == null) continue;
bool? returnedShouldBeRegistered = currentPropertyDataType.GetProperty("ShouldBeRegistered")?.GetValue(testInstance, null) as bool?;
if (returnedShouldBeRegistered == null) continue;
if ((bool)returnedShouldBeRegistered)
{
RegistryEntry res = new RegistryEntry();
res.PropertyType = currentPropertyDataType;
res.HasCustomStructSerialization = (bool)returnedHasCustomStructSerialization;
var nameParam = Expression.Parameter(typeof(FName));
res.Creator = Expression.Lambda>(
Expression.New(currentPropertyDataType.GetConstructor(new[] { typeof(FName), }), new[] { nameParam, }),
nameParam
).Compile();
_propertyTypeRegistry[returnedPropType.Value] = res;
}
}
}
// Fetch the current git commit while we're here
UAPUtils.CurrentCommit = string.Empty;
using (Stream stream = registryParentDataType.Assembly.GetManifestResourceStream("UAssetAPI.git_commit.txt"))
{
if (stream != null)
{
using (StreamReader reader = new StreamReader(stream))
{
if (reader != null) UAPUtils.CurrentCommit = reader.ReadToEnd().Trim();
}
}
}
}
///
/// Generates an unversioned header based on a list of properties, and sorts the list in the correct order to be serialized.
///
/// The list of properties to sort and generate an unversioned header from.
/// The name of the parent of all the properties.
/// The path to the module that the parent class/struct of this property is contained within.
/// The UAsset which the properties are contained within.
public static FUnversionedHeader GenerateUnversionedHeader(ref List data, FName parentName, FName parentModulePath, UAsset asset)
{
var sortedProps = new List();
if (!asset.HasUnversionedProperties) return null; // no point in wasting time generating it
if (asset.Mappings == null) return null;
int firstNumAll = int.MaxValue;
int lastNumAll = int.MinValue;
HashSet propertiesToTouch = new HashSet();
Dictionary propMap = new Dictionary();
HashSet zeroProps = new HashSet();
foreach (PropertyData entry in data)
{
if (!asset.Mappings.TryGetProperty(entry.Name, entry.Ancestry, entry.ArrayIndex, asset, out _, out int idx)) throw new FormatException("No valid property \"" + entry.Name.ToString() + "\" in class " + entry.Ancestry.Parent.ToString());
propMap[idx] = entry;
if (entry.CanBeZero(asset) && entry.IsZero) zeroProps.Add(idx);
if (idx < firstNumAll) firstNumAll = idx;
if (idx > lastNumAll) lastNumAll = idx;
propertiesToTouch.Add(idx);
}
int lastNumBefore = -1;
List allFrags = new List();
if (propertiesToTouch.Count > 0)
{
while (true)
{
HashSet fragmentHasAnyZeros = new HashSet(); // add 0 if any zeros from 0 to (FFragment.ValueMax-1), 1 if any zeros from FFragment.ValueMax to (FFragment.ValueMax*2-1), etc.
int firstNum = lastNumBefore + 1;
while (!propertiesToTouch.Contains(firstNum) && firstNum <= lastNumAll) firstNum++;
if (firstNum > lastNumAll) break;
#if DEBUGVERBOSE
if (allFrags.Count > 0) Debug.WriteLine("W: " + allFrags[allFrags.Count - 1]);
#endif
int lastNum = firstNum;
while (propertiesToTouch.Contains(lastNum))
{
if (zeroProps.Contains(lastNum))
{
int valueNum = lastNum - firstNum + 1;
fragmentHasAnyZeros.Add(valueNum / FFragment.ValueMax);
}
sortedProps.Add(propMap[lastNum]);
lastNum++;
}
lastNum--;
var newFrag = FFragment.GetFromBounds(lastNumBefore, firstNum, lastNum, fragmentHasAnyZeros.Contains(0), false);
// add extra 127s if we went over the max for either skip or value
while (newFrag.SkipNum > FFragment.SkipMax)
{
allFrags.Add(new FFragment(FFragment.SkipMax, 0, false, false));
newFrag.SkipNum -= FFragment.SkipMax;
}
int fragIdx = 0;
while (newFrag.ValueNum > FFragment.ValueMax)
{
allFrags.Add(new FFragment(newFrag.SkipNum, FFragment.ValueMax, false, fragmentHasAnyZeros.Contains(fragIdx), firstNum + FFragment.ValueMax * fragIdx));
newFrag.ValueNum -= FFragment.ValueMax;
newFrag.FirstNum += FFragment.ValueMax;
newFrag.SkipNum = 0;
newFrag.bHasAnyZeroes = fragmentHasAnyZeros.Contains(++fragIdx);
}
allFrags.Add(newFrag);
lastNumBefore = lastNum;
}
allFrags[allFrags.Count - 1].bIsLast = true;
#if DEBUGVERBOSE
Debug.WriteLine("W: " + allFrags[allFrags.Count - 1]);
#endif
}
else
{
// add "blank" fragment
// i'm pretty sure that any SkipNum should work here as long as ValueNum = 0, but this is what the engine does
string highestSchema = parentName?.ToString();
// i doubt that this is true, empirically tested; need more data
int numSkip = 0;
if (asset.ObjectVersion >= ObjectVersion.VER_UE4_CORRECT_LICENSEE_FLAG)
{
numSkip = Math.Min(asset.Mappings.GetAllProperties(highestSchema, parentModulePath?.ToString(), asset).Count, FFragment.SkipMax);
}
else
{
numSkip = asset.Mappings.Schemas[highestSchema].Properties.Count == 0 ? 0 : Math.Min(asset.Mappings.GetAllProperties(highestSchema, parentModulePath?.ToString(), asset).Count, FFragment.SkipMax);
}
allFrags.Add(new FFragment(numSkip, 0, true, false));
}
// generate zero mask
bool bHasNonZeroValues = false;
List zeroMaskList = new List();
foreach (var frag in allFrags)
{
if (frag.bHasAnyZeroes)
{
for (int i = 0; i < frag.ValueNum; i++)
{
bool isZero = zeroProps.Contains(frag.FirstNum + i);
if (!isZero) bHasNonZeroValues = true;
zeroMaskList.Add(isZero);
}
}
}
BitArray zeroMask = new BitArray(zeroMaskList.ToArray());
var res = new FUnversionedHeader();
res.Fragments = new LinkedList();
foreach (var frag in allFrags) res.Fragments.AddLast(frag);
res.ZeroMask = zeroMask;
res.bHasNonZeroValues = bHasNonZeroValues;
if (res.Fragments.Count > 0)
{
res.CurrentFragment = res.Fragments.First;
res.UnversionedPropertyIndex = res.CurrentFragment.Value.FirstNum;
}
data.Clear();
data.AddRange(sortedProps);
return res;
}
///
/// Initializes the correct PropertyData class based off of serialized name, type, etc.
///
/// The serialized type of this property.
/// The serialized name of this property.
/// The ancestry of the parent of this property.
/// The name of the parent class/struct of this property.
/// The path to the module that the parent class/struct of this property is contained within.
/// The UAsset which this property is contained within.
/// The BinaryReader to read from. If left unspecified, you must call the method manually.
/// The length of this property on disk in bytes.
/// Property tag flags, if available.
/// The duplication index of this property.
/// Does this property serialize its header in the current context?
/// Is the body of this property empty?
/// The complete property type name, if available.
/// A new PropertyData instance based off of the passed parameters.
public static PropertyData TypeToClass(FName type, FName name, AncestryInfo ancestry, FName parentName, FName parentModulePath, UAsset asset, AssetBinaryReader reader = null, int leng = 0, EPropertyTagFlags propertyTagFlags = EPropertyTagFlags.None, int ArrayIndex = 0, bool includeHeader = true, bool isZero = false, FPropertyTypeName propertyTypeName = null)
{
long startingOffset = 0;
if (reader != null) startingOffset = reader.BaseStream.Position;
if (type.Value.Value == "None") return null;
PropertyData data = null;
if (PropertyTypeRegistry.ContainsKey(type.Value.Value))
{
data = PropertyTypeRegistry[type.Value.Value].Creator.Invoke(name);
}
else
{
#if DEBUGVERBOSE
Debug.WriteLine("-----------");
Debug.WriteLine("Parsing unknown type " + type.ToString());
Debug.WriteLine("Length: " + leng);
if (reader != null) Debug.WriteLine("Pos: " + reader.BaseStream.Position);
Debug.WriteLine("Last type: " + lastType.PropertyType?.ToString());
if (lastType is ArrayPropertyData) Debug.WriteLine("Last array's type was " + ((ArrayPropertyData)lastType).ArrayType?.ToString());
if (lastType is StructPropertyData) Debug.WriteLine("Last struct's type was " + ((StructPropertyData)lastType).StructType?.ToString());
if (lastType is MapPropertyData lastTypeMap)
{
if (lastTypeMap.Value.Count == 0)
{
Debug.WriteLine("Last map's key type was " + lastTypeMap.KeyType?.ToString());
Debug.WriteLine("Last map's value type was " + lastTypeMap.ValueType?.ToString());
}
else
{
Debug.WriteLine("Last map's key type was " + lastTypeMap.Value.Keys.ElementAt(0).PropertyType?.ToString());
Debug.WriteLine("Last map's value type was " + lastTypeMap.Value[0].PropertyType?.ToString());
}
}
Debug.WriteLine("-----------");
#endif
if (leng > 0)
{
data = new UnknownPropertyData(name);
((UnknownPropertyData)data).SetSerializingPropertyType(type.Value);
}
else
{
if (reader == null) throw new FormatException("Unknown property type: " + type.ToString() + " (on " + name.ToString() + ")");
throw new FormatException("Unknown property type: " + type.ToString() + " (on " + name.ToString() + " at " + reader.BaseStream.Position + ")");
}
}
#if DEBUGVERBOSE
lastType = data;
#endif
data.IsZero = isZero;
data.PropertyTagFlags = propertyTagFlags;
data.Ancestry.Initialize(ancestry, parentName, parentModulePath);
data.ArrayIndex = ArrayIndex;
data.PropertyTypeName = propertyTypeName;
if (reader != null && !isZero)
{
long posBefore = reader.BaseStream.Position;
try
{
data.Read(reader, includeHeader, leng);
}
catch (Exception)
{
// if asset is unversioned, bubble the error up to make the whole export fail
// because unversioned headers aren't properly reconstructed currently
if (data is StructPropertyData && !reader.Asset.HasUnversionedProperties)
{
reader.BaseStream.Position = posBefore;
data = new RawStructPropertyData(name);
data.Ancestry.Initialize(ancestry, parentName, parentModulePath);
data.ArrayIndex = ArrayIndex;
data.PropertyTypeName = propertyTypeName;
data.Read(reader, includeHeader, leng);
}
else
{
throw;
}
}
if (data.Offset == 0) data.Offset = startingOffset; // fallback
}
else if (reader != null && isZero)
{
data.InitializeZero(reader);
}
return data;
}
///
/// Reads a property into memory.
///
/// The BinaryReader to read from. The underlying stream should be at the position of the property to be read.
/// The ancestry of the parent of this property.
/// The name of the parent class/struct of this property.
/// The path to the module that the parent class/struct of this property is contained within.
/// The unversioned header to be used when reading this property. Leave null if none exists.
/// Does this property serialize its header in the current context?
/// The property read from disk.
public static PropertyData Read(AssetBinaryReader reader, AncestryInfo ancestry, FName parentName, FName parentModulePath, FUnversionedHeader header, bool includeHeader)
{
long startingOffset = reader.BaseStream.Position;
FName name = null;
FName type = null;
int leng = 0;
EPropertyTagFlags propertyTagFlags = EPropertyTagFlags.None;
FPropertyTypeName typeName = null;
int ArrayIndex = 0;
string structType = null;
bool isZero = false;
if (reader.Asset.HasUnversionedProperties)
{
if (reader.Asset.Mappings == null)
{
throw new InvalidMappingsException();
}
UsmapSchema relevantSchema = reader.Asset.Mappings.GetSchemaFromName(parentName?.ToString(), reader.Asset, parentModulePath?.ToString());
while (header.UnversionedPropertyIndex > header.CurrentFragment.Value.LastNum)
{
if (header.CurrentFragment.Value.bIsLast) return null;
header.CurrentFragment = header.CurrentFragment.Next;
header.UnversionedPropertyIndex = header.CurrentFragment.Value.FirstNum;
}
int practicingUnversionedPropertyIndex = header.UnversionedPropertyIndex;
while (practicingUnversionedPropertyIndex >= relevantSchema.PropCount) // if needed, go to parent struct
{
practicingUnversionedPropertyIndex -= relevantSchema.PropCount;
if (relevantSchema.SuperType != null && relevantSchema.SuperTypeModulePath != null && reader.Asset.Mappings.Schemas.ContainsKey(relevantSchema.SuperTypeModulePath + "." + relevantSchema.SuperType))
{
relevantSchema = reader.Asset.Mappings.Schemas[relevantSchema.SuperTypeModulePath + "." + relevantSchema.SuperType];
}
else if (relevantSchema.SuperType != null && reader.Asset.Mappings.Schemas.ContainsKey(relevantSchema.SuperType) && relevantSchema.Name != relevantSchema.SuperType) // name is insufficient if name of super is same as name of child
{
relevantSchema = reader.Asset.Mappings.Schemas[relevantSchema.SuperType];
}
else
{
relevantSchema = null;
}
if (relevantSchema == null) throw new FormatException("Failed to find a valid property for schema index " + header.UnversionedPropertyIndex + " in the class " + parentName.ToString());
}
UsmapProperty relevantProperty = relevantSchema.Properties[practicingUnversionedPropertyIndex];
header.UnversionedPropertyIndex += 1;
name = FName.DefineDummy(reader.Asset, relevantProperty.Name);
type = FName.DefineDummy(reader.Asset, relevantProperty.PropertyData.Type.ToString());
leng = 1; // not serialized
ArrayIndex = relevantProperty.ArrayIndex;
if (relevantProperty.PropertyData is UsmapStructData usmapStruc) structType = usmapStruc.StructType;
// check if property is zero
if (header.CurrentFragment.Value.bHasAnyZeroes)
{
isZero = header.ZeroMaskIndex >= header.ZeroMask.Count ? false : header.ZeroMask.Get(header.ZeroMaskIndex);
header.ZeroMaskIndex++;
}
}
else if (reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
name = reader.ReadFName();
if (name.Value.Value == "None") return null;
typeName = new FPropertyTypeName(reader);
type = typeName.GetName();
leng = reader.ReadInt32();
propertyTagFlags = (EPropertyTagFlags)reader.ReadByte();
if (propertyTagFlags.HasFlag(EPropertyTagFlags.HasArrayIndex))
{
ArrayIndex = reader.ReadInt32();
}
}
else
{
name = reader.ReadFName();
if (name.Value.Value == "None") return null;
type = reader.ReadFName();
leng = reader.ReadInt32();
ArrayIndex = reader.ReadInt32();
}
PropertyData result = TypeToClass(type, name, ancestry, parentName, parentModulePath, reader.Asset, reader, leng, propertyTagFlags, ArrayIndex, includeHeader, isZero, typeName);
if (structType != null && result is StructPropertyData strucProp) strucProp.StructType = FName.DefineDummy(reader.Asset, structType);
result.Offset = startingOffset;
//Debug.WriteLine(type);
return result;
}
internal static readonly Regex allNonLetters = new Regex("[^a-zA-Z]", RegexOptions.Compiled);
///
/// Reads an FProperty into memory. Primarily used as a part of serialization.
///
/// The BinaryReader to read from. The underlying stream should be at the position of the FProperty to be read.
/// The FProperty read from disk.
public static FProperty ReadFProperty(AssetBinaryReader reader)
{
FName serializedType = reader.ReadFName();
Type requestedType = Type.GetType("UAssetAPI.FieldTypes.F" + allNonLetters.Replace(serializedType.Value.Value, string.Empty));
if (requestedType == null) requestedType = typeof(FGenericProperty);
var res = (FProperty)Activator.CreateInstance(requestedType);
res.SerializedType = serializedType;
res.Read(reader);
return res;
}
///
/// Serializes an FProperty from memory.
///
/// The FProperty to serialize.
/// The BinaryWriter to serialize the FProperty to.
public static void WriteFProperty(FProperty prop, AssetBinaryWriter writer)
{
writer.Write(prop.SerializedType);
prop.Write(writer);
}
///
/// Reads a UProperty into memory. Primarily used as a part of serialization.
///
/// The BinaryReader to read from. The underlying stream should be at the position of the UProperty to be read.
/// The type of UProperty to be read.
/// The FProperty read from disk.
public static UProperty ReadUProperty(AssetBinaryReader reader, FName serializedType)
{
return ReadUProperty(reader, Type.GetType("UAssetAPI.FieldTypes.U" + allNonLetters.Replace(serializedType.Value.Value, string.Empty)));
}
///
/// Reads a UProperty into memory. Primarily used as a part of serialization.
///
/// The BinaryReader to read from. The underlying stream should be at the position of the UProperty to be read.
/// The type of UProperty to be read.
/// The FProperty read from disk.
public static UProperty ReadUProperty(AssetBinaryReader reader, Type requestedType)
{
if (requestedType == null) requestedType = typeof(UGenericProperty);
var res = (UProperty)Activator.CreateInstance(requestedType);
res.Read(reader);
return res;
}
///
/// Reads a UProperty into memory. Primarily used as a part of serialization.
///
/// The BinaryReader to read from. The underlying stream should be at the position of the UProperty to be read.
/// The FProperty read from disk.
public static T ReadUProperty(AssetBinaryReader reader) where T : UProperty
{
var res = (UProperty)Activator.CreateInstance(typeof(T));
res.Read(reader);
return (T)res;
}
///
/// Serializes a UProperty from memory.
///
/// The UProperty to serialize.
/// The BinaryWriter to serialize the UProperty to.
public static void WriteUProperty(UProperty prop, AssetBinaryWriter writer)
{
prop.Write(writer);
}
///
/// Serializes a property from memory.
///
/// The property to serialize.
/// The BinaryWriter to serialize the property to.
/// Does this property serialize its header in the current context?
/// The serial offset where the length of the property is stored.
public static int Write(PropertyData property, AssetBinaryWriter writer, bool includeHeader)
{
if (property == null) return -1;
property.Offset = writer.BaseStream.Position;
if (writer.Asset.HasUnversionedProperties)
{
if (!property.IsZero || !property.CanBeZero(writer.Asset)) property.Write(writer, includeHeader);
return -1; // length is not serialized
}
else if (writer.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
writer.Write(property.Name);
if (property is UnknownPropertyData unknownProp)
{
writer.Write(new FName(writer.Asset, unknownProp.SerializingPropertyType));
writer.Write((int)0);
}
else
{
property.PropertyTypeName.Write(writer);
}
// update flags appropriately
if (property is BoolPropertyData bProp)
{
if (bProp.Value) property.PropertyTagFlags |= EPropertyTagFlags.BoolTrue;
else property.PropertyTagFlags &= ~EPropertyTagFlags.BoolTrue;
}
if (property.ArrayIndex != 0) property.PropertyTagFlags |= EPropertyTagFlags.HasArrayIndex;
else property.PropertyTagFlags &= ~EPropertyTagFlags.HasArrayIndex;
if (property.PropertyGuid != null) property.PropertyTagFlags |= EPropertyTagFlags.HasPropertyGuid;
else property.PropertyTagFlags &= ~EPropertyTagFlags.HasPropertyGuid;
int oldLoc = (int)writer.BaseStream.Position;
writer.Write((int)0); // initial length
writer.Write((byte)property.PropertyTagFlags);
if (property.ArrayIndex != 0) writer.Write(property.ArrayIndex);
int realLength = property.Write(writer, includeHeader);
int newLoc = (int)writer.BaseStream.Position;
writer.Seek(oldLoc, SeekOrigin.Begin);
writer.Write(realLength);
writer.Seek(newLoc, SeekOrigin.Begin);
return oldLoc;
}
else
{
writer.Write(property.Name);
if (property is UnknownPropertyData unknownProp)
{
writer.Write(new FName(writer.Asset, unknownProp.SerializingPropertyType));
}
else if (property is RawStructPropertyData)
{
writer.Write(new FName(writer.Asset, FString.FromString("StructProperty")));
}
else
{
writer.Write(new FName(writer.Asset, property.PropertyType));
}
int oldLoc = (int)writer.BaseStream.Position;
writer.Write((int)0); // initial length
writer.Write(property.ArrayIndex);
int realLength = property.Write(writer, includeHeader);
int newLoc = (int)writer.BaseStream.Position;
writer.Seek(oldLoc, SeekOrigin.Begin);
writer.Write(realLength);
writer.Seek(newLoc, SeekOrigin.Begin);
return oldLoc;
}
}
}
}
================================================
FILE: UAssetAPI/Pak/Interop.cs
================================================
/*
This code was written by @trumank as part of the repak crate: https://github.com/trumank/repak
MIT License
Copyright 2024 Truman Kilen, spuds
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
namespace UAssetAPI;
using System;
using System.Runtime.InteropServices;
public static class RePakInterop
{
public const string NativeLib = "repak_bind";
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr pak_setup_allocator();
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr pak_teardown_allocator();
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr pak_builder_new();
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern void pak_builder_drop(IntPtr builder);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern void pak_reader_drop(IntPtr reader);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern void pak_writer_drop(IntPtr writer);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern void pak_buffer_drop(IntPtr buffer, ulong length);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern void pak_cstring_drop(IntPtr cstrign);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr pak_builder_key(IntPtr builder, byte[] key);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr pak_builder_compression(IntPtr builder, byte[] compressions, int length);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr pak_builder_reader(IntPtr builder, StreamCallbacks ctx);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr pak_builder_writer(IntPtr builder, StreamCallbacks ctx, PakVersion version, string mount_point, ulong path_hash_seed = 0);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern PakVersion pak_reader_version(IntPtr reader);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr pak_reader_mount_point(IntPtr reader);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern int pak_reader_get(IntPtr reader, string path, StreamCallbacks ctx, out IntPtr buffer, out ulong length);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr pak_reader_files(IntPtr reader, out ulong length);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr pak_drop_files(IntPtr buffer, ulong length);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern int pak_writer_write_file(IntPtr writer, string path, byte[] data, int data_len);
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl)]
public static extern int pak_writer_write_index(IntPtr writer);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate long ReadCallback(IntPtr context, IntPtr buffer, ulong bufferLen);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int WriteCallback(IntPtr context, IntPtr buffer, int bufferLen);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate ulong SeekCallback(IntPtr context, long offset, int origin);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int FlushCallback(IntPtr context);
[StructLayout(LayoutKind.Sequential)]
public struct StreamCallbacks
{
public IntPtr Context;
public ReadCallback ReadCb;
public WriteCallback WriteCb;
public SeekCallback SeekCb;
public FlushCallback FlushCb;
}
}
================================================
FILE: UAssetAPI/Pak/RePak.cs
================================================
/*
This code has been slightly adapted from code written by @trumank as part of the repak crate: https://github.com/trumank/repak
MIT License
Copyright 2024 Truman Kilen, spuds
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
namespace UAssetAPI;
using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Runtime.InteropServices;
using UAssetAPI.PropertyTypes.Objects;
public enum PakVersion : byte
{
V0 = 0,
V1 = 1,
V2 = 2,
V3 = 3,
V4 = 4,
V5 = 5,
V6 = 6,
V7 = 7,
V8A = 8,
V8B = 9,
V9 = 10,
V10 = 11,
V11 = 12
}
public enum PakCompression : byte
{
Zlib,
Gzip,
Oodle,
Zstd
}
public class PakBuilder : SafeHandleZeroOrMinusOneIsInvalid
{
public PakBuilder() : base(true)
{
try
{
SetHandle(RePakInterop.pak_builder_new());
}
catch (Exception ex)
{
if (ex is DllNotFoundException || ex is BadImageFormatException)
{
// extract dll if needed
string outPath = Path.Combine(AppContext.BaseDirectory, RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "repak_bind.so" : "repak_bind.dll");
string resourceName = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "UAssetAPI.repak_bind.so.gz" : "UAssetAPI.repak_bind.dll.gz";
using (var resource = typeof(PropertyData).Assembly.GetManifestResourceStream(resourceName))
{
if (resource != null)
{
using (var file = new FileStream(outPath, FileMode.Create, FileAccess.Write))
{
using (var gzipStream = new GZipStream(resource, CompressionMode.Decompress))
{
gzipStream.CopyTo(file);
}
}
}
else
{
throw new DllNotFoundException("Failed to find resource: " + resourceName);
}
}
NativeLibrary.Load(outPath);
SetHandle(RePakInterop.pak_builder_new());
}
else
{
throw;
}
}
}
protected override bool ReleaseHandle()
{
RePakInterop.pak_builder_drop(handle);
return true;
}
public PakBuilder Key(byte[] key)
{
if (key.Length != 32) throw new Exception("Invalid AES key length");
SetHandle(RePakInterop.pak_builder_key(handle, key));
return this;
}
public PakBuilder Compression(PakCompression[] compressions)
{
SetHandle(RePakInterop.pak_builder_compression(handle, compressions.Select(c => Convert.ToByte(c)).ToArray(), compressions.Length));
return this;
}
public PakWriter Writer(Stream stream, PakVersion version = PakVersion.V11, string mountPoint = "../../../", ulong pathHashSeed = 0)
{
if (handle == IntPtr.Zero) throw new Exception("PakBuilder handle invalid");
var streamCtx = StreamCallbacks.Create(stream);
IntPtr writerHandle = RePakInterop.pak_builder_writer(handle, streamCtx, version, mountPoint, pathHashSeed);
// pak_builder_reader consumes the builder
SetHandleAsInvalid();
SetHandle(IntPtr.Zero);
return new PakWriter(writerHandle, streamCtx.Context);
}
public PakReader Reader(Stream stream)
{
if (handle == IntPtr.Zero) throw new Exception("PakBuilder handle invalid");
var streamCtx = StreamCallbacks.Create(stream);
IntPtr readerHandle = RePakInterop.pak_builder_reader(handle, streamCtx);
StreamCallbacks.Free(streamCtx.Context);
// pak_builder_reader consumes the builder
SetHandleAsInvalid();
SetHandle(IntPtr.Zero);
if (readerHandle == IntPtr.Zero) throw new Exception("Failed to create PakReader");
return new PakReader(readerHandle, stream);
}
}
public class PakWriter : SafeHandleZeroOrMinusOneIsInvalid
{
private IntPtr _streamCtx;
public PakWriter(IntPtr handle, IntPtr streamCtx) : base(true)
{
SetHandle(handle);
_streamCtx = streamCtx;
}
protected override bool ReleaseHandle()
{
RePakInterop.pak_writer_drop(handle);
StreamCallbacks.Free(_streamCtx);
return true;
}
public void WriteFile(string path, byte[] data)
{
if (handle == IntPtr.Zero) throw new Exception("PakWriter handle invalid");
int result = RePakInterop.pak_writer_write_file(handle, path, data, data.Length);
if (result != 0) throw new Exception("Failed to write file");
}
public void WriteIndex()
{
int result = RePakInterop.pak_writer_write_index(handle);
// write_index drops the writer
SetHandleAsInvalid();
SetHandle(IntPtr.Zero);
StreamCallbacks.Free(_streamCtx);
if (result != 0) throw new Exception("Failed to write index");
}
}
public class PakReader : SafeHandleZeroOrMinusOneIsInvalid
{
public PakReader(IntPtr handle, Stream stream) : base(true)
{
SetHandle(handle);
}
protected override bool ReleaseHandle()
{
RePakInterop.pak_reader_drop(handle);
return true;
}
public string GetMountPoint()
{
if (handle == IntPtr.Zero) throw new Exception("PakReader handle invalid");
var cstring = RePakInterop.pak_reader_mount_point(handle);
var mountPoint = Marshal.PtrToStringAnsi(cstring);
RePakInterop.pak_cstring_drop(cstring);
return mountPoint;
}
public PakVersion GetVersion()
{
if (handle == IntPtr.Zero) throw new Exception("PakReader handle invalid");
return RePakInterop.pak_reader_version(handle);
}
public byte[] Get(Stream stream, string path)
{
if (handle == IntPtr.Zero) throw new Exception("PakReader handle invalid");
var streamCtx = StreamCallbacks.Create(stream);
IntPtr bufferPtr;
ulong length;
int result = RePakInterop.pak_reader_get(handle, path, streamCtx, out bufferPtr, out length);
StreamCallbacks.Free(streamCtx.Context);
if (result != 0) return null;
byte[] buffer = new byte[length];
Marshal.Copy(bufferPtr, buffer, 0, (int)length);
RePakInterop.pak_buffer_drop(bufferPtr, length);
return buffer;
}
public string[] Files()
{
if (handle == IntPtr.Zero) throw new Exception("PakReader handle invalid");
ulong length;
IntPtr filesPtr = RePakInterop.pak_reader_files(handle, out length);
var files = new List();
for (ulong i = 0; i < length; i++)
{
IntPtr currentPtr = Marshal.ReadIntPtr(filesPtr, (int)i * IntPtr.Size);
files.Add(Marshal.PtrToStringAnsi(currentPtr));
}
RePakInterop.pak_drop_files(filesPtr, length);
return files.ToArray();
}
}
public static class StreamCallbacks
{
public static RePakInterop.StreamCallbacks Create(Stream stream)
{
return new RePakInterop.StreamCallbacks
{
Context = GCHandle.ToIntPtr(GCHandle.Alloc(stream)),
ReadCb = StreamCallbacks.ReadCallback,
WriteCb = StreamCallbacks.WriteCallback,
SeekCb = StreamCallbacks.SeekCallback,
FlushCb = StreamCallbacks.FlushCallback
};
}
public static void Free(IntPtr streamCtx)
{
GCHandle.FromIntPtr(streamCtx).Free();
}
public static long ReadCallback(IntPtr context, IntPtr buffer, ulong bufferLen)
{
var stream = (Stream)GCHandle.FromIntPtr(context).Target;
try
{
byte[] bufferManaged = new byte[bufferLen];
int bytesRead = stream.Read(bufferManaged, 0, (int)bufferLen);
Marshal.Copy(bufferManaged, 0, buffer, bytesRead);
return bytesRead;
}
catch (Exception e)
{
Console.WriteLine($"Error during read {e}");
return -1;
}
}
public static int WriteCallback(IntPtr context, IntPtr buffer, int bufferLen)
{
var stream = (Stream)GCHandle.FromIntPtr(context).Target;
var bufferManaged = new byte[bufferLen];
Marshal.Copy(buffer, bufferManaged, 0, bufferLen);
try
{
stream.Write(bufferManaged, 0, bufferLen);
return bufferLen;
}
catch (Exception e)
{
Console.WriteLine($"Error during write {e}");
return -1;
}
}
public static ulong SeekCallback(IntPtr context, long offset, int origin)
{
var stream = (Stream)GCHandle.FromIntPtr(context).Target;
try
{
long newPosition = stream.Seek(offset, (SeekOrigin)origin);
return (ulong)newPosition;
}
catch (Exception e)
{
Console.WriteLine($"Error during seek {e}");
return ulong.MaxValue;
}
}
public static int FlushCallback(IntPtr context)
{
var stream = (Stream)GCHandle.FromIntPtr(context).Target;
try
{
stream.Flush();
return 0;
}
catch (Exception e)
{
Console.WriteLine($"Error during flush {e}");
return 1;
}
}
}
================================================
FILE: UAssetAPI/Properties/AssemblyInfo.cs
================================================
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#if DEBUGTRACING
using PostSharp.Patterns.Diagnostics;
using PostSharp.Extensibility;
#endif
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("178417ec-1177-413e-be85-c83aecd64279")]
#if DEBUGTRACING
[assembly: UAssetAPI.Trace.LoggingAspect]
[assembly: UAssetAPI.Trace.LoggingAspect(AttributeTargetTypes="UAssetAPI.Trace.*", AttributeExclude = true)]
#endif
================================================
FILE: UAssetAPI/Properties/Resources.Designer.cs
================================================
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
using UAssetAPI.ExportTypes;
namespace UAssetAPI.Properties {
using System;
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
///
/// Returns the cached ResourceManager instance used by this class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UAssetAPI.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
///
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
///
/// Looks up a localized resource of type System.Byte[].
///
internal static byte[] AC7Key {
get {
object obj = ResourceManager.GetObject("AC7Key", resourceCulture);
return ((byte[])(obj));
}
}
}
}
================================================
FILE: UAssetAPI/Properties/Resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
..\Resources\AC7Key.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
================================================
FILE: UAssetAPI/PropertyTypes/Objects/ArrayPropertyData.cs
================================================
using Newtonsoft.Json;
using System;
using System.IO;
using UAssetAPI.PropertyTypes.Structs;
using UAssetAPI.UnrealTypes;
using UAssetAPI.Unversioned;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes an array.
///
public class ArrayPropertyData : PropertyData
{
[JsonProperty]
public FName ArrayType;
[JsonProperty]
public StructPropertyData DummyStruct;
internal bool ShouldSerializeStructsDifferently = true;
public bool ShouldSerializeDummyStruct()
{
return Value.Length == 0;
}
public ArrayPropertyData(FName name) : base(name)
{
Value = [];
}
public ArrayPropertyData()
{
Value = [];
}
private static readonly FString CurrentPropertyType = new FString("ArrayProperty");
public override FString PropertyType => CurrentPropertyType;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader && !reader.Asset.HasUnversionedProperties)
{
if (reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
if (PropertyTypeName is null) throw new FormatException("PropertyTypeName is required to read ArrayProperty with complete type names.");
ArrayType = PropertyTypeName.GetParameter(0).GetName();
}
else
{
ArrayType = reader.ReadFName();
}
this.ReadEndPropertyTag(reader);
}
FName arrayStructType = null;
if (reader.Asset.Mappings != null && ArrayType == null && reader.Asset.Mappings.TryGetPropertyData(Name, Ancestry, reader.Asset, out UsmapArrayData strucDat1))
{
ArrayType = FName.DefineDummy(reader.Asset, strucDat1.InnerType.Type.ToString());
if (strucDat1.InnerType is UsmapStructData strucDat2) arrayStructType = FName.DefineDummy(reader.Asset, strucDat2.StructType);
}
if (reader.Asset.HasUnversionedProperties && ArrayType == null)
{
throw new InvalidOperationException("Unable to determine array type for array " + Name.Value.Value + " in class " + Ancestry.Parent.Value.Value);
}
int numEntries = reader.ReadInt32();
if (ArrayType.Value.Value == "StructProperty" && ShouldSerializeStructsDifferently && !reader.Asset.HasUnversionedProperties)
{
var results = new PropertyData[numEntries];
FName name = this.Name;
long structLength = 1;
FName fullType = FName.DefineDummy(reader.Asset, "Generic");
Guid structGUID = new Guid();
bool isSpecialCase = false;
if (reader.Asset is UAsset asset)
{
isSpecialCase = reader.Asset.ObjectVersion == ObjectVersion.VER_UE4_INNER_ARRAY_TAG_INFO && asset.WillSerializeNameHashes == true;
}
if (reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
fullType = PropertyTypeName.GetParameter(0).GetParameter(0).GetName();
}
else if (reader.Asset.ObjectVersion >= ObjectVersion.VER_UE4_INNER_ARRAY_TAG_INFO && !isSpecialCase)
{
name = reader.ReadFName();
if (name.Value.Value.Equals("None"))
{
Value = results;
return;
}
FName thisArrayType = reader.ReadFName();
if (thisArrayType.Value.Value.Equals("None"))
{
Value = results;
return;
}
if (thisArrayType.Value.Value != ArrayType.Value.Value) throw new FormatException("Invalid array type: " + thisArrayType.ToString() + " vs " + ArrayType.ToString());
structLength = reader.ReadInt64(); // length value
fullType = reader.ReadFName();
structGUID = new Guid(reader.ReadBytes(16));
reader.ReadPropertyGuid();
}
else
{
// override using mappings or ArrayStructTypeOverride if applicable
if (arrayStructType != null)
{
fullType = arrayStructType;
}
else if (reader.Asset.ArrayStructTypeOverride.ContainsKey(this.Name.Value.Value))
{
fullType = FName.DefineDummy(reader.Asset, reader.Asset.ArrayStructTypeOverride[this.Name.Value.Value]);
}
}
if (numEntries == 0)
{
DummyStruct = new StructPropertyData(name, fullType)
{
StructGUID = structGUID
};
}
else
{
var propTypeName = PropertyTypeName?.GetParameter(0);
for (int i = 0; i < numEntries; i++)
{
var data = new StructPropertyData(name, fullType);
data.Offset = reader.BaseStream.Position;
data.Ancestry.Initialize(Ancestry, Name);
data.PropertyTypeName = propTypeName;
data.Read(reader, false, structLength, 0, PropertySerializationContext.Array);
data.StructGUID = structGUID;
results[i] = data;
}
DummyStruct = (StructPropertyData)results[0];
}
Value = results;
}
else
{
if (numEntries == 0)
{
Value = [];
return;
}
int averageSizeEstimate = (int)((leng1 - 4) / numEntries);
if (averageSizeEstimate <= 0) averageSizeEstimate = 1; // missing possible edge case where leng1 = 4 and numEntries = 2, may result is wrong size
var propTypeName = PropertyTypeName?.GetParameter(0);
var results = new PropertyData[numEntries];
for (int i = 0; i < numEntries; i++)
{
results[i] = MainSerializer.TypeToClass(ArrayType, FName.DefineDummy(reader.Asset, i.ToString(), int.MinValue), Ancestry, Name, null, reader.Asset, propertyTypeName: propTypeName);
results[i].Offset = reader.BaseStream.Position;
if (results[i] is StructPropertyData data) data.StructType = arrayStructType == null ? FName.DefineDummy(reader.Asset, "Generic") : arrayStructType;
results[i].Read(reader, false, averageSizeEstimate, 0, PropertySerializationContext.Array);
}
Value = results;
}
}
public override void ResolveAncestries(UAsset asset, AncestryInfo ancestrySoFar)
{
var ancestryNew = (AncestryInfo)ancestrySoFar.Clone();
ancestryNew.SetAsParent(Name);
if (Value != null)
{
for (int i = 0; i < Value.Length; i++) Value[i].ResolveAncestries(asset, ancestryNew);
}
base.ResolveAncestries(asset, ancestrySoFar);
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (Value == null) Value = [];
// let's get our ArrayType if we don't already know it
// if Value has entries, take it from there
if (Value.Length > 0)
{
ArrayType = writer.Asset.HasUnversionedProperties ? FName.DefineDummy(writer.Asset, Value[0].PropertyType) : new FName(writer.Asset, Value[0].PropertyType);
}
// otherwise, let's check mappings
FName arrayStructType = null;
if (writer.Asset.Mappings != null && ArrayType == null && writer.Asset.Mappings.TryGetPropertyData(Name, Ancestry, writer.Asset, out UsmapArrayData strucDat1))
{
ArrayType = FName.DefineDummy(writer.Asset, strucDat1.InnerType.Type.ToString());
if (strucDat1.InnerType is UsmapStructData strucDat2) arrayStructType = FName.DefineDummy(writer.Asset, strucDat2.StructType);
}
// at this point, if we couldn't get our ArrayType and we're using unversioned properties, we can't continue; otherwise, not needed
if (writer.Asset.HasUnversionedProperties && ArrayType == null)
{
throw new InvalidOperationException("Unable to determine array type for array " + Name.Value.Value + " in class " + Ancestry.Parent.Value.Value);
}
// begin actual serialization
if (includeHeader && !writer.Asset.HasUnversionedProperties)
{
if (writer.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
writer.Write(ArrayType);
}
this.WriteEndPropertyTag(writer);
}
int here = (int)writer.BaseStream.Position;
writer.Write(Value.Length);
if (ArrayType?.Value?.Value == "StructProperty" && ShouldSerializeStructsDifferently && !writer.Asset.HasUnversionedProperties)
{
if (Value.Length == 0 && DummyStruct == null)
{
// let's try and reconstruct DummyStruct, if we can
if (arrayStructType == null && writer.Asset.ArrayStructTypeOverride.ContainsKey(this.Name.Value.Value))
{
arrayStructType = FName.DefineDummy(writer.Asset, writer.Asset.ArrayStructTypeOverride[this.Name.Value.Value]);
}
if (arrayStructType == null)
{
throw new InvalidOperationException("Unable to reconstruct DummyStruct within empty StructProperty array " + Name.Value.Value + " in class " + Ancestry.Parent.Value.Value);
}
DummyStruct = new StructPropertyData(this.Name, arrayStructType)
{
StructGUID = Guid.Empty // not sure what else to use here...
};
}
if (Value.Length > 0) DummyStruct = (StructPropertyData)Value[0];
FName fullType = DummyStruct.StructType;
int lengthLoc = -1;
bool isSpecialCase = false;
if (writer.Asset is UAsset)
{
isSpecialCase = writer.Asset.ObjectVersion == ObjectVersion.VER_UE4_INNER_ARRAY_TAG_INFO && ((UAsset)writer.Asset).WillSerializeNameHashes == true;
}
if (writer.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME && writer.Asset.ObjectVersion >= ObjectVersion.VER_UE4_INNER_ARRAY_TAG_INFO && !isSpecialCase)
{
writer.Write(DummyStruct.Name);
writer.Write(new FName(writer.Asset, "StructProperty"));
lengthLoc = (int)writer.BaseStream.Position;
writer.Write((long)0);
writer.Write(fullType);
if (writer.Asset.ObjectVersion >= ObjectVersion.VER_UE4_STRUCT_GUID_IN_PROPERTY_TAG) writer.Write(DummyStruct.StructGUID.ToByteArray());
if (writer.Asset.ObjectVersion >= ObjectVersion.VER_UE4_PROPERTY_GUID_IN_PROPERTY_TAG) writer.Write((byte)0);
}
for (int i = 0; i < Value.Length; i++)
{
((StructPropertyData)Value[i]).StructType = fullType;
Value[i].Offset = writer.BaseStream.Position;
Value[i].Write(writer, false);
}
if (writer.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME && writer.Asset.ObjectVersion >= ObjectVersion.VER_UE4_INNER_ARRAY_TAG_INFO && !isSpecialCase)
{
int fullLen = (int)writer.BaseStream.Position - lengthLoc;
int newLoc = (int)writer.BaseStream.Position;
writer.Seek(lengthLoc, SeekOrigin.Begin);
writer.Write(fullLen - 32 - (includeHeader ? 1 : 0));
writer.Seek(newLoc, SeekOrigin.Begin);
}
}
else
{
for (int i = 0; i < Value.Length; i++)
{
Value[i].Offset = writer.BaseStream.Position;
Value[i].Write(writer, false, PropertySerializationContext.Array);
}
}
return (int)writer.BaseStream.Position - here;
}
public override void FromString(string[] d, UAsset asset)
{
if (d[4] != null) ArrayType = FName.FromString(asset, d[4]);
}
protected override void HandleCloned(PropertyData res)
{
ArrayPropertyData cloningProperty = (ArrayPropertyData)res;
cloningProperty.ArrayType = (FName)this.ArrayType?.Clone();
cloningProperty.DummyStruct = (StructPropertyData)this.DummyStruct?.Clone();
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/BoolPropertyData.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a boolean ().
///
public class BoolPropertyData : PropertyData
{
public BoolPropertyData(FName name) : base(name) { }
public BoolPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("BoolProperty");
public override FString PropertyType => CurrentPropertyType;
public override object DefaultValue => false;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (reader.Asset.HasUnversionedProperties || reader.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
Value = reader.ReadBoolean();
}
else
{
if (serializationContext is PropertySerializationContext.Map or PropertySerializationContext.Array)
Value = reader.ReadBoolean();
else
Value = this.PropertyTagFlags.HasFlag(EPropertyTagFlags.BoolTrue);
}
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (writer.Asset.HasUnversionedProperties || writer.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
writer.Write(Value);
}
else if (serializationContext is PropertySerializationContext.Map or PropertySerializationContext.Array)
{
writer.Write(Value);
}
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
return 0;
}
public override string ToString()
{
return Convert.ToString(Value);
}
public override void FromString(string[] d, UAsset asset)
{
Value = d[0].Equals("1") || d[0].ToLowerInvariant().Equals("true");
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/BytePropertyData.cs
================================================
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.Unversioned;
namespace UAssetAPI.PropertyTypes.Objects;
public enum BytePropertyType
{
Byte,
FName,
}
///
/// Describes a byte or an enumeration value.
///
public class BytePropertyData : PropertyData
{
[JsonProperty]
[JsonConverter(typeof(StringEnumConverter))]
public BytePropertyType ByteType;
[JsonProperty]
public FName EnumType;
[JsonProperty]
public byte Value;
[JsonProperty]
public FName EnumValue;
public bool ShouldSerializeValue()
{
return ByteType == BytePropertyType.Byte;
}
public bool ShouldSerializeEnumValue()
{
return ByteType == BytePropertyType.FName;
}
public BytePropertyData(FName name) : base(name) { }
public BytePropertyData() { }
private static readonly FString CurrentPropertyType = new FString("ByteProperty");
public override FString PropertyType { get { return CurrentPropertyType; } }
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
ReadCustom(reader, includeHeader, leng1, leng2, true);
}
private void ReadCustom(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2, bool canRepeat)
{
if (includeHeader && !reader.Asset.HasUnversionedProperties)
{
if (reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
if (PropertyTypeName is null) throw new FormatException("PropertyTypeName is required to read ByteProperty with complete type names.");
EnumType = PropertyTypeName.GetParameter(0).GetName();
}
else
{
EnumType = reader.ReadFName();
}
this.ReadEndPropertyTag(reader);
}
bool useFailsafe = true;
if (reader.Asset.Mappings != null && reader.Asset.Mappings.TryGetPropertyData(Name, Ancestry, reader.Asset, out UsmapPropertyData propDat))
{
useFailsafe = false;
ByteType = propDat is UsmapEnumData ? BytePropertyType.FName : BytePropertyType.Byte; // TODO: not always accurate?
}
// override with length if it makes sense to do so
if (!reader.Asset.HasUnversionedProperties)
{
switch (leng1)
{
case 1:
ByteType = BytePropertyType.Byte;
useFailsafe = false;
break;
case 8:
ByteType = BytePropertyType.FName;
useFailsafe = false;
break;
}
}
if (useFailsafe)
{
switch (leng1)
{
case 0: // Should be only seen in maps; fallback "make our best guess and pray we're right" behavior
int nameMapPointer = reader.ReadInt32();
int nameMapIndex = reader.ReadInt32();
reader.BaseStream.Position -= sizeof(int) * 2;
// In the case of it being serialized as just a byte, it will probably try to parse part of the next property and produce something too big for the name map
if (nameMapPointer >= 0 && nameMapPointer < reader.Asset.GetNameMapIndexList().Count && nameMapIndex == 0 && !reader.Asset.GetNameReference(nameMapPointer).ToString().Contains("/"))
{
ByteType = BytePropertyType.FName;
break;
}
else
{
ByteType = BytePropertyType.Byte;
break;
}
default:
if (canRepeat)
{
ReadCustom(reader, false, leng2, 0, false);
return;
}
throw new FormatException("Invalid length " + leng1 + " for ByteProperty");
}
}
if (ByteType == BytePropertyType.Byte)
{
Value = reader.ReadByte();
}
else if (ByteType == BytePropertyType.FName)
{
EnumValue = reader.ReadFName();
}
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader && !writer.Asset.HasUnversionedProperties)
{
if (writer.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
writer.Write(EnumType);
}
this.WriteEndPropertyTag(writer);
}
switch (ByteType)
{
case BytePropertyType.Byte:
writer.Write((byte)Value);
return 1;
case BytePropertyType.FName:
writer.Write(EnumValue);
return 8;
default:
throw new FormatException("Invalid BytePropertyType " + ByteType);
}
}
public FName GetEnumBase()
{
return EnumType;
}
public FName GetEnumFull()
{
return EnumValue;
}
public override string ToString()
{
if (ByteType == BytePropertyType.Byte) return Convert.ToString(Value);
//return GetEnumFull().Value;
return Value.ToString();
}
public override void FromString(string[] d, UAsset asset)
{
EnumType = FName.FromString(asset, d[0]);
if (byte.TryParse(d[1], out byte res))
{
ByteType = BytePropertyType.Byte;
Value = res;
}
else
{
ByteType = BytePropertyType.FName;
EnumValue = FName.FromString(asset, d[1]);
}
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/DelegatePropertyData.cs
================================================
using Newtonsoft.Json;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a function bound to an Object.
///
[JsonObject(MemberSerialization.OptIn)]
public class FDelegate
{
///
/// References the main actor export
///
[JsonProperty]
public FPackageIndex Object;
///
/// The name of the delegate
///
[JsonProperty]
public FName Delegate;
public FDelegate(FPackageIndex _object, FName @delegate)
{
Object = _object;
Delegate = @delegate;
}
public FDelegate() { }
public FDelegate(AssetBinaryReader reader)
{
Object = new FPackageIndex(reader);
Delegate = reader.ReadFName();
}
public int Write(AssetBinaryWriter writer)
{
writer.XFERPTR(Object);
int size = sizeof(int);
writer.Write(Delegate);
size += 8;
return size;
}
}
///
/// Describes a function bound to an Object.
///
public class DelegatePropertyData : PropertyData
{
public DelegatePropertyData(FName name) : base(name) { }
public DelegatePropertyData() { }
private static readonly FString CurrentPropertyType = new FString("DelegateProperty");
public override FString PropertyType => CurrentPropertyType;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = new FDelegate(reader);
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
Value ??= new FDelegate(FPackageIndex.FromRawIndex(0), null);
return Value.Write(writer);
}
public override string ToString()
{
return null;
}
public override void FromString(string[] d, UAsset asset)
{
}
protected override void HandleCloned(PropertyData res)
{
DelegatePropertyData cloningProperty = (DelegatePropertyData)res;
cloningProperty.Value = new FDelegate(this.Value.Object, this.Value.Delegate);
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/DoublePropertyData.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.JSON;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes an IEEE 64-bit floating point variable ().
///
public class DoublePropertyData : PropertyData
{
///
/// The double that this property represents.
///
[JsonProperty]
[JsonConverter(typeof(FSignedZeroJsonConverter))]
public double Value
{
get => GetObject();
set => SetObject(value);
}
public DoublePropertyData(FName name) : base(name) { }
public DoublePropertyData() { }
private static readonly FString CurrentPropertyType = new FString("DoubleProperty");
public override FString PropertyType => CurrentPropertyType;
public override object DefaultValue => (double)0;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadDouble();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
writer.Write(Value);
return sizeof(double);
}
public override string ToString()
{
return Convert.ToString(Value);
}
public override void FromString(string[] d, UAsset asset)
{
Value = 0;
if (double.TryParse(d[0], out double res)) Value = res;
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/EnumPropertyData.cs
================================================
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using UAssetAPI.UnrealTypes;
using UAssetAPI.Unversioned;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes an enumeration value.
///
public class EnumPropertyData : PropertyData
{
[JsonProperty]
public FName EnumType;
///
/// Only used with unversioned properties.
///
[JsonProperty]
public FName InnerType;
public EnumPropertyData(FName name) : base(name) { }
public EnumPropertyData() { }
private static readonly List ValidEnumInnerTypeList = ["ByteProperty", "UInt16Property", "UInt32Property", "Int8Property", "Int16Property", "IntProperty", "Int64Property"];
private static readonly FString CurrentPropertyType = new FString("EnumProperty");
public override FString PropertyType { get { return CurrentPropertyType; } }
public static readonly string InvalidEnumIndexFallbackPrefix = "UASSETAPI_INVALID_ENUM_IDX_";
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (reader.Asset.Mappings != null && reader.Asset.Mappings.TryGetPropertyData(Name, Ancestry, reader.Asset, out UsmapEnumData enumDat1))
{
EnumType = reader.Asset.HasUnversionedProperties ? FName.DefineDummy(reader.Asset, enumDat1.Name) : new FName(reader.Asset, enumDat1.Name);
InnerType = reader.Asset.HasUnversionedProperties ? FName.DefineDummy(reader.Asset, enumDat1.InnerType.Type.ToString()) : new FName(reader.Asset, enumDat1.Name);
}
if (reader.Asset.HasUnversionedProperties && serializationContext == PropertySerializationContext.Normal)
{
Value = null;
if (InnerType?.Value.Value == "ByteProperty" || InnerType?.Value.Value == "UInt16Property" || InnerType?.Value.Value == "UInt32Property")
{
long enumIndice = 0;
switch (InnerType?.Value.Value)
{
case "ByteProperty":
enumIndice = reader.ReadByte();
if (enumIndice == byte.MaxValue) return;
break;
case "UInt16Property":
enumIndice = reader.ReadUInt16();
if (enumIndice == ushort.MaxValue) return;
break;
case "UInt32Property":
enumIndice = reader.ReadUInt32();
if (enumIndice == uint.MaxValue) return;
break;
}
var listOfValues = reader.Asset.Mappings.EnumMap[EnumType.Value.Value].Values;
if (enumIndice < listOfValues.Count)
{
Value = FName.DefineDummy(reader.Asset, listOfValues[enumIndice]);
}
else
{
// fallback
Value = FName.DefineDummy(reader.Asset, InvalidEnumIndexFallbackPrefix + enumIndice.ToString());
}
return;
}
if (InnerType?.Value.Value == "Int8Property" || InnerType?.Value.Value == "Int16Property" ||
InnerType?.Value.Value == "IntProperty" || InnerType?.Value.Value == "Int64Property")
{
long enumIndice = 0;
switch (InnerType?.Value.Value)
{
case "Int8Property":
enumIndice = reader.ReadSByte();
break;
case "Int16Property":
enumIndice = reader.ReadInt16();
break;
case "IntProperty":
enumIndice = reader.ReadInt32();
break;
case "Int64Property":
enumIndice = reader.ReadInt64();
break;
}
var listOfValues = reader.Asset.Mappings.EnumMap[EnumType.Value.Value].Values;
if (enumIndice < listOfValues.Count)
{
Value = FName.DefineDummy(reader.Asset, listOfValues[enumIndice]);
}
else
{
// fallback
Value = FName.DefineDummy(reader.Asset, InvalidEnumIndexFallbackPrefix + enumIndice.ToString());
}
return;
}
}
if (includeHeader && !reader.Asset.HasUnversionedProperties)
{
if (reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
if (PropertyTypeName is null) throw new FormatException("PropertyTypeName is required to read EnumProperty with complete type names.");
EnumType = PropertyTypeName.GetParameter(0).GetName();
}
else
{
EnumType = reader.ReadFName();
}
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadFName();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (writer.Asset.Mappings != null && writer.Asset.Mappings.TryGetPropertyData(Name, Ancestry, writer.Asset, out UsmapEnumData enumDat1))
{
EnumType = writer.Asset.HasUnversionedProperties ? FName.DefineDummy(writer.Asset, enumDat1.Name) : new FName(writer.Asset, enumDat1.Name);
InnerType = writer.Asset.HasUnversionedProperties ? FName.DefineDummy(writer.Asset, enumDat1.InnerType.Type.ToString()) : new FName(writer.Asset, enumDat1.Name);
}
if (writer.Asset.HasUnversionedProperties && serializationContext == PropertySerializationContext.Normal)
{
if (ValidEnumInnerTypeList.Contains(InnerType?.Value?.Value))
{
long enumIndice = 0;
var listOfEnums = writer.Asset.Mappings.EnumMap[EnumType.Value.Value].Values;
var validIndices = listOfEnums.Where(pair => pair.Value == Value.Value.Value).Select(pair => pair.Key);
if (Value == null)
{
enumIndice = -1;
}
else if (validIndices.Count() == 0)
{
bool success = false;
if (Value.Value.Value.StartsWith(InvalidEnumIndexFallbackPrefix))
{
success = long.TryParse(Value.Value.Value.Substring(InvalidEnumIndexFallbackPrefix.Length), out enumIndice);
}
if (!success)
{
throw new FormatException("Could not serialize EnumProperty value " + Value.Value.Value + " as " + InnerType?.Value?.Value);
}
}
else
{
enumIndice = validIndices.FirstOrDefault();
}
switch (InnerType?.Value?.Value)
{
case "ByteProperty":
writer.Write((byte)enumIndice);
return sizeof(byte);
case "UInt16Property":
writer.Write((ushort)enumIndice);
return sizeof(ushort);
case "UInt32Property":
writer.Write((uint)enumIndice);
return sizeof(uint);
case "Int8Property":
writer.Write((sbyte)enumIndice);
return sizeof(sbyte);
case "Int16Property":
writer.Write((short)enumIndice);
return sizeof(short);
case "IntProperty":
writer.Write((int)enumIndice);
return sizeof(int);
case "Int64Property":
writer.Write((long)enumIndice);
return sizeof(long);
}
}
}
if (includeHeader && !writer.Asset.HasUnversionedProperties)
{
if (writer.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
writer.Write(EnumType);
}
this.WriteEndPropertyTag(writer);
}
writer.Write(Value);
return sizeof(int) * 2;
}
internal override void InitializeZero(AssetBinaryReader reader)
{
if (reader.Asset.Mappings.TryGetPropertyData(Name, Ancestry, reader.Asset, out UsmapEnumData enumDat1))
{
EnumType = FName.DefineDummy(reader.Asset, enumDat1.Name);
InnerType = FName.DefineDummy(reader.Asset, enumDat1.InnerType.Type.ToString());
}
// fill in data for enumIndice = 0 to provide clarity for end-user
if (ValidEnumInnerTypeList.Contains(InnerType?.Value?.Value))
{
long enumIndice = 0;
var listOfValues = reader.Asset.Mappings.EnumMap[EnumType.Value.Value].Values;
if (enumIndice == byte.MaxValue)
{
Value = null;
}
else if (enumIndice < listOfValues.Count)
{
Value = FName.DefineDummy(reader.Asset, listOfValues[enumIndice]);
}
else
{
// fallback
Value = FName.DefineDummy(reader.Asset, InvalidEnumIndexFallbackPrefix + enumIndice.ToString());
}
}
}
public override string ToString()
{
return Value.ToString();
}
// note: Value must be overridden manually after this is called in cases where serializationContext != PropertySerializationContext.Normal, to ensure not dummy
public override void FromString(string[] d, UAsset asset)
{
if (d[0] != "null" && d[0] != null)
{
EnumType = asset.HasUnversionedProperties ? FName.DefineDummy(asset, d[0]) : FName.FromString(asset, d[0]);
}
else
{
EnumType = null;
}
if (d[1] != "null" && d[1] != null)
{
Value = (asset.HasUnversionedProperties && (ValidEnumInnerTypeList.Contains(InnerType?.Value?.Value))) ? FName.DefineDummy(asset, d[1]) : FName.FromString(asset, d[1]);
}
else
{
Value = null;
}
}
protected override void HandleCloned(PropertyData res)
{
EnumPropertyData cloningProperty = (EnumPropertyData)res;
cloningProperty.EnumType = (FName)this.EnumType?.Clone();
cloningProperty.InnerType = (FName)this.InnerType?.Clone();
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/FieldPathPropertyData.cs
================================================
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a reference variable to another object which may be null, and may become valid or invalid at any point. Near synonym for .
///
public class FieldPathPropertyData : BasePropertyData
{
public FieldPathPropertyData(FName name) : base(name) { }
public FieldPathPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("FieldPathProperty");
public override FString PropertyType => CurrentPropertyType;
public override bool HasCustomStructSerialization => false;
public override object DefaultValue => new FFieldPath();
public override string ToString()
{
// Expected format is: FullPackageName.Subobject[:Subobject:...]:FieldName
return "";
}
public override void FromString(string[] d, UAsset asset)
{
// Expected format is: FullPackageName.Subobject[:Subobject:...]:FieldName
Value = new FFieldPath();
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/FloatPropertyData.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.JSON;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes an IEEE 32-bit floating point variable ().
///
public class FloatPropertyData : PropertyData
{
///
/// The float that this property represents.
///
[JsonProperty]
[JsonConverter(typeof(FSignedZeroJsonConverter))]
public float Value
{
get => GetObject();
set => SetObject(value);
}
public FloatPropertyData(FName name) : base(name) { }
public FloatPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("FloatProperty");
public override FString PropertyType { get { return CurrentPropertyType; } }
public override object DefaultValue { get { return (float)0; } }
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadSingle();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
writer.Write(Value);
return sizeof(float);
}
public override string ToString()
{
return Convert.ToString(Value); // maybe: , System.Globalization.CultureInfo.InvariantCulture
}
public override void FromString(string[] d, UAsset asset)
{
Value = 0;
if (float.TryParse(d[0], out float res)) Value = res;
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/Int16PropertyData.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a 16-bit signed integer variable ().
///
public class Int16PropertyData : PropertyData
{
public Int16PropertyData(FName name) : base(name) { }
public Int16PropertyData() { }
private static readonly FString CurrentPropertyType = new FString("Int16Property");
public override FString PropertyType => CurrentPropertyType;
public override object DefaultValue => (short)0;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = (reader.Asset.HasUnversionedProperties && serializationContext != PropertySerializationContext.Normal) ? (short)reader.ReadInt64() : reader.ReadInt16();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
if (writer.Asset.HasUnversionedProperties && serializationContext != PropertySerializationContext.Normal)
{
writer.Write((long)Value);
return sizeof(long);
}
writer.Write(Value);
return sizeof(short);
}
public override string ToString()
{
return Convert.ToString(Value);
}
public override void FromString(string[] d, UAsset asset)
{
Value = 0;
if (short.TryParse(d[0], out short res)) Value = res;
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/Int64PropertyData.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a 64-bit signed integer variable ().
///
public class Int64PropertyData : PropertyData
{
public Int64PropertyData(FName name) : base(name) { }
public Int64PropertyData() { }
private static readonly FString CurrentPropertyType = new FString("Int64Property");
public override FString PropertyType { get { return CurrentPropertyType; } }
public override object DefaultValue { get { return (long)0; } }
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadInt64();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
writer.Write(Value);
return sizeof(long);
}
public override string ToString()
{
return Convert.ToString(Value);
}
public override void FromString(string[] d, UAsset asset)
{
Value = 0;
if (long.TryParse(d[0], out long res)) Value = res;
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/Int8PropertyData.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes an 8-bit signed integer variable ().
///
public class Int8PropertyData : PropertyData
{
public Int8PropertyData(FName name) : base(name) { }
public Int8PropertyData() { }
private static readonly FString CurrentPropertyType = new FString("Int8Property");
public override FString PropertyType => CurrentPropertyType;
public override object DefaultValue => (sbyte)0;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadSByte();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
writer.Write(Value);
return sizeof(sbyte);
}
public override string ToString()
{
return Convert.ToString(Value);
}
public override void FromString(string[] d, UAsset asset)
{
Value = 0;
if (sbyte.TryParse(d[0], out sbyte res)) Value = res;
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/IntPropertyData.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a 32-bit signed integer variable ().
///
public class IntPropertyData : PropertyData
{
public IntPropertyData(FName name) : base(name) { }
public IntPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("IntProperty");
public override FString PropertyType => CurrentPropertyType;
public override object DefaultValue => (int)0;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadInt32();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
writer.Write(Value);
return sizeof(int);
}
public override string ToString()
{
return Convert.ToString(Value);
}
public override void FromString(string[] d, UAsset asset)
{
Value = 0;
if (int.TryParse(d[0], out int res)) Value = res;
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/InterfacePropertyData.cs
================================================
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a reference variable to another object (import/export) which may be null ().
///
public class InterfacePropertyData : ObjectPropertyData
{
public InterfacePropertyData(FName name) : base(name) { }
public InterfacePropertyData() { }
private static readonly FString CurrentPropertyType = new FString("InterfaceProperty");
public override FString PropertyType => CurrentPropertyType;
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/MapPropertyData.cs
================================================
using Newtonsoft.Json;
using System;
using System.Linq;
using UAssetAPI.JSON;
using UAssetAPI.PropertyTypes.Structs;
using UAssetAPI.UnrealTypes;
using UAssetAPI.Unversioned;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a map.
///
public class MapPropertyData : PropertyData
{
///
/// The map that this property represents.
///
[JsonProperty]
[JsonConverter(typeof(TMapJsonConverter))]
public TMap Value;
///
/// Used when the length of the map is zero.
/// ]
[JsonProperty]
public FName KeyType;
///
/// Used when the length of the map is zero.
///
[JsonProperty]
public FName ValueType;
public bool ShouldSerializeKeyType() => Value.Count == 0;
public bool ShouldSerializeValueType() => Value.Count == 0;
[JsonProperty]
public PropertyData[] KeysToRemove = null;
public MapPropertyData(FName name) : base(name)
{
Value = new TMap();
}
public MapPropertyData()
{
Value = new TMap();
}
private static readonly FString CurrentPropertyType = new FString("MapProperty");
public override FString PropertyType { get { return CurrentPropertyType; } }
private PropertyData MapTypeToClass(FName type, FName name, AssetBinaryReader reader, int leng, bool includeHeader, bool isKey)
{
switch (type.Value.Value)
{
case "StructProperty":
FName strucType = null;
FPropertyTypeName propertyTypeNameLocal = PropertyTypeName?.GetParameter(isKey ? 0 : 1);
if (!reader.Asset.HasUnversionedProperties && reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
strucType = propertyTypeNameLocal?.GetParameter(0).GetName();
}
else if (reader.Asset.Mappings != null && reader.Asset.Mappings.TryGetPropertyData(Name, Ancestry, reader.Asset, out UsmapMapData mapDat))
{
if (isKey && mapDat.InnerType is UsmapStructData strucDat1)
{
strucType = FName.DefineDummy(reader.Asset, strucDat1.StructType);
}
else if (mapDat.ValueType is UsmapStructData strucDat2)
{
strucType = FName.DefineDummy(reader.Asset, strucDat2.StructType);
}
}
else if (reader.Asset.MapStructTypeOverride.ContainsKey(name.Value.Value))
{
if (isKey)
{
strucType = FName.DefineDummy(reader.Asset, reader.Asset.MapStructTypeOverride[name.Value.Value].Item1);
}
else
{
strucType = FName.DefineDummy(reader.Asset, reader.Asset.MapStructTypeOverride[name.Value.Value].Item2);
if (name.Value.Value == "TrackSignatureToTrackIdentifier" && reader.Asset.GetEngineVersion() <= EngineVersion.VER_UE4_18)
strucType = FName.DefineDummy(reader.Asset, "Generic");
}
}
if (strucType?.Value == null) strucType = FName.DefineDummy(reader.Asset, "Generic");
StructPropertyData data = new StructPropertyData(name, strucType);
data.Ancestry.Initialize(Ancestry, Name);
data.Offset = reader.BaseStream.Position;
data.PropertyTypeName = propertyTypeNameLocal;
data.Read(reader, false, 1, 0, PropertySerializationContext.Map);
return data;
default:
var res = MainSerializer.TypeToClass(type, name, Ancestry, Name, null, reader.Asset, null, leng, propertyTypeName: PropertyTypeName?.GetParameter(0));
res.Ancestry.Initialize(Ancestry, Name);
res.Read(reader, includeHeader, leng, 0, PropertySerializationContext.Map);
return res;
}
}
private TMap ReadRawMap(AssetBinaryReader reader, FName type1, FName type2, int numEntries)
{
var resultingDict = new TMap();
PropertyData data1 = null;
PropertyData data2 = null;
for (int i = 0; i < numEntries; i++)
{
data1 = MapTypeToClass(type1, Name, reader, 0, false, true);
data2 = MapTypeToClass(type2, Name, reader, 0, false, false);
resultingDict.Add(data1, data2);
}
return resultingDict;
}
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
FName type1 = null, type2 = null;
if (includeHeader && !reader.Asset.HasUnversionedProperties)
{
if (reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
if (PropertyTypeName is null) throw new FormatException("PropertyTypeName is required to read MapProperty with complete type names.");
type1 = PropertyTypeName.GetParameter(0).GetName();
type2 = PropertyTypeName.GetParameter(1).GetName();
}
else
{
type1 = reader.ReadFName();
type2 = reader.ReadFName();
}
this.ReadEndPropertyTag(reader);
}
if (reader.Asset.Mappings != null && type1 == null && type2 == null && reader.Asset.Mappings.TryGetPropertyData(Name, Ancestry, reader.Asset, out UsmapMapData strucDat1))
{
type1 = FName.DefineDummy(reader.Asset, strucDat1.InnerType.Type.ToString());
type2 = FName.DefineDummy(reader.Asset, strucDat1.ValueType.Type.ToString());
}
int numKeysToRemove = reader.ReadInt32();
KeysToRemove = new PropertyData[numKeysToRemove];
for (int i = 0; i < numKeysToRemove; i++)
{
KeysToRemove[i] = MapTypeToClass(type1, Name, reader, 0, false, true);
}
int numEntries = reader.ReadInt32();
if (numEntries == 0)
{
KeyType = type1;
ValueType = type2;
}
Value = ReadRawMap(reader, type1, type2, numEntries);
}
public override void ResolveAncestries(UAsset asset, AncestryInfo ancestrySoFar)
{
var ancestryNew = (AncestryInfo)ancestrySoFar.Clone();
ancestryNew.SetAsParent(Name);
if (Value != null)
{
foreach (var entry in Value)
{
entry.Key.ResolveAncestries(asset, ancestryNew);
entry.Value.ResolveAncestries(asset, ancestryNew);
}
}
base.ResolveAncestries(asset, ancestrySoFar);
}
private void WriteRawMap(AssetBinaryWriter writer, TMap map)
{
if (map == null) return;
foreach (var entry in map)
{
entry.Key.Offset = writer.BaseStream.Position;
entry.Key.Write(writer, false, PropertySerializationContext.Map);
entry.Value.Offset = writer.BaseStream.Position;
entry.Value.Write(writer, false, PropertySerializationContext.Map);
}
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader && !writer.Asset.HasUnversionedProperties)
{
if (writer.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
if (Value.Count > 0)
{
writer.Write(new FName(writer.Asset, Value.Keys.ElementAt(0).PropertyType));
writer.Write(new FName(writer.Asset, Value[0].PropertyType));
}
else
{
writer.Write(KeyType);
writer.Write(ValueType);
}
}
this.WriteEndPropertyTag(writer);
}
int here = (int)writer.BaseStream.Position;
writer.Write(KeysToRemove?.Length ?? 0);
if (KeysToRemove != null)
{
for (int i = 0; i < KeysToRemove.Length; i++)
{
var entry = KeysToRemove[i];
entry.Offset = writer.BaseStream.Position;
entry.Write(writer, false, PropertySerializationContext.Array);
}
}
writer.Write(Value?.Count ?? 0);
WriteRawMap(writer, Value);
return (int)writer.BaseStream.Position - here;
}
protected override void HandleCloned(PropertyData res)
{
MapPropertyData cloningProperty = (MapPropertyData)res;
if (this.Value != null)
{
var newDict = new TMap();
foreach (var entry in this.Value)
{
newDict[(PropertyData)entry.Key.Clone()] = (PropertyData)entry.Value.Clone();
}
cloningProperty.Value = newDict;
}
else
{
cloningProperty.Value = null;
}
cloningProperty.KeysToRemove = (PropertyData[])this.KeysToRemove?.Clone();
cloningProperty.KeyType = (FName)this.KeyType?.Clone();
cloningProperty.ValueType = (FName)this.ValueType?.Clone();
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/MulticastDelegatePropertyData.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a list of functions bound to an Object.
///
public class MulticastDelegatePropertyData : PropertyData
{
public MulticastDelegatePropertyData(FName name) : base(name) { }
public MulticastDelegatePropertyData() { }
private static readonly FString CurrentPropertyType = new FString("MulticastDelegateProperty");
public override FString PropertyType => CurrentPropertyType;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadArray(() => new FDelegate(reader));
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
Value ??= [];
writer.Write(Value.Length);
var size = 4;
for (int i = 0; i < Value.Length; i++)
{
size += Value[i].Write(writer);
}
return size;
}
public override string ToString()
{
string oup = "(";
for (int i = 0; i < Value.Length; i++)
{
oup += "(" + Convert.ToString(Value[i].Object.Index) + ", " + Value[i].Delegate.Value.Value + "), ";
}
return oup.Substring(0, oup.Length - 2) + ")";
}
public override void FromString(string[] d, UAsset asset)
{
}
protected override void HandleCloned(PropertyData res)
{
MulticastDelegatePropertyData cloningProperty = (MulticastDelegatePropertyData)res;
if (Value != null)
{
FDelegate[] newData = new FDelegate[Value.Length];
for (int i = 0; i < Value.Length; i++)
{
newData[i] = new FDelegate(Value[i].Object, (FName)Value[i].Delegate.Clone());
}
cloningProperty.Value = newData;
}
else
{
cloningProperty.Value = null;
}
}
}
///
/// Describes a list of functions bound to an Object.
///
public class MulticastSparseDelegatePropertyData : MulticastDelegatePropertyData
{
public MulticastSparseDelegatePropertyData(FName name) : base(name) { }
public MulticastSparseDelegatePropertyData() { }
private static readonly FString CurrentPropertyType = new FString("MulticastSparseDelegateProperty");
public override FString PropertyType => CurrentPropertyType;
}
///
/// Describes a list of functions bound to an Object.
///
public class MulticastInlineDelegatePropertyData : MulticastDelegatePropertyData
{
public MulticastInlineDelegatePropertyData(FName name) : base(name) { }
public MulticastInlineDelegatePropertyData() { }
private static readonly FString CurrentPropertyType = new FString("MulticastInlineDelegateProperty");
public override FString PropertyType => CurrentPropertyType;
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/NamePropertyData.cs
================================================
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes an .
///
public class NamePropertyData : PropertyData
{
public NamePropertyData(FName name) : base(name) { }
public NamePropertyData() { }
private static readonly FString CurrentPropertyType = new FString("NameProperty");
public override FString PropertyType => CurrentPropertyType;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadFName();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
writer.Write(Value);
return sizeof(int) * 2;
}
public override bool CanBeZero(UAsset asset)
{
return Value?.Value?.Value == null; // if the index is 0, we need to serialize it anyways
}
public override string ToString()
{
return Value == null ? "null" : Value.ToString();
}
public override void FromString(string[] d, UAsset asset)
{
Value = FName.FromString(asset, d[0]);
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/ObjectPropertyData.cs
================================================
using UAssetAPI.UnrealTypes;
using UAssetAPI.ExportTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a reference variable to another object (import/export) which may be null ().
///
public class ObjectPropertyData : PropertyData
{
public ObjectPropertyData(FName name) : base(name) { }
public ObjectPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("ObjectProperty");
public override FString PropertyType => CurrentPropertyType;
public override object DefaultValue => FPackageIndex.FromRawIndex(0);
///
/// Returns true if this ObjectProperty represents an import.
///
/// Is this ObjectProperty an import?
public bool IsImport() => Value.IsImport();
///
/// Returns true if this ObjectProperty represents an export.
///
/// Is this ObjectProperty an export?
public bool IsExport() => Value.IsExport();
///
/// Return true if this ObjectProperty represents null (i.e. neither an import nor an export)
///
/// Does this ObjectProperty represent null?
public bool IsNull() => Value.IsNull();
///
/// Check that this ObjectProperty is an import index and return the corresponding import.
///
/// The import that this ObjectProperty represents in the import map.
/// Thrown when this is not an index into the import map.
public Import ToImport(UAsset asset) => Value.ToImport(asset);
///
/// Check that this ObjectProperty is an export index and return the corresponding export.
///
/// The export that this ObjectProperty represents in the the export map.
/// Thrown when this is not an index into the export map.
public Export ToExport(UAsset asset) => Value.ToExport(asset);
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = new FPackageIndex(reader);
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
writer.Write(Value.Index);
return sizeof(int);
}
public override string ToString()
{
return Value.ToString();
}
public override void FromString(string[] d, UAsset asset)
{
if (int.TryParse(d[0], out int res))
{
Value = new FPackageIndex(res);
return;
}
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/PropertyData.cs
================================================
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects
{
public enum PropertySerializationContext
{
Normal,
Array,
Map,
StructFallback // a StructPropertyData with custom struct serialization falling back to standard serialization before/after reading custom data
}
[Flags]
public enum EPropertyTagFlags
{
None = 0x00,
HasArrayIndex = 0x01,
HasPropertyGuid = 0x02,
HasPropertyExtensions = 0x04,
HasBinaryOrNativeSerialize = 0x08,
BoolTrue = 0x10,
SkippedSerialize = 0x20,
}
[Flags]
public enum EPropertyTagExtension : byte
{
NoExtension = 0x00,
ReserveForFutureUse = 0x01,
OverridableInformation = 0x02,
}
public enum EOverriddenPropertyOperation
{
///
/// no overridden operation was recorded on this property
///
None = 0,
///
/// some sub property has recorded overridden operation
///
Modified,
///
/// everything has been overridden from this property down to every sub property/sub object
///
Replace,
///
/// this element was added in the container
///
Add,
///
/// this element was removed from the container
///
Remove
};
public class AncestryInfo : ICloneable
{
public List Ancestors = new List(5);
public FName Parent
{
get
{
if (Ancestors.Count == 0) return null;
return Ancestors[Ancestors.Count - 1];
}
set
{
Ancestors[Ancestors.Count - 1] = value;
}
}
public object Clone() // shallow
{
var res = new AncestryInfo();
res.Ancestors.AddRange(Ancestors);
return res;
}
public AncestryInfo CloneWithoutParent()
{
AncestryInfo res = (AncestryInfo)this.Clone();
res.Ancestors.RemoveAt(res.Ancestors.Count - 1);
return res;
}
public void Initialize(AncestryInfo ancestors, FName dad, FName modulePath = null)
{
Ancestors.Clear();
if (ancestors != null) Ancestors.AddRange(ancestors.Ancestors);
SetAsParent(dad, modulePath);
}
public void SetAsParent(FName dad, FName modulePath = null)
{
if (dad != null) Ancestors.Add(string.IsNullOrEmpty(modulePath?.Value?.Value) ? dad : FName.DefineDummy(null, modulePath.ToString() + "." + dad.ToString()));
}
}
///
/// Generic Unreal property class.
///
[JsonObject(MemberSerialization.OptIn)]
public abstract class PropertyData : ICloneable
{
///
/// The name of this property.
///
[JsonProperty]
public FName Name = null;
///
/// The ancestry of this property. Contains information about all the classes/structs that this property is contained within. Not serialized.
///
[JsonIgnore]
public AncestryInfo Ancestry = new AncestryInfo();
///
/// The array index of this property. Used to distinguish properties with the same name in the same struct.
///
[JsonProperty]
public int ArrayIndex = 0;
///
/// An optional property GUID. Nearly always null.
///
public Guid? PropertyGuid = null;
///
/// Whether or not this property is "zero," meaning that its body can be skipped during unversioned property serialization because it consists solely of null bytes.
/// This field will always be treated as if it is false if does not return true.
///
[JsonProperty]
public bool IsZero;
[JsonProperty]
public EPropertyTagFlags PropertyTagFlags;
[JsonProperty]
public FPropertyTypeName PropertyTypeName = null;
///
/// Optional extensions to serialize with this property.
///
[JsonProperty]
public EPropertyTagExtension PropertyTagExtensions; // always serialize just cuz we cant guarantee access to Asset here to check for versions between PROPERTY_TAG_EXTENSION_AND_OVERRIDABLE_SERIALIZATION and PROPERTY_TAG_COMPLETE_TYPE_NAME
[JsonProperty]
public EOverriddenPropertyOperation OverrideOperation;
[JsonProperty]
public bool bExperimentalOverridableLogic;
public bool ShouldSerializeOverrideOperation()
{
return PropertyTagExtensions.HasFlag(EPropertyTagExtension.OverridableInformation);
}
public bool ShouldSerializebExperimentalOverridableLogic()
{
return PropertyTagExtensions.HasFlag(EPropertyTagExtension.OverridableInformation);
}
///
/// The offset of this property on disk. This is for the user only, and has no bearing in the API itself.
///
public long Offset = -1;
///
/// An optional tag which can be set on any property in memory. This is for the user only, and has no bearing in the API itself.
///
public object Tag;
protected object _rawValue;
public virtual object RawValue
{
get
{
if (_rawValue == null && DefaultValue != null) _rawValue = DefaultValue;
return _rawValue;
}
set
{
_rawValue = value;
}
}
public void SetObject(object value)
{
RawValue = value;
}
public T GetObject()
{
if (RawValue is null) return default;
return (T)RawValue;
}
public PropertyData(FName name)
{
Name = name;
}
public PropertyData()
{
}
private static FString FallbackPropertyType = new FString(string.Empty);
///
/// Determines whether or not this particular property should be registered in the property registry and automatically used when parsing assets.
///
public virtual bool ShouldBeRegistered { get { return true; } }
///
/// Determines whether or not this particular property has custom serialization within a StructProperty.
///
public virtual bool HasCustomStructSerialization { get { return false; } }
///
/// The type of this property as an FString.
///
public virtual FString PropertyType { get { return FallbackPropertyType; } }
///
/// The default value of this property, used as a fallback when no value is defined. Null by default.
///
public virtual object DefaultValue { get { return null; } }
///
/// Reads out a property from a BinaryReader.
///
/// The BinaryReader to read from.
/// Whether or not to also read the "header" of the property, which is data considered by the Unreal Engine to be data that is part of the PropertyData base class rather than any particular child class.
/// An estimate for the length of the data being read out.
/// A second estimate for the length of the data being read out.
/// The context in which this property is being read.
public virtual void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
}
///
/// Resolves the ancestry of all child properties of this property.
///
public virtual void ResolveAncestries(UAsset asset, AncestryInfo ancestrySoFar)
{
Ancestry = ancestrySoFar;
}
///
/// Complete reading the property tag of this property.
///
protected virtual void ReadEndPropertyTag(AssetBinaryReader reader)
{
if (reader.Asset.HasUnversionedProperties) return;
if (reader.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
PropertyGuid = reader.ReadPropertyGuid();
}
else if (PropertyTagFlags.HasFlag(EPropertyTagFlags.HasPropertyGuid))
{
PropertyGuid = new Guid(reader.ReadBytes(16));
}
if (reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_EXTENSION_AND_OVERRIDABLE_SERIALIZATION)
{
if (reader.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME || PropertyTagFlags.HasFlag(EPropertyTagFlags.HasPropertyExtensions))
{
PropertyTagExtensions = (EPropertyTagExtension)reader.ReadByte();
if (PropertyTagExtensions.HasFlag(EPropertyTagExtension.OverridableInformation))
{
OverrideOperation = (EOverriddenPropertyOperation)reader.ReadByte();
bExperimentalOverridableLogic = reader.ReadBooleanInt();
}
}
}
}
///
/// Writes a property to a BinaryWriter.
///
/// The BinaryWriter to write from.
/// Whether or not to also write the "header" of the property, which is data considered by the Unreal Engine to be data that is part of the PropertyData base class rather than any particular child class.
/// The context in which this property is being written.
/// The length in bytes of the data that was written.
public virtual int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
return 0;
}
///
/// Initialize this property when serialized as zero.
///
/// The BinaryReader to read from.
internal virtual void InitializeZero(AssetBinaryReader reader)
{
}
///
/// Complete writing the property tag of this property.
///
protected virtual void WriteEndPropertyTag(AssetBinaryWriter writer)
{
if (writer.Asset.HasUnversionedProperties) return;
if (writer.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
writer.WritePropertyGuid(PropertyGuid);
if (writer.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_EXTENSION_AND_OVERRIDABLE_SERIALIZATION)
{
if (writer.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME || PropertyTagFlags.HasFlag(EPropertyTagFlags.HasPropertyExtensions))
{
writer.Write((byte)PropertyTagExtensions);
if (PropertyTagExtensions.HasFlag(EPropertyTagExtension.OverridableInformation))
{
writer.Write((byte)OverrideOperation);
writer.Write(bExperimentalOverridableLogic ? 1 : 0);
}
}
}
}
///
/// Does the body of this property entirely consist of null bytes? If so, the body can be skipped during serialization in unversioned properties.
///
/// The asset to test serialization within.
/// Whether or not the property can be serialized as zero.
public virtual bool CanBeZero(UAsset asset)
{
MemoryStream testStrm = new MemoryStream(32); this.Write(new AssetBinaryWriter(testStrm, asset), false); byte[] testByteArray = testStrm.ToArray();
foreach (byte entry in testByteArray)
{
if (entry != 0) return false;
}
return true;
}
///
/// Sets certain fields of the property based off of an array of strings.
///
/// An array of strings to derive certain fields from.
/// The asset that the property belongs to.
public virtual void FromString(string[] d, UAsset asset)
{
}
///
/// Performs a deep clone of the current PropertyData instance.
///
/// A deep copy of the current property.
public object Clone()
{
var res = (PropertyData)MemberwiseClone();
res.Name = (FName)this.Name.Clone();
if (res.RawValue is ICloneable cloneableValue) res.RawValue = cloneableValue.Clone();
HandleCloned(res);
return res;
}
protected virtual void HandleCloned(PropertyData res)
{
// Child classes can implement this for custom cloning behavior
}
}
public abstract class PropertyData : PropertyData
{
///
/// The "main value" of this property, if such a concept is applicable to the property in question. Properties may contain other values as well, in which case they will be present as other fields in the child class.
///
[JsonProperty]
public T Value
{
get => GetObject();
set => SetObject(value);
}
public PropertyData(FName name) : base(name) { }
public PropertyData() : base() { }
}
public interface IStruct
{
abstract static T Read(AssetBinaryReader reader);
abstract static T FromString(string[] d, UAsset asset);
int Write(AssetBinaryWriter writer);
}
public abstract class BasePropertyData : PropertyData where T : IStruct, new()
{
public BasePropertyData(FName name) : base(name) { }
public BasePropertyData() : base() { }
public override bool HasCustomStructSerialization => true;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = T.Read(reader);
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
Value ??= new T();
return Value.Write(writer);
}
public override string ToString()
{
return Value.ToString();
}
public override void FromString(string[] d, UAsset asset)
{
Value = T.FromString(d, asset);
}
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/SetPropertyData.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
using UAssetAPI.Unversioned;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a set.
///
public class SetPropertyData : ArrayPropertyData
{
public PropertyData[] ElementsToRemove = null;
public SetPropertyData(FName name) : base(name)
{
Value = [];
ElementsToRemove = [];
}
public SetPropertyData()
{
Value = [];
ElementsToRemove = [];
}
private static readonly FString CurrentPropertyType = new FString("SetProperty");
public override FString PropertyType => CurrentPropertyType;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
ShouldSerializeStructsDifferently = false;
if (includeHeader && !reader.Asset.HasUnversionedProperties)
{
if (reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
if (PropertyTypeName is null) throw new FormatException("PropertyTypeName is required to read SetProperty with complete type names.");
ArrayType = PropertyTypeName.GetParameter(0).GetName();
}
else
{
ArrayType = reader.ReadFName();
}
this.ReadEndPropertyTag(reader);
}
if (reader.Asset.Mappings != null && ArrayType == null && reader.Asset.Mappings.TryGetPropertyData(Name, Ancestry, reader.Asset, out UsmapArrayData strucDat1))
{
ArrayType = FName.DefineDummy(reader.Asset, strucDat1.InnerType.Type.ToString());
}
if (reader.Asset.HasUnversionedProperties && ArrayType == null)
{
throw new InvalidOperationException("Unable to determine array type for array " + Name.Value.Value + " in class " + Ancestry.Parent.Value.Value);
}
var removedItemsDummy = new ArrayPropertyData(FName.DefineDummy(reader.Asset, "ElementsToRemove"));
removedItemsDummy.Ancestry.Initialize(Ancestry, Name);
removedItemsDummy.ShouldSerializeStructsDifferently = false;
removedItemsDummy.ArrayType = ArrayType;
removedItemsDummy.PropertyTypeName = PropertyTypeName;
removedItemsDummy.Read(reader, false, leng1, leng2);
ElementsToRemove = removedItemsDummy.Value;
base.Read(reader, false, leng1-4, leng2);
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
ShouldSerializeStructsDifferently = false;
if (Value.Length > 0) ArrayType = writer.Asset.HasUnversionedProperties ? FName.DefineDummy(writer.Asset, Value[0].PropertyType) : new FName(writer.Asset, Value[0].PropertyType);
if (includeHeader && !writer.Asset.HasUnversionedProperties)
{
if (writer.Asset.ObjectVersionUE5 < ObjectVersionUE5.PROPERTY_TAG_COMPLETE_TYPE_NAME)
{
writer.Write(ArrayType);
}
this.WriteEndPropertyTag(writer);
}
var removedItemsDummy = new ArrayPropertyData(FName.DefineDummy(writer.Asset, "ElementsToRemove"));
removedItemsDummy.ShouldSerializeStructsDifferently = false;
removedItemsDummy.ArrayType = ArrayType;
removedItemsDummy.Value = ElementsToRemove;
int leng1 = removedItemsDummy.Write(writer, false);
return leng1 + base.Write(writer, false);
}
protected override void HandleCloned(PropertyData res)
{
base.HandleCloned(res);
SetPropertyData cloningProperty = (SetPropertyData)res;
if (this.ElementsToRemove != null)
{
PropertyData[] newData = new PropertyData[this.ElementsToRemove.Length];
for (int i = 0; i < this.Value.Length; i++)
{
newData[i] = (PropertyData)this.Value[i].Clone();
}
cloningProperty.ElementsToRemove = newData;
}
else
{
cloningProperty.ElementsToRemove = null;
}
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/SoftObjectPropertyData.cs
================================================
using System;
using UAssetAPI.CustomVersions;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a reference variable to another object which may be null, and may become valid or invalid at any point. Near synonym for .
///
public class AssetObjectPropertyData : PropertyData
{
public uint ID = 0;
public AssetObjectPropertyData(FName name) : base(name) { }
public AssetObjectPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("AssetObjectProperty");
public override FString PropertyType => CurrentPropertyType;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadFString();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
return writer.Write(Value);
}
public override string ToString()
{
return "(" + Value + ", " + ID + ")";
}
public override void FromString(string[] d, UAsset asset)
{
//asset.AddNameReference(FString.FromString(d[0]));
Value = FString.FromString(d[0]);
}
}
public struct FTopLevelAssetPath
{
///
/// Name of the package containing the asset e.g. /Path/To/Package
/// If less than 5.1, this is null
///
public FName PackageName;
///
/// Name of the asset within the package e.g. 'AssetName'.
/// If less than 5.1, this contains the full path instead
///
public FName AssetName;
public FTopLevelAssetPath(FName packageName, FName assetName)
{
PackageName = packageName;
AssetName = assetName;
}
}
///
/// A reference variable to another object which may be null, and may become valid or invalid at any point.
///
public struct FSoftObjectPath : IEquatable, IStruct
{
///
/// Asset path, patch to a top level object in a package. This is /package/path.assetname/
///
public FTopLevelAssetPath AssetPath;
///
/// Optional FString for subobject within an asset. This is the sub path after the :
///
public FString SubPathString;
public FSoftObjectPath(FName packageName, FName assetName, FString subPathString)
{
AssetPath = new FTopLevelAssetPath(packageName, assetName);
SubPathString = subPathString;
}
public FSoftObjectPath(FTopLevelAssetPath assetPath, FString subPathString)
{
AssetPath = assetPath;
SubPathString = subPathString;
}
public FSoftObjectPath(AssetBinaryReader reader, bool allowIndex = true)
{
if (allowIndex && reader.Asset.SoftObjectPathList != null && reader.Asset.SoftObjectPathList.Count > 0)
{
// serialize as idx
int idx = reader.ReadInt32();
FSoftObjectPath target = reader.Asset.SoftObjectPathList[idx];
this.AssetPath = target.AssetPath;
this.SubPathString = target.SubPathString;
}
else
{
if (reader.Asset.ObjectVersionUE5 >= ObjectVersionUE5.FSOFTOBJECTPATH_REMOVE_ASSET_PATH_FNAMES)
{
AssetPath = new FTopLevelAssetPath(reader.ReadFName(), reader.ReadFName());
}
else if (reader.Asset.ObjectVersion >= ObjectVersion.VER_UE4_ADDED_SOFT_OBJECT_PATH)
{
AssetPath = new FTopLevelAssetPath(null, reader.ReadFName());
}
else
{
AssetPath = new FTopLevelAssetPath(null, null);
}
SubPathString = reader.Asset.GetCustomVersion() < FFortniteMainBranchObjectVersion.SoftObjectPathUtf8SubPaths
? reader.ReadFString()
: reader.ReadUtf8String();
}
}
public static FSoftObjectPath Read(AssetBinaryReader reader) => new FSoftObjectPath(reader);
public int Write(AssetBinaryWriter writer, bool allowIndex = true)
{
if (allowIndex && writer.Asset.SoftObjectPathList != null && writer.Asset.SoftObjectPathList.Count > 0)
{
// serialize as idx
int idx = -1;
for (int i = 0; i < writer.Asset.SoftObjectPathList.Count; i++)
{
FSoftObjectPath testingEntry = writer.Asset.SoftObjectPathList[i];
if (testingEntry == this)
{
idx = i;
break;
}
}
if (idx < 0) throw new FormatException("Failed to find AssetPath in SoftObjectPathList");
writer.Write(idx);
return sizeof(int);
}
if (writer.Asset.ObjectVersion < ObjectVersion.VER_UE4_ADDED_SOFT_OBJECT_PATH)
return writer.Write(SubPathString);
var offset = writer.BaseStream.Position;
if (writer.Asset.ObjectVersionUE5 >= ObjectVersionUE5.FSOFTOBJECTPATH_REMOVE_ASSET_PATH_FNAMES) writer.Write(AssetPath.PackageName);
writer.Write(AssetPath.AssetName);
if (writer.Asset.GetCustomVersion() < FFortniteMainBranchObjectVersion.SoftObjectPathUtf8SubPaths)
writer.Write(SubPathString);
else
writer.WriteUtf8String(SubPathString);
return (int)(writer.BaseStream.Position - offset);
}
public int Write(AssetBinaryWriter writer) => Write(writer, true);
public static bool operator ==(FSoftObjectPath lhs, FSoftObjectPath rhs)
{
return lhs.Equals(rhs);
}
public static bool operator !=(FSoftObjectPath lhs, FSoftObjectPath rhs)
{
return !lhs.Equals(rhs);
}
public bool Equals(FSoftObjectPath other)
{
return AssetPath.PackageName == other.AssetPath.PackageName &&
AssetPath.AssetName == other.AssetPath.AssetName &&
SubPathString == other.SubPathString;
}
public override bool Equals(object obj)
{
return obj is FSoftObjectPath other && Equals(other);
}
public override int GetHashCode()
{
return HashCode.Combine(AssetPath.PackageName, AssetPath.AssetName, SubPathString);
}
public override string ToString()
{
return $"({AssetPath.PackageName}, {AssetPath.AssetName}, {SubPathString})";
}
public static FSoftObjectPath FromString(string[] d, UAsset asset)
{
FName one = FName.FromString(asset, d[0]);
FName two = FName.FromString(asset, d[1]);
FString three = string.IsNullOrEmpty(d[2]) ? null : FString.FromString(d[2]);
return new FSoftObjectPath(one, two, three);
}
}
///
/// Describes a reference variable to another object which may be null, and may become valid or invalid at any point. Near synonym for .
///
public class SoftObjectPropertyData : BasePropertyData
{
public SoftObjectPropertyData(FName name) : base(name) { }
public SoftObjectPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("SoftObjectProperty");
public override bool HasCustomStructSerialization => false;
public override FString PropertyType => CurrentPropertyType;
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/StrPropertyData.cs
================================================
using System.Text;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes an .
///
public class StrPropertyData : PropertyData
{
public StrPropertyData(FName name) : base(name) { }
public StrPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("StrProperty");
public override FString PropertyType => CurrentPropertyType;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadFString();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
int here = (int)writer.BaseStream.Position;
writer.Write(Value);
return (int)writer.BaseStream.Position - here;
}
public override string ToString()
{
return Value.ToString();
}
public override void FromString(string[] d, UAsset asset)
{
var encoding = Encoding.UTF8;
if (d.Length >= 5) encoding = (d[4].Equals(Encoding.Unicode.HeaderName) ? Encoding.Unicode : Encoding.UTF8);
Value = FString.FromString(d[0], encoding);
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/TextHistoryType.cs
================================================
namespace UAssetAPI.PropertyTypes.Objects;
public enum TextHistoryType
{
None = -1,
Base = 0,
NamedFormat,
OrderedFormat,
ArgumentFormat,
AsNumber,
AsPercent,
AsCurrency,
AsDate,
AsTime,
AsDateTime,
Transform,
StringTableEntry,
TextGenerator,
RawText // Uncertain, Back 4 Blood specific serialization
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/TextPropertyData.cs
================================================
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using UAssetAPI.CustomVersions;
using UAssetAPI.UnrealTypes;
using UAssetAPI.UnrealTypes.EngineEnums;
namespace UAssetAPI.PropertyTypes.Objects;
[Flags]
public enum ETextFlag
{
Transient = 1 << 0,
CultureInvariant = 1 << 1,
ConvertedProperty = 1 << 2,
Immutable = 1 << 3,
InitializedFromString = 1 << 4
}
public enum ETransformType : byte
{
ToLower = 0,
ToUpper,
}
public class FNumberFormattingOptions
{
public bool AlwaysSign;
public bool UseGrouping;
public ERoundingMode RoundingMode;
public int MinimumIntegralDigits;
public int MaximumIntegralDigits;
public int MinimumFractionalDigits;
public int MaximumFractionalDigits;
public FNumberFormattingOptions()
{
AlwaysSign = false;
UseGrouping = true;
RoundingMode = ERoundingMode.HalfToEven;
MinimumIntegralDigits = 1;
MaximumIntegralDigits = 316;
MinimumFractionalDigits = 0;
MaximumFractionalDigits = 3;
}
public FNumberFormattingOptions(AssetBinaryReader reader)
{
if (reader.Asset.GetCustomVersion() >= FEditorObjectVersion.AddedAlwaysSignNumberFormattingOption)
AlwaysSign = reader.ReadBooleanInt();
UseGrouping = reader.ReadBooleanInt();
RoundingMode = (ERoundingMode)reader.ReadByte();
MinimumIntegralDigits = reader.ReadInt32();
MaximumIntegralDigits = reader.ReadInt32();
MinimumFractionalDigits = reader.ReadInt32();
MaximumFractionalDigits = reader.ReadInt32();
}
public void Write(AssetBinaryWriter writer)
{
if (writer.Asset.GetCustomVersion() >= FEditorObjectVersion.AddedAlwaysSignNumberFormattingOption)
writer.Write(AlwaysSign ? 1 : 0);
writer.Write(UseGrouping ? 1 : 0);
writer.Write((byte)RoundingMode);
writer.Write(MinimumIntegralDigits);
writer.Write(MaximumIntegralDigits);
writer.Write(MinimumFractionalDigits);
writer.Write(MaximumFractionalDigits);
}
}
public class FFormatArgumentValue
{
public EFormatArgumentType Type;
public object Value;
public FFormatArgumentValue() { }
public FFormatArgumentValue(EFormatArgumentType type, object value)
{
Type = type;
Value = value;
}
public FFormatArgumentValue(AssetBinaryReader reader, bool isArgumentData = false)
{
Type = (EFormatArgumentType)reader.ReadByte();
switch (Type)
{
case EFormatArgumentType.Int:
Value = isArgumentData && reader.Asset.GetCustomVersion() < FUE5ReleaseStreamObjectVersion.TextFormatArgumentData64bitSupport ? reader.ReadInt32() : reader.ReadInt64();
break;
case EFormatArgumentType.UInt:
Value = reader.ReadUInt64();
break;
case EFormatArgumentType.Double:
Value = reader.ReadDouble();
break;
case EFormatArgumentType.Float:
Value = reader.ReadSingle();
break;
case EFormatArgumentType.Text:
var val = new TextPropertyData(FName.DefineDummy(reader.Asset, "Value"));
val.Read(reader, false, 1, 0, PropertySerializationContext.Normal);
Value = val;
break;
default:
throw new NotImplementedException("EFormatArgumentType type " + Type.ToString() + " is not implemented for reading");
}
}
public int Write(AssetBinaryWriter writer, bool isArgumentData = false)
{
int sz = 0;
writer.Write((byte)Type); sz += sizeof(byte);
switch (Type)
{
case EFormatArgumentType.Int:
if (isArgumentData && writer.Asset.GetCustomVersion() < FUE5ReleaseStreamObjectVersion.TextFormatArgumentData64bitSupport)
{
writer.Write((int)(long)Value);
sz += sizeof(int);
}
else
{
writer.Write((long)Value);
sz += sizeof(long);
}
break;
case EFormatArgumentType.UInt:
writer.Write((ulong)Value);
sz += sizeof(ulong);
break;
case EFormatArgumentType.Double:
writer.Write((double)Value);
sz += sizeof(double);
break;
case EFormatArgumentType.Float:
writer.Write((float)Value);
sz += sizeof(float);
break;
case EFormatArgumentType.Text:
int here = (int)writer.BaseStream.Position;
var val = (TextPropertyData)Value;
val.Write(writer, false);
sz += (int)writer.BaseStream.Position - here;
break;
default:
throw new NotImplementedException("EFormatArgumentType type " + Type.ToString() + " is not implemented for writing");
}
return sz;
}
}
public class FFormatArgumentData
{
public FString ArgumentName;
public FFormatArgumentValue ArgumentValue;
public FFormatArgumentData() { }
public FFormatArgumentData(FString name, FFormatArgumentValue value)
{
ArgumentName = name;
ArgumentValue = value;
}
public FFormatArgumentData(AssetBinaryReader reader)
{
Read(reader);
}
public void Read(AssetBinaryReader reader)
{
ArgumentName = reader.ReadFString();
ArgumentValue = new FFormatArgumentValue(reader, true);
}
public int Write(AssetBinaryWriter writer)
{
int sz = writer.Write(ArgumentName);
sz += ArgumentValue.Write(writer, true);
return sz;
}
}
///
/// Describes an FText.
///
public class TextPropertyData : PropertyData
{
/// Flags with various information on what sort of FText this is
[JsonProperty]
public ETextFlag Flags = 0;
/// The HistoryType of this FText.
[JsonProperty]
[JsonConverter(typeof(StringEnumConverter))]
public TextHistoryType HistoryType = TextHistoryType.Base;
/// The string table ID being referenced, if applicable
[JsonProperty]
public FName TableId = null;
/// A namespace to use when parsing texts that use LOCTEXT
[JsonProperty]
public FString Namespace = null;
/// The source string for this FText. In the Unreal Engine, this is also known as SourceString.
[JsonProperty]
public FString CultureInvariantString = null;
// OrderedFormat
[JsonProperty]
public TextPropertyData SourceFmt;
[JsonProperty]
public FFormatArgumentValue[] Arguments;
//ArgumentFormat
[JsonProperty]
public FFormatArgumentData[] ArgumentsData;
//Transform
[JsonProperty]
public ETransformType TransformType;
//AsNumber
[JsonProperty]
FFormatArgumentValue SourceValue;
[JsonProperty]
FNumberFormattingOptions FormatOptions;
[JsonProperty]
FString TargetCulture;
public bool ShouldSerializeTableId()
{
return HistoryType == TextHistoryType.StringTableEntry;
}
public TextPropertyData(FName name) : base(name) { }
public TextPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("TextProperty");
public override FString PropertyType => CurrentPropertyType;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
if (reader.Asset.ObjectVersion < ObjectVersion.VER_UE4_FTEXT_HISTORY)
{
CultureInvariantString = reader.ReadFString();
if (reader.Asset.ObjectVersion >= ObjectVersion.VER_UE4_ADDED_NAMESPACE_AND_KEY_DATA_TO_FTEXT)
{
Namespace = reader.ReadFString();
Value = reader.ReadFString();
}
else
{
Namespace = null;
Value = reader.ReadFString();
}
}
Flags = (ETextFlag)reader.ReadUInt32();
if (reader.Asset.ObjectVersion >= ObjectVersion.VER_UE4_FTEXT_HISTORY)
{
HistoryType = (TextHistoryType)reader.ReadSByte();
switch (HistoryType)
{
case TextHistoryType.None:
Value = null;
if (reader.Asset.GetCustomVersion() >= FEditorObjectVersion.CultureInvariantTextSerializationKeyStability)
{
bool bHasCultureInvariantString = reader.ReadInt32() == 1;
if (bHasCultureInvariantString)
{
CultureInvariantString = reader.ReadFString();
}
}
break;
case TextHistoryType.Base:
Namespace = reader.ReadFString();
Value = reader.ReadFString(); // Key
CultureInvariantString = reader.ReadFString(); // SourceString
break;
case TextHistoryType.StringTableEntry:
TableId = reader.ReadFName();
Value = reader.ReadFString();
break;
case TextHistoryType.RawText:
Value = reader.ReadFString();
break;
case TextHistoryType.OrderedFormat:
SourceFmt = new TextPropertyData(FName.DefineDummy(reader.Asset, "SourceFmt"));
SourceFmt.Read(reader, false, 1, 0, serializationContext);
int ArgumentsSize = reader.ReadInt32();
Arguments = new FFormatArgumentValue[ArgumentsSize];
for (int i = 0; i < ArgumentsSize; i++)
{
Arguments[i] = new FFormatArgumentValue(reader);
}
break;
case TextHistoryType.ArgumentFormat:
SourceFmt = new TextPropertyData(FName.DefineDummy(reader.Asset, "SourceFmt"));
SourceFmt.Read(reader, false, 1, 0, serializationContext);
ArgumentsSize = reader.ReadInt32();
ArgumentsData = new FFormatArgumentData[ArgumentsSize];
for (int i = 0; i < ArgumentsSize; i++)
{
ArgumentsData[i] = new FFormatArgumentData(reader);
}
break;
case TextHistoryType.Transform:
SourceFmt = new TextPropertyData(FName.DefineDummy(reader.Asset, "SourceFmt"));
SourceFmt.Read(reader, false, 1, 0, serializationContext);
TransformType = (ETransformType)reader.ReadByte();
break;
case TextHistoryType.AsNumber:
SourceValue = new FFormatArgumentValue(reader);
if (reader.ReadBooleanInt())
{
FormatOptions = new FNumberFormattingOptions(reader);
}
TargetCulture = reader.ReadFString();
break;
default:
throw new NotImplementedException("Unimplemented reader for " + HistoryType.ToString() + " @ " + reader.BaseStream.Position);
}
}
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
var here = writer.BaseStream.Position;
if (writer.Asset.ObjectVersion < ObjectVersion.VER_UE4_FTEXT_HISTORY)
{
writer.Write(CultureInvariantString);
if (writer.Asset.ObjectVersion >= ObjectVersion.VER_UE4_ADDED_NAMESPACE_AND_KEY_DATA_TO_FTEXT)
{
writer.Write(Namespace);
writer.Write(Value);
}
else
{
writer.Write(Value);
}
}
writer.Write((uint)Flags);
if (writer.Asset.ObjectVersion >= ObjectVersion.VER_UE4_FTEXT_HISTORY)
{
writer.Write((sbyte)HistoryType);
switch (HistoryType)
{
case TextHistoryType.None:
if (writer.Asset.GetCustomVersion() >= FEditorObjectVersion.CultureInvariantTextSerializationKeyStability)
{
if (CultureInvariantString == null || string.IsNullOrEmpty(CultureInvariantString.Value))
{
writer.Write(0);
}
else
{
writer.Write(1);
writer.Write(CultureInvariantString);
}
}
break;
case TextHistoryType.Base:
writer.Write(Namespace);
writer.Write(Value);
writer.Write(CultureInvariantString);
break;
case TextHistoryType.StringTableEntry:
writer.Write(TableId);
writer.Write(Value);
break;
case TextHistoryType.RawText:
writer.Write(Value);
break;
case TextHistoryType.OrderedFormat:
SourceFmt.Write(writer, false, serializationContext);
writer.Write(Arguments.Length);
for (int i = 0; i < Arguments.Length; i++)
{
Arguments[i].Write(writer);
}
break;
case TextHistoryType.ArgumentFormat:
SourceFmt.Write(writer, false, serializationContext);
writer.Write(ArgumentsData.Length);
for (int i = 0; i < ArgumentsData.Length; i++)
{
ArgumentsData[i].Write(writer);
}
break;
case TextHistoryType.Transform:
SourceFmt.Write(writer, false, serializationContext);
writer.Write((byte)TransformType);
break;
case TextHistoryType.AsNumber:
SourceValue.Write(writer);
if (FormatOptions != null)
{
writer.Write(1);
FormatOptions.Write(writer);
}
else
{
writer.Write(0);
}
writer.Write(TargetCulture);
break;
default:
throw new NotImplementedException("Unimplemented writer for " + HistoryType.ToString());
}
}
return (int)(writer.BaseStream.Position - here);
}
public override string ToString()
{
if (Value == null) return "null";
switch (HistoryType)
{
case TextHistoryType.None:
return "None, " + CultureInvariantString;
case TextHistoryType.Base:
return "Base, " + Namespace + ", " + Value + ", " + CultureInvariantString;
case TextHistoryType.StringTableEntry:
return "StringTableEntry, " + TableId + ", " + Value;
default:
throw new NotImplementedException("Unimplemented display for " + HistoryType.ToString());
}
}
public override void FromString(string[] d, UAsset asset)
{
throw new NotImplementedException("TextPropertyData.FromString is currently unimplemented");
}
protected override void HandleCloned(PropertyData res)
{
TextPropertyData cloningProperty = (TextPropertyData)res;
cloningProperty.TableId = (FName)TableId?.Clone();
cloningProperty.Namespace = (FString)Namespace?.Clone();
cloningProperty.CultureInvariantString = (FString)CultureInvariantString?.Clone();
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/UInt16PropertyData.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a 16-bit unsigned integer variable ().
///
public class UInt16PropertyData : PropertyData
{
public UInt16PropertyData(FName name) : base(name) { }
public UInt16PropertyData() { }
private static readonly FString CurrentPropertyType = new FString("UInt16Property");
public override FString PropertyType => CurrentPropertyType;
public override object DefaultValue => (ushort)0;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = (reader.Asset.HasUnversionedProperties && serializationContext != PropertySerializationContext.Normal) ? (ushort)reader.ReadInt64() : reader.ReadUInt16();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
if (writer.Asset.HasUnversionedProperties && serializationContext != PropertySerializationContext.Normal)
{
writer.Write((long)Value);
return sizeof(long);
}
writer.Write(Value);
return sizeof(ushort);
}
public override string ToString()
{
return Convert.ToString(Value);
}
public override void FromString(string[] d, UAsset asset)
{
Value = 0;
if (ushort.TryParse(d[0], out ushort res)) Value = res;
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/UInt32PropertyData.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a 32-bit unsigned integer variable ().
///
public class UInt32PropertyData : PropertyData
{
public UInt32PropertyData(FName name) : base(name) { }
public UInt32PropertyData() { }
private static readonly FString CurrentPropertyType = new FString("UInt32Property");
public override FString PropertyType => CurrentPropertyType;
public override object DefaultValue => (uint)0;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadUInt32();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
writer.Write(Value);
return sizeof(uint);
}
public override string ToString()
{
return Convert.ToString(Value);
}
public override void FromString(string[] d, UAsset asset)
{
Value = 0;
if (uint.TryParse(d[0], out uint res)) Value = res;
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/UInt64PropertyData.cs
================================================
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a 64-bit unsigned integer variable ().
///
public class UInt64PropertyData : PropertyData
{
public UInt64PropertyData(FName name) : base(name) { }
public UInt64PropertyData() { }
private static readonly FString CurrentPropertyType = new FString("UInt64Property");
public override FString PropertyType { get { return CurrentPropertyType; } }
public override object DefaultValue { get { return (ulong)0; } }
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadUInt64();
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
writer.Write(Value);
return sizeof(ulong);
}
public override string ToString()
{
return Convert.ToString(Value);
}
public override void FromString(string[] d, UAsset asset)
{
Value = 0;
if (ulong.TryParse(d[0], out ulong res)) Value = res;
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/UnknownPropertyData.cs
================================================
using Newtonsoft.Json;
using System;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects;
///
/// Describes a property which UAssetAPI has no specific serialization for, and is instead represented as an array of bytes as a fallback.
///
public class UnknownPropertyData : PropertyData
{
[JsonProperty]
public FString SerializingPropertyType = CurrentPropertyType;
public UnknownPropertyData(FName name) : base(name) { }
public UnknownPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("UnknownProperty");
public override FString PropertyType { get { return CurrentPropertyType; } }
public void SetSerializingPropertyType(FString newType)
{
SerializingPropertyType = newType;
}
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = reader.ReadBytes((int)leng1);
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
writer.Write(Value);
return Value.Length;
}
public override string ToString()
{
return Convert.ToString(Value);
}
protected override void HandleCloned(PropertyData res)
{
UnknownPropertyData cloningProperty = (UnknownPropertyData)res;
cloningProperty.SerializingPropertyType = (FString)SerializingPropertyType?.Clone();
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Objects/WeakObjectPropertyData.cs
================================================
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Objects
{
public class WeakObjectPropertyData : ObjectPropertyData
{
public WeakObjectPropertyData(FName name) : base(name)
{
}
public WeakObjectPropertyData()
{
}
private static readonly FString CurrentPropertyType = new FString("WeakObjectProperty");
public override FString PropertyType { get { return CurrentPropertyType; } }
public override object DefaultValue { get { return FPackageIndex.FromRawIndex(0); } }
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Structs/ClothLODDataPropertyData.cs
================================================
using UAssetAPI.UnrealTypes;
using UAssetAPI.PropertyTypes.Objects;
namespace UAssetAPI.PropertyTypes.Structs;
///
/// A structure for holding mesh-to-mesh triangle influences to skin one mesh to another (similar to a wrap deformer)
///
public class FMeshToMeshVertData
{
///
/// Barycentric coords and distance along normal for the position of the final vert
///
public Vector4fPropertyData PositionBaryCoordsAndDist;
///
/// Barycentric coords and distance along normal for the location of the unit normal endpoint.
/// Actual normal = ResolvedNormalPosition - ResolvedPosition
///
public Vector4fPropertyData NormalBaryCoordsAndDist;
///
/// Barycentric coords and distance along normal for the location of the unit Tangent endpoint.
/// Actual normal = ResolvedNormalPosition - ResolvedPosition
///
public Vector4fPropertyData TangentBaryCoordsAndDist;
///
/// Contains the 3 indices for verts in the source mesh forming a triangle, the last element
/// is a flag to decide how the skinning works, 0xffff uses no simulation, and just normal
/// skinning, anything else uses the source mesh and the above skin data to get the final position
///
public ushort[] SourceMeshVertIndices;
///
/// For weighted averaging of multiple triangle influences
///
public float Weight = 0.0f;
///
/// Dummy for alignment
///
public uint Padding;
public void Read(AssetBinaryReader reader)
{
PositionBaryCoordsAndDist = new Vector4fPropertyData(FName.DefineDummy(reader.Asset, "PositionBaryCoordsAndDist"));
PositionBaryCoordsAndDist.Offset = reader.BaseStream.Position;
PositionBaryCoordsAndDist.Read(reader, false, 0);
NormalBaryCoordsAndDist = new Vector4fPropertyData(FName.DefineDummy(reader.Asset, "NormalBaryCoordsAndDist"));
NormalBaryCoordsAndDist.Offset = reader.BaseStream.Position;
NormalBaryCoordsAndDist.Read(reader, false, 0);
TangentBaryCoordsAndDist = new Vector4fPropertyData(FName.DefineDummy(reader.Asset, "TangentBaryCoordsAndDist"));
TangentBaryCoordsAndDist.Offset = reader.BaseStream.Position;
TangentBaryCoordsAndDist.Read(reader, false, 0);
SourceMeshVertIndices = new ushort[4];
for (int i = 0; i < 4; i++)
{
SourceMeshVertIndices[i] = reader.ReadUInt16();
}
Weight = reader.ReadSingle();
Padding = reader.ReadUInt32();
}
public int Write(AssetBinaryWriter writer)
{
int res = 0;
res += PositionBaryCoordsAndDist.Write(writer, false);
res += NormalBaryCoordsAndDist.Write(writer, false);
res += TangentBaryCoordsAndDist.Write(writer, false);
for (int i = 0; i < 4; i++)
{
writer.Write(SourceMeshVertIndices.Length > i ? SourceMeshVertIndices[i] : (ushort)0); res += sizeof(ushort);
}
writer.Write(Weight); res += sizeof(float);
writer.Write(Padding); res += sizeof(uint);
return res;
}
public FMeshToMeshVertData(AssetBinaryReader reader)
{
Read(reader);
}
public FMeshToMeshVertData(Vector4fPropertyData positionBaryCoordsAndDist, Vector4fPropertyData normalBaryCoordsAndDist, Vector4fPropertyData tangentBaryCoordsAndDist, ushort[] sourceMeshVertIndices, float weight, uint padding)
{
PositionBaryCoordsAndDist = positionBaryCoordsAndDist;
NormalBaryCoordsAndDist = normalBaryCoordsAndDist;
TangentBaryCoordsAndDist = tangentBaryCoordsAndDist;
SourceMeshVertIndices = sourceMeshVertIndices;
Weight = weight;
Padding = padding;
}
public FMeshToMeshVertData() { }
}
///
/// Common Cloth LOD representation for all clothing assets.
///
public class ClothLODDataPropertyData : StructPropertyData
{
///
/// Skinning data for transitioning from a higher detail LOD to this one
///
public FMeshToMeshVertData[] TransitionUpSkinData;
///
/// Skinning data for transitioning from a lower detail LOD to this one
///
public FMeshToMeshVertData[] TransitionDownSkinData;
public ClothLODDataPropertyData(FName name, FName forcedType) : base(name, forcedType) { }
public ClothLODDataPropertyData(FName name) : base(name) { }
public ClothLODDataPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("ClothLODData");
public override bool HasCustomStructSerialization => true;
public override FString PropertyType => CurrentPropertyType;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
StructType = FName.DefineDummy(reader.Asset, PropertyType);
base.Read(reader, includeHeader, 1, leng2, PropertySerializationContext.StructFallback);
int sizeUpData = reader.ReadInt32();
TransitionUpSkinData = new FMeshToMeshVertData[sizeUpData];
for (int i = 0; i < sizeUpData; i++)
{
TransitionUpSkinData[i] = new FMeshToMeshVertData(reader);
}
int sizeDownData = reader.ReadInt32();
TransitionDownSkinData = new FMeshToMeshVertData[sizeDownData];
for (int i = 0; i < sizeDownData; i++)
{
TransitionDownSkinData[i] = new FMeshToMeshVertData(reader);
}
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
StructType = FName.DefineDummy(writer.Asset, PropertyType);
int res = base.Write(writer, includeHeader, PropertySerializationContext.StructFallback);
if (TransitionUpSkinData == null) TransitionUpSkinData = [];
writer.Write(TransitionUpSkinData.Length); res += sizeof(int);
for (int i = 0; i < TransitionUpSkinData.Length; i++)
{
res += TransitionUpSkinData[i].Write(writer);
}
if (TransitionDownSkinData == null) TransitionDownSkinData = [];
writer.Write(TransitionDownSkinData.Length); res += sizeof(int);
for (int i = 0; i < TransitionDownSkinData.Length; i++)
{
res += TransitionDownSkinData[i].Write(writer);
}
return res;
}
public override string ToString()
{
return base.ToString();
}
public override void FromString(string[] d, UAsset asset)
{
base.FromString(d, asset);
}
}
public class ClothLODDataCommonPropertyData : ClothLODDataPropertyData
{
public ClothLODDataCommonPropertyData(FName name, FName forcedType) : base(name, forcedType) { }
public ClothLODDataCommonPropertyData(FName name) : base(name) { }
public ClothLODDataCommonPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("ClothLODDataCommon");
public override bool HasCustomStructSerialization => true;
public override FString PropertyType => CurrentPropertyType;
}
================================================
FILE: UAssetAPI/PropertyTypes/Structs/ClothTetherDataPropertyData.cs
================================================
using UAssetAPI.PropertyTypes.Objects;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Structs;
///
/// Long range attachment tether pathfinding based on Dijkstra's algorithm.
///
public class ClothTetherDataPropertyData : StructPropertyData
{
public (int, int, float)[][] Tethers;
public ClothTetherDataPropertyData(FName name, FName forcedType) : base(name, forcedType) { }
public ClothTetherDataPropertyData(FName name) : base(name) { }
public ClothTetherDataPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("ClothTetherData");
public override bool HasCustomStructSerialization => true;
public override FString PropertyType => CurrentPropertyType;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
StructType = FName.DefineDummy(reader.Asset, CurrentPropertyType);
base.Read(reader, false, 1, 0, PropertySerializationContext.StructFallback);
int numElements = reader.ReadInt32();
Tethers = new (int, int, float)[numElements][];
for (int i = 0; i < numElements; i++)
{
int numInnerElements = reader.ReadInt32();
Tethers[i] = new (int, int, float)[numInnerElements];
for (int j = 0; j < numInnerElements; j++)
{
Tethers[i][j] = (reader.ReadInt32(), reader.ReadInt32(), reader.ReadSingle());
}
}
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
StructType = FName.DefineDummy(writer.Asset, CurrentPropertyType);
int totalSize = base.Write(writer, includeHeader, PropertySerializationContext.StructFallback);
if (Tethers == null) Tethers = [];
writer.Write(Tethers.Length);
totalSize += sizeof(int);
for (int i = 0; i < Tethers.Length; i++)
{
writer.Write(Tethers[i].Length);
totalSize += sizeof(int);
for (int j = 0; j < Tethers[i].Length; j++)
{
writer.Write(Tethers[i][j].Item1);
writer.Write(Tethers[i][j].Item2);
writer.Write(Tethers[i][j].Item3);
totalSize += sizeof(int) * 2 + sizeof(float);
}
}
return totalSize;
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Structs/Core/ColorPropertyData.cs
================================================
using System.Drawing;
using UAssetAPI.PropertyTypes.Objects;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Structs;
///
/// Describes a color with 8 bits of precision per channel.
///
public class ColorPropertyData : PropertyData // R, G, B, A
{
public ColorPropertyData(FName name) : base(name) { }
public ColorPropertyData() { }
private static readonly FString CurrentPropertyType = new FString("Color");
public override bool HasCustomStructSerialization => true;
public override FString PropertyType => CurrentPropertyType;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = Color.FromArgb(reader.ReadInt32());
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
writer.Write(Value.ToArgb());
return sizeof(int);
}
public override string ToString()
{
return Value.ToString();
}
public override void FromString(string[] d, UAsset asset)
{
if (!int.TryParse(d[0], out int colorR)) return;
if (!int.TryParse(d[1], out int colorG)) return;
if (!int.TryParse(d[2], out int colorB)) return;
if (!int.TryParse(d[3], out int colorA)) return;
Value = Color.FromArgb(colorA, colorR, colorG, colorB);
}
protected override void HandleCloned(PropertyData res)
{
ColorPropertyData cloningProperty = (ColorPropertyData)res;
cloningProperty.Value = Color.FromArgb(this.Value.ToArgb());
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Structs/Core/DateTimePropertyData.cs
================================================
using System;
using UAssetAPI.PropertyTypes.Objects;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Structs;
///
/// Implements a date and time.
///
/// Values of this type represent dates and times between Midnight 00:00:00, January 1, 0001 and
/// Midnight 23:59:59.9999999, December 31, 9999 in the Gregorian calendar. Internally, the time
/// values are stored in ticks of 0.1 microseconds (= 100 nanoseconds) since January 1, 0001.
///
/// The companion class () is provided for
/// enabling date and time based arithmetic, such as calculating the difference between two dates
/// or adding a certain amount of time to a given date.
///
public class DateTimePropertyData : PropertyData
{
public DateTimePropertyData(FName name) : base(name) { }
public DateTimePropertyData() { }
private static readonly FString CurrentPropertyType = new FString("DateTime");
public override bool HasCustomStructSerialization => true;
public override FString PropertyType => CurrentPropertyType;
public override void Read(AssetBinaryReader reader, bool includeHeader, long leng1, long leng2 = 0, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.ReadEndPropertyTag(reader);
}
Value = new DateTime(reader.ReadInt64()); // number of ticks since January 1, 0001
}
public override int Write(AssetBinaryWriter writer, bool includeHeader, PropertySerializationContext serializationContext = PropertySerializationContext.Normal)
{
if (includeHeader)
{
this.WriteEndPropertyTag(writer);
}
writer.Write(Value.Ticks);
return sizeof(long);
}
public override void FromString(string[] d, UAsset asset)
{
Value = DateTime.Parse(d[0]);
}
public override string ToString()
{
return Value.ToString();
}
protected override void HandleCloned(PropertyData res)
{
DateTimePropertyData cloningProperty = (DateTimePropertyData)res;
cloningProperty.Value = new DateTime(this.Value.Ticks);
}
}
================================================
FILE: UAssetAPI/PropertyTypes/Structs/Core/GuidPropertyData.cs
================================================
using System;
using UAssetAPI.PropertyTypes.Objects;
using UAssetAPI.UnrealTypes;
namespace UAssetAPI.PropertyTypes.Structs;
///
/// Describes a 128-bit