--- title: 大钊提供的一种获取UE Private函数的方法 date: 2022-12-09 14:51:47 excerpt: 摘要 tags: rating: ⭐⭐ --- ## Hacker.h ```c++ // Copyright (c) 2015 fjz13. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. #pragma once #include "MedusaCorePreDeclares.h" MEDUSA_BEGIN; namespace Hacker { //used to steal class private member template struct PrivateMemberStealer { friend typename Tag::type GetPrivate(Tag) { return M; } }; } MEDUSA_END; #define MEDUSA_STEAL_PRIVATE_MEMBER(className,memberType,memberName) \ namespace Medusa{namespace Hacker{\ struct className##_##memberName \ {\ typedef memberType className::*type;\ friend type GetPrivate(className##_##memberName);\ };\ template struct PrivateMemberStealer;\ }} #define MEDUSA_REF_PRIVATE_MEMBER(obj,className,memberName) obj->*GetPrivate(::Medusa::Hacker::className##_##memberName()) #define MEDUSA_VAR_PRIVATE_MEMBER(var,obj,className,memberName) auto& var=obj->*(GetPrivate(::Medusa::Hacker::className##_##memberName())); #define MEDUSA_STEAL_PRIVATE_FUNCTION(className,memberName,returnType,...) \ namespace Medusa{namespace Hacker{\ struct className##_##memberName \ {\ typedef returnType (className::*type)(__VA_ARGS__);\ friend type GetPrivate(className##_##memberName);\ };\ template struct PrivateMemberStealer;\ }} #define MEDUSA_REF_PRIVATE_FUNCTION(obj,className,memberName) GetPrivate(::Medusa::Hacker::className##_##memberName()) #define MEDUSA_PRIVATE_FUNCTION_CALL(obj,className,memberName,...) {auto func=GetPrivate(::Medusa::Hacker::className##_##memberName());(obj->*func)(__VA_ARGS__);} ``` ## AbcInjection.h ```c++ #pragma once #include "AbcMagicPreCompiled.h" #include "Core/Collection/List.h" namespace AbcInjection { void SetMatrixSamples(UGeometryCacheTrack* obj, const FMatrix* MatricesPtr, int32 MatricesCount, const float* SampleTimesPtr, int32 SampleTimesCount); void AddMatrixSample(UGeometryCacheTrack* obj, const FMatrix& Matrix, const float SampleTime); void ReserverMatrixSampleSize(UGeometryCacheTrack* obj, int32 size); void SetNumMaterials(UGeometryCacheTrack* obj, uint32 val); void ReserveSamples(UGeometryCacheTrack_FlipbookAnimation* obj,uint32 count); FGeometryCacheMeshData& MutableMeshSampleData(UGeometryCacheTrack_FlipbookAnimation* obj, uint32 index); void SetMeshSampleTime(UGeometryCacheTrack_FlipbookAnimation* obj, uint32 index, float time); FGeometryCacheMeshData& MutableMeshData(UGeometryCacheTrack_TransformAnimation* obj); void RegisterMorphTargets(USkeletalMesh* obj,const Medusa::List& MorphTargets); } ``` ## AbcInjection.cpp ```c++ #include "AbcInjection.h" #include "AbcMagicPreCompiled.h" #include "GeometryCacheTrack.h" #include "GeometryCacheTrackFlipbookAnimation.h" #include "GeometryCacheTrackTransformAnimation.h" #include "Engine/SkeletalMesh.h" #include "Animation/MorphTarget.h" #include "Core/Compile/Hacker.h" MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack, TArray, MatrixSamples); MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack, TArray, MatrixSampleTimes); MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack, uint32, NumMaterials); MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack_FlipbookAnimation, TArray, MeshSamples); MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack_FlipbookAnimation, TArray, MeshSampleTimes); MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack_FlipbookAnimation, uint32, NumMeshSamples); MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack_TransformAnimation, FGeometryCacheMeshData, MeshData); MEDUSA_STEAL_PRIVATE_MEMBER(USkeletalMesh, TArray, MorphTargets); #ifdef ALEMBIC_CORE_419 MEDUSA_STEAL_PRIVATE_FUNCTION(USkeletalMesh, InvalidateRenderData, void); #endif namespace AbcInjection { void SetMatrixSamples(UGeometryCacheTrack* obj, const FMatrix* MatricesPtr, int32 MatricesCount, const float* SampleTimesPtr, int32 SampleTimesCount) { MEDUSA_VAR_PRIVATE_MEMBER(matrixSamples, obj, UGeometryCacheTrack, MatrixSamples); MEDUSA_VAR_PRIVATE_MEMBER(matrixSampleTimes, obj, UGeometryCacheTrack, MatrixSampleTimes); matrixSamples.Append(MatricesPtr, MatricesCount); matrixSampleTimes.Append(SampleTimesPtr, SampleTimesCount); } void AddMatrixSample(UGeometryCacheTrack* obj, const FMatrix& Matrix, const float SampleTime) { MEDUSA_VAR_PRIVATE_MEMBER(matrixSamples, obj, UGeometryCacheTrack, MatrixSamples); MEDUSA_VAR_PRIVATE_MEMBER(matrixSampleTimes, obj, UGeometryCacheTrack, MatrixSampleTimes); matrixSamples.Add(Matrix); matrixSampleTimes.Add(SampleTime); } void ReserverMatrixSampleSize(UGeometryCacheTrack* obj, int32 size) { MEDUSA_VAR_PRIVATE_MEMBER(matrixSamples, obj, UGeometryCacheTrack, MatrixSamples); MEDUSA_VAR_PRIVATE_MEMBER(matrixSampleTimes, obj, UGeometryCacheTrack, MatrixSampleTimes); matrixSamples.Reserve(size); matrixSampleTimes.Reserve(size); } void SetNumMaterials(UGeometryCacheTrack* obj, uint32 val) { MEDUSA_REF_PRIVATE_MEMBER(obj, UGeometryCacheTrack, NumMaterials) = val; } void ReserveSamples(UGeometryCacheTrack_FlipbookAnimation* obj, uint32 count) { MEDUSA_VAR_PRIVATE_MEMBER(meshSamples, obj, UGeometryCacheTrack_FlipbookAnimation, MeshSamples); MEDUSA_VAR_PRIVATE_MEMBER(meshSampleTimes, obj, UGeometryCacheTrack_FlipbookAnimation, MeshSampleTimes); MEDUSA_VAR_PRIVATE_MEMBER(numMeshSamples, obj, UGeometryCacheTrack_FlipbookAnimation, NumMeshSamples); meshSamples.AddDefaulted(count); meshSampleTimes.AddDefaulted(count); numMeshSamples++; } FGeometryCacheMeshData& MutableMeshSampleData(UGeometryCacheTrack_FlipbookAnimation* obj, uint32 index) { MEDUSA_VAR_PRIVATE_MEMBER(meshSamples, obj, UGeometryCacheTrack_FlipbookAnimation, MeshSamples); return meshSamples[index]; } void SetMeshSampleTime(UGeometryCacheTrack_FlipbookAnimation* obj, uint32 index, float time) { MEDUSA_VAR_PRIVATE_MEMBER(meshSampleTimes, obj, UGeometryCacheTrack_FlipbookAnimation, MeshSampleTimes); meshSampleTimes[index] = time; } FGeometryCacheMeshData& MutableMeshData(UGeometryCacheTrack_TransformAnimation* obj) { MEDUSA_VAR_PRIVATE_MEMBER(meshData, obj, UGeometryCacheTrack_TransformAnimation, MeshData); return meshData; } void RegisterMorphTargets(USkeletalMesh* obj, const Medusa::List& MorphTargets) { MEDUSA_VAR_PRIVATE_MEMBER(morphTargets, obj, USkeletalMesh, MorphTargets); for (UMorphTarget* morphTarget : MorphTargets) { morphTarget->BaseSkelMesh = obj; morphTarget->MarkPackageDirty(); morphTargets.Add(morphTarget); } obj->MarkPackageDirty(); // need to refresh the map obj->InitMorphTargets(); // invalidate render data #ifdef ALEMBIC_CORE_419 MEDUSA_PRIVATE_FUNCTION_CALL(obj, USkeletalMesh, InvalidateRenderData); #endif } } ```