Merge branch 'master' into pr/19

This commit is contained in:
IcePixelx 2021-07-31 16:12:27 +02:00
commit ea2e07a0f1
45 changed files with 1617 additions and 1385 deletions

186
external/minhook/include/MinHook.h vendored Normal file
View File

@ -0,0 +1,186 @@
/*
* MinHook - The Minimalistic API Hooking Library for x64/x86
* Copyright (C) 2009-2017 Tsuda Kageyu.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* 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.
*/
#pragma once
#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__)
#error MinHook supports only x86 and x64 systems.
#endif
#include <windows.h>
// MinHook Error Codes.
typedef enum MH_STATUS
{
// Unknown error. Should not be returned.
MH_UNKNOWN = -1,
// Successful.
MH_OK = 0,
// MinHook is already initialized.
MH_ERROR_ALREADY_INITIALIZED,
// MinHook is not initialized yet, or already uninitialized.
MH_ERROR_NOT_INITIALIZED,
// The hook for the specified target function is already created.
MH_ERROR_ALREADY_CREATED,
// The hook for the specified target function is not created yet.
MH_ERROR_NOT_CREATED,
// The hook for the specified target function is already enabled.
MH_ERROR_ENABLED,
// The hook for the specified target function is not enabled yet, or already
// disabled.
MH_ERROR_DISABLED,
// The specified pointer is invalid. It points the address of non-allocated
// and/or non-executable region.
MH_ERROR_NOT_EXECUTABLE,
// The specified target function cannot be hooked.
MH_ERROR_UNSUPPORTED_FUNCTION,
// Failed to allocate memory.
MH_ERROR_MEMORY_ALLOC,
// Failed to change the memory protection.
MH_ERROR_MEMORY_PROTECT,
// The specified module is not loaded.
MH_ERROR_MODULE_NOT_FOUND,
// The specified function is not found.
MH_ERROR_FUNCTION_NOT_FOUND
}
MH_STATUS;
// Can be passed as a parameter to MH_EnableHook, MH_DisableHook,
// MH_QueueEnableHook or MH_QueueDisableHook.
#define MH_ALL_HOOKS NULL
#ifdef __cplusplus
extern "C" {
#endif
// Initialize the MinHook library. You must call this function EXACTLY ONCE
// at the beginning of your program.
MH_STATUS WINAPI MH_Initialize(VOID);
// Uninitialize the MinHook library. You must call this function EXACTLY
// ONCE at the end of your program.
MH_STATUS WINAPI MH_Uninitialize(VOID);
// Creates a Hook for the specified target function, in disabled state.
// Parameters:
// pTarget [in] A pointer to the target function, which will be
// overridden by the detour function.
// pDetour [in] A pointer to the detour function, which will override
// the target function.
// ppOriginal [out] A pointer to the trampoline function, which will be
// used to call the original target function.
// This parameter can be NULL.
MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal);
// Creates a Hook for the specified API function, in disabled state.
// Parameters:
// pszModule [in] A pointer to the loaded module name which contains the
// target function.
// pszTarget [in] A pointer to the target function name, which will be
// overridden by the detour function.
// pDetour [in] A pointer to the detour function, which will override
// the target function.
// ppOriginal [out] A pointer to the trampoline function, which will be
// used to call the original target function.
// This parameter can be NULL.
MH_STATUS WINAPI MH_CreateHookApi(
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal);
// Creates a Hook for the specified API function, in disabled state.
// Parameters:
// pszModule [in] A pointer to the loaded module name which contains the
// target function.
// pszTarget [in] A pointer to the target function name, which will be
// overridden by the detour function.
// pDetour [in] A pointer to the detour function, which will override
// the target function.
// ppOriginal [out] A pointer to the trampoline function, which will be
// used to call the original target function.
// This parameter can be NULL.
// ppTarget [out] A pointer to the target function, which will be used
// with other functions.
// This parameter can be NULL.
MH_STATUS WINAPI MH_CreateHookApiEx(
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget);
// Removes an already created hook.
// Parameters:
// pTarget [in] A pointer to the target function.
MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget);
// Enables an already created hook.
// Parameters:
// pTarget [in] A pointer to the target function.
// If this parameter is MH_ALL_HOOKS, all created hooks are
// enabled in one go.
MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget);
// Disables an already created hook.
// Parameters:
// pTarget [in] A pointer to the target function.
// If this parameter is MH_ALL_HOOKS, all created hooks are
// disabled in one go.
MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget);
// Queues to enable an already created hook.
// Parameters:
// pTarget [in] A pointer to the target function.
// If this parameter is MH_ALL_HOOKS, all created hooks are
// queued to be enabled.
MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget);
// Queues to disable an already created hook.
// Parameters:
// pTarget [in] A pointer to the target function.
// If this parameter is MH_ALL_HOOKS, all created hooks are
// queued to be disabled.
MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget);
// Applies all queued changes in one go.
MH_STATUS WINAPI MH_ApplyQueued(VOID);
// Translates the MH_STATUS to its name as a string.
const char * WINAPI MH_StatusToString(MH_STATUS status);
#ifdef __cplusplus
}
#endif

BIN
external/minhook/lib/libMinHook.x64.lib vendored Normal file

Binary file not shown.

View File

