|
发表于 2023-9-24 22:47:03
|
查看: 3371 |
回复: 1
#include "pch.h"
#include "世界坐标转屏幕坐标.h"
#include"TGame.h"
//-----------项目代码-------------------
#pragma once
ULONG64 offset_OwningGameInstance = 0x290;
ULONG64 offset_ULocalPlayer = 0x38;//本地角色
ULONG64 offset_UPlayerController = 0x30;//角色控制器
bool WorldToScreenEx(IN FVector3 WorldLocation, OUT FVector3* Screenlocation);
// [GWorld+0]
//UINT_PTR TGame::GetGWorld()
//{
// return RP(GetPByPdbName("GWorld") + 0);
//}
UINT_PTR TGame::GetGameInstance()
{
// [[GWorld+0]+0x290]
return RP(GetGWorld() + offset_OwningGameInstance);
}
UINT_PTR TGame::GetLocalPlayer()
{
// [[[[[GWorld+0]+0x290]+38]+30]+0*8]
return RP(RP(GetGameInstance() + offset_ULocalPlayer) + 0x00);
}
// 函数类型指针 type_ProjectWorldLocationToScreen
typedef bool(__thiscall* type_ProjectWorldLocationToScreen)(
UINT_PTR vrcx_this, // PlayerController*
FVector3* WorldLocation, // IN 待转换的世界坐标
FVector3* ScreenLocation, // OUT 返回转换后的屏幕坐标
bool bPlayerViewportRelative //IN 是否相对玩家视口 false
);
//需要主线程 里调用 bool WorldToScreenEx(IN FVector3 WorldLocation, OUT FVector3& Screenlocation)
//void TGame::WorldToScreen(IN float* worldpos3, OUT float* screenpos2, bool bPlayerViewportRelative,BOOL isEx)
void TGame::WorldToScreen(IN FVector3* worldpos3, OUT FVector3* screenpos2, bool bPlayerViewportRelative, BOOL isEx)
{
if (isEx)
{
WorldToScreenEx(*worldpos3, screenpos2);
return;
}
printf("内置 pcall_worldtoScreen line=%d \r\n", __LINE__);
type_ProjectWorldLocationToScreen pcall_worldtoScreen = (type_ProjectWorldLocationToScreen)GetPByPdbName("APlayerController::ProjectWorldLocationToScreen");
//获取 PlayerController
UINT_PTR vrcx_PlayerController = TGame::GetPlayerController();
//printf("pcall_worldtoScreen=%p,GetPlayerController()=%zX \r\n", pcall_worldtoScreen, vrcx_PlayerController);
//LogFileW("c:\\log\\遍历怪物数组draw.txt", L"pcall_worldtoScreen=%zX,GetAPlayerController()=%zX \r\n", pcall_worldtoScreen, vrcx_PlayerController);
if (pcall_worldtoScreen && vrcx_PlayerController)
{
//需要主线程调用
pcall_worldtoScreen(
vrcx_PlayerController, // PlayerController指针
worldpos3, // IN 待转换的世界坐标
screenpos2, // OUT 返回转换后的屏幕坐标
bPlayerViewportRelative);//=false);
}
else
{
//MessageBoxA(0, __FILE__, "世界坐标转屏幕坐标 错误", MB_OK);
printf("错误 pcall_worldtoScreen=%p,GetAPlayerController()=%zX \r\n", pcall_worldtoScreen, vrcx_PlayerController);
}
}
/*
PlayerController.h
typedef bool (__thiscall* type_ProjectWorldLocationToScreen)(
UINT_PTR vrcx_this,
float* WorldLocation, // IN 待转换的世界坐标
float* ScreenLocation, // OUT 返回转换后的屏幕坐标
bool bPlayerViewportRelative //IN 是否相对玩家视口
);
bool PlayerController::ProjectWorldLocationToScreen(FVector WorldLocation, FVector2D& ScreenLocation, bool bPlayerViewportRelative = false) const;
UGameInstance::GetFirstLocalPlayerController
00007FF649ADDA60 | 48:895C24 08 | mov qword ptr ss:[rsp+8],rbx | gameinstance.cpp:555,
00007FF649ADDA65 | 48:897424 10 | mov qword ptr ss:[rsp+10],rsi |
00007FF649ADDA6A | 57 | push rdi |
00007FF649ADDA6B | 48:83EC 30 | sub rsp,30 |
00007FF649ADDA6F | 8B71 40 | mov esi,dword ptr ds:[rcx+40] | gameinstance.cpp:556
00007FF649ADDA72 | 48:8BF9 | mov rdi,rcx | [[GWorld+0]+0x290]
00007FF649ADDA75 | 33DB | xor ebx,ebx | gameinstance.cpp:556
00007FF649ADDA77 | 3BDE | cmp ebx,esi |
00007FF649ADDA79 | 74 6C | je shootergame.7FF649ADDAE7 |
00007FF649ADDA7B | 8B57 40 | mov edx,dword ptr ds:[rdi+40] |
00007FF649ADDA7E | 33C9 | xor ecx,ecx |
00007FF649ADDA80 | 3BDA | cmp ebx,edx |
00007FF649ADDA82 | 0F9CC1 | setl cl |
00007FF649ADDA85 | 33C0 | xor eax,eax |
00007FF649ADDA87 | 85DB | test ebx,ebx |
00007FF649ADDA89 | 0F99C0 | setns al |
00007FF649ADDA8C | 85C8 | test eax,ecx |
00007FF649ADDA8E | 75 28 | jne shootergame.7FF649ADDAB8 |
00007FF649ADDA90 | 895424 28 | mov dword ptr ss:[rsp+28],edx |
00007FF649ADDA94 | 4C:8D0D 65C61201 | lea r9,qword ptr ds:[<L"Array index out of bounds: %i fr"...>] | 00007FF64AC0A100:L"Array index out of bounds: %i from an array of size %i"
00007FF649ADDA9B | 48:8D0D CEC61201 | lea rcx,qword ptr ds:[<"(Index >= 0) & (Index < ArrayNum"...>] | 00007FF64AC0A170:"(Index >= 0) & (Index < ArrayNum)"
00007FF649ADDAA2 | 48:8D15 D7BF1201 | lea rdx,qword ptr ds:[<"F:\\build\\LostIsland\\Engine\\Sourc"...>] | 00007FF64AC09A80:"F:\\build\\LostIsland\\Engine\\Source\\Runtime\\Core\\Public\\Containers\\Array.h"
00007FF649ADDAA9 | 41:B8 3C020000 | mov r8d,23C |
00007FF649ADDAAF | 895C24 20 | mov dword ptr ss:[rsp+20],ebx |
00007FF649ADDAB3 | E8 A8DE84FF | call <shootergame.public: static void __cdecl FDebug::AssertFailed(char const *, char |
00007FF649ADDAB8 | 48:8B47 38 | mov rax,qword ptr ds:[rdi+38] | [[[GWorld+0]+0x290]+38]
00007FF649ADDABC | 48:63CB | movsxd rcx,ebx |
00007FF649ADDABF | 48:8B04C8 | mov rax,qword ptr ds:[rax+rcx*8] //player 数组? [[[[GWorld+0]+0x290]+38]+0*8]
00007FF649ADDAC3 | 48:85C0 | test rax,rax | gameinstance.cpp:558
00007FF649ADDAC6 | 74 07 | je shootergame.7FF649ADDACF |
00007FF649ADDAC8 | 48:8378 30 00 | cmp qword ptr ds:[rax+30],0 |
00007FF649ADDACD | 75 04 | jne shootergame.7FF649ADDAD3 |
00007FF649ADDACF | FFC3 | inc ebx | gameinstance.cpp:556
00007FF649ADDAD1 | EB A4 | jmp shootergame.7FF649ADDA77 |
00007FF649ADDAD3 | 48:8B40 30 | mov rax,qword ptr ds:[rax+30] | rax = [[[[[GWorld+0]+0x290]+38]+0*8]+30]
00007FF649ADDAD7 | 48:8B5C24 40 | mov rbx,qword ptr ss:[rsp+40] | gameinstance.cpp:567
00007FF649ADDADC | 48:8B7424 48 | mov rsi,qword ptr ss:[rsp+48] |
00007FF649ADDAE1 | 48:83C4 30 | add rsp,30 |
00007FF649ADDAE5 | 5F | pop rdi |
00007FF649ADDAE6 | C3 | ret |
00007FF649ADDAE7 | 48:8B5C24 40 | mov rbx,qword ptr ss:[rsp+40] |
00007FF649ADDAEC | 48:8B7424 48 | mov rsi,qword ptr ss:[rsp+48] |
00007FF649ADDAF1 | 33C0 | xor eax,eax |
00007FF649ADDAF3 | 48:83C4 30 | add rsp,30 |
00007FF649ADDAF7 | 5F | pop rdi |
00007FF649ADDAF8 | C3 | ret |
APlayerController* UGameInstance::GetFirstLocalPlayerController(const UWorld* World) const
{
if (World == nullptr)
{
for (ULocalPlayer* Player : LocalPlayers)
{
// Returns the first non-null UPlayer::PlayerController without filtering by UWorld.
if (Player && Player->PlayerController)
{
// return first non-null entry
return Player->PlayerController;
}
}
}
else
{
// Only return a local PlayerController from the given World.
for (FConstPlayerControllerIterator Iterator = World->GetPlayerControllerIterator(); Iterator; ++Iterator)
{
APlayerController* PC = Iterator->Get();
if (PC && PC->IsLocalController())
{
return PC;
}
}
}
// didn't find one
return nullptr;
}
*/
#include"pch.h"
#include<Windows.h>
#include"世界坐标转屏幕坐标.h"
#define PI 3.14159265358979323846264338327950288419716939937510
//矩阵
D3DXMATRIX Matrix(FVector3 rot, FVector3 origin = FVector3(0, 0, 0))
{
float radPitch = (rot.x * float(PI) / 180.f);
float radYaw = (rot.y * float(PI) / 180.f);
float radRoll = (rot.z * float(PI) / 180.f);
float SP = sinf(radPitch);
float CP = cosf(radPitch);
float SY = sinf(radYaw);
float CY = cosf(radYaw);
float SR = sinf(radRoll);
float CR = cosf(radRoll);
D3DMATRIX matrix;
matrix.m[0][0] = CP * CY;
matrix.m[0][1] = CP * SY;
matrix.m[0][2] = SP;
matrix.m[0][3] = 0.f;
matrix.m[1][0] = SR * SP * CY - CR * SY;
matrix.m[1][1] = SR * SP * SY + CR * CY;
matrix.m[1][2] = -SR * CP;
matrix.m[1][3] = 0.f;
matrix.m[2][0] = -(CR * SP * CY + SR * SY);
matrix.m[2][1] = CY * SR - CR * SP * SY;
matrix.m[2][2] = CR * CP;
matrix.m[2][3] = 0.f;
matrix.m[3][0] = origin.x;
matrix.m[3][1] = origin.y;
matrix.m[3][2] = origin.z;
matrix.m[3][3] = 1.f;
return matrix;
}
/*
//相机坐标
AShooterPlayerController=[[[[[GWorld]+290]+38]+0]+30]
PlayerCameraManager = [AShooterPlayerController+4F0]
// [[[[[GWorld]+290]+38]+0]+30]+4F0
+480 //3、FOV视角 float [[[[[[GWorld]+290]+38]+0]+30]+4F0]+480 真实视角 修改有效
+4D8 //1、相机坐标float pos3[3] FVector3 [[[[[[GWorld]+290]+38]+0]+30]+4F0]+4D0+8
+4E4 //2、相机旋转坐标 float pos[3] [[[[[[GWorld]+290]+38]+0]+30]+4F0]+4D0+8+C
+500 //2、相机旋转坐标 float pos[3]
+500 //3、FOV视角 float [[[[[[GWorld]+290]+38]+0]+30]+4F0]+4D0+8+28 可读
+C40 //3、FOV视角 float [[[[[[GWorld]+290]+38]+0]+30]+4F0]+C40 可读
+FE8 //3、FOV视角 float [[[[[[GWorld]+290]+38]+0]+30]+4F0]+FE8 可读
*/
// UGameInstance::GetFirstLocalPlayerController // PlayerController::ProjectWorldLocationToScreen
UINT_PTR TGame::GetPlayerController()
{
UINT_PTR ULocalPlayer = GetLocalPlayer();
// [[[[[GWorld+0]+0x290]+38]+0*8]+30]
return RP(ULocalPlayer + offset_UPlayerController);
}
UINT_PTR TGame::GetPlayerCameraManager()
{ // [[[[[[GWorld]+290]+38]+0]+30]+4F0]
//return RP(RP(RP(RP(RP(GetGWorld() + 0x290) + 0x38) + 0x00) + 0x30) + 0x4F0);
return RP(GetPlayerController() + 0x4F0);
}
FVector3 TGame::GetCameraRotation()
{
//[[[[[[GWorld]+290]+38]+0]+30]+4F0]+4D8
UINT_PTR pbase = GetPlayerCameraManager() + 0x4D8;
FVector3 Rotation = RP<FVector3>(pbase);
return Rotation;
}
FVector3 TGame::GetCameraLocation()
{
//[[[[[[GWorld]+290]+38]+0]+30]+4F0]+4E4
UINT_PTR pbase = GetPlayerCameraManager() + 0x4E4;
FVector3 Rotation = RP<FVector3>(pbase);
return Rotation;
}
float TGame::GetFov()
{ //FOV弧度
//+500 //3、FOV视角 float [[[[[[GWorld]+290]+38]+0]+30]+4F0]+4D0+8+28 可读
float Fov = 0;
UINT_PTR pbase = GetPlayerCameraManager() + 0x500;
Fov = RP<float>(pbase);
return Fov;
}
/*
GSystemResolution
+00 分辩率宽度 x int
+04 分辩率高度 y int
*/
INT64 GetResolution(OUT int& x, int& y)
{
UINT_PTR pbase_GetResolution = GetPByPdbName("GSystemResolution");
INT64 pos = RP<INT64>(pbase_GetResolution + 0x00);
//y = RP<int>(pbase_GetResolution+0x04);
x = pos && 0xFFFFFFFF;
y = pos >> 32;
return pos;
}
INT64 TGame::GetResolution(OUT int& x, int& y)
{
UINT_PTR pbase_GetResolution = GetPByPdbName("GSystemResolution");
INT64 pos = RP<INT64>(pbase_GetResolution + 0x00);
//y = RP<int>(pbase_GetResolution+0x04);
x = GetResolutionWidth();
y = GetResolutionHeight();
return pos;
}
//判断坐标是否在屏幕内
INT64 TGame::在屏幕内(int x, int y)
{
int w, h;
GetResolution(w, h);
if((abs(x) <= w) && (abs(y) <= h))
{
return true;
}else
{
return false;
}
}
int TGame::GetResolutionWidth()
{
UINT_PTR pbase_GetResolution = GetPByPdbName("GSystemResolution");
int pos = RP<int>(pbase_GetResolution + 0x00);
return pos;
}
int TGame::GetResolutionHeight()
{
UINT_PTR pbase_GetResolution = GetPByPdbName("GSystemResolution");
int pos = RP<int>(pbase_GetResolution + 0x04);
return pos;
}
int TGame::窗口客户端中心X()
{
int pos = GetResolutionWidth();
return pos / 2;
}
int TGame::窗口客户端中心Y()
{
int pos = GetResolutionHeight();
return pos / 2;
}
/*
//本地角色 APlayerController* UShooterLocalPlayer = [[[[GWorld]+290]+38]+0]
//这个接口 可以重点关注
bool APlayerController::ProjectWorldLocationToScreen(
FVector WorldLocation, // IN 待转换的世界坐标
FVector2D& ScreenLocation, // OUT 返回转换后的屏幕坐标
bool bPlayerViewportRelative //IN 是否相对玩家视口
)
{
return UGameplayStatics::ProjectWorldToScreen(this, WorldLocation, ScreenLocation, bPlayerViewportRelative);
}
*/
//世界坐标转屏幕坐标
bool TGame::WorldToScreenEx(IN FVector3 WorldLocation, OUT FVector3* Screenlocation)
{
//获取相机旋转坐标
FVector3 Rotation = GetCameraRotation();
D3DMATRIX tempMatrix = Matrix(Rotation);
FVector3 vAxisX, vAxisY, vAxisZ;
vAxisX = FVector3(tempMatrix.m[0][0], tempMatrix.m[0][1], tempMatrix.m[0][2]);
vAxisY = FVector3(tempMatrix.m[1][0], tempMatrix.m[1][1], tempMatrix.m[1][2]);
vAxisZ = FVector3(tempMatrix.m[2][0], tempMatrix.m[2][1], tempMatrix.m[2][2]);
//世界矩阵-相机矩阵
FVector3 vDelta = WorldLocation - GetCameraLocation();
FVector3 vTransformed = FVector3(vDelta.Dot(vAxisY), vDelta.Dot(vAxisZ), vDelta.Dot(vAxisX));
if (vTransformed.z < 1.f)
return 0;
float FovAngle = GetFov();
//Screenlocation.x = g_Game->窗口客户端中心X + vTransformed.x * (g_Game->窗口客户端中心X / tanf(FovAngle * (float)PI / 360.f)) / vTransformed.z;
//Screenlocation.y = 窗口客户端中心Y() - vTransformed.y * (g_Game->窗口客户端中心X / tanf(FovAngle * (float)PI / 360.f)) / vTransformed.z;
int 窗口客户端中心X = TGame::窗口客户端中心X();
int 窗口客户端中心Y = TGame::窗口客户端中心Y();
Screenlocation->x = 窗口客户端中心X + vTransformed.x * (窗口客户端中心X / tanf(FovAngle * (float)PI / 360.f)) / vTransformed.z;
Screenlocation->y = 窗口客户端中心Y - vTransformed.y * (窗口客户端中心X / tanf(FovAngle * (float)PI / 360.f)) / vTransformed.z;
Screenlocation->z = 0.0f;
return 1;
}
UINT_PTR TGame::Get_UMatrix()
{
/*
*/
ULONG64 offset_UMatrixXbase = GetPByPdbName("GetCanvasByName") + 0x21;
UINT_PTR offset_UMatrix = offset_UMatrixXbase + 7 + RP<DWORD>(offset_UMatrixXbase + 3);
return offset_UMatrix;
}
//Rm(Rm(Rm(g_Game->GameBase + g_Game->offset_UMatrix) + 0x20) + 0xB0, tempMatrix, 64);
bool TGame::WorldToScreenRect(IN FVector3 WorldLocation, OUT FVector4& Rect)
{
float View{}, Top{}, Lift{}, BoxY{}, BoxH{};
float tempMatrix[4][4]{};
// Rm(Rm(Rm(base+offset_UMatrix) + 0x20) + 0xB0, tempMatrix, 64);
RM(R8(R8(Get_UMatrix()+0) + 0x20) + 0xB0,OUT tempMatrix);
View =
tempMatrix[0][3] * WorldLocation.x +
tempMatrix[1][3] * WorldLocation.y +
tempMatrix[2][3] * WorldLocation.z +
tempMatrix[3][3];
if (View < 1.f)
return false;
View = 1 / View;
Top = 窗口客户端中心X() + (
tempMatrix[0][0] * WorldLocation.x +
tempMatrix[1][0] * WorldLocation.y +
tempMatrix[2][0] * WorldLocation.z +
tempMatrix[3][0]
) * View * 窗口客户端中心X();
Lift = 窗口客户端中心Y() - (
tempMatrix[0][1] * WorldLocation.x +
tempMatrix[1][1] * WorldLocation.y +
tempMatrix[2][1] * WorldLocation.z +
tempMatrix[3][1]
) * View * 窗口客户端中心Y();
BoxY = 窗口客户端中心Y() - (
tempMatrix[0][1] * WorldLocation.x +
tempMatrix[1][1] * WorldLocation.y +
tempMatrix[2][1] * (WorldLocation.z + 75.0f) +
tempMatrix[3][1]
) * View * 窗口客户端中心Y();
Rect.h = Lift - BoxY;
Rect.w = Rect.h * (float)0.6015625;
Rect.x = Top - Rect.w / 1.4f;
Rect.y = BoxY;
Rect.w *= 1.5f;
Rect.h *= 2.3f;
return true;
}
|
游戏安全课程 学员办理咨询联系QQ150330575 手机 139 9636 2600 免费课程 在 www.bilibili.com 搜 郁金香灬老师
|
|