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
 | 
						|
	}
 | 
						|
 | 
						|
}
 | 
						|
``` |