@ -1,46 +0,0 @@
#include "pch.h"
#include "cnetchan.h"
//-----------------------------------------------------------------------------
// Hook and log the receive datagram
//-----------------------------------------------------------------------------
bool HNET_ReceiveDatagram(int sock, void* inpacket, bool raw)
{
bool result = org_NET_ReceiveDatagram(sock, inpacket, raw);
if (result)
{
int i = NULL;
netpacket_t* pkt = (netpacket_t*)inpacket;
// Log received packet data
HexDump("[+] NET_ReceiveDatagram", 0, &pkt->data[i], pkt->wiresize);
}
return result;
}
//-----------------------------------------------------------------------------
// Hook and log send datagram
//-----------------------------------------------------------------------------
unsigned int HNET_SendDatagram(SOCKET s, const char* buf, int len, int flags)
{
unsigned int result = org_NET_SendDatagram(s, buf, len, flags);
if (result)
{
// Log transmitted packet data
HexDump("[+] NET_SendDatagram", 0, buf, len);
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
void AttachCNetChanHooks()
{
DetourAttach((LPVOID*)&org_NET_ReceiveDatagram, &HNET_ReceiveDatagram);
DetourAttach((LPVOID*)&org_NET_SendDatagram, &HNET_SendDatagram);
}
void DetachCNetChanHooks()
{
DetourDetach((LPVOID*)&org_NET_ReceiveDatagram, &HNET_ReceiveDatagram);
DetourDetach((LPVOID*)&org_NET_SendDatagram, &HNET_SendDatagram);
}

View File

@ -1,34 +0,0 @@
#pragma once
#include "pch.h"
#include "hooks.h"
bool HNET_ReceiveDatagram(int sock, void* inpacket, bool raw);
unsigned int HNET_SendDatagram(SOCKET s, const char* buf, int len, int flags);
void AttachCNetChanHooks();
void DetachCNetChanHooks();
typedef unsigned __int64 QWORD;
struct __declspec(align(8)) netpacket_t
{
DWORD family_maybe;
sockaddr_in sin;
WORD sin_port;
BYTE gap16;
BYTE byte17;
DWORD source;
double received;
unsigned __int8* data;
QWORD label;
BYTE byte38;
QWORD qword40;
QWORD qword48;
BYTE gap50[8];
QWORD qword58;
QWORD qword60;
QWORD qword68;
int less_than_12;
DWORD wiresize;
BYTE gap78[8];
QWORD qword80;
};

View File

@ -1,39 +0,0 @@
#include "pch.h"
#include "concommand.h"
//-----------------------------------------------------------------------------
// Purpose: test each ConCommand query before execution
// Input : *cmd - flag
// Output : true if execution is not permitted, false if permitted
//-----------------------------------------------------------------------------
bool HConCommand_IsFlagSet(int* cmd, int flag)
{
int real_flags = *((cmd + (56 / sizeof(int))));
if (g_bDebugConsole)
{
printf("--------------------------------------------------\n");
printf(" Flaged: %08X\n", real_flags);
}
// Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY
real_flags &= 0xFFFFBFFD;
if (g_bDebugConsole)
{
printf(" Masked: %08X\n", real_flags);
printf(" Verify: %08X\n", flag);
printf("--------------------------------------------------\n");
}
if (flag & 0x80000) { return true; }
if (!g_bReturnAllFalse) { return (real_flags & flag) != 0; }
else { return false; } // Returning false on all queries may cause problems
}
void AttachConCommandHooks()
{
DetourAttach((LPVOID*)&org_ConCommand_IsFlagSet, &HConCommand_IsFlagSet);
}
void DetachConCommandHooks()
{
DetourDetach((LPVOID*)&org_ConCommand_IsFlagSet, &HConCommand_IsFlagSet);
}

View File

@ -1,7 +0,0 @@
#pragma once
#include "hooks.h"
bool HConCommand_IsFlagSet(int* cmd, int flag);
void AttachConCommandHooks();
void DetachConCommandHooks();

View File

@ -1,8 +1,6 @@
#include "pch.h"
#include "hooks.h"
#include "console.h"
#include "iconvar.h"
#include "concommand.h"
//#############################################################################
// INITIALIZATION
@ -71,8 +69,8 @@ DWORD __stdcall ProcessConsoleWorker(LPVOID)
///////////////////////////////////////////////////////////////////////
// Engine toggles
if (sCommand == "toggle net") { ToggleNetTrace(); continue; }
if (sCommand == "toggle dev") { ToggleDevCommands(); continue; }
if (sCommand == "toggle net") { Hooks::ToggleNetHooks(); continue; }
if (sCommand == "toggle dev") { Hooks::ToggleDevCommands(); continue; }
if (sCommand == "toggle fal") { g_bReturnAllFalse = !g_bReturnAllFalse; continue; }
///////////////////////////////////////////////////////////////////////
// Debug toggles
@ -80,12 +78,12 @@ DWORD __stdcall ProcessConsoleWorker(LPVOID)
if (sCommand == "console test") { g_bDebugConsole = !g_bDebugConsole; continue; }
///////////////////////////////////////////////////////////////////////
// Exec toggles
if (sCommand == "1") { org_CommandExecute(NULL, "exec autoexec_dev"); }
if (sCommand == "1") { addr_CommandExecute(NULL, "exec autoexec_dev"); }
if (sCommand == "2") { g_bDebugLoading = !g_bDebugLoading; continue; }
///////////////////////////////////////////////////////////////////////
// Execute the command in the r5 SQVM
org_CommandExecute(NULL, sCommand.c_str());
addr_CommandExecute(NULL, sCommand.c_str());
sCommand.clear();
///////////////////////////////////////////////////////////////////////

View File

@ -1,10 +1,15 @@
#include "pch.h"
#include "cvengineserver.h"
#include "hooks.h"
namespace Hooks
{
IsPersistenceDataAvailableFn originalIsPersistenceDataAvailable = nullptr;
}
//-----------------------------------------------------------------------------
// Sets the persistence var in the playerstruct to ready for each client
// Sets the persistence var in the playerstruct to ready for each client
//-----------------------------------------------------------------------------
bool HPersistence_IsAvailable(__int64 thisptr, int client)
bool Hooks::IsPersistenceDataAvailable(__int64 thisptr, int client)
{
static bool isPersistenceVarSet[256];
@ -27,16 +32,5 @@ bool HPersistence_IsAvailable(__int64 thisptr, int client)
isPersistenceVarSet[client] = true;
}
///////////////////////////////////////////////////////////////////////////
return org_Persistence_IsAvailable(thisptr, client);
}
void AttachCEngineServerHooks()
{
DetourAttach((LPVOID*)&org_Persistence_IsAvailable, &HPersistence_IsAvailable);
}
void DetachCEngineServerHooks()
{
DetourDetach((LPVOID*)&org_Persistence_IsAvailable, &HPersistence_IsAvailable);
return originalIsPersistenceDataAvailable(thisptr, client);
}

View File

@ -1,8 +0,0 @@
#pragma once
#include "pch.h"
#include "hooks.h"
bool HPersistence_IsAvailable(__int64 thisptr, int client);
void AttachCEngineServerHooks();
void DetachCEngineServerHooks();

View File

@ -10,7 +10,7 @@
void InitializeR5Dedicated()
{
SetupConsole();
InstallHooks();
Hooks::InstallHooks();
printf("+-----------------------------------------------------------------------------+\n");
printf("| R5 DEDICATED SERVER --------------------------------------------------- |\n");
printf("+-----------------------------------------------------------------------------+\n");
@ -20,7 +20,7 @@ void InitializeR5Dedicated()
void TerminateR5Dedicated()
{
FreeConsole();
RemoveHooks();
Hooks::RemoveHooks();
}
//#############################################################################

View File

@ -1,78 +1,99 @@
#include "pch.h"
#include "hooks.h"
#include "iconvar.h"
#include "concommand.h"
#include "cvengineserver.h"
#include "cnetchan.h"
#include "sqvm.h"
#include "msgbox.h"
#include "opcodes.h"
//#################################################################################
// MANAGEMENT
//#################################################################################
void InstallHooks()
void Hooks::InstallHooks()
{
///////////////////////////////////////////////////////////////////////////////
// Begin the detour transaction, to hook the the process
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
// Initialize Minhook
MH_Initialize();
// Hook Squirrel functions
MH_CreateHook(addr_SQVM_Print, &Hooks::SQVM_Print, NULL);
MH_CreateHook(addr_SQVM_LoadRson, &Hooks::SQVM_LoadRson, reinterpret_cast<void**>(&originalSQVM_LoadRson));
MH_CreateHook(addr_SQVM_LoadScript, &Hooks::SQVM_LoadScript, reinterpret_cast<void**>(&originalSQVM_LoadScript));
///////////////////////////////////////////////////////////////////////////////
// Hook functions
AttachIConVarHooks();
AttachConCommandHooks();
AttachCEngineServerHooks();
AttachSQVMHooks();
AttachMSGBoxHooks();
// Hook Game Functions
// MH_CreateHook(addr_CHLClient_FrameStageNotify, &Hooks::FrameStageNotify, reinterpret_cast<void**>(&originalFrameStageNotify));
MH_CreateHook(addr_CVEngineServer_IsPersistenceDataAvailable, &Hooks::IsPersistenceDataAvailable, reinterpret_cast<void**>(&originalIsPersistenceDataAvailable));
///////////////////////////////////////////////////////////////////////////////
// Commit the transaction
if (DetourTransactionCommit() != NO_ERROR)
{
// Failed to hook into the process, terminate
TerminateProcess(GetCurrentProcess(), 0xBAD0C0DE);
}
// Hook Netchan functions
MH_CreateHook(addr_NET_ReceiveDatagram, &Hooks::NET_ReceiveDatagram, reinterpret_cast<void**>(&originalNET_ReceiveDatagram));
MH_CreateHook(addr_NET_SendDatagram, &Hooks::NET_SendDatagram, reinterpret_cast<void**>(&originalNET_SendDatagram));
///////////////////////////////////////////////////////////////////////////////
// Hook ConVar | ConCommand functions.
MH_CreateHook(addr_ConVar_IsFlagSet, &Hooks::ConVar_IsFlagSet, NULL);
MH_CreateHook(addr_ConCommand_IsFlagSet, &Hooks::ConCommand_IsFlagSet, NULL);
///////////////////////////////////////////////////////////////////////////////
// Hook Utility functions
MH_CreateHook(addr_MSG_EngineError, &Hooks::MSG_EngineError, reinterpret_cast<void**>(&originalMSG_EngineError));
///////////////////////////////////////////////////////////////////////////////
// Enable Squirrel hooks
MH_EnableHook(addr_SQVM_Print);
MH_EnableHook(addr_SQVM_LoadRson);
MH_EnableHook(addr_SQVM_LoadScript);
///////////////////////////////////////////////////////////////////////////////
// Enable Game hooks
MH_EnableHook(addr_CHLClient_FrameStageNotify);
MH_EnableHook(addr_CVEngineServer_IsPersistenceDataAvailable);
///////////////////////////////////////////////////////////////////////////////
// Enabled Utility hooks
MH_EnableHook(addr_MSG_EngineError);
InstallOpcodes();
}
void RemoveHooks()
void Hooks::RemoveHooks()
{
///////////////////////////////////////////////////////////////////////////////
// Begin the detour transaction, to unhook the the process
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
// Unhook Squirrel functions
MH_RemoveHook(addr_SQVM_Print);
MH_RemoveHook(addr_SQVM_LoadRson);
MH_RemoveHook(addr_SQVM_LoadScript);
///////////////////////////////////////////////////////////////////////////////
// Unhook functions
DetachIConVarHooks();
DetachConCommandHooks();
DetachCEngineServerHooks();
DetachSQVMHooks();
DetachMSGBoxHooks();
// Unhook Game Functions
MH_RemoveHook(addr_CHLClient_FrameStageNotify);
MH_RemoveHook(addr_CVEngineServer_IsPersistenceDataAvailable);
///////////////////////////////////////////////////////////////////////////////
// Commit the transaction
DetourTransactionCommit();
// Unhook Netchan functions
MH_RemoveHook(addr_NET_ReceiveDatagram);
MH_RemoveHook(addr_NET_SendDatagram);
///////////////////////////////////////////////////////////////////////////////
// Unhook ConVar | ConCommand functions.
MH_RemoveHook(addr_ConVar_IsFlagSet);
MH_RemoveHook(addr_ConCommand_IsFlagSet);
///////////////////////////////////////////////////////////////////////////////
// Unhook Utility functions
MH_RemoveHook(addr_MSG_EngineError);
///////////////////////////////////////////////////////////////////////////////
// Reset Minhook
MH_Uninitialize();
}
//#################################################################################
// TOGGLES
//#################################################################################
void ToggleDevCommands()
void Hooks::ToggleDevCommands()
{
static bool bDev = true;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
static bool bDev = true;;
if (!bDev)
{
AttachIConVarHooks();
AttachConCommandHooks();
MH_EnableHook(addr_ConVar_IsFlagSet);
MH_EnableHook(addr_ConCommand_IsFlagSet);
printf("\n");
printf("+--------------------------------------------------------+\n");
printf("|>>>>>>>>>>>>>| DEVONLY COMMANDS ACTIVATED |<<<<<<<<<<<<<|\n");
@ -82,8 +103,8 @@ void ToggleDevCommands()
}
else
{
DetachIConVarHooks();
DetachConCommandHooks();
MH_DisableHook(addr_ConVar_IsFlagSet);
MH_DisableHook(addr_ConCommand_IsFlagSet);
printf("\n");
printf("+--------------------------------------------------------+\n");
printf("|>>>>>>>>>>>>| DEVONLY COMMANDS DEACTIVATED |<<<<<<<<<<<<|\n");
@ -91,24 +112,17 @@ void ToggleDevCommands()
printf("\n");
}
if (DetourTransactionCommit() != NO_ERROR)
{
TerminateProcess(GetCurrentProcess(), 0xBAD0C0DE);
}
bDev = !bDev;
}
void ToggleNetTrace()
void Hooks::ToggleNetHooks()
{
static bool bNet = true;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
if (!bNet)
{
AttachCNetChanHooks();
MH_EnableHook(addr_NET_ReceiveDatagram);
MH_EnableHook(addr_NET_SendDatagram);
printf("\n");
printf("+--------------------------------------------------------+\n");
printf("|>>>>>>>>>>>>>| NETCHANNEL TRACE ACTIVATED |<<<<<<<<<<<<<|\n");
@ -117,7 +131,8 @@ void ToggleNetTrace()
}
else
{
DetachCNetChanHooks();
MH_DisableHook(addr_NET_ReceiveDatagram);
MH_DisableHook(addr_NET_SendDatagram);
printf("\n");
printf("+--------------------------------------------------------+\n");
printf("|>>>>>>>>>>>>| NETCHANNEL TRACE DEACTIVATED |<<<<<<<<<<<<|\n");
@ -125,10 +140,5 @@ void ToggleNetTrace()
printf("\n");
}
if (DetourTransactionCommit() != NO_ERROR)
{
TerminateProcess(GetCurrentProcess(), 0xBAD0C0DE);
}
bNet = !bNet;
}

View File

@ -1,11 +1,5 @@
#pragma once
#include "pch.h"
#include "iconvar.h"
#include "concommand.h"
#include "cvengineserver.h"
#include "cnetchan.h"
#include "sqvm.h"
#include "msgbox.h"
// Define the signatures or offsets to be searched and hooked
namespace
{
@ -13,77 +7,130 @@ namespace
#pragma region Console
/*0x140202090*/
FUNC_AT_ADDRESS(org_CommandExecute, void(*)(void*, const char*), r5_patterns.PatternSearch("48 89 5C 24 ? 57 48 83 EC 20 48 8D 0D ? ? ? ? 41 8B D8").GetPtr());
FUNC_AT_ADDRESS(addr_CommandExecute, void(*)(void*, const char*), r5_patterns.PatternSearch("48 89 5C 24 ? 57 48 83 EC 20 48 8D 0D ? ? ? ? 41 8B D8").GetPtr());
/*0x14046FE90*/
FUNC_AT_ADDRESS(org_IConVar_IsFlagSet, bool(*)(int**, int), r5_patterns.PatternSearch("48 8B 41 48 85 50 38").GetPtr());
FUNC_AT_ADDRESS(addr_ConVar_IsFlagSet, bool(*)(int**, int), r5_patterns.PatternSearch("48 8B 41 48 85 50 38").GetPtr());
/*0x14046F490*/
FUNC_AT_ADDRESS(org_ConCommand_IsFlagSet, bool(*)(int*, int), r5_patterns.PatternSearch("85 51 38 0F 95 C0 C3").GetPtr());
FUNC_AT_ADDRESS(addr_ConCommand_IsFlagSet, bool(*)(int*, int), r5_patterns.PatternSearch("85 51 38 0F 95 C0 C3").GetPtr());
#pragma endregion
#pragma region Squirrel
/*0x141057FD0*/
FUNC_AT_ADDRESS(org_SQVM_PrintFunc, void*, r5_patterns.PatternSearch("83 F8 01 48 8D 3D ? ? ? ?").OffsetSelf(0x3).FollowNearCallSelf(0x3, 0x7).GetPtr());
FUNC_AT_ADDRESS(addr_SQVM_Print, void*, r5_patterns.PatternSearch("83 F8 01 48 8D 3D ? ? ? ?").OffsetSelf(0x3).FollowNearCallSelf(0x3, 0x7).GetPtr());
//DWORD64 p_SQVM_LoadScript = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x48\x89\x4C\x24\x08\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\x6C", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // For S0 and S1
/*0x141055630*/
// For anything S2 and above (current S8
FUNC_AT_ADDRESS(org_SQVM_LoadScript, bool(*)(void*, const char*, const char*, int), r5_patterns.PatternSearch("48 8B C4 48 89 48 08 55 41 56 48 8D 68").GetPtr());
FUNC_AT_ADDRESS(addr_SQVM_LoadScript, bool(*)(void*, const char*, const char*, int), r5_patterns.PatternSearch("48 8B C4 48 89 48 08 55 41 56 48 8D 68").GetPtr());
/*0x140C957E0*/
FUNC_AT_ADDRESS(org_SQVM_LoadRson, int(*)(const char*), r5_patterns.PatternSearch("4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33").GetPtr());
FUNC_AT_ADDRESS(addr_SQVM_LoadRson, int(*)(const char*), r5_patterns.PatternSearch("4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33").GetPtr());
#pragma endregion
#pragma region NetChannel
/*0x1402655F0*/
FUNC_AT_ADDRESS(org_NET_ReceiveDatagram, bool(*)(int, void*, bool), r5_patterns.PatternSearch("48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 50 EB").GetPtr());
FUNC_AT_ADDRESS(addr_NET_ReceiveDatagram, bool(*)(int, void*, bool), r5_patterns.PatternSearch("48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 50 EB").GetPtr());
/*0x1402662D0*/
FUNC_AT_ADDRESS(org_NET_SendDatagram, int(*)(SOCKET, const char*, int, int), r5_patterns.PatternSearch("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ? 05 ? ?").GetPtr());
FUNC_AT_ADDRESS(addr_NET_SendDatagram, int(*)(SOCKET, const char*, int, int), r5_patterns.PatternSearch("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ? 05 ? ?").GetPtr());
#pragma endregion
#pragma region CHLClient
/*0x1405C0740*/
FUNC_AT_ADDRESS(org_CHLClient_FrameStageNotify, void(*)(void* rcx, int curStage), r5_patterns.PatternSearch("48 83 EC 28 89 15 ?? ?? ?? ??").GetPtr());
FUNC_AT_ADDRESS(addr_CHLClient_FrameStageNotify, void(*)(void* rcx, int curStage), r5_patterns.PatternSearch("48 83 EC 28 89 15 ?? ?? ?? ??").GetPtr());
#pragma endregion
#pragma region CVEngineServer
/*0x140315CF0*/
FUNC_AT_ADDRESS(org_Persistence_IsAvailable, bool(*)(__int64, int), r5_patterns.PatternSearch("3B 15 ?? ?? ?? ?? 7D 33").GetPtr());
FUNC_AT_ADDRESS(addr_CVEngineServer_IsPersistenceDataAvailable, bool(*)(__int64, int), r5_patterns.PatternSearch("3B 15 ?? ?? ?? ?? 7D 33").GetPtr());
#pragma endregion
#pragma region Utility
/*0x140295600*/
FUNC_AT_ADDRESS(org_MSG_EngineError, int(*)(char*, va_list), r5_patterns.PatternSearch("48 89 5C 24 08 48 89 74 24 10 57 48 81 EC 30 08 00 00 48 8B DA").GetPtr());
FUNC_AT_ADDRESS(addr_MSG_EngineError, int(*)(char*, va_list), r5_patterns.PatternSearch("48 89 5C 24 08 48 89 74 24 10 57 48 81 EC 30 08 00 00 48 8B DA").GetPtr());
#pragma endregion
inline bool g_bDebugConsole = false;
inline bool g_bReturnAllFalse = false;
inline bool g_bDebugLoading = false;
// Un-used atm.
// DWORD64 p_KeyValues_FindKey = /*1404744E0*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "40 56 57 41 57 48 81 EC ?? ?? ?? ?? 45"));
void PrintHAddress() // Test the sigscan results
{
std::cout << "+--------------------------------------------------------+" << std::endl;
PRINT_ADDRESS("CommandExecute", org_CommandExecute);
PRINT_ADDRESS("IConVar_IsFlagSet", org_IConVar_IsFlagSet);
PRINT_ADDRESS("ConCommand_IsFlagSet", org_ConCommand_IsFlagSet);
PRINT_ADDRESS("SQVM_Print", org_SQVM_PrintFunc);
PRINT_ADDRESS("SQVM_LoadScript", org_SQVM_LoadScript);
PRINT_ADDRESS("SQVM_LoadRson", org_SQVM_LoadRson);
PRINT_ADDRESS("NET_ReceiveDatagram", org_NET_ReceiveDatagram);
PRINT_ADDRESS("NET_SendDatagram ", org_NET_SendDatagram);
PRINT_ADDRESS("CHLClient::FrameStageNotify", org_CHLClient_FrameStageNotify);
PRINT_ADDRESS("CVEngineServer::Persistence_IsAvailable", org_Persistence_IsAvailable);
PRINT_ADDRESS("MSG_EngineError", org_MSG_EngineError);
PRINT_ADDRESS("CommandExecute", addr_CommandExecute);
PRINT_ADDRESS("ConVar_IsFlagSet", addr_ConVar_IsFlagSet);
PRINT_ADDRESS("ConCommand_IsFlagSet", addr_ConCommand_IsFlagSet);
PRINT_ADDRESS("SQVM_Print", addr_SQVM_Print);
PRINT_ADDRESS("SQVM_LoadScript", addr_SQVM_LoadScript);
PRINT_ADDRESS("SQVM_LoadRson", addr_SQVM_LoadRson);
PRINT_ADDRESS("NET_ReceiveDatagram", addr_NET_ReceiveDatagram);
PRINT_ADDRESS("NET_SendDatagram ", addr_NET_SendDatagram);
PRINT_ADDRESS("CHLClient::FrameStageNotify", addr_CHLClient_FrameStageNotify);
PRINT_ADDRESS("CVEngineServer::IsPersistenceDataAvailable", addr_CVEngineServer_IsPersistenceDataAvailable);
PRINT_ADDRESS("MSG_EngineError", addr_MSG_EngineError);
std::cout << "+--------------------------------------------------------+" << std::endl;
// TODO implement error handling when sigscan fails or result is 0
}
}
void InstallHooks();
void RemoveHooks();
inline bool g_bDebugLoading = false;
inline bool g_bReturnAllFalse = false;
inline bool g_bDebugConsole = false;
void ToggleDevCommands();
void ToggleNetTrace();
namespace Hooks
{
#pragma region CHLClient
// void __fastcall FrameStageNotify(CHLClient* rcx, ClientFrameStage_t curStage);
// using FrameStageNotifyFn = void(__fastcall*)(CHLClient*, ClientFrameStage_t);
// extern FrameStageNotifyFn originalFrameStageNotify;
#pragma endregion
#pragma region Squirrel
void* SQVM_Print(void* sqvm, char* fmt, ...);
__int64 SQVM_LoadRson(const char* rson_name);
bool SQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag);
using SQVM_LoadRsonFn = __int64(*)(const char*);
extern SQVM_LoadRsonFn originalSQVM_LoadRson;
using SQVM_LoadScriptFn = bool(*)(void*, const char*, const char*, int);
extern SQVM_LoadScriptFn originalSQVM_LoadScript;
#pragma endregion
#pragma region CVEngineServer
bool IsPersistenceDataAvailable(__int64 thisptr, int client);
using IsPersistenceDataAvailableFn = bool(*)(__int64, int);
extern IsPersistenceDataAvailableFn originalIsPersistenceDataAvailable;
#pragma endregion
#pragma region NetChannel
bool NET_ReceiveDatagram(int sock, void* inpacket, bool raw);
unsigned int NET_SendDatagram(SOCKET s, const char* buf, int len, int flags);
using NET_ReceiveDatagramFn = bool(*)(int, void*, bool);
extern NET_ReceiveDatagramFn originalNET_ReceiveDatagram;
using NET_SendDatagramFn = unsigned int(*)(SOCKET, const char*, int, int);
extern NET_SendDatagramFn originalNET_SendDatagram;
#pragma endregion
#pragma region ConVar
bool ConVar_IsFlagSet(int** cvar, int flag);
bool ConCommand_IsFlagSet(int* cmd, int flag);
#pragma endregion
#pragma region Other
int MSG_EngineError(char* fmt, va_list args);
using MSG_EngineErrorFn = int(*)(char*, va_list);
extern MSG_EngineErrorFn originalMSG_EngineError;
#pragma endregion
void InstallHooks();
void RemoveHooks();
void ToggleNetHooks();
void ToggleDevCommands();
}

View File

@ -1,12 +1,13 @@
#include "pch.h"
#include "iconvar.h"
#include "hooks.h"
//-----------------------------------------------------------------------------
// Purpose: test each ConVar query before setting the cvar
// Input : **cvar - flag
// Output : true if change is not permitted, false if permitted
//-----------------------------------------------------------------------------
bool HConVar_IsFlagSet(int** cvar, int flag)
bool Hooks::ConVar_IsFlagSet(int** cvar, int flag)
{
int real_flags = *(*(cvar + (72 / (sizeof(void*)))) + (56 / sizeof(int)));
if (g_bDebugConsole)
@ -24,16 +25,46 @@ bool HConVar_IsFlagSet(int** cvar, int flag)
}
if (flag & 0x80000) { return true; }
if (!g_bReturnAllFalse) { return (real_flags & flag) != 0; }
else { return false; } // Returning false on all queries may cause problems
if (!g_bReturnAllFalse)
{
return (real_flags & flag) != 0;
}
else
{
return false;
}
}
void AttachIConVarHooks()
{
DetourAttach((LPVOID*)&org_IConVar_IsFlagSet, &HConVar_IsFlagSet);
}
//-----------------------------------------------------------------------------
// Purpose: test each ConCommand query before execution
// Input : *cmd - flag
// Output : true if execution is not permitted, false if permitted
//-----------------------------------------------------------------------------
void DetachIConVarHooks()
bool Hooks::ConCommand_IsFlagSet(int* cmd, int flag)
{
DetourDetach((LPVOID*)&org_IConVar_IsFlagSet, &HConVar_IsFlagSet);
int real_flags = *((cmd + (56 / sizeof(int))));
if (g_bDebugConsole)
{
printf("--------------------------------------------------\n");
printf(" Flaged: %08X\n", real_flags);
}
// Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY
real_flags &= 0xFFFFBFFD;
if (g_bDebugConsole)
{
printf(" Masked: %08X\n", real_flags);
printf(" Verify: %08X\n", flag);
printf("--------------------------------------------------\n");
}
if (flag & 0x80000) { return true; }
if (!g_bReturnAllFalse)
{
return(real_flags & flag) != 0;
}
else
{
return false;
}
}

View File

@ -1,7 +0,0 @@
#pragma once
#include "hooks.h"
bool HConVar_IsFlagSet(int** cvar, int flag);
void AttachIConVarHooks();
void DetachIConVarHooks();

View File

@ -1,24 +1,19 @@
#include "pch.h"
#include "hooks.h"
namespace Hooks
{
MSG_EngineErrorFn originalMSG_EngineError = nullptr;
}
//-----------------------------------------------------------------------------
// Engine Error message box
//-----------------------------------------------------------------------------
int HMSG_EngineError(char* fmt, va_list args)
int Hooks::MSG_EngineError(char* fmt, va_list args)
{
printf("\nENGINE ERROR #####################################\n");
vprintf(fmt, args);
///////////////////////////////////////////////////////////////////////////
return org_MSG_EngineError(fmt, args);
}
void AttachMSGBoxHooks()
{
DetourAttach((LPVOID*)&org_MSG_EngineError, &HMSG_EngineError);
}
void DetachMSGBoxHooks()
{
DetourDetach((LPVOID*)&org_MSG_EngineError, &HMSG_EngineError);
return originalMSG_EngineError(fmt, args);
}

View File

@ -1,7 +0,0 @@
#pragma once
#include "hooks.h"
int HMSG_EngineError(char* fmt, va_list args);
void AttachMSGBoxHooks();
void DetachMSGBoxHooks();

