197 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			197 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								---
							 | 
						||
| 
								 | 
							
								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<typename Tag, typename Tag::type M>
							 | 
						||
| 
								 | 
							
									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<className##_##memberName, &className::memberName>;\
							 | 
						||
| 
								 | 
							
									}}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#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<className##_##memberName, &className::memberName>;\
							 | 
						||
| 
								 | 
							
									}}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#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<UMorphTarget*>& 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<FMatrix>, MatrixSamples);
							 | 
						||
| 
								 | 
							
								MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack, TArray<float>, MatrixSampleTimes);
							 | 
						||
| 
								 | 
							
								MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack, uint32, NumMaterials);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack_FlipbookAnimation, TArray<FGeometryCacheMeshData>, MeshSamples);
							 | 
						||
| 
								 | 
							
								MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack_FlipbookAnimation, TArray<float>, MeshSampleTimes);
							 | 
						||
| 
								 | 
							
								MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack_FlipbookAnimation, uint32, NumMeshSamples);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								MEDUSA_STEAL_PRIVATE_MEMBER(UGeometryCacheTrack_TransformAnimation, FGeometryCacheMeshData, MeshData);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								MEDUSA_STEAL_PRIVATE_MEMBER(USkeletalMesh, TArray<UMorphTarget*>, 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<UMorphTarget*>& 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
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								```
							 |