71
r5dedicated/net.cpp Normal file
View File

@ -0,0 +1,71 @@
#include "pch.h"
#include "hooks.h"
namespace Hooks
{
NET_ReceiveDatagramFn originalNET_ReceiveDatagram = nullptr;
NET_SendDatagramFn originalNET_SendDatagram = nullptr;
}
typedef unsigned __int64 QWORD;
struct __declspec(align(8)) netpacket_t
{
DWORD family_maybe;
sockaddr_in sin;
WORD sin_port;
BYTE gap16;
BYTE byte17;
DWORD source;
double received;
unsigned __int8* data;
QWORD label;
BYTE byte38;
QWORD qword40;
QWORD qword48;
BYTE gap50[8];
QWORD qword58;
QWORD qword60;
QWORD qword68;
int less_than_12;
DWORD wiresize;
BYTE gap78[8];
QWORD qword80;
};
//-----------------------------------------------------------------------------
// Hook and log the receive datagram
//-----------------------------------------------------------------------------
bool Hooks::NET_ReceiveDatagram(int sock, void* inpacket, bool raw)
{
bool result = originalNET_ReceiveDatagram(sock, inpacket, raw);
if (result)
{
int i = NULL;
netpacket_t* pkt = (netpacket_t*)inpacket;
///////////////////////////////////////////////////////////////////////////
// Log received packet data
HexDump("[+] NET_ReceiveDatagram", 0, &pkt->data[i], pkt->wiresize);
}
return result;
}
//-----------------------------------------------------------------------------
// Hook and log send datagram
//-----------------------------------------------------------------------------
unsigned int Hooks::NET_SendDatagram(SOCKET s, const char* buf, int len, int flags)
{
unsigned int result = originalNET_SendDatagram(s, buf, len, flags);
if (result)
{
///////////////////////////////////////////////////////////////////////////
// Log transmitted packet data
HexDump("[+] NET_SendDatagram", 0, buf, len);
}
return result;
}

View File

@ -3,7 +3,7 @@
#define WIN32_LEAN_AND_MEAN // Prevent winsock2 redefinition.
#include <windows.h>
#include <detours.h>
#include <minhook.h>
#include <WinSock2.h>
#include <thread>
#include <fstream>

View File

@ -87,8 +87,8 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>dedicated</TargetName>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)external\detours\include;$(SolutionDir)external\spdlog\include;$(SolutionDir)shared\include;$(SolutionDir)r5dedicated;$(IncludePath)</IncludePath>
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(SolutionDir)external\detours\libs;$(LibraryPath)</LibraryPath>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)external\minhook\include;$(SolutionDir)external\spdlog\include;$(SolutionDir)shared\include;$(SolutionDir)r5dedicated;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)external\minhook\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -164,19 +164,18 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>detours.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>libMinHook.x64.lib</AdditionalDependencies>
<ModuleDefinitionFile>r5dedicated.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\shared\utility.cpp" />
<ClCompile Include="concommand.cpp" />
<ClCompile Include="console.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="hooks.cpp" />
<ClCompile Include="iconvar.cpp" />
<ClCompile Include="msgbox.cpp" />
<ClCompile Include="cnetchan.cpp" />
<ClCompile Include="net.cpp" />
<ClCompile Include="opcodes.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
@ -186,6 +185,7 @@
<ClCompile Include="sqvm.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\external\minhook\include\MinHook.h" />
<ClInclude Include="..\external\spdlog\include\async.h" />
<ClInclude Include="..\external\spdlog\include\async_logger-inl.h" />
<ClInclude Include="..\external\spdlog\include\async_logger.h" />
@ -284,17 +284,11 @@
<ClInclude Include="..\shared\include\httplib.h" />
<ClInclude Include="..\shared\include\json.hpp" />
<ClInclude Include="..\shared\include\utility.h" />
<ClInclude Include="concommand.h" />
<ClInclude Include="console.h" />
<ClInclude Include="dllmain.h" />
<ClInclude Include="hooks.h" />
<ClInclude Include="iconvar.h" />
<ClInclude Include="msgbox.h" />
<ClInclude Include="cnetchan.h" />
<ClInclude Include="opcodes.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="cvengineserver.h" />
<ClInclude Include="sqvm.h" />
</ItemGroup>
<ItemGroup>
<None Include="r5dedicated.def" />

View File

@ -17,27 +17,9 @@
<Filter Include="shared\include">
<UniqueIdentifier>{a0165b58-06b1-4b6a-b5d1-5d643517ad14}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\iconvar">
<UniqueIdentifier>{06affed3-5a59-4b95-88ca-72d92c91909b}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\concommand">
<UniqueIdentifier>{0742106d-702f-499e-99f1-e43f2a6ae561}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\cvengineserver">
<UniqueIdentifier>{338a4fb7-7519-4628-9206-679d33824965}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\other">
<UniqueIdentifier>{cc424eef-0c7a-4fb0-9d84-30bf8db2e253}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\squirrel">
<UniqueIdentifier>{74afa89f-72af-4e13-aa90-70f7a1957154}</UniqueIdentifier>
</Filter>
<Filter Include="core\resource">
<UniqueIdentifier>{35b40ed1-12bd-4bcf-9c05-5a42a0096619}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\netchannel">
<UniqueIdentifier>{05e6e9a7-801b-49b0-9c5a-21c4868befb7}</UniqueIdentifier>
</Filter>
<Filter Include="shared\libraries">
<UniqueIdentifier>{a7199092-e8a9-49fa-97e1-b2d0ea21001b}</UniqueIdentifier>
</Filter>
@ -62,6 +44,42 @@
<Filter Include="shared\libraries\spdlog\include\sinks">
<UniqueIdentifier>{eaefe9b7-d14d-48b6-878a-53a5ada7454b}</UniqueIdentifier>
</Filter>
<Filter Include="shared\libraries\minhook">
<UniqueIdentifier>{245e8064-9b24-4631-9326-340dfb761fde}</UniqueIdentifier>
</Filter>
<Filter Include="shared\libraries\minhook\include">
<UniqueIdentifier>{485b5648-149f-4664-a961-be9cd520e9e3}</UniqueIdentifier>
</Filter>
<Filter Include="r5-sdk">
<UniqueIdentifier>{f5326cf2-826e-4499-98de-e818e096939d}</UniqueIdentifier>
</Filter>
<Filter Include="r5-sdk\include">
<UniqueIdentifier>{4c680991-cc41-4265-a6f3-b46d698bd72f}</UniqueIdentifier>
</Filter>
<Filter Include="r5-sdk\src">
<UniqueIdentifier>{8aac7eb6-9810-4fa2-bbfe-499fb2950f01}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src">
<UniqueIdentifier>{f28b1a49-9b41-48d2-9462-1674af3d72a2}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src\other">
<UniqueIdentifier>{cc424eef-0c7a-4fb0-9d84-30bf8db2e253}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src\squirrel">
<UniqueIdentifier>{74afa89f-72af-4e13-aa90-70f7a1957154}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src\netchannel">
<UniqueIdentifier>{05e6e9a7-801b-49b0-9c5a-21c4868befb7}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src\iconvar">
<UniqueIdentifier>{06affed3-5a59-4b95-88ca-72d92c91909b}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src\cvengineserver">
<UniqueIdentifier>{338a4fb7-7519-4628-9206-679d33824965}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\include">
<UniqueIdentifier>{31cdde4d-3641-497c-9b34-20d3d7c89d87}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\shared\include\address.h">
@ -79,36 +97,12 @@
<ClInclude Include="console.h">
<Filter>core\include</Filter>
</ClInclude>
<ClInclude Include="cnetchan.h">
<Filter>hooks\netchannel</Filter>
</ClInclude>
<ClInclude Include="pch.h">
<Filter>core\include</Filter>
</ClInclude>
<ClInclude Include="concommand.h">
<Filter>hooks\concommand</Filter>
</ClInclude>
<ClInclude Include="cvengineserver.h">
<Filter>hooks\cvengineserver</Filter>
</ClInclude>
<ClInclude Include="sqvm.h">
<Filter>hooks\squirrel</Filter>
</ClInclude>
<ClInclude Include="msgbox.h">
<Filter>hooks\other</Filter>
</ClInclude>
<ClInclude Include="hooks.h">
<Filter>hooks</Filter>
</ClInclude>
<ClInclude Include="dllmain.h">
<Filter>core\include</Filter>
</ClInclude>
<ClInclude Include="opcodes.h">
<Filter>hooks\other</Filter>
</ClInclude>
<ClInclude Include="iconvar.h">
<Filter>hooks\iconvar</Filter>
</ClInclude>
<ClInclude Include="..\external\spdlog\include\async.h">
<Filter>shared\libraries\spdlog\include</Filter>
</ClInclude>
@ -391,6 +385,15 @@
<ClInclude Include="..\external\spdlog\include\sinks\win_eventlog_sink.h">
<Filter>shared\libraries\spdlog\include\sinks</Filter>
</ClInclude>
<ClInclude Include="..\external\minhook\include\MinHook.h">
<Filter>shared\libraries\minhook\include</Filter>
</ClInclude>
<ClInclude Include="opcodes.h">
<Filter>r5-sdk\include</Filter>
</ClInclude>
<ClInclude Include="hooks.h">
<Filter>hooks\include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="console.cpp">
@ -402,33 +405,30 @@
<ClCompile Include="pch.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="hooks.cpp">
<Filter>hooks</Filter>
</ClCompile>
<ClCompile Include="cnetchan.cpp">
<Filter>hooks\netchannel</Filter>
</ClCompile>
<ClCompile Include="concommand.cpp">
<Filter>hooks\concommand</Filter>
<ClCompile Include="net.cpp">
<Filter>hooks\src\netchannel</Filter>
</ClCompile>
<ClCompile Include="cvengineserver.cpp">
<Filter>hooks\cvengineserver</Filter>
<Filter>hooks\src\cvengineserver</Filter>
</ClCompile>
<ClCompile Include="sqvm.cpp">
<Filter>hooks\squirrel</Filter>
<Filter>hooks\src\squirrel</Filter>
</ClCompile>
<ClCompile Include="msgbox.cpp">
<Filter>hooks\other</Filter>
</ClCompile>
<ClCompile Include="opcodes.cpp">
<Filter>hooks\other</Filter>
</ClCompile>
<ClCompile Include="iconvar.cpp">
<Filter>hooks\iconvar</Filter>
<Filter>hooks\src\other</Filter>
</ClCompile>
<ClCompile Include="..\shared\utility.cpp">
<Filter>shared</Filter>
</ClCompile>
<ClCompile Include="iconvar.cpp">
<Filter>hooks\src\iconvar</Filter>
</ClCompile>
<ClCompile Include="opcodes.cpp">
<Filter>r5-sdk\src</Filter>
</ClCompile>
<ClCompile Include="hooks.cpp">
<Filter>hooks\src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="r5dedicated.def">

View File

@ -1,11 +1,18 @@
#include "pch.h"
#include "sqvm.h"
#include "hooks.h"
namespace Hooks
{
SQVM_LoadRsonFn originalSQVM_LoadRson = nullptr;
SQVM_LoadScriptFn originalSQVM_LoadScript = nullptr;
}
//---------------------------------------------------------------------------------
// Print the output of the VM.
// TODO: separate SV CL and UI
//---------------------------------------------------------------------------------
void* HSQVM_PrintFunc(void* sqvm, char* fmt, ...)
void* Hooks::SQVM_Print(void* sqvm, char* fmt, ...)
{
va_list args;
va_start(args, fmt);
@ -17,11 +24,13 @@ void* HSQVM_PrintFunc(void* sqvm, char* fmt, ...)
//---------------------------------------------------------------------------------
// Load the include file from the mods directory
//---------------------------------------------------------------------------------
__int64 HSQVM_LoadRson(const char* rson_name)
__int64 Hooks::SQVM_LoadRson(const char* rson_name)
{
char filepath[MAX_PATH] = { 0 };
sprintf_s(filepath, MAX_PATH, "platform\\%s", rson_name);
///////////////////////////////////////////////////////////////////////////////
// Flip forward slashes in filepath to windows-style backslash
for (int i = 0; i < strlen(filepath); i++)
{
@ -31,15 +40,17 @@ __int64 HSQVM_LoadRson(const char* rson_name)
}
}
///////////////////////////////////////////////////////////////////////////////
// Returns the new path if the rson exists on the disk
if (FileExists(filepath) && org_SQVM_LoadRson(rson_name))
if (FileExists(filepath) && originalSQVM_LoadRson(rson_name))
{
printf("\n");
printf("##################################################\n");
printf("] '%s'\n", filepath);
printf("##################################################\n");
printf("\n");
return org_SQVM_LoadRson(filepath);
return originalSQVM_LoadRson(filepath);
}
printf("\n");
@ -47,17 +58,20 @@ __int64 HSQVM_LoadRson(const char* rson_name)
printf("] '%s'\n", rson_name);
printf("##################################################\n");
printf("\n");
return org_SQVM_LoadRson(rson_name);
return originalSQVM_LoadRson(rson_name);
}
//---------------------------------------------------------------------------------
// Load the script file from the mods directory
//---------------------------------------------------------------------------------
bool HSQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag)
bool Hooks::SQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag)
{
char filepath[MAX_PATH] = { 0 };
sprintf_s(filepath, MAX_PATH, "platform\\%s", script_path);
///////////////////////////////////////////////////////////////////////////////
// Flip forward slashes in filepath to windows-style backslash
for (int i = 0; i < strlen(filepath); i++)
{
@ -70,9 +84,9 @@ bool HSQVM_LoadScript(void* sqvm, const char* script_path, const char* script_na
{
printf(" [+] Loading SQVM Script '%s' ...\n", filepath);
}
///////////////////////////////////////////////////////////////////////////////
// Returns true if the script exists on the disk
if (FileExists(filepath) && org_SQVM_LoadScript(sqvm, filepath, script_name, flag))
if (FileExists(filepath) && originalSQVM_LoadScript(sqvm, filepath, script_name, flag))
{
return true;
}
@ -81,20 +95,5 @@ bool HSQVM_LoadScript(void* sqvm, const char* script_path, const char* script_na
printf(" [!] FAILED. Try SP / VPK for '%s'\n", filepath);
}
///////////////////////////////////////////////////////////////////////////////
return org_SQVM_LoadScript(sqvm, script_path, script_name, flag);
}
void AttachSQVMHooks()
{
DetourAttach((LPVOID*)&org_SQVM_PrintFunc, &HSQVM_PrintFunc);
DetourAttach((LPVOID*)&org_SQVM_LoadRson, &HSQVM_LoadRson);
DetourAttach((LPVOID*)&org_SQVM_LoadScript, &HSQVM_LoadScript);
}
void DetachSQVMHooks()
{
DetourDetach((LPVOID*)&org_SQVM_PrintFunc, &HSQVM_PrintFunc);
DetourDetach((LPVOID*)&org_SQVM_LoadRson, &HSQVM_LoadRson);
DetourDetach((LPVOID*)&org_SQVM_LoadScript, &HSQVM_LoadScript);
return originalSQVM_LoadScript(sqvm, script_path, script_name, flag);
}

View File

@ -1,10 +0,0 @@
#pragma once
#include "pch.h"
#include "hooks.h"
void* HSQVM_PrintFunc(void* sqvm, char* fmt, ...);
__int64 HSQVM_LoadRson(const char* rson_name);
bool HSQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag);
void AttachSQVMHooks();
void DetachSQVMHooks();

View File

@ -2,18 +2,4 @@
/////////////////////////////////////////////////////////////////////////////
// Initialization
void SetupConsole();
void RemoveCMHooks();
void ToggleDevCommands();
/////////////////////////////////////////////////////////////////////////////
// Hooks
bool HConVar_IsFlagSet(int** cvar, int flag);
bool HConCommand_IsFlagSet(int* cmd, int flag);
/////////////////////////////////////////////////////////////////////////////
// Globals
inline bool g_bDebugConsole = false;
inline bool g_bReturnAllFalse = false;
/////////////////////////////////////////////////////////////////////////////
void SetupConsole();

View File

@ -79,3 +79,255 @@ enum class DXGISwapChainVTbl : short
GetFrameStatistics = 16,
GetLastPresentCount = 17,
};
#define MAX_SPLITSCREEN_CLIENT_BITS 2
#define MAX_SPLITSCREEN_CLIENTS ( 1 << MAX_SPLITSCREEN_CLIENT_BITS ) // 4
enum
{
MAX_JOYSTICKS = MAX_SPLITSCREEN_CLIENTS,
MOUSE_BUTTON_COUNT = 5,
};
enum JoystickAxis_t
{
JOY_AXIS_X = 0,
JOY_AXIS_Y,
JOY_AXIS_Z,
JOY_AXIS_R,
JOY_AXIS_U,
JOY_AXIS_V,
MAX_JOYSTICK_AXES,
};
enum
{
JOYSTICK_MAX_BUTTON_COUNT = 32,
JOYSTICK_POV_BUTTON_COUNT = 4,
JOYSTICK_AXIS_BUTTON_COUNT = MAX_JOYSTICK_AXES * 2,
};
#define JOYSTICK_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_BUTTON + ((_joystick) * JOYSTICK_MAX_BUTTON_COUNT) + (_button) )
#define JOYSTICK_POV_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_POV_BUTTON + ((_joystick) * JOYSTICK_POV_BUTTON_COUNT) + (_button) )
#define JOYSTICK_AXIS_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_AXIS_BUTTON + ((_joystick) * JOYSTICK_AXIS_BUTTON_COUNT) + (_button) )
#define JOYSTICK_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_BUTTON_INTERNAL( _joystick, _button ) )
#define JOYSTICK_POV_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_POV_BUTTON_INTERNAL( _joystick, _button ) )
#define JOYSTICK_AXIS_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_AXIS_BUTTON_INTERNAL( _joystick, _button ) )
enum ButtonCode_t
{
BUTTON_CODE_INVALID = -1,
BUTTON_CODE_NONE = 0,
KEY_FIRST = 0,
KEY_NONE = KEY_FIRST,
KEY_0,
KEY_1,
KEY_2,
KEY_3,
KEY_4,
KEY_5,
KEY_6,
KEY_7,
KEY_8,
KEY_9,
KEY_A,
KEY_B,
KEY_C,
KEY_D,
KEY_E,
KEY_F,
KEY_G,
KEY_H,
KEY_I,
KEY_J,
KEY_K,
KEY_L,
KEY_M,
KEY_N,
KEY_O,
KEY_P,
KEY_Q,
KEY_R,
KEY_S,
KEY_T,
KEY_U,
KEY_V,
KEY_W,
KEY_X,
KEY_Y,
KEY_Z,
KEY_PAD_0,
KEY_PAD_1,
KEY_PAD_2,
KEY_PAD_3,
KEY_PAD_4,
KEY_PAD_5,
KEY_PAD_6,
KEY_PAD_7,
KEY_PAD_8,
KEY_PAD_9,
KEY_PAD_DIVIDE,
KEY_PAD_MULTIPLY,
KEY_PAD_MINUS,
KEY_PAD_PLUS,
KEY_PAD_ENTER,
KEY_PAD_DECIMAL,
KEY_LBRACKET,
KEY_RBRACKET,
KEY_SEMICOLON,
KEY_APOSTROPHE,
KEY_BACKQUOTE,
KEY_COMMA,
KEY_PERIOD,
KEY_SLASH,
KEY_BACKSLASH,
KEY_MINUS,
KEY_EQUAL,
KEY_ENTER,
KEY_SPACE,
KEY_BACKSPACE,
KEY_TAB,
KEY_CAPSLOCK,
KEY_NUMLOCK,
KEY_ESCAPE,
KEY_SCROLLLOCK,
KEY_INSERT,
KEY_DELETE,
KEY_HOME,
KEY_END,
KEY_PAGEUP,
KEY_PAGEDOWN,
KEY_BREAK,
KEY_LSHIFT,
KEY_RSHIFT,
KEY_LALT,
KEY_RALT,
KEY_LCONTROL,
KEY_RCONTROL,
KEY_LWIN,
KEY_RWIN,
KEY_APP,
KEY_UP,
KEY_LEFT,
KEY_DOWN,
KEY_RIGHT,
KEY_F1,
KEY_F2,
KEY_F3,
KEY_F4,
KEY_F5,
KEY_F6,
KEY_F7,
KEY_F8,
KEY_F9,
KEY_F10,
KEY_F11,
KEY_F12,
KEY_CAPSLOCKTOGGLE,
KEY_NUMLOCKTOGGLE,
KEY_SCROLLLOCKTOGGLE,
KEY_LAST = KEY_SCROLLLOCKTOGGLE,
KEY_COUNT = KEY_LAST - KEY_FIRST + 1,
// Mouse
MOUSE_FIRST = KEY_LAST + 1,
MOUSE_LEFT = MOUSE_FIRST,
MOUSE_RIGHT,
MOUSE_MIDDLE,
MOUSE_4,
MOUSE_5,
MOUSE_WHEEL_UP, // A fake button which is 'pressed' and 'released' when the wheel is moved up
MOUSE_WHEEL_DOWN, // A fake button which is 'pressed' and 'released' when the wheel is moved down
MOUSE_LAST = MOUSE_WHEEL_DOWN,
MOUSE_COUNT = MOUSE_LAST - MOUSE_FIRST + 1,
// Joystick
JOYSTICK_FIRST = MOUSE_LAST + 1,
JOYSTICK_FIRST_BUTTON = JOYSTICK_FIRST,
JOYSTICK_LAST_BUTTON = JOYSTICK_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_MAX_BUTTON_COUNT - 1),
JOYSTICK_FIRST_POV_BUTTON,
JOYSTICK_LAST_POV_BUTTON = JOYSTICK_POV_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_POV_BUTTON_COUNT - 1),
JOYSTICK_FIRST_AXIS_BUTTON,
JOYSTICK_LAST_AXIS_BUTTON = JOYSTICK_AXIS_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_AXIS_BUTTON_COUNT - 1),
JOYSTICK_LAST = JOYSTICK_LAST_AXIS_BUTTON,
BUTTON_CODE_LAST,
BUTTON_CODE_COUNT = BUTTON_CODE_LAST - KEY_FIRST + 1,
// Helpers for XBox 360
KEY_XBUTTON_UP = JOYSTICK_FIRST_POV_BUTTON, // POV buttons
KEY_XBUTTON_RIGHT,
KEY_XBUTTON_DOWN,
KEY_XBUTTON_LEFT,
KEY_XBUTTON_A = JOYSTICK_FIRST_BUTTON, // Buttons
KEY_XBUTTON_B,
KEY_XBUTTON_X,
KEY_XBUTTON_Y,
KEY_XBUTTON_LEFT_SHOULDER,
KEY_XBUTTON_RIGHT_SHOULDER,
KEY_XBUTTON_BACK,
KEY_XBUTTON_START,
KEY_XBUTTON_STICK1,
KEY_XBUTTON_STICK2,
KEY_XBUTTON_INACTIVE_START,
KEY_XSTICK1_RIGHT = JOYSTICK_FIRST_AXIS_BUTTON, // XAXIS POSITIVE
KEY_XSTICK1_LEFT, // XAXIS NEGATIVE
KEY_XSTICK1_DOWN, // YAXIS POSITIVE
KEY_XSTICK1_UP, // YAXIS NEGATIVE
KEY_XBUTTON_LTRIGGER, // ZAXIS POSITIVE
KEY_XBUTTON_RTRIGGER, // ZAXIS NEGATIVE
KEY_XSTICK2_RIGHT, // UAXIS POSITIVE
KEY_XSTICK2_LEFT, // UAXIS NEGATIVE
KEY_XSTICK2_DOWN, // VAXIS POSITIVE
KEY_XSTICK2_UP, // VAXIS NEGATIVE
};
// Buttons are not confirmed to be the same. They have been always the same throughout the source engine. Lets hope they did not change them.
enum KeyValuesTypes
{
TYPE_NONE = 0x0,
TYPE_STRING = 0x1,
TYPE_INT = 0x2,
TYPE_FLOAT = 0x3,
TYPE_PTR = 0x4,
TYPE_WSTRING = 0x5,
TYPE_COLOR = 0x6,
TYPE_UINT64 = 0x7,
TYPE_COMPILED_INT_BYTE = 0x8,
TYPE_COMPILED_INT_0 = 0x9,
TYPE_COMPILED_INT_1 = 0xA,
TYPE_NUMTYPES = 0xB,
};
enum ClientFrameStage_t
{
FRAME_UNDEFINED = -1, // (haven't run any frames yet)
FRAME_START,
// A network packet is being recieved
FRAME_NET_UPDATE_START,
// Data has been received and we're going to start calling PostDataUpdate
FRAME_NET_UPDATE_POSTDATAUPDATE_START,
// Data has been received and we've called PostDataUpdate on all data recipients
FRAME_NET_UPDATE_POSTDATAUPDATE_END,
// We've received all packets, we can now do interpolation, prediction, etc..
FRAME_NET_UPDATE_END,
// We're about to start rendering the scene
FRAME_RENDER_START,
// We've finished rendering the scene.
FRAME_RENDER_END,
FRAME_NET_FULL_FRAME_UPDATE_ON_REMOVE
};

View File

@ -1,223 +1,6 @@
#pragma once
#include "patterns.h"
/////////////////////////////////////////////////////////////////////////////
// Enums
#define MAX_SPLITSCREEN_CLIENT_BITS 2
#define MAX_SPLITSCREEN_CLIENTS ( 1 << MAX_SPLITSCREEN_CLIENT_BITS ) // 4
enum
{
MAX_JOYSTICKS = MAX_SPLITSCREEN_CLIENTS,
MOUSE_BUTTON_COUNT = 5,
};
enum JoystickAxis_t
{
JOY_AXIS_X = 0,
JOY_AXIS_Y,
JOY_AXIS_Z,
JOY_AXIS_R,
JOY_AXIS_U,
JOY_AXIS_V,
MAX_JOYSTICK_AXES,
};
enum
{
JOYSTICK_MAX_BUTTON_COUNT = 32,
JOYSTICK_POV_BUTTON_COUNT = 4,
JOYSTICK_AXIS_BUTTON_COUNT = MAX_JOYSTICK_AXES * 2,
};
#define JOYSTICK_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_BUTTON + ((_joystick) * JOYSTICK_MAX_BUTTON_COUNT) + (_button) )
#define JOYSTICK_POV_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_POV_BUTTON + ((_joystick) * JOYSTICK_POV_BUTTON_COUNT) + (_button) )
#define JOYSTICK_AXIS_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_AXIS_BUTTON + ((_joystick) * JOYSTICK_AXIS_BUTTON_COUNT) + (_button) )
#define JOYSTICK_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_BUTTON_INTERNAL( _joystick, _button ) )
#define JOYSTICK_POV_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_POV_BUTTON_INTERNAL( _joystick, _button ) )
#define JOYSTICK_AXIS_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_AXIS_BUTTON_INTERNAL( _joystick, _button ) )
enum ButtonCode_t
{
BUTTON_CODE_INVALID = -1,
BUTTON_CODE_NONE = 0,
KEY_FIRST = 0,
KEY_NONE = KEY_FIRST,
KEY_0,
KEY_1,
KEY_2,
KEY_3,
KEY_4,
KEY_5,
KEY_6,
KEY_7,
KEY_8,
KEY_9,
KEY_A,
KEY_B,
KEY_C,
KEY_D,
KEY_E,
KEY_F,
KEY_G,
KEY_H,
KEY_I,
KEY_J,
KEY_K,
KEY_L,
KEY_M,
KEY_N,
KEY_O,
KEY_P,
KEY_Q,
KEY_R,
KEY_S,
KEY_T,
KEY_U,
KEY_V,
KEY_W,
KEY_X,
KEY_Y,
KEY_Z,
KEY_PAD_0,
KEY_PAD_1,
KEY_PAD_2,
KEY_PAD_3,
KEY_PAD_4,
KEY_PAD_5,
KEY_PAD_6,
KEY_PAD_7,
KEY_PAD_8,
KEY_PAD_9,
KEY_PAD_DIVIDE,
KEY_PAD_MULTIPLY,
KEY_PAD_MINUS,
KEY_PAD_PLUS,
KEY_PAD_ENTER,
KEY_PAD_DECIMAL,
KEY_LBRACKET,
KEY_RBRACKET,
KEY_SEMICOLON,
KEY_APOSTROPHE,
KEY_BACKQUOTE,
KEY_COMMA,
KEY_PERIOD,
KEY_SLASH,
KEY_BACKSLASH,
KEY_MINUS,
KEY_EQUAL,
KEY_ENTER,
KEY_SPACE,
KEY_BACKSPACE,
KEY_TAB,
KEY_CAPSLOCK,
KEY_NUMLOCK,
KEY_ESCAPE,
KEY_SCROLLLOCK,
KEY_INSERT,
KEY_DELETE,
KEY_HOME,
KEY_END,
KEY_PAGEUP,
KEY_PAGEDOWN,
KEY_BREAK,
KEY_LSHIFT,
KEY_RSHIFT,
KEY_LALT,
KEY_RALT,
KEY_LCONTROL,
KEY_RCONTROL,
KEY_LWIN,
KEY_RWIN,
KEY_APP,
KEY_UP,
KEY_LEFT,
KEY_DOWN,
KEY_RIGHT,
KEY_F1,
KEY_F2,
KEY_F3,
KEY_F4,
KEY_F5,
KEY_F6,
KEY_F7,
KEY_F8,
KEY_F9,
KEY_F10,
KEY_F11,
KEY_F12,
KEY_CAPSLOCKTOGGLE,
KEY_NUMLOCKTOGGLE,
KEY_SCROLLLOCKTOGGLE,
KEY_LAST = KEY_SCROLLLOCKTOGGLE,
KEY_COUNT = KEY_LAST - KEY_FIRST + 1,
// Mouse
MOUSE_FIRST = KEY_LAST + 1,
MOUSE_LEFT = MOUSE_FIRST,
MOUSE_RIGHT,
MOUSE_MIDDLE,
MOUSE_4,
MOUSE_5,
MOUSE_WHEEL_UP, // A fake button which is 'pressed' and 'released' when the wheel is moved up
MOUSE_WHEEL_DOWN, // A fake button which is 'pressed' and 'released' when the wheel is moved down
MOUSE_LAST = MOUSE_WHEEL_DOWN,
MOUSE_COUNT = MOUSE_LAST - MOUSE_FIRST + 1,
// Joystick
JOYSTICK_FIRST = MOUSE_LAST + 1,
JOYSTICK_FIRST_BUTTON = JOYSTICK_FIRST,
JOYSTICK_LAST_BUTTON = JOYSTICK_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_MAX_BUTTON_COUNT - 1),
JOYSTICK_FIRST_POV_BUTTON,
JOYSTICK_LAST_POV_BUTTON = JOYSTICK_POV_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_POV_BUTTON_COUNT - 1),
JOYSTICK_FIRST_AXIS_BUTTON,
JOYSTICK_LAST_AXIS_BUTTON = JOYSTICK_AXIS_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_AXIS_BUTTON_COUNT - 1),
JOYSTICK_LAST = JOYSTICK_LAST_AXIS_BUTTON,
BUTTON_CODE_LAST,
BUTTON_CODE_COUNT = BUTTON_CODE_LAST - KEY_FIRST + 1,
// Helpers for XBox 360
KEY_XBUTTON_UP = JOYSTICK_FIRST_POV_BUTTON, // POV buttons
KEY_XBUTTON_RIGHT,
KEY_XBUTTON_DOWN,
KEY_XBUTTON_LEFT,
KEY_XBUTTON_A = JOYSTICK_FIRST_BUTTON, // Buttons
KEY_XBUTTON_B,
KEY_XBUTTON_X,
KEY_XBUTTON_Y,
KEY_XBUTTON_LEFT_SHOULDER,
KEY_XBUTTON_RIGHT_SHOULDER,
KEY_XBUTTON_BACK,
KEY_XBUTTON_START,
KEY_XBUTTON_STICK1,
KEY_XBUTTON_STICK2,
KEY_XBUTTON_INACTIVE_START,
KEY_XSTICK1_RIGHT = JOYSTICK_FIRST_AXIS_BUTTON, // XAXIS POSITIVE
KEY_XSTICK1_LEFT, // XAXIS NEGATIVE
KEY_XSTICK1_DOWN, // YAXIS POSITIVE
KEY_XSTICK1_UP, // YAXIS NEGATIVE
KEY_XBUTTON_LTRIGGER, // ZAXIS POSITIVE
KEY_XBUTTON_RTRIGGER, // ZAXIS NEGATIVE
KEY_XSTICK2_RIGHT, // UAXIS POSITIVE
KEY_XSTICK2_LEFT, // UAXIS NEGATIVE
KEY_XSTICK2_DOWN, // VAXIS POSITIVE
KEY_XSTICK2_UP, // VAXIS NEGATIVE
};
// Buttons are not confirmed to be the same. They have been always the same throughout the source engine. Lets hope they did not change them.
/////////////////////////////////////////////////////////////////////////////
// Classes and Structs
@ -351,22 +134,6 @@ public:
int m_mutex; // 0x0130
};
enum KeyValuesTypes
{
TYPE_NONE = 0x0,
TYPE_STRING = 0x1,
TYPE_INT = 0x2,
TYPE_FLOAT = 0x3,
TYPE_PTR = 0x4,
TYPE_WSTRING = 0x5,
TYPE_COLOR = 0x6,
TYPE_UINT64 = 0x7,
TYPE_COMPILED_INT_BYTE = 0x8,
TYPE_COMPILED_INT_0 = 0x9,
TYPE_COMPILED_INT_1 = 0xA,
TYPE_NUMTYPES = 0xB,
};
class KeyValues
{
public:
@ -485,28 +252,6 @@ public:
bool m_bWorkshopMapDownloadPending; //0x026A
};
enum ClientFrameStage_t
{
FRAME_UNDEFINED = -1, // (haven't run any frames yet)
FRAME_START,
// A network packet is being recieved
FRAME_NET_UPDATE_START,
// Data has been received and we're going to start calling PostDataUpdate
FRAME_NET_UPDATE_POSTDATAUPDATE_START,
// Data has been received and we've called PostDataUpdate on all data recipients
FRAME_NET_UPDATE_POSTDATAUPDATE_END,
// We've received all packets, we can now do interpolation, prediction, etc..
FRAME_NET_UPDATE_END,
// We're about to start rendering the scene
FRAME_RENDER_START,
// We've finished rendering the scene.
FRAME_RENDER_END,
FRAME_NET_FULL_FRAME_UPDATE_ON_REMOVE
};
class CHLClient
{
public:

View File

@ -1,14 +1,87 @@
#pragma once
#include "patterns.h"
#include "structs.h"
#include "overlay.h"
#include "hooks.h"
#include "gameclasses.h"
/////////////////////////////////////////////////////////////////////////////
// Initialization
void InstallENHooks();
void RemoveENHooks();
void ToggleDevCommands();
void ToggleNetHooks();
/////////////////////////////////////////////////////////////////////////////
// Globals
inline bool g_bDebugLoading = false;
inline bool g_bReturnAllFalse = false;
inline bool g_bDebugConsole = false;
extern bool g_bBlockInput;
/////////////////////////////////////////////////////////////////////////////
namespace Hooks
{
#pragma region CHLClient
void __fastcall FrameStageNotify(CHLClient* rcx, ClientFrameStage_t curStage);
using FrameStageNotifyFn = void(__fastcall*)(CHLClient*, ClientFrameStage_t);
extern FrameStageNotifyFn originalFrameStageNotify;
#pragma endregion
#pragma region Squirrel
void* SQVM_Print(void* sqvm, char* fmt, ...);
__int64 SQVM_LoadRson(const char* rson_name);
bool SQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag);
using SQVM_LoadRsonFn = __int64(*)(const char*);
extern SQVM_LoadRsonFn originalSQVM_LoadRson;
using SQVM_LoadScriptFn = bool(*)(void*, const char*, const char*, int);
extern SQVM_LoadScriptFn originalSQVM_LoadScript;
#pragma endregion
#pragma region CVEngineServer
bool IsPersistenceDataAvailable(__int64 thisptr, int client);
using IsPersistenceDataAvailableFn = bool(*)(__int64, int);
extern IsPersistenceDataAvailableFn originalIsPersistenceDataAvailable;
#pragma endregion
#pragma region NetChannel
bool NET_ReceiveDatagram(int sock, void* inpacket, bool raw);
unsigned int NET_SendDatagram(SOCKET s, const char* buf, int len, int flags);
using NET_ReceiveDatagramFn = bool(*)(int, void*, bool);
extern NET_ReceiveDatagramFn originalNET_ReceiveDatagram;
using NET_SendDatagramFn = unsigned int(*)(SOCKET, const char*, int, int);
extern NET_SendDatagramFn originalNET_SendDatagram;
#pragma endregion
#pragma region ConVar
bool ConVar_IsFlagSet(int** cvar, int flag);
bool ConCommand_IsFlagSet(int* cmd, int flag);
#pragma endregion
#pragma region WinAPI
BOOL WINAPI GetCursorPos(LPPOINT lpPoint);
BOOL WINAPI SetCursorPos(int X, int Y);
BOOL WINAPI ClipCursor(const RECT* lpRect);
BOOL WINAPI ShowCursor(BOOL bShow);
using GetCursorPosFn = BOOL(WINAPI*)(LPPOINT);
extern GetCursorPosFn originalGetCursorPos;
using SetCursorPosFn = BOOL(WINAPI*)(int, int);
extern SetCursorPosFn originalSetCursorPos;
using ClipCursorFn = BOOL(WINAPI*)(const RECT*);
extern ClipCursorFn originalClipCursor;
using ShowCursorFn = BOOL(WINAPI*)(BOOL);
extern ShowCursorFn originalShowCursor;
#pragma endregion
#pragma region Other
int MSG_EngineError(char* fmt, va_list args);
using MSG_EngineErrorFn = int(*)(char*, va_list);
extern MSG_EngineErrorFn originalMSG_EngineError;
#pragma endregion
void InstallHooks();
void RemoveHooks();
void ToggleNetHooks();
void ToggleDevCommands();
}

View File

@ -1,11 +1 @@
#pragma once
/////////////////////////////////////////////////////////////////////////////
// Internals
void InstallIPHooks();
void RemoveIPHooks();
/////////////////////////////////////////////////////////////////////////////
// Globals
extern BOOL g_bBlockInput;
/////////////////////////////////////////////////////////////////////////////
#pragma once

View File

@ -7,50 +7,50 @@ namespace
#pragma region Console
/*0x140202090*/
FUNC_AT_ADDRESS(org_CommandExecute, void(*)(void*, const char*), r5_patterns.PatternSearch("48 89 5C 24 ? 57 48 83 EC 20 48 8D 0D ? ? ? ? 41 8B D8").GetPtr());
FUNC_AT_ADDRESS(addr_CommandExecute, void(*)(void*, const char*), r5_patterns.PatternSearch("48 89 5C 24 ? 57 48 83 EC 20 48 8D 0D ? ? ? ? 41 8B D8").GetPtr());
/*0x14046FE90*/
FUNC_AT_ADDRESS(org_ConVar_IsFlagSet, bool(*)(int**, int), r5_patterns.PatternSearch("48 8B 41 48 85 50 38").GetPtr());
FUNC_AT_ADDRESS(addr_ConVar_IsFlagSet, bool(*)(int**, int), r5_patterns.PatternSearch("48 8B 41 48 85 50 38").GetPtr());
/*0x14046F490*/
FUNC_AT_ADDRESS(org_ConCommand_IsFlagSet, bool(*)(int*, int), r5_patterns.PatternSearch("85 51 38 0F 95 C0 C3").GetPtr());
FUNC_AT_ADDRESS(addr_ConCommand_IsFlagSet, bool(*)(int*, int), r5_patterns.PatternSearch("85 51 38 0F 95 C0 C3").GetPtr());
#pragma endregion
#pragma region Squirrel
/*0x141057FD0*/
FUNC_AT_ADDRESS(org_SQVM_Print, void*, r5_patterns.PatternSearch("83 F8 01 48 8D 3D ? ? ? ?").OffsetSelf(0x3).FollowNearCallSelf(0x3, 0x7).GetPtr());
FUNC_AT_ADDRESS(addr_SQVM_Print, void*, r5_patterns.PatternSearch("83 F8 01 48 8D 3D ? ? ? ?").OffsetSelf(0x3).FollowNearCallSelf(0x3, 0x7).GetPtr());
//DWORD64 p_SQVM_LoadScript = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x48\x89\x4C\x24\x08\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\x6C", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // For S0 and S1
/*0x141055630*/
// For anything S2 and above (current S8
FUNC_AT_ADDRESS(org_SQVM_LoadScript, bool(*)(void*, const char*, const char*, int), r5_patterns.PatternSearch("48 8B C4 48 89 48 08 55 41 56 48 8D 68").GetPtr());
FUNC_AT_ADDRESS(addr_SQVM_LoadScript, bool(*)(void*, const char*, const char*, int), r5_patterns.PatternSearch("48 8B C4 48 89 48 08 55 41 56 48 8D 68").GetPtr());
/*0x140C957E0*/
FUNC_AT_ADDRESS(org_SQVM_LoadRson, int(*)(const char*), r5_patterns.PatternSearch("4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33").GetPtr());
FUNC_AT_ADDRESS(addr_SQVM_LoadRson, int(*)(const char*), r5_patterns.PatternSearch("4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33").GetPtr());
#pragma endregion
#pragma region NetChannel
/*0x1402655F0*/
FUNC_AT_ADDRESS(org_NET_ReceiveDatagram, bool(*)(int, void*, bool), r5_patterns.PatternSearch("48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 50 EB").GetPtr());
FUNC_AT_ADDRESS(addr_NET_ReceiveDatagram, bool(*)(int, void*, bool), r5_patterns.PatternSearch("48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 50 EB").GetPtr());
/*0x1402662D0*/
FUNC_AT_ADDRESS(org_NET_SendDatagram, int(*)(SOCKET, const char*, int, int), r5_patterns.PatternSearch("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ? 05 ? ?").GetPtr());
FUNC_AT_ADDRESS(addr_NET_SendDatagram, int(*)(SOCKET, const char*, int, int), r5_patterns.PatternSearch("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ? 05 ? ?").GetPtr());
#pragma endregion
#pragma region CHLClient
/*0x1405C0740*/
FUNC_AT_ADDRESS(org_CHLClient_FrameStageNotify, void(*)(void* rcx, int curStage), r5_patterns.PatternSearch("48 83 EC 28 89 15 ?? ?? ?? ??").GetPtr());
FUNC_AT_ADDRESS(addr_CHLClient_FrameStageNotify, void(*)(void* rcx, int curStage), r5_patterns.PatternSearch("48 83 EC 28 89 15 ?? ?? ?? ??").GetPtr());
#pragma endregion
#pragma region CVEngineServer
/*0x140315CF0*/
FUNC_AT_ADDRESS(org_CVEngineServer_IsPersistenceDataAvailable, bool(*)(__int64, int), r5_patterns.PatternSearch("3B 15 ?? ?? ?? ?? 7D 33").GetPtr());
FUNC_AT_ADDRESS(addr_CVEngineServer_IsPersistenceDataAvailable, bool(*)(__int64, int), r5_patterns.PatternSearch("3B 15 ?? ?? ?? ?? 7D 33").GetPtr());
#pragma endregion
#pragma region Utility
/*0x140295600*/
FUNC_AT_ADDRESS(org_MSG_EngineError, int(*)(char*, va_list), r5_patterns.PatternSearch("48 89 5C 24 08 48 89 74 24 10 57 48 81 EC 30 08 00 00 48 8B DA").GetPtr());
FUNC_AT_ADDRESS(addr_MSG_EngineError, int(*)(char*, va_list), r5_patterns.PatternSearch("48 89 5C 24 08 48 89 74 24 10 57 48 81 EC 30 08 00 00 48 8B DA").GetPtr());
#pragma endregion
// Un-used atm.
// DWORD64 p_KeyValues_FindKey = /*1404744E0*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "40 56 57 41 57 48 81 EC ?? ?? ?? ?? 45"));
@ -58,17 +58,17 @@ namespace
void PrintHAddress() // Test the sigscan results
{
std::cout << "+--------------------------------------------------------+" << std::endl;
PRINT_ADDRESS("CommandExecute", org_CommandExecute);
PRINT_ADDRESS("ConVar_IsFlagSet", org_ConVar_IsFlagSet);
PRINT_ADDRESS("ConCommand_IsFlagSet", org_ConCommand_IsFlagSet);
PRINT_ADDRESS("SQVM_Print", org_SQVM_Print);
PRINT_ADDRESS("SQVM_LoadScript", org_SQVM_LoadScript);
PRINT_ADDRESS("SQVM_LoadRson", org_SQVM_LoadRson);
PRINT_ADDRESS("NET_ReceiveDatagram", org_NET_ReceiveDatagram);
PRINT_ADDRESS("NET_SendDatagram ", org_NET_SendDatagram);
PRINT_ADDRESS("CHLClient::FrameStageNotify", org_CHLClient_FrameStageNotify);
PRINT_ADDRESS("CVEngineServer::IsPersistenceDataAvailable", org_CVEngineServer_IsPersistenceDataAvailable);
PRINT_ADDRESS("MSG_EngineError", org_MSG_EngineError);
PRINT_ADDRESS("CommandExecute", addr_CommandExecute);
PRINT_ADDRESS("ConVar_IsFlagSet", addr_ConVar_IsFlagSet);
PRINT_ADDRESS("ConCommand_IsFlagSet", addr_ConCommand_IsFlagSet);
PRINT_ADDRESS("SQVM_Print", addr_SQVM_Print);
PRINT_ADDRESS("SQVM_LoadScript", addr_SQVM_LoadScript);
PRINT_ADDRESS("SQVM_LoadRson", addr_SQVM_LoadRson);
PRINT_ADDRESS("NET_ReceiveDatagram", addr_NET_ReceiveDatagram);
PRINT_ADDRESS("NET_SendDatagram ", addr_NET_SendDatagram);
PRINT_ADDRESS("CHLClient::FrameStageNotify", addr_CHLClient_FrameStageNotify);
PRINT_ADDRESS("CVEngineServer::IsPersistenceDataAvailable", addr_CVEngineServer_IsPersistenceDataAvailable);
PRINT_ADDRESS("MSG_EngineError", addr_MSG_EngineError);
std::cout << "+--------------------------------------------------------+" << std::endl;
// TODO implement error handling when sigscan fails or result is 0
}

View File

@ -3,7 +3,7 @@
#define WIN32_LEAN_AND_MEAN // Prevent winsock2 redefinition.
#include <windows.h>
#include <detours.h>
#include <minhook.h>
#include <thread>
#include <fstream>
#include <stdio.h>
@ -19,8 +19,6 @@
#include <Psapi.h>
#include <vector>
// Our headers
#include "imgui.h"
@ -34,6 +32,7 @@
#include "json.hpp"
#include "address.h"
#include "enums.h"
#define FUNC_AT_ADDRESS(name, funcbody, addr) \
using _##name = funcbody; \

View File

@ -87,8 +87,8 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(SolutionDir)external\detours\include;$(SolutionDir)external\imgui\include;$(SolutionDir)external\spdlog\include;$(SolutionDir)shared\include;$(SolutionDir)r5dev\include;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)external\detours\libs;$(LibraryPath)</LibraryPath>
<IncludePath>$(SolutionDir)external\minhook\include;$(SolutionDir)external\imgui\include;$(SolutionDir)external\spdlog\include;$(SolutionDir)shared\include;$(SolutionDir)r5dev\include;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)external\minhook\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -165,6 +165,7 @@
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -173,16 +174,13 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>r5dev.def</ModuleDefinitionFile>
<AdditionalDependencies>detours.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>libMinHook.x64.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>del "$(TargetDir)\r5detours.dll" &amp;&amp; rename "$(TargetPath)" "r5detours.dll"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\external\detours\include\detours.h" />
<ClInclude Include="..\external\detours\include\detver.h" />
<ClInclude Include="..\external\detours\include\syelog.h" />
<ClInclude Include="..\external\imgui\include\imconfig.h" />
<ClInclude Include="..\external\imgui\include\imgui.h" />
<ClInclude Include="..\external\imgui\include\imgui_impl_dx11.h" />
@ -191,6 +189,7 @@
<ClInclude Include="..\external\imgui\include\imstb_rectpack.h" />
<ClInclude Include="..\external\imgui\include\imstb_textedit.h" />
<ClInclude Include="..\external\imgui\include\imstb_truetype.h" />
<ClInclude Include="..\external\minhook\include\MinHook.h" />
<ClInclude Include="..\external\spdlog\include\async.h" />
<ClInclude Include="..\external\spdlog\include\async_logger-inl.h" />
<ClInclude Include="..\external\spdlog\include\async_logger.h" />
@ -349,10 +348,14 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pch.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="src\hooks.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pch.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="src\hooks\chlclient.cpp" />
<ClCompile Include="src\hooks\cvengineserver.cpp" />
<ClCompile Include="src\hooks\hooks.cpp" />
<ClCompile Include="src\hooks\iconvar.cpp" />
<ClCompile Include="src\hooks\msgbox.cpp" />
<ClCompile Include="src\hooks\net.cpp" />
<ClCompile Include="src\hooks\sqvm.cpp" />
<ClCompile Include="src\hooks\winapi.cpp" />
<ClCompile Include="src\id3dx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pch.h</PrecompiledHeaderFile>

View File

@ -1,9 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{a80939e5-3b3c-4873-885e-834e95d68d34}</UniqueIdentifier>
</Filter>
<Filter Include="core">
<UniqueIdentifier>{927ea852-3616-4fc4-8b32-781f65853a6b}</UniqueIdentifier>
</Filter>
@ -16,25 +13,15 @@
<Filter Include="shared\include">
<UniqueIdentifier>{633d6e7a-c709-4d64-a134-b383d43c8c8e}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="shared\libraries">
<UniqueIdentifier>{7cef4f92-94d9-43af-bea5-c6963d68fff2}</UniqueIdentifier>
</Filter>
<Filter Include="shared\libraries\detours">
<UniqueIdentifier>{584562a8-0382-488c-909c-67bbb1d1af3c}</UniqueIdentifier>
</Filter>
<Filter Include="shared\libraries\imgui">
<UniqueIdentifier>{c72b9789-72e9-4657-8a42-8712aaf8690e}</UniqueIdentifier>
</Filter>
<Filter Include="shared\libraries\spdlog">
<UniqueIdentifier>{757af774-e575-4623-8582-71efb0ae53a4}</UniqueIdentifier>
</Filter>
<Filter Include="shared\libraries\detours\include">
<UniqueIdentifier>{3fa7f9a9-dc07-4d42-9172-0944829c010f}</UniqueIdentifier>
</Filter>
<Filter Include="shared\libraries\imgui\include">
<UniqueIdentifier>{c18fb898-adc3-4aa8-902c-4777bbc76e5b}</UniqueIdentifier>
</Filter>
@ -59,38 +46,62 @@
<Filter Include="core\resource">
<UniqueIdentifier>{30005d10-4213-441c-b18b-4dd47fcb8812}</UniqueIdentifier>
</Filter>
<Filter Include="External Libraries\stb">
<UniqueIdentifier>{10c4f432-81f6-46f2-9ab0-ac70ee08bff7}</UniqueIdentifier>
<Filter Include="shared\libraries\minhook">
<UniqueIdentifier>{e901ef66-ddeb-4aff-9d7e-786d74a791e9}</UniqueIdentifier>
</Filter>
<Filter Include="External Libraries\stb\Header Files">
<UniqueIdentifier>{558c4758-4b1c-4480-946d-ff6c9df375ee}</UniqueIdentifier>
<Filter Include="shared\libraries\minhook\include">
<UniqueIdentifier>{da82c6eb-abba-4b52-84bf-9f3758a169bf}</UniqueIdentifier>
</Filter>
<Filter Include="hooks">
<UniqueIdentifier>{6a6d7e33-2ce0-4b53-bcf6-41dc6dacdc5f}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src">
<UniqueIdentifier>{e449786f-692c-4d6c-a292-b0720bf9e2a9}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src\winapi">
<UniqueIdentifier>{46b49d69-ea42-467c-86d8-00611f2718ff}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src\other">
<UniqueIdentifier>{2ec9179b-7320-47da-b170-f021d0279310}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src\squirrel">
<UniqueIdentifier>{83391c47-4a5b-4231-a9ef-29e119c5bb69}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src\netchannel">
<UniqueIdentifier>{c27e3539-0070-40fa-b262-0ecd39f47919}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src\iconvar">
<UniqueIdentifier>{afb847fc-853f-4e6f-bde6-91bf345369b4}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src\cvengineserver">
<UniqueIdentifier>{9f8f15a7-6e69-4a79-b644-a92ad815c600}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\src\chlclient">
<UniqueIdentifier>{25c5fe7f-23c0-4d44-b92d-ea4b127eec05}</UniqueIdentifier>
</Filter>
<Filter Include="hooks\include">
<UniqueIdentifier>{0420f99f-468e-4ba5-abe3-960cc332b636}</UniqueIdentifier>
</Filter>
<Filter Include="gui">
<UniqueIdentifier>{a40dcf17-855b-4965-b58d-6c7d24edc627}</UniqueIdentifier>
</Filter>
<Filter Include="gui\src">
<UniqueIdentifier>{03d79a58-4706-4ee0-b0ea-6251a2fafada}</UniqueIdentifier>
</Filter>
<Filter Include="gui\include">
<UniqueIdentifier>{89bf5311-5686-4077-9b79-c6306dc1bd91}</UniqueIdentifier>
</Filter>
<Filter Include="r5-sdk">
<UniqueIdentifier>{3a4ca756-24d2-47e8-af7f-0e8a75933c4b}</UniqueIdentifier>
</Filter>
<Filter Include="r5-sdk\src">
<UniqueIdentifier>{58dbc5f6-cf3c-4d71-80c8-caefffb39beb}</UniqueIdentifier>
</Filter>
<Filter Include="r5-sdk\include">
<UniqueIdentifier>{0136e8e8-91ef-45c1-8661-476b5c20fc48}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\console.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\hooks.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\opcptc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\id3dx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\overlay.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\input.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\serverlisting.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\gameclasses.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\dllmain.cpp">
<Filter>core</Filter>
</ClCompile>
@ -121,38 +132,53 @@
<ClCompile Include="..\shared\utility.cpp">
<Filter>shared</Filter>
</ClCompile>
<ClCompile Include="..\external\imgui\src\imgui_stdlib.cpp">
<Filter>External Libraries\imgui\Source Files</Filter>
<ClCompile Include="src\hooks\chlclient.cpp">
<Filter>hooks\src\chlclient</Filter>
</ClCompile>
<ClCompile Include="src\hooks\sqvm.cpp">
<Filter>hooks\src\squirrel</Filter>
</ClCompile>
<ClCompile Include="src\hooks\cvengineserver.cpp">
<Filter>hooks\src\cvengineserver</Filter>
</ClCompile>
<ClCompile Include="src\hooks\msgbox.cpp">
<Filter>hooks\src\other</Filter>
</ClCompile>
<ClCompile Include="src\hooks\net.cpp">
<Filter>hooks\src\netchannel</Filter>
</ClCompile>
<ClCompile Include="src\hooks\iconvar.cpp">
<Filter>hooks\src\iconvar</Filter>
</ClCompile>
<ClCompile Include="src\hooks\winapi.cpp">
<Filter>hooks\src\winapi</Filter>
</ClCompile>
<ClCompile Include="src\hooks\hooks.cpp">
<Filter>hooks\src</Filter>
</ClCompile>
<ClCompile Include="src\overlay.cpp">
<Filter>gui\src</Filter>
</ClCompile>
<ClCompile Include="src\serverlisting.cpp">
<Filter>gui\src</Filter>
</ClCompile>
<ClCompile Include="src\id3dx.cpp">
<Filter>gui\src</Filter>
</ClCompile>
<ClCompile Include="src\gameclasses.cpp">
<Filter>r5-sdk\src</Filter>
</ClCompile>
<ClCompile Include="src\console.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="src\input.cpp">
<Filter>core</Filter>
</ClCompile>
<ClCompile Include="src\opcptc.cpp">
<Filter>r5-sdk\src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\console.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\hooks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\opcptc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\patterns.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\r5dev.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\structs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\external\detours\include\detver.h">
<Filter>shared\libraries\detours\include</Filter>
</ClInclude>
<ClInclude Include="..\external\detours\include\syelog.h">
<Filter>shared\libraries\detours\include</Filter>
</ClInclude>
<ClInclude Include="..\external\detours\include\detours.h">
<Filter>shared\libraries\detours\include</Filter>
</ClInclude>
<ClInclude Include="..\external\imgui\include\imgui_impl_win32.h">
<Filter>shared\libraries\imgui\include</Filter>
</ClInclude>
@ -177,18 +203,6 @@
<ClInclude Include="..\external\imgui\include\imgui_impl_dx11.h">
<Filter>shared\libraries\imgui\include</Filter>
</ClInclude>
<ClInclude Include="include\id3dx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\overlay.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\enums.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\input.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\external\spdlog\include\async_logger-inl.h">
<Filter>shared\libraries\spdlog\include</Filter>
</ClInclude>
@ -471,12 +485,6 @@
<ClInclude Include="..\external\spdlog\include\sinks\qt_sinks.h">
<Filter>shared\libraries\spdlog\include\sinks</Filter>
</ClInclude>
<ClInclude Include="include\gameclasses.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\serverlisting.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\shared\include\address.h">
<Filter>shared\include</Filter>
</ClInclude>
@ -492,11 +500,44 @@
<ClInclude Include="include\pch.h">
<Filter>core\include</Filter>
</ClInclude>
<ClInclude Include="include\imgui_stdlib.h">
<Filter>External Libraries\imgui\Header Files</Filter>
<ClInclude Include="..\external\minhook\include\MinHook.h">
<Filter>shared\libraries\minhook\include</Filter>
</ClInclude>
<ClInclude Include="..\external\stb\include\stb_image.h">
<Filter>External Libraries\stb\Header Files</Filter>
<ClInclude Include="include\hooks.h">
<Filter>hooks\include</Filter>
</ClInclude>
<ClInclude Include="include\id3dx.h">
<Filter>gui\include</Filter>
</ClInclude>
<ClInclude Include="include\overlay.h">
<Filter>gui\include</Filter>
</ClInclude>
<ClInclude Include="include\serverlisting.h">
<Filter>gui\include</Filter>
</ClInclude>
<ClInclude Include="include\gameclasses.h">
<Filter>r5-sdk\include</Filter>
</ClInclude>
<ClInclude Include="include\r5dev.h">
<Filter>core\include</Filter>
</ClInclude>
<ClInclude Include="include\console.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="include\patterns.h">
<Filter>r5-sdk\include</Filter>
</ClInclude>
<ClInclude Include="include\structs.h">
<Filter>r5-sdk\include</Filter>
</ClInclude>
<ClInclude Include="include\opcptc.h">
<Filter>r5-sdk\include</Filter>
</ClInclude>
<ClInclude Include="include\enums.h">
<Filter>r5-sdk\include</Filter>
</ClInclude>
<ClInclude Include="include\input.h">
<Filter>core\include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>

View File

@ -54,62 +54,13 @@ void SetupConsole()
}
}
//#############################################################################
// CONSOLE HOOKS
//#############################################################################
bool HConVar_IsFlagSet(int** cvar, int flag)
{
int real_flags = *(*(cvar + (72 / (sizeof(void*)))) + (56 / sizeof(int)));
if (g_bDebugConsole)
{
printf("--------------------------------------------------\n");
printf(" Flaged: %08X\n", real_flags);
}
// Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY
real_flags &= 0xFFFFBFFD;
if (g_bDebugConsole)
{
printf(" Masked: %08X\n", real_flags);
printf(" Verify: %08X\n", flag);
printf("--------------------------------------------------\n");
}
if (flag & 0x80000) { return true; }
if (!g_bReturnAllFalse) { return (real_flags & flag) != 0; }
else { return false; }
}
bool HConCommand_IsFlagSet(int* cmd, int flag)
{
int real_flags = *((cmd + (56 / sizeof(int))));
if (g_bDebugConsole)
{
printf("--------------------------------------------------\n");
printf(" Flaged: %08X\n", real_flags);
}
// Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY
real_flags &= 0xFFFFBFFD;
if (g_bDebugConsole)
{
printf(" Masked: %08X\n", real_flags);
printf(" Verify: %08X\n", flag);
printf("--------------------------------------------------\n");
}
if (flag & 0x80000) { return true; }
if (!g_bReturnAllFalse) { return (real_flags & flag) != 0; }
else { return false; }
}
//#############################################################################
// WORKER THREAD
//#############################################################################
DWORD __stdcall ProcessConsoleWorker(LPVOID)
{
// Loop forever
while (true)
while (true) // Loop forever
{
std::string sCommand;
@ -120,8 +71,8 @@ DWORD __stdcall ProcessConsoleWorker(LPVOID)
///////////////////////////////////////////////////////////////////////
// Engine toggles
if (sCommand == "toggle net") { ToggleNetHooks(); continue; }
if (sCommand == "toggle dev") { ToggleDevCommands(); continue; }
if (sCommand == "toggle net") { Hooks::ToggleNetHooks(); continue; }
if (sCommand == "toggle dev") { Hooks::ToggleDevCommands(); continue; }
if (sCommand == "toggle fal") { g_bReturnAllFalse = !g_bReturnAllFalse; continue; }
///////////////////////////////////////////////////////////////////////
// Debug toggles
@ -130,12 +81,12 @@ DWORD __stdcall ProcessConsoleWorker(LPVOID)
if (sCommand == "console test") { g_bDebugConsole = !g_bDebugConsole; continue; }
///////////////////////////////////////////////////////////////////////
// Exec toggles
if (sCommand == "1") { ToggleDevCommands(); org_CommandExecute(NULL, "exec autoexec_dev"); }
if (sCommand == "1") { Hooks::ToggleDevCommands(); addr_CommandExecute(NULL, "exec autoexec_dev"); }
if (sCommand == "2") { g_bDebugLoading = !g_bDebugLoading; continue; }
///////////////////////////////////////////////////////////////////////
// Execute the command in the r5 SQVM
org_CommandExecute(NULL, sCommand.c_str());
addr_CommandExecute(NULL, sCommand.c_str());
sCommand.clear();
///////////////////////////////////////////////////////////////////////
@ -144,66 +95,4 @@ DWORD __stdcall ProcessConsoleWorker(LPVOID)
}
return 0;
}
//#############################################################################
// MANAGEMENT
//#############################################################################
void RemoveCMHooks()
{
///////////////////////////////////////////////////////////////////////////
// Begin the detour transaction, to unhook the the process
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
///////////////////////////////////////////////////////////////////////////
// Unhook Console functions
DetourDetach((LPVOID*)&org_ConVar_IsFlagSet, &HConVar_IsFlagSet);
DetourDetach((LPVOID*)&org_ConCommand_IsFlagSet, &HConCommand_IsFlagSet);
///////////////////////////////////////////////////////////////////////////
// Commit the transaction
DetourTransactionCommit();
}
//#############################################################################
// TOGGLES
//#############################################################################
void ToggleDevCommands()
{
static bool g_dev = false;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
if (!g_dev)
{
DetourAttach((LPVOID*)&org_ConVar_IsFlagSet, &HConVar_IsFlagSet);
DetourAttach((LPVOID*)&org_ConCommand_IsFlagSet, &HConCommand_IsFlagSet);
printf("\n");
printf("+--------------------------------------------------------+\n");
printf("|>>>>>>>>>>>>>| DEVONLY COMMANDS ACTIVATED |<<<<<<<<<<<<<|\n");
printf("+--------------------------------------------------------+\n");
printf("\n");
}
else
{
DetourDetach((LPVOID*)&org_ConVar_IsFlagSet, &HConVar_IsFlagSet);
DetourDetach((LPVOID*)&org_ConCommand_IsFlagSet, &HConCommand_IsFlagSet);
printf("\n");
printf("+--------------------------------------------------------+\n");
printf("|>>>>>>>>>>>>| DEVONLY COMMANDS DEACTIVATED |<<<<<<<<<<<<|\n");
printf("+--------------------------------------------------------+\n");
printf("\n");
}
if (DetourTransactionCommit() != NO_ERROR)
{
TerminateProcess(GetCurrentProcess(), 0xBAD0C0DE);
}
g_dev = !g_dev;
}
}

View File

@ -5,7 +5,6 @@
#include "hooks.h"
#include "opcptc.h"
#include "console.h"
#include "gameclasses.h"
//#############################################################################
// INITIALIZATION
@ -14,9 +13,7 @@
void InitializeR5Dev()
{
SetupConsole();
InstallENHooks();
InstallIPHooks();
InstallDXHooks();
Hooks::InstallHooks();
InstallOpcodes();
SetupDXSwapChain();
printf("+-----------------------------------------------------------------------------+\n");
@ -27,10 +24,8 @@ void InitializeR5Dev()
void TerminateR5Dev()
{
RemoveCMHooks();
RemoveENHooks();
RemoveIPHooks();
RemoveDXHooks();
Hooks::RemoveHooks();
FreeConsole();
}
@ -38,7 +33,7 @@ void TerminateR5Dev()
// ENTRYPOINT
//#############################################################################
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)

View File

@ -1,289 +0,0 @@
#include "pch.h"
#include "patterns.h"
#include "structs.h"
#include "overlay.h"
#include "hooks.h"
#include "gameclasses.h"
//#################################################################################
// NETCHANNEL HOOKS
//#################################################################################
bool HNET_ReceiveDatagram(int sock, void* inpacket, bool raw)
{
bool result = org_NET_ReceiveDatagram(sock, inpacket, raw);
if (result)
{
int i = NULL;
netpacket_t* pkt = (netpacket_t*)inpacket;
///////////////////////////////////////////////////////////////////////////
// Log received packet data
HexDump("[+] NET_ReceiveDatagram", 0, &pkt->data[i], pkt->wiresize);
}
return result;
}
unsigned int HNET_SendDatagram(SOCKET s, const char* buf, int len, int flags)
{
unsigned int result = org_NET_SendDatagram(s, buf, len, flags);
if (result)
{
///////////////////////////////////////////////////////////////////////////
// Log transmitted packet data
HexDump("[+] NET_SendDatagram", 0, buf, len);
}
return result;
}
//#################################################################################
// CHLCLIENT HOOKS
//#################################################################################
void __fastcall HCHLClient__FrameStageNotify(CHLClient* rcx, ClientFrameStage_t curStage) /* __fastcall so we can make sure first argument will be RCX and second RDX. */
{
switch (curStage)
{
case FRAME_START: // FrameStageNotify gets called every frame by CEngine::Frame with the stage being FRAME_START. We can use this to check/set global variables.
{
if (!GameGlobals::IsInitialized)
GameGlobals::InitGameGlobals();
break;
}
default:
break;
}
org_CHLClient_FrameStageNotify(rcx, curStage);
}
//#################################################################################
// SQUIRRELVM HOOKS
//#################################################################################
void* HSQVM_Print(void* sqvm, char* fmt, ...)
{
char buf[1024];
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
buf[IM_ARRAYSIZE(buf) - 1] = 0;
va_end(args);
Items.push_back(Strdup(buf));
return NULL;
}
__int64 HSQVM_LoadRson(const char* rson_name)
{
char filepath[MAX_PATH] = { 0 };
sprintf_s(filepath, MAX_PATH, "platform\\%s", rson_name);
///////////////////////////////////////////////////////////////////////////////
// Flip forward slashes in filepath to windows-style backslash
for (int i = 0; i < strlen(filepath); i++)
{
if (filepath[i] == '/')
{
filepath[i] = '\\';
}
}
///////////////////////////////////////////////////////////////////////////////
// Returns the new path if the rson exists on the disk
if (FileExists(filepath) && org_SQVM_LoadRson(rson_name))
{
printf("\n");
printf("##################################################\n");
printf("] '%s'\n", filepath);
printf("##################################################\n");
printf("\n");
return org_SQVM_LoadRson(filepath);
}
printf("\n");
printf("##################################################\n");
printf("] '%s'\n", rson_name);
printf("##################################################\n");
printf("\n");
return org_SQVM_LoadRson(rson_name);
}
bool HSQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag)
{
char filepath[MAX_PATH] = { 0 };
sprintf_s(filepath, MAX_PATH, "platform\\%s", script_path);
///////////////////////////////////////////////////////////////////////////////
// Flip forward slashes in filepath to windows-style backslash
for (int i = 0; i < strlen(filepath); i++)
{
if (filepath[i] == '/')
{
filepath[i] = '\\';
}
}
if (g_bDebugLoading)
{
printf(" [+] Loading SQVM Script '%s' ...\n", filepath);
}
///////////////////////////////////////////////////////////////////////////////
// Returns true if the script exists on the disk
if (FileExists(filepath) && org_SQVM_LoadScript(sqvm, filepath, script_name, flag))
{
return true;
}
if (g_bDebugLoading)
{
printf(" [!] FAILED. Try SP / VPK for '%s'\n", filepath);
}
return org_SQVM_LoadScript(sqvm, script_path, script_name, flag);
}
//#################################################################################
// UTILITY HOOKS
//#################################################################################
int HMSG_EngineError(char* fmt, va_list args)
{
printf("\nENGINE ERROR #####################################\n");
vprintf(fmt, args);
return org_MSG_EngineError(fmt, args);
}
// TODO: turn this into a playerstruct constructor if it ever becomes necessary
bool HCVEngineServer_IsPersistenceDataAvailable(__int64 thisptr, int client)
{
static bool isPersistenceVarSet[256];
// TODO: Maybe not hardcode
std::uintptr_t playerStructBase = 0x16073B200;
std::uintptr_t playerStructSize = 0x4A4C0;
std::uintptr_t persistenceVar = 0x5BC;
std::uintptr_t targetPlayerStruct = playerStructBase + client * playerStructSize;
*(char*)(targetPlayerStruct + persistenceVar) = (char)0x5;
if (!isPersistenceVarSet[client])
{
printf("\n");
printf("##################################################\n");
printf("] SETTING PERSISTENCE VAR FOR CLIENT #%d\n", client);
printf("##################################################\n");
printf("\n");
isPersistenceVarSet[client] = true;
}
return org_CVEngineServer_IsPersistenceDataAvailable(thisptr, client);
}
//#################################################################################
// MANAGEMENT
//#################################################################################
void InstallENHooks()
{
///////////////////////////////////////////////////////////////////////////////
// Begin the detour transaction
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
///////////////////////////////////////////////////////////////////////////////
// Hook Squirrel functions
DetourAttach((LPVOID*)&org_SQVM_Print, &HSQVM_Print);
DetourAttach((LPVOID*)&org_SQVM_LoadRson, &HSQVM_LoadRson);
DetourAttach((LPVOID*)&org_SQVM_LoadScript, &HSQVM_LoadScript);
///////////////////////////////////////////////////////////////////////////////
// Hook Game Functions
DetourAttach((LPVOID*)&org_CHLClient_FrameStageNotify, &HCHLClient__FrameStageNotify);
///////////////////////////////////////////////////////////////////////////////
// Hook Utility functions
DetourAttach((LPVOID*)&org_MSG_EngineError, &HMSG_EngineError);
DetourAttach((LPVOID*)&org_CVEngineServer_IsPersistenceDataAvailable, &HCVEngineServer_IsPersistenceDataAvailable);
///////////////////////////////////////////////////////////////////////////////
// Commit the transaction
if (DetourTransactionCommit() != NO_ERROR)
{
// Failed to hook into the process, terminate
TerminateProcess(GetCurrentProcess(), 0xBAD0C0DE);
}
}
void RemoveENHooks()
{
///////////////////////////////////////////////////////////////////////////////
// Begin the detour transaction, to unhook the the process
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
///////////////////////////////////////////////////////////////////////////////
// Unhook Squirrel functions
DetourDetach((LPVOID*)&org_SQVM_Print, &HSQVM_Print);
DetourDetach((LPVOID*)&org_SQVM_LoadRson, &HSQVM_LoadRson);
DetourDetach((LPVOID*)&org_SQVM_LoadScript, &HSQVM_LoadScript);
///////////////////////////////////////////////////////////////////////////////
// Unhook Game Functions
DetourDetach((LPVOID*)&org_CHLClient_FrameStageNotify, &HCHLClient__FrameStageNotify);
///////////////////////////////////////////////////////////////////////////////
// Unhook Netchan functions
DetourDetach((LPVOID*)&org_NET_SendDatagram, &HNET_SendDatagram);
DetourDetach((LPVOID*)&org_NET_ReceiveDatagram, &HNET_ReceiveDatagram);
///////////////////////////////////////////////////////////////////////////////
// Unhook Utility functions
DetourDetach((LPVOID*)&org_MSG_EngineError, &HMSG_EngineError);
DetourDetach((LPVOID*)&org_CVEngineServer_IsPersistenceDataAvailable, &HCVEngineServer_IsPersistenceDataAvailable);
///////////////////////////////////////////////////////////////////////////////
// Commit the transaction
DetourTransactionCommit();
}
//#################################################################################
// TOGGLES
//#################################################################################
void ToggleNetHooks()
{
static bool g_net = false;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
if (!g_net)
{
DetourAttach((LPVOID*)&org_NET_SendDatagram, &HNET_SendDatagram);
DetourAttach((LPVOID*)&org_NET_ReceiveDatagram, &HNET_ReceiveDatagram);
printf("\n");
printf("+--------------------------------------------------------+\n");
printf("|>>>>>>>>>>>>>| NETCHANNEL TRACE ACTIVATED |<<<<<<<<<<<<<|\n");
printf("+--------------------------------------------------------+\n");
printf("\n");
}
else
{
DetourDetach((LPVOID*)&org_NET_SendDatagram, &HNET_SendDatagram);
DetourDetach((LPVOID*)&org_NET_ReceiveDatagram, &HNET_ReceiveDatagram);
printf("\n");
printf("+--------------------------------------------------------+\n");
printf("|>>>>>>>>>>>>| NETCHANNEL TRACE DEACTIVATED |<<<<<<<<<<<<|\n");
printf("+--------------------------------------------------------+\n");
printf("\n");
}
if (DetourTransactionCommit() != NO_ERROR)
{
TerminateProcess(GetCurrentProcess(), 0xBAD0C0DE);
}
g_net = !g_net;
}

View File

@ -0,0 +1,25 @@
#include "pch.h"
#include "hooks.h"
namespace Hooks
{
FrameStageNotifyFn originalFrameStageNotify = nullptr;
}
void __fastcall Hooks::FrameStageNotify(CHLClient* rcx, ClientFrameStage_t curStage)
{
switch (curStage)
{
case FRAME_START: // FrameStageNotify gets called every frame by CEngine::Frame with the stage being FRAME_START. We can use this to check/set global variables.
{
if (!GameGlobals::IsInitialized)
GameGlobals::InitGameGlobals();
break;
}
default:
break;
}
originalFrameStageNotify(rcx, curStage);
}

View File

@ -0,0 +1,34 @@
#include "pch.h"
#include "hooks.h"
namespace Hooks
{
IsPersistenceDataAvailableFn originalIsPersistenceDataAvailable = nullptr;
}
// TODO: turn this into a playerstruct constructor if it ever becomes necessary
bool Hooks::IsPersistenceDataAvailable(__int64 thisptr, int client)
{
static bool isPersistenceVarSet[256];
// TODO: Maybe not hardcode
std::uintptr_t playerStructBase = 0x16073B200;
std::uintptr_t playerStructSize = 0x4A4C0;
std::uintptr_t persistenceVar = 0x5BC;
std::uintptr_t targetPlayerStruct = playerStructBase + client * playerStructSize;
*(char*)(targetPlayerStruct + persistenceVar) = (char)0x5;
if (!isPersistenceVarSet[client])
{
printf("\n");
printf("##################################################\n");
printf("] SETTING PERSISTENCE VAR FOR CLIENT #%d\n", client);
printf("##################################################\n");
printf("\n");
isPersistenceVarSet[client] = true;
}
return originalIsPersistenceDataAvailable(thisptr, client);
}

173
r5dev/src/hooks/hooks.cpp Normal file
View File

@ -0,0 +1,173 @@
#include "pch.h"
#include "hooks.h"
bool g_bBlockInput = false;
void Hooks::InstallHooks()
{
///////////////////////////////////////////////////////////////////////////////
// Initialize Minhook
MH_Initialize();
///////////////////////////////////////////////////////////////////////////////
// Hook Squirrel functions
MH_CreateHook(addr_SQVM_Print, &Hooks::SQVM_Print, NULL);
MH_CreateHook(addr_SQVM_LoadRson, &Hooks::SQVM_LoadRson, reinterpret_cast<void**>(&originalSQVM_LoadRson));
MH_CreateHook(addr_SQVM_LoadScript, &Hooks::SQVM_LoadScript, reinterpret_cast<void**>(&originalSQVM_LoadScript));
///////////////////////////////////////////////////////////////////////////////
// Hook Game Functions
MH_CreateHook(addr_CHLClient_FrameStageNotify, &Hooks::FrameStageNotify, reinterpret_cast<void**>(&originalFrameStageNotify));
MH_CreateHook(addr_CVEngineServer_IsPersistenceDataAvailable, &Hooks::IsPersistenceDataAvailable, reinterpret_cast<void**>(&originalIsPersistenceDataAvailable));
///////////////////////////////////////////////////////////////////////////////
// Hook Netchan functions
MH_CreateHook(addr_NET_ReceiveDatagram, &Hooks::NET_ReceiveDatagram, reinterpret_cast<void**>(&originalNET_ReceiveDatagram));
MH_CreateHook(addr_NET_SendDatagram, &Hooks::NET_SendDatagram, reinterpret_cast<void**>(&originalNET_SendDatagram));
///////////////////////////////////////////////////////////////////////////////
// Hook ConVar | ConCommand functions.
MH_CreateHook(addr_ConVar_IsFlagSet, &Hooks::ConVar_IsFlagSet, NULL);
MH_CreateHook(addr_ConCommand_IsFlagSet, &Hooks::ConCommand_IsFlagSet, NULL);
///////////////////////////////////////////////////////////////////////////////
// Hook WinAPI
HMODULE user32dll = GetModuleHandleA("user32.dll");
void* SetCursorPosPtr = GetProcAddress(user32dll, "SetCursorPos");
void* ClipCursorPtr = GetProcAddress(user32dll, "ClipCursor");
void* GetCursorPosPtr = GetProcAddress(user32dll, "GetCursorPos");
void* ShowCursorPtr = GetProcAddress(user32dll, "ShowCursor");
MH_CreateHook(SetCursorPosPtr, &Hooks::SetCursorPos, reinterpret_cast<void**>(&originalSetCursorPos));
MH_CreateHook(ClipCursorPtr, &Hooks::ClipCursor, reinterpret_cast<void**>(&originalClipCursor));
MH_CreateHook(GetCursorPosPtr, &Hooks::GetCursorPos, reinterpret_cast<void**>(&originalGetCursorPos));
MH_CreateHook(ShowCursorPtr, &Hooks::ShowCursor, reinterpret_cast<void**>(&originalShowCursor));
///////////////////////////////////////////////////////////////////////////////
// Hook Utility functions
MH_CreateHook(addr_MSG_EngineError, &Hooks::MSG_EngineError, reinterpret_cast<void**>(&originalMSG_EngineError));
///////////////////////////////////////////////////////////////////////////////
// Enable Squirrel hooks
MH_EnableHook(addr_SQVM_Print);
MH_EnableHook(addr_SQVM_LoadRson);
MH_EnableHook(addr_SQVM_LoadScript);
///////////////////////////////////////////////////////////////////////////////
// Enable Game hooks
MH_EnableHook(addr_CHLClient_FrameStageNotify);
MH_EnableHook(addr_CVEngineServer_IsPersistenceDataAvailable);
///////////////////////////////////////////////////////////////////////////////
// Enable WinAPI hooks
MH_EnableHook(SetCursorPosPtr);
MH_EnableHook(ClipCursorPtr);
MH_EnableHook(GetCursorPosPtr);
MH_EnableHook(ShowCursorPtr);
///////////////////////////////////////////////////////////////////////////////
// Enabled Utility hooks
MH_EnableHook(addr_MSG_EngineError);
}
void Hooks::RemoveHooks()
{
///////////////////////////////////////////////////////////////////////////////
// Unhook Squirrel functions
MH_RemoveHook(addr_SQVM_Print);
MH_RemoveHook(addr_SQVM_LoadRson);
MH_RemoveHook(addr_SQVM_LoadScript);
///////////////////////////////////////////////////////////////////////////////
// Unhook Game Functions
MH_RemoveHook(addr_CHLClient_FrameStageNotify);
MH_RemoveHook(addr_CVEngineServer_IsPersistenceDataAvailable);
///////////////////////////////////////////////////////////////////////////////
// Unhook Netchan functions
MH_RemoveHook(addr_NET_ReceiveDatagram);
MH_RemoveHook(addr_NET_SendDatagram);
///////////////////////////////////////////////////////////////////////////////
// Unhook ConVar | ConCommand functions.
MH_RemoveHook(addr_ConVar_IsFlagSet);
MH_RemoveHook(addr_ConCommand_IsFlagSet);
///////////////////////////////////////////////////////////////////////////////
// Unhook WinAPI
HMODULE user32dll = GetModuleHandleA("user32.dll");
void* SetCursorPosPtr = GetProcAddress(user32dll, "SetCursorPos");
void* ClipCursorPtr = GetProcAddress(user32dll, "ClipCursor");
void* GetCursorPosPtr = GetProcAddress(user32dll, "GetCursorPos");
void* ShowCursorPtr = GetProcAddress(user32dll, "ShowCursor");
MH_RemoveHook(SetCursorPosPtr);
MH_RemoveHook(ClipCursorPtr);
MH_RemoveHook(GetCursorPosPtr);
MH_RemoveHook(ShowCursorPtr);
///////////////////////////////////////////////////////////////////////////////
// Unhook Utility functions
MH_RemoveHook(addr_MSG_EngineError);
///////////////////////////////////////////////////////////////////////////////
// Reset Minhook
MH_Uninitialize();
}
void Hooks::ToggleNetHooks()
{
static bool g_net = false;
if (!g_net)
{
MH_EnableHook(addr_NET_ReceiveDatagram);
MH_EnableHook(addr_NET_SendDatagram);
printf("\n");
printf("+--------------------------------------------------------+\n");
printf("|>>>>>>>>>>>>>| NETCHANNEL TRACE ACTIVATED |<<<<<<<<<<<<<|\n");
printf("+--------------------------------------------------------+\n");
printf("\n");
}
else
{
MH_DisableHook(addr_NET_ReceiveDatagram);
MH_DisableHook(addr_NET_SendDatagram);
printf("\n");
printf("+--------------------------------------------------------+\n");
printf("|>>>>>>>>>>>>| NETCHANNEL TRACE DEACTIVATED |<<<<<<<<<<<<|\n");
printf("+--------------------------------------------------------+\n");
printf("\n");
}
g_net = !g_net;
}
void Hooks::ToggleDevCommands()
{
static bool g_dev = false;
if (!g_dev)
{
MH_EnableHook(addr_ConVar_IsFlagSet);
MH_EnableHook(addr_ConCommand_IsFlagSet);
printf("\n");
printf("+--------------------------------------------------------+\n");
printf("|>>>>>>>>>>>>>| DEVONLY COMMANDS ACTIVATED |<<<<<<<<<<<<<|\n");
printf("+--------------------------------------------------------+\n");
printf("\n");
}
else
{
MH_DisableHook(addr_ConVar_IsFlagSet);
MH_DisableHook(addr_ConCommand_IsFlagSet);
printf("\n");
printf("+--------------------------------------------------------+\n");
printf("|>>>>>>>>>>>>| DEVONLY COMMANDS DEACTIVATED |<<<<<<<<<<<<|\n");
printf("+--------------------------------------------------------+\n");
printf("\n");
}
g_dev = !g_dev;
}

View File

@ -0,0 +1,58 @@
#include "pch.h"
#include "hooks.h"
bool Hooks::ConVar_IsFlagSet(int** cvar, int flag)
{
int real_flags = *(*(cvar + (72 / (sizeof(void*)))) + (56 / sizeof(int)));
if (g_bDebugConsole)
{
printf("--------------------------------------------------\n");
printf(" Flaged: %08X\n", real_flags);
}
// Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY
real_flags &= 0xFFFFBFFD;
if (g_bDebugConsole)
{
printf(" Masked: %08X\n", real_flags);
printf(" Verify: %08X\n", flag);
printf("--------------------------------------------------\n");
}
if (flag & 0x80000) { return true; }
if (!g_bReturnAllFalse)
{
return (real_flags & flag) != 0;
}
else
{
return false;
}
}
bool Hooks::ConCommand_IsFlagSet(int* cmd, int flag)
{
int real_flags = *((cmd + (56 / sizeof(int))));
if (g_bDebugConsole)
{
printf("--------------------------------------------------\n");
printf(" Flaged: %08X\n", real_flags);
}
// Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY
real_flags &= 0xFFFFBFFD;
if (g_bDebugConsole)
{
printf(" Masked: %08X\n", real_flags);
printf(" Verify: %08X\n", flag);
printf("--------------------------------------------------\n");
}
if (flag & 0x80000) { return true; }
if (!g_bReturnAllFalse)
{
return(real_flags & flag) != 0;
}
else
{
return false;
}
}

View File

@ -0,0 +1,15 @@
#include "pch.h"
#include "hooks.h"
namespace Hooks
{
MSG_EngineErrorFn originalMSG_EngineError = nullptr;
}
int Hooks::MSG_EngineError(char* fmt, va_list args)
{
printf("\nENGINE ERROR #####################################\n");
vprintf(fmt, args);
return originalMSG_EngineError(fmt, args);
}

37
r5dev/src/hooks/net.cpp Normal file
View File

@ -0,0 +1,37 @@
#include "pch.h"
#include "hooks.h"
namespace Hooks
{
NET_ReceiveDatagramFn originalNET_ReceiveDatagram = nullptr;
NET_SendDatagramFn originalNET_SendDatagram = nullptr;
}
bool Hooks::NET_ReceiveDatagram(int sock, void* inpacket, bool raw)
{
bool result = originalNET_ReceiveDatagram(sock, inpacket, raw);
if (result)
{
int i = NULL;
netpacket_t* pkt = (netpacket_t*)inpacket;
///////////////////////////////////////////////////////////////////////////
// Log received packet data
HexDump("[+] NET_ReceiveDatagram", 0, &pkt->data[i], pkt->wiresize);
}
return result;
}
unsigned int Hooks::NET_SendDatagram(SOCKET s, const char* buf, int len, int flags)
{
unsigned int result = originalNET_SendDatagram(s, buf, len, flags);
if (result)
{
///////////////////////////////////////////////////////////////////////////
// Log transmitted packet data
HexDump("[+] NET_SendDatagram", 0, buf, len);
}
return result;
}

90
r5dev/src/hooks/sqvm.cpp Normal file
View File

@ -0,0 +1,90 @@
#include "pch.h"
#include "hooks.h"
namespace Hooks
{
SQVM_LoadRsonFn originalSQVM_LoadRson = nullptr;
SQVM_LoadScriptFn originalSQVM_LoadScript = nullptr;
}
void* Hooks::SQVM_Print(void* sqvm, char* fmt, ...)
{
char buf[1024];
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
buf[IM_ARRAYSIZE(buf) - 1] = 0;
va_end(args);
Items.push_back(Strdup(buf));
return NULL;
}
__int64 Hooks::SQVM_LoadRson(const char* rson_name)
{
char filepath[MAX_PATH] = { 0 };
sprintf_s(filepath, MAX_PATH, "platform\\%s", rson_name);
///////////////////////////////////////////////////////////////////////////////
// Flip forward slashes in filepath to windows-style backslash
for (int i = 0; i < strlen(filepath); i++)
{
if (filepath[i] == '/')
{
filepath[i] = '\\';
}
}
///////////////////////////////////////////////////////////////////////////////
// Returns the new path if the rson exists on the disk
if (FileExists(filepath) && originalSQVM_LoadRson(rson_name))
{
printf("\n");
printf("##################################################\n");
printf("] '%s'\n", filepath);
printf("##################################################\n");
printf("\n");
return originalSQVM_LoadRson(filepath);
}
printf("\n");
printf("##################################################\n");
printf("] '%s'\n", rson_name);
printf("##################################################\n");
printf("\n");
return originalSQVM_LoadRson(rson_name);
}
bool Hooks::SQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag)
{
char filepath[MAX_PATH] = { 0 };
sprintf_s(filepath, MAX_PATH, "platform\\%s", script_path);
///////////////////////////////////////////////////////////////////////////////
// Flip forward slashes in filepath to windows-style backslash
for (int i = 0; i < strlen(filepath); i++)
{
if (filepath[i] == '/')
{
filepath[i] = '\\';
}
}
if (g_bDebugLoading)
{
printf(" [+] Loading SQVM Script '%s' ...\n", filepath);
}
///////////////////////////////////////////////////////////////////////////////
// Returns true if the script exists on the disk
if (FileExists(filepath) && originalSQVM_LoadScript(sqvm, filepath, script_name, flag))
{
return true;
}
if (g_bDebugLoading)
{
printf(" [!] FAILED. Try SP / VPK for '%s'\n", filepath);
}
return originalSQVM_LoadScript(sqvm, script_path, script_name, flag);
}

View File

@ -0,0 +1,59 @@
#include "pch.h"
#include "hooks.h"
namespace Hooks
{
namespace
{
static POINT g_pLastCursorPos{ 0 };
}
GetCursorPosFn originalGetCursorPos = nullptr;
SetCursorPosFn originalSetCursorPos = nullptr;
ClipCursorFn originalClipCursor = nullptr;
ShowCursorFn originalShowCursor = nullptr;
}
BOOL WINAPI Hooks::GetCursorPos(LPPOINT lpPoint)
{
if (g_bBlockInput)
{
assert(lpPoint != nullptr);
*lpPoint = g_pLastCursorPos;
}
return originalGetCursorPos(lpPoint);
}
BOOL WINAPI Hooks::SetCursorPos(int X, int Y)
{
g_pLastCursorPos.x = X;
g_pLastCursorPos.y = Y;
if (g_bBlockInput)
{
return TRUE;
}
return originalSetCursorPos(X, Y);
}
BOOL WINAPI Hooks::ClipCursor(const RECT* lpRect)
{
if (g_bBlockInput)
{
lpRect = nullptr;
}
return originalClipCursor(lpRect);
}
BOOL WINAPI Hooks::ShowCursor(BOOL bShow)
{
if (g_bBlockInput)
{
bShow = TRUE;
}
return originalShowCursor(bShow);
}

View File

@ -1,10 +1,8 @@
#include "pch.h"
#include "id3dx.h"
#include "input.h"
#include "enums.h"
#include "hooks.h"
#include "console.h"
#include "detours.h"
#include "overlay.h"
#include "patterns.h"
#include "gameclasses.h"
@ -271,12 +269,14 @@ void DrawImGui()
GameGlobals::InputSystem->EnableInput(false); // Disable input.
DrawConsole();
}
if(g_bShowBrowser)
if (g_bShowBrowser)
{
GameGlobals::InputSystem->EnableInput(false); // Disable input.
DrawBrowser();
}
else
if (!g_bShowConsole && !g_bShowBrowser)
{
GameGlobals::InputSystem->EnableInput(true); // Enable input.
}
@ -356,6 +356,8 @@ HRESULT GetDeviceAndCtxFromSwapchain(IDXGISwapChain* pSwapChain, ID3D11Device**
return ret;
}
IDXGIResizeBuffers originalResizeBuffers = nullptr;
HRESULT __stdcall GetResizeBuffers(IDXGISwapChain* pSwapChain, UINT nBufferCount, UINT nWidth, UINT nHeight, DXGI_FORMAT dxFormat, UINT nSwapChainFlags)
{
g_bShowConsole = false;
@ -371,16 +373,18 @@ HRESULT __stdcall GetResizeBuffers(IDXGISwapChain* pSwapChain, UINT nBufferCount
ImGui_ImplDX11_CreateDeviceObjects();
///////////////////////////////////////////////////////////////////////////////
return g_oResizeBuffers(pSwapChain, nBufferCount, nWidth, nHeight, dxFormat, nSwapChainFlags);
return originalResizeBuffers(pSwapChain, nBufferCount, nWidth, nHeight, dxFormat, nSwapChainFlags);
}
IDXGISwapChainPresent originalPresent = nullptr;
HRESULT __stdcall Present(IDXGISwapChain* pSwapChain, UINT nSyncInterval, UINT nFlags)
{
if (!g_bInitialized)
{
if (FAILED(GetDeviceAndCtxFromSwapchain(pSwapChain, &g_pDevice, &g_pDeviceContext)))
{
return g_fnIDXGISwapChainPresent(pSwapChain, nSyncInterval, nFlags);
return originalPresent(pSwapChain, nSyncInterval, nFlags);
std::cout << "+--------------------------------------------------------+" << std::endl;
std::cout << "| >>>>>>>>>>| GET DVS AND CTX FROM SCP FAILED |<<<<<<<<< |" << std::endl;
std::cout << "+--------------------------------------------------------+" << std::endl;
@ -401,7 +405,7 @@ HRESULT __stdcall Present(IDXGISwapChain* pSwapChain, UINT nSyncInterval, UINT n
DrawImGui();
g_bInitialized = true;
///////////////////////////////////////////////////////////////////////////////
return g_fnIDXGISwapChainPresent(pSwapChain, nSyncInterval, nFlags);
return originalPresent(pSwapChain, nSyncInterval, nFlags);
}
//#################################################################################
@ -410,42 +414,45 @@ HRESULT __stdcall Present(IDXGISwapChain* pSwapChain, UINT nSyncInterval, UINT n
void InstallDXHooks()
{
g_oPostMessageA = (IPostMessageA)DetourFindFunction("user32.dll", "PostMessageA");
g_oPostMessageW = (IPostMessageW)DetourFindFunction("user32.dll", "PostMessageW");
///////////////////////////////////////////////////////////////////////////////
// Begin the detour transaction
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
HMODULE user32dll = GetModuleHandleA("user32.dll");
IPostMessageA PostMessageA = (IPostMessageA)GetProcAddress(user32dll, "PostMessageA");
IPostMessageW PostMessageW = (IPostMessageW)GetProcAddress(user32dll, "PostMessageW");
///////////////////////////////////////////////////////////////////////////////
// Hook PostMessage
DetourAttach(&(LPVOID&)g_oPostMessageA, (PBYTE)HPostMessageA);
DetourAttach(&(LPVOID&)g_oPostMessageW, (PBYTE)HPostMessageW);
MH_CreateHook(PostMessageA, &HPostMessageA, reinterpret_cast<void**>(&g_oPostMessageA));
MH_CreateHook(PostMessageW, &HPostMessageW, reinterpret_cast<void**>(&g_oPostMessageW));
///////////////////////////////////////////////////////////////////////////////
// Hook SwapChain
DetourAttach(&(LPVOID&)g_fnIDXGISwapChainPresent, (PBYTE)Present);
DetourAttach(&(LPVOID&)g_oResizeBuffers, (PBYTE)GetResizeBuffers);
MH_CreateHook(g_fnIDXGISwapChainPresent, &Present, reinterpret_cast<void**>(&originalPresent));
MH_CreateHook(g_oResizeBuffers, &GetResizeBuffers, reinterpret_cast<void**>(&originalResizeBuffers));
///////////////////////////////////////////////////////////////////////////////
// Commit the transaction
DetourTransactionCommit();
// Enable hooks
MH_EnableHook(PostMessageA);
MH_EnableHook(PostMessageW);
MH_EnableHook(g_fnIDXGISwapChainPresent);
MH_EnableHook(g_oResizeBuffers);
}
void RemoveDXHooks()
{
///////////////////////////////////////////////////////////////////////////////
// Begin the detour transaction
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
HMODULE user32dll = GetModuleHandleA("user32.dll");
IPostMessageA PostMessageA = (IPostMessageA)GetProcAddress(user32dll, "PostMessageA");
IPostMessageW PostMessageW = (IPostMessageW)GetProcAddress(user32dll, "PostMessageW");
///////////////////////////////////////////////////////////////////////////////
// Unhook PostMessage
DetourDetach(&(LPVOID&)g_oPostMessageA, (PBYTE)HPostMessageA);
DetourDetach(&(LPVOID&)g_oPostMessageW, (PBYTE)HPostMessageW);
MH_RemoveHook(PostMessageA);
MH_RemoveHook(PostMessageW);
///////////////////////////////////////////////////////////////////////////////
// Unhook SwapChain
DetourDetach(&(LPVOID&)g_fnIDXGISwapChainPresent, (PBYTE)Present);
DetourDetach(&(LPVOID&)g_oResizeBuffers, (PBYTE)GetResizeBuffers);
///////////////////////////////////////////////////////////////////////////////
// Commit the transaction
DetourTransactionCommit();
MH_RemoveHook(g_fnIDXGISwapChainPresent);
MH_RemoveHook(g_oResizeBuffers);
///////////////////////////////////////////////////////////////////////////////
// Shutdown ImGui

View File

@ -1,119 +1,2 @@
#include "pch.h"
#include "input.h"
/*-----------------------------------------------------------------------------
* _input.cpp
*-----------------------------------------------------------------------------*/
///////////////////////////////////////////////////////////////////////////////
typedef BOOL(WINAPI* IGetCursorPos)(LPPOINT lpPoint);
typedef BOOL(WINAPI* ISetCursorPos)(int nX, int nY);
typedef BOOL(WINAPI* IClipCursor)(const RECT* lpRect);
typedef BOOL(WINAPI* IShowCursor)(BOOL bShow);
///////////////////////////////////////////////////////////////////////////////
static IGetCursorPos g_oGetCursorPos = nullptr;
static ISetCursorPos g_oSetCursorPos = nullptr;
static IClipCursor g_oClipCursor = nullptr;
static IShowCursor g_oShowCursor = nullptr;
///////////////////////////////////////////////////////////////////////////////
static POINT g_pLastCursorPos { 0 };
extern BOOL g_bBlockInput = false;
//#############################################################################
// INITIALIZATION
//#############################################################################
void SetupIPHooks()
{
g_oSetCursorPos = (ISetCursorPos)DetourFindFunction("user32.dll", "SetCursorPos");
g_oClipCursor = (IClipCursor )DetourFindFunction("user32.dll", "ClipCursor" );
g_oGetCursorPos = (IGetCursorPos)DetourFindFunction("user32.dll", "GetCursorPos");
g_oShowCursor = (IShowCursor )DetourFindFunction("user32.dll", "ShowCursor" );
}
//#############################################################################
// INPUT HOOKS
//#############################################################################
BOOL WINAPI HGetCursorPos(LPPOINT lpPoint)
{
if (g_bBlockInput)
{
assert(lpPoint != nullptr);
*lpPoint = g_pLastCursorPos;
}
return g_oGetCursorPos(lpPoint);
}
BOOL WINAPI HSetCursorPos(int X, int Y)
{
g_pLastCursorPos.x = X;
g_pLastCursorPos.y = Y;
if (g_bBlockInput)
{
return TRUE;
}
return g_oSetCursorPos(X, Y);
}
BOOL WINAPI HClipCursor(const RECT* lpRect)
{
if (g_bBlockInput)
{
lpRect = nullptr;
}
return g_oClipCursor(lpRect);
}
BOOL WINAPI HShowCursor(BOOL bShow)
{
if (g_bBlockInput)
{
bShow = TRUE;
}
return g_oShowCursor(bShow);
}
//#############################################################################
// MANAGEMENT
//#############################################################################
void InstallIPHooks()
{
SetupIPHooks();
///////////////////////////////////////////////////////////////////////////
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
///////////////////////////////////////////////////////////////////////////
DetourAttach(&(LPVOID&)g_oGetCursorPos, (PBYTE)HGetCursorPos);
DetourAttach(&(LPVOID&)g_oSetCursorPos, (PBYTE)HSetCursorPos);
DetourAttach(&(LPVOID&)g_oClipCursor, (PBYTE)HClipCursor);
DetourAttach(&(LPVOID&)g_oShowCursor, (PBYTE)HShowCursor);
///////////////////////////////////////////////////////////////////////////
DetourTransactionCommit();
}
void RemoveIPHooks()
{
///////////////////////////////////////////////////////////////////////////
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
///////////////////////////////////////////////////////////////////////////
DetourDetach(&(LPVOID&)g_oGetCursorPos, (PBYTE)HGetCursorPos);
DetourDetach(&(LPVOID&)g_oSetCursorPos, (PBYTE)HSetCursorPos);
DetourDetach(&(LPVOID&)g_oClipCursor, (PBYTE)HClipCursor);
DetourDetach(&(LPVOID&)g_oShowCursor, (PBYTE)HShowCursor);
///////////////////////////////////////////////////////////////////////////
DetourTransactionCommit();
}
#include "input.h"

View File

@ -67,7 +67,7 @@ void CGameConsole::Draw(const char* title)
///////////////////////////////////////////////////////////////////////
if (ImGui::SmallButton("Developer mode"))
{
ToggleDevCommands();
Hooks::ToggleDevCommands();
AddLog("+--------------------------------------------------------+\n");
AddLog("|>>>>>>>>>>>>>>| DEVONLY COMMANDS TOGGLED |<<<<<<<<<<<<<<|\n");
AddLog("+--------------------------------------------------------+\n");
@ -76,7 +76,7 @@ void CGameConsole::Draw(const char* title)
ImGui::SameLine();
if (ImGui::SmallButton("Netchannel Trace"))
{
ToggleNetHooks();
Hooks::ToggleNetHooks();
AddLog("+--------------------------------------------------------+\n");
AddLog("|>>>>>>>>>>>>>>| NETCHANNEL TRACE TOGGLED |<<<<<<<<<<<<<<|\n");
AddLog("+--------------------------------------------------------+\n");
@ -266,7 +266,7 @@ void CGameConsole::ProcessCommand(const char* command_line)
void CGameConsole::ExecCommand(const char* command_line)
{
org_CommandExecute(NULL, command_line);
addr_CommandExecute(NULL, command_line);
}
///////////////////////////////////////////////////////////////////////////
@ -762,7 +762,7 @@ void CCompanion::HostServerSection()
if (StartAsDedi)
{
ToggleDevCommands();
Hooks::ToggleDevCommands();
}
}
else
@ -848,7 +848,7 @@ void CCompanion::ProcessCommand(const char* command_line)
void CCompanion::ExecCommand(const char* command_line)
{
org_CommandExecute(NULL, command_line);
addr_CommandExecute(NULL, command_line);
}
void CCompanion::ConnectToServer(const std::string& ip, const std::string& port)