Improvements to GameConsole class

* Improvements to GameConsole quality

* Add post-build events for renaming release executables to allow debugging "Debug" and "Release" from the same install

* Segmentate codeblocks for easier reading and scrolling
This commit is contained in:
Amos 2021-06-17 17:07:26 -07:00
parent 181f88d902
commit 62a0b5cebb
12 changed files with 180 additions and 121 deletions

View File

@ -22,5 +22,6 @@ extern HRESULT __stdcall Present(IDXGISwapChain* pSwapChain, UINT nSyncInterval,
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Globals // Globals
extern DWORD g_dThreadId; extern DWORD g_dThreadId;
extern BOOL g_bShowMenu;
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@ -5,6 +5,7 @@
// Define the signatures or offsets to be searched and hooked // Define the signatures or offsets to be searched and hooked
namespace namespace
{ {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* ==== CONSOLE ========================================================================================================================================================= */ /* ==== CONSOLE ========================================================================================================================================================= */
DWORD64 p_CommandExecute = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8D\x0D\x27\x61\xa5\x1E\x41\x8B\xD8", "xxxx?xxxxxxxx????xxx"); DWORD64 p_CommandExecute = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8D\x0D\x27\x61\xa5\x1E\x41\x8B\xD8", "xxxx?xxxxxxxx????xxx");
void (*CommandExecute)(void* self, const char* cmd) = (void (*)(void*, const char*))p_CommandExecute; /*48 89 5C 24 ?? 57 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 41 8B D8*/ void (*CommandExecute)(void* self, const char* cmd) = (void (*)(void*, const char*))p_CommandExecute; /*48 89 5C 24 ?? 57 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 41 8B D8*/
@ -15,6 +16,7 @@ namespace
LONGLONG p_ConCommand_IsFlagSet = FindPattern("r5apex.exe", (const unsigned char*)"\x85\x51\x38\x0F\x95\xC0\xC3", "xxxxxxx"); LONGLONG p_ConCommand_IsFlagSet = FindPattern("r5apex.exe", (const unsigned char*)"\x85\x51\x38\x0F\x95\xC0\xC3", "xxxxxxx");
bool (*ConCommand_IsFlagSet)(int* cmd, int flag) = (bool (*)(int*, int))p_ConCommand_IsFlagSet; /*85 51 38 0F 95 C0 C3*/ bool (*ConCommand_IsFlagSet)(int* cmd, int flag) = (bool (*)(int*, int))p_ConCommand_IsFlagSet; /*85 51 38 0F 95 C0 C3*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* ==== SQUIRREL ======================================================================================================================================================== */ /* ==== SQUIRREL ======================================================================================================================================================== */
DWORD64 p_SQVM_Print = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x8B\xC4\x48\x89\x50\x10\x4C\x89\x40\x18\x4C\x89\x48\x20\x53\x56\x57\x48\x81\xEC\x30\x08\x00\x00\x48\x8B\xDA\x48\x8D\x70\x18\x48\x8B\xF9\xE8\x00\x00\x00\xFF\x48\x89\x74\x24\x28\x48\x8D\x54\x24\x30\x33", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx???xxxxxxxxxxxx"); DWORD64 p_SQVM_Print = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x8B\xC4\x48\x89\x50\x10\x4C\x89\x40\x18\x4C\x89\x48\x20\x53\x56\x57\x48\x81\xEC\x30\x08\x00\x00\x48\x8B\xDA\x48\x8D\x70\x18\x48\x8B\xF9\xE8\x00\x00\x00\xFF\x48\x89\x74\x24\x28\x48\x8D\x54\x24\x30\x33", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx???xxxxxxxxxxxx");
void* SQVM_Print = (void*)p_SQVM_Print; /*48 8B C4 48 89 50 10 4C 89 40 18 4C 89 48 20 53 56 57 48 81 EC 30 08 00 00 48 8B DA 48 8D 70 18 48 8B F9 E8 ?? ?? ?? FF 48 89 74 24 28 48 8D 54 24 30 33*/ void* SQVM_Print = (void*)p_SQVM_Print; /*48 8B C4 48 89 50 10 4C 89 40 18 4C 89 48 20 53 56 57 48 81 EC 30 08 00 00 48 8B DA 48 8D 70 18 48 8B F9 E8 ?? ?? ?? FF 48 89 74 24 28 48 8D 54 24 30 33*/
@ -26,6 +28,7 @@ namespace
DWORD64 p_SQVM_LoadRson = FindPattern("r5apex.exe", (const unsigned char*)"\x4C\x8B\xDC\x49\x89\x5B\x08\x57\x48\x81\xEC\xA0\x00\x00\x00\x33", "xxxxxxxxxxxxxxxx"); DWORD64 p_SQVM_LoadRson = FindPattern("r5apex.exe", (const unsigned char*)"\x4C\x8B\xDC\x49\x89\x5B\x08\x57\x48\x81\xEC\xA0\x00\x00\x00\x33", "xxxxxxxxxxxxxxxx");
int (*SQVM_LoadRson)(const char* rson_name) = (int (*)(const char*))p_SQVM_LoadRson; /*4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33*/ int (*SQVM_LoadRson)(const char* rson_name) = (int (*)(const char*))p_SQVM_LoadRson; /*4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* ==== NETCHAN ========================================================================================================================================================= */ /* ==== NETCHAN ========================================================================================================================================================= */
DWORD64 p_NET_ReceiveDatagram = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x50\xEB", "xxxxxxxxxxxxxxxxxxxxxxxxx"); DWORD64 p_NET_ReceiveDatagram = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x50\xEB", "xxxxxxxxxxxxxxxxxxxxxxxxx");
bool (*NET_ReceiveDatagram)(int, void*, bool) = (bool (*)(int, void*, bool))p_NET_ReceiveDatagram; /*E8 ?? ?? ?? ?? 84 C0 75 35 48 8B D3*/ bool (*NET_ReceiveDatagram)(int, void*, bool) = (bool (*)(int, void*, bool))p_NET_ReceiveDatagram; /*E8 ?? ?? ?? ?? 84 C0 75 35 48 8B D3*/
@ -33,6 +36,7 @@ namespace
DWORD64 p_NET_SendDatagram = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x56\x41\x57\x48\x81\xEC\x00\x05\x00\x00", "xxxxxxxxxxxxxxxxxxxxxxx?xxx"); DWORD64 p_NET_SendDatagram = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x56\x41\x57\x48\x81\xEC\x00\x05\x00\x00", "xxxxxxxxxxxxxxxxxxxxxxx?xxx");
unsigned int (*NET_SendDatagram)(SOCKET s, const char* buf, int len, int flags) = (unsigned int (*)(SOCKET, const char*, int, int))p_NET_SendDatagram; /*48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ?? 05 00 00*/ unsigned int (*NET_SendDatagram)(SOCKET s, const char* buf, int len, int flags) = (unsigned int (*)(SOCKET, const char*, int, int))p_NET_SendDatagram; /*48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ?? 05 00 00*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* ==== WINAPI ========================================================================================================================================================== */ /* ==== WINAPI ========================================================================================================================================================== */
DWORD64 p_SetCursorPosition = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x85\xD2\x0F\x00\x00\x00\x00\x00\x48\x89\x6C\x24\x00\x56\x48\x83\xEC\x40\x4C", "xxxx?????xxxx?xxxxxx"); // Uncomment for anything that is not between S1 build 525 and S4 build 856 DWORD64 p_SetCursorPosition = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x85\xD2\x0F\x00\x00\x00\x00\x00\x48\x89\x6C\x24\x00\x56\x48\x83\xEC\x40\x4C", "xxxx?????xxxx?xxxxxx"); // Uncomment for anything that is not between S1 build 525 and S4 build 856
//DWORD64 p_SetCursorPosition = FindPattern("r5apex.exe", "\x48\x89\x6C\x24\x18\x48\x89\x74\x24\x20\x57\x48\x83\xEC\x40\x48\x8B\xF9", "xxxxxxxxxxxxxxxxxx"); // Uncomment for anything that is between S1 build 525 and S4 build 856 //DWORD64 p_SetCursorPosition = FindPattern("r5apex.exe", "\x48\x89\x6C\x24\x18\x48\x89\x74\x24\x20\x57\x48\x83\xEC\x40\x48\x8B\xF9", "xxxxxxxxxxxxxxxxxx"); // Uncomment for anything that is between S1 build 525 and S4 build 856
@ -41,6 +45,7 @@ namespace
//DWORD64 p_GameWindowProc = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x4C\x24\x00\x56\x41\x54\x41\x56\x41\x57\x48\x83\xEC\x48", "xxxx?xxxxxxxxxxx"); //DWORD64 p_GameWindowProc = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x4C\x24\x00\x56\x41\x54\x41\x56\x41\x57\x48\x83\xEC\x48", "xxxx?xxxxxxxxxxx");
//unsigned int (*GameWindowProc)(int game, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) = (unsigned int (*)(int, HWND, UINT, WPARAM, LPARAM))p_GameWindowProc; /*48 89 4C 24 ?? 56 41 54 41 56 41 57 48 83 EC 48*/ //unsigned int (*GameWindowProc)(int game, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) = (unsigned int (*)(int, HWND, UINT, WPARAM, LPARAM))p_GameWindowProc; /*48 89 4C 24 ?? 56 41 54 41 56 41 57 48 83 EC 48*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* ==== ------- ========================================================================================================================================================= */ /* ==== ------- ========================================================================================================================================================= */
void PrintHAddress() // Test the sigscan results void PrintHAddress() // Test the sigscan results

View File

@ -24,6 +24,7 @@
<ProjectGuid>{28cc6b4f-7a95-4933-ada9-65e38d48516d}</ProjectGuid> <ProjectGuid>{28cc6b4f-7a95-4933-ada9-65e38d48516d}</ProjectGuid>
<RootNamespace>r5dev</RootNamespace> <RootNamespace>r5dev</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>r5dev</ProjectName>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -51,6 +52,7 @@
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -176,8 +178,7 @@
<AdditionalDependencies>detours.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>detours.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command> <Command>del "$(TargetDir)\r5detours.dll" &amp;&amp; rename "$(TargetPath)" "r5detours.dll"</Command>
</Command>
</PostBuildEvent> </PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

View File

@ -16,6 +16,7 @@
void SetupConsole() void SetupConsole()
{ {
///////////////////////////////////////////////////////////////////////////////
// Create the console window // Create the console window
if (AllocConsole() == FALSE) if (AllocConsole() == FALSE)
{ {
@ -23,6 +24,7 @@ void SetupConsole()
return; return;
} }
///////////////////////////////////////////////////////////////////////////////
// Set the window title // Set the window title
FILE* sBuildTxt; FILE* sBuildTxt;
CHAR sBuildBuf[1024] = { 0 }; CHAR sBuildBuf[1024] = { 0 };
@ -37,12 +39,14 @@ void SetupConsole()
} }
SetConsoleTitle(sBuildBuf); SetConsoleTitle(sBuildBuf);
///////////////////////////////////////////////////////////////////////////////
// Open input/output streams // Open input/output streams
FILE* fDummy; FILE* fDummy;
freopen_s(&fDummy, "CONIN$", "r", stdin); freopen_s(&fDummy, "CONIN$", "r", stdin);
freopen_s(&fDummy, "CONOUT$", "w", stdout); freopen_s(&fDummy, "CONOUT$", "w", stdout);
freopen_s(&fDummy, "CONOUT$", "w", stderr); freopen_s(&fDummy, "CONOUT$", "w", stderr);
///////////////////////////////////////////////////////////////////////////////
// Create a worker thread to process console commands // Create a worker thread to process console commands
DWORD threadId0; DWORD threadId0;
DWORD __stdcall ProcessConsoleWorker(LPVOID); DWORD __stdcall ProcessConsoleWorker(LPVOID);
@ -67,6 +71,7 @@ bool Hook_ConVar_IsFlagSet(int** cvar, int flag)
printf("--------------------------------------------------\n"); printf("--------------------------------------------------\n");
printf(" Flaged: %08X\n", real_flags); printf(" Flaged: %08X\n", real_flags);
} }
///////////////////////////////////////////////////////////////////////////////
// Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY // Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY
real_flags &= 0xFFFFBFFD; real_flags &= 0xFFFFBFFD;
if (g_bDebugConsole) if (g_bDebugConsole)
@ -89,6 +94,7 @@ bool Hook_ConCommand_IsFlagSet(int* cmd, int flag)
printf("--------------------------------------------------\n"); printf("--------------------------------------------------\n");
printf(" Flaged: %08X\n", real_flags); printf(" Flaged: %08X\n", real_flags);
} }
///////////////////////////////////////////////////////////////////////////////
// Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY // Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY
real_flags &= 0xFFFFBFFD; real_flags &= 0xFFFFBFFD;
if (g_bDebugConsole) if (g_bDebugConsole)
@ -114,27 +120,31 @@ DWORD __stdcall ProcessConsoleWorker(LPVOID)
{ {
std::string sCommand; std::string sCommand;
///////////////////////////////////////////////////////////////////////////
// Get the user input on the debug console // Get the user input on the debug console
printf(">"); printf(">");
std::getline(std::cin, sCommand); std::getline(std::cin, sCommand);
///////////////////////////////////////////////////////////////////////////
// Engine toggles // Engine toggles
if (sCommand == "toggle net") { ToggleNetHooks(); continue; } if (sCommand == "toggle net") { ToggleNetHooks(); continue; }
if (sCommand == "toggle dev") { ToggleDevCommands(); continue; } if (sCommand == "toggle dev") { ToggleDevCommands(); continue; }
if (sCommand == "toggle fal") { g_bReturnAllFalse = !g_bReturnAllFalse; continue; } if (sCommand == "toggle fal") { g_bReturnAllFalse = !g_bReturnAllFalse; continue; }
///////////////////////////////////////////////////////////////////////////
// Debug toggles // Debug toggles
if (sCommand == "pattern test") { PrintHAddress(); PrintOAddress(); continue; } if (sCommand == "pattern test") { PrintHAddress(); PrintOAddress(); continue; }
if (sCommand == "console test") { g_bDebugConsole = !g_bDebugConsole; continue; } if (sCommand == "console test") { g_bDebugConsole = !g_bDebugConsole; continue; }
///////////////////////////////////////////////////////////////////////////
// Exec toggles // Exec toggles
if (sCommand == "1") { ToggleDevCommands(); CommandExecute(NULL, "exec autoexec_dev"); } if (sCommand == "1") { ToggleDevCommands(); CommandExecute(NULL, "exec autoexec_dev"); }
if (sCommand == "2") { g_bDebugLog = !g_bDebugLog; continue; } if (sCommand == "2") { g_bDebugLog = !g_bDebugLog; continue; }
///////////////////////////////////////////////////////////////////////////
// Execute the command in the r5 SQVM // Execute the command in the r5 SQVM
CommandExecute(NULL, sCommand.c_str()); CommandExecute(NULL, sCommand.c_str());
sCommand.clear(); sCommand.clear();
///////////////////////////////////////////////////////////////////////////
// Sleep and loop // Sleep and loop
Sleep(50); Sleep(50);
} }

View File

@ -30,7 +30,7 @@ void TerminateR5Dev()
} }
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// Main // Entry
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)

View File

@ -23,6 +23,7 @@ bool Hook_NET_ReceiveDatagram(int sock, void* inpacket, bool raw)
int i = NULL; int i = NULL;
netpacket_t* pkt = (netpacket_t*)inpacket; netpacket_t* pkt = (netpacket_t*)inpacket;
///////////////////////////////////////////////////////////////////////////
// Log received packet data // Log received packet data
HexDump("[+] NET_ReceiveDatagram", "platform\\log\\netchan.log", "a", 0, &pkt->data[i], pkt->wiresize); HexDump("[+] NET_ReceiveDatagram", "platform\\log\\netchan.log", "a", 0, &pkt->data[i], pkt->wiresize);
} }
@ -35,6 +36,7 @@ unsigned int Hook_NET_SendDatagram(SOCKET s, const char* buf, int len, int flags
unsigned int result = NET_SendDatagram(s, buf, len, flags); unsigned int result = NET_SendDatagram(s, buf, len, flags);
if (result) if (result)
{ {
///////////////////////////////////////////////////////////////////////////
// Log transmitted packet data // Log transmitted packet data
HexDump("[+] NET_SendDatagram", "platform\\log\\netchan.log", "a", 0, buf, len); HexDump("[+] NET_SendDatagram", "platform\\log\\netchan.log", "a", 0, buf, len);
} }
@ -74,6 +76,7 @@ bool Hook_SQVM_LoadScript(void* sqvm, const char* script_path, const char* scrip
char filepath[MAX_PATH] = { 0 }; char filepath[MAX_PATH] = { 0 };
sprintf_s(filepath, MAX_PATH, "platform\\%s", script_path); sprintf_s(filepath, MAX_PATH, "platform\\%s", script_path);
///////////////////////////////////////////////////////////////////////////////
// Flip forward slashes in filepath to windows-style backslash // Flip forward slashes in filepath to windows-style backslash
for (int i = 0; i < strlen(filepath); i++) for (int i = 0; i < strlen(filepath); i++)
{ {
@ -82,14 +85,20 @@ bool Hook_SQVM_LoadScript(void* sqvm, const char* script_path, const char* scrip
filepath[i] = '\\'; filepath[i] = '\\';
} }
} }
if (g_bDebugLog)
if (g_bDebugLog) { printf(" [+] Loading SQVM Script '%s' ...\n", filepath); } {
printf(" [+] Loading SQVM Script '%s' ...\n", filepath);
}
///////////////////////////////////////////////////////////////////////////////
// Returns true if the script exists on the disk
if (FileExists(filepath) && SQVM_LoadScript(sqvm, filepath, script_name, flag)) if (FileExists(filepath) && SQVM_LoadScript(sqvm, filepath, script_name, flag))
{ {
return true; // Redirect to disk worked / script exists on disk.. return true;
}
if (g_bDebugLog)
{
printf(" [!] FAILED. Try SP / VPK for '%s'\n", filepath);
} }
if (g_bDebugLog) { printf(" [!] FAILED. Try SP / VPK for '%s'\n", filepath); }
return SQVM_LoadScript(sqvm, script_path, script_name, flag); return SQVM_LoadScript(sqvm, script_path, script_name, flag);
} }
@ -99,15 +108,16 @@ bool Hook_SQVM_LoadScript(void* sqvm, const char* script_path, const char* scrip
void InstallHooks() void InstallHooks()
{ {
///////////////////////////////////////////////////////////////////////////////
// Begin the detour transaction // Begin the detour transaction
DetourTransactionBegin(); DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread()); DetourUpdateThread(GetCurrentThread());
///////////////////////////////////////////////////////////////////////////////
// Hook Engine functions // Hook Engine functions
DetourAttach((LPVOID*)&SQVM_Print, &Hook_SQVM_Print); DetourAttach((LPVOID*)&SQVM_Print, &Hook_SQVM_Print);
DetourAttach((LPVOID*)&SQVM_LoadRson, &Hook_SQVM_LoadRson); DetourAttach((LPVOID*)&SQVM_LoadRson, &Hook_SQVM_LoadRson);
DetourAttach((LPVOID*)&SQVM_LoadScript, &Hook_SQVM_LoadScript); DetourAttach((LPVOID*)&SQVM_LoadScript, &Hook_SQVM_LoadScript);
///////////////////////////////////////////////////////////////////////////////
// Commit the transaction // Commit the transaction
if (DetourTransactionCommit() != NO_ERROR) if (DetourTransactionCommit() != NO_ERROR)
{ {
@ -118,21 +128,24 @@ void InstallHooks()
void RemoveHooks() void RemoveHooks()
{ {
///////////////////////////////////////////////////////////////////////////////
// Begin the detour transaction, to unhook the the process // Begin the detour transaction, to unhook the the process
DetourTransactionBegin(); DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread()); DetourUpdateThread(GetCurrentThread());
///////////////////////////////////////////////////////////////////////////////
// Unhook Squirrel functions // Unhook Squirrel functions
DetourDetach((LPVOID*)&SQVM_Print, &Hook_SQVM_Print); DetourDetach((LPVOID*)&SQVM_Print, &Hook_SQVM_Print);
DetourDetach((LPVOID*)&SQVM_LoadRson, &Hook_SQVM_LoadRson); DetourDetach((LPVOID*)&SQVM_LoadRson, &Hook_SQVM_LoadRson);
DetourDetach((LPVOID*)&SQVM_LoadScript, &Hook_SQVM_LoadScript); DetourDetach((LPVOID*)&SQVM_LoadScript, &Hook_SQVM_LoadScript);
///////////////////////////////////////////////////////////////////////////////
// Unhook Netchan functions // Unhook Netchan functions
DetourDetach((LPVOID*)&NET_SendDatagram, &Hook_NET_SendDatagram); DetourDetach((LPVOID*)&NET_SendDatagram, &Hook_NET_SendDatagram);
DetourDetach((LPVOID*)&NET_ReceiveDatagram, &Hook_NET_ReceiveDatagram); DetourDetach((LPVOID*)&NET_ReceiveDatagram, &Hook_NET_ReceiveDatagram);
///////////////////////////////////////////////////////////////////////////////
// Unhook Console functions // Unhook Console functions
DetourDetach((LPVOID*)&ConVar_IsFlagSet, &Hook_ConVar_IsFlagSet); DetourDetach((LPVOID*)&ConVar_IsFlagSet, &Hook_ConVar_IsFlagSet);
DetourDetach((LPVOID*)&ConCommand_IsFlagSet, &Hook_ConCommand_IsFlagSet); DetourDetach((LPVOID*)&ConCommand_IsFlagSet, &Hook_ConCommand_IsFlagSet);
///////////////////////////////////////////////////////////////////////////////
// Commit the transaction // Commit the transaction
DetourTransactionCommit(); DetourTransactionCommit();
} }

View File

@ -26,14 +26,13 @@ typedef HRESULT(__stdcall* IDXGISwapChainPresent)(IDXGISwapChain* pSwapChain, UI
typedef HRESULT(__stdcall* IDXGIResizeBuffers) (IDXGISwapChain* pSwapChain, UINT nBufferCount, UINT nWidth, UINT nHeight, DXGI_FORMAT dxFormat, UINT nSwapChainFlags); typedef HRESULT(__stdcall* IDXGIResizeBuffers) (IDXGISwapChain* pSwapChain, UINT nBufferCount, UINT nWidth, UINT nHeight, DXGI_FORMAT dxFormat, UINT nSwapChainFlags);
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static BOOL g_bShowMenu = false; extern BOOL g_bShowMenu = false;
static BOOL g_bInitialized = false; static BOOL g_bInitialized = false;
static BOOL g_bPresentHooked = false; static BOOL g_bPresentHooked = false;
static BOOL g_bListener[256] = { 0 };
static HWND g_hGameWindow = NULL; static WNDPROC g_oWndProc = NULL;
static WNDPROC g_oWndProc = NULL; static HWND g_hGameWindow = NULL;
extern DWORD g_dThreadId = NULL; extern DWORD g_dThreadId = NULL;
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
static IDXGISwapChainPresent g_fnIDXGISwapChainPresent = nullptr; static IDXGISwapChainPresent g_fnIDXGISwapChainPresent = nullptr;
@ -62,7 +61,7 @@ LRESULT CALLBACK hWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
if (uMsg == WM_KEYUP) if (uMsg == WM_KEYDOWN)
{ {
if (wParam == VK_OEM_3) if (wParam == VK_OEM_3)
{ {
@ -79,7 +78,7 @@ LRESULT CALLBACK hWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return true; return true;
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
return CallWindowProc(g_oWndProc, hWnd, uMsg, wParam, lParam); return CallWindowProc(g_oWndProc, hWnd, uMsg, wParam, lParam);
} }

View File

@ -11,17 +11,21 @@ void InstallOpcodes()
// JNZ --> JMP | Prevent OriginSDK from initializing on the client // JNZ --> JMP | Prevent OriginSDK from initializing on the client
//WriteProcessMemory(GetCurrentProcess(), LPVOID(dst000 + 0x0B), "\xE9\x63\x02\x00\x00\x00", 6, NULL); //WriteProcessMemory(GetCurrentProcess(), LPVOID(dst000 + 0x0B), "\xE9\x63\x02\x00\x00\x00", 6, NULL);
///////////////////////////////////////////////////////////////////////////
// JE --> NOP | Allow execution of map commands even if the OriginSDK is not running // JE --> NOP | Allow execution of map commands even if the OriginSDK is not running
WriteProcessMemory(GameProcess, LPVOID(dst001 + 0x2B), "\x90\x90\x90\x90\x90\x90", 6, NULL); WriteProcessMemory(GameProcess, LPVOID(dst001 + 0x2B), "\x90\x90\x90\x90\x90\x90", 6, NULL);
WriteProcessMemory(GameProcess, LPVOID(dst001 + 0x39), "\x90\x90\x90\x90\x90\x90", 6, NULL); WriteProcessMemory(GameProcess, LPVOID(dst001 + 0x39), "\x90\x90\x90\x90\x90\x90", 6, NULL);
WriteProcessMemory(GameProcess, LPVOID(dst001 + 0x46), "\x90\x90\x90\x90\x90\x90", 6, NULL); WriteProcessMemory(GameProcess, LPVOID(dst001 + 0x46), "\x90\x90\x90\x90\x90\x90", 6, NULL);
///////////////////////////////////////////////////////////////////////////
// JL --> NOP | Enable clientcommand callbacks without persistent player data // JL --> NOP | Enable clientcommand callbacks without persistent player data
WriteProcessMemory(GameProcess, LPVOID(dst002 + 0x76), "\x90\x90", 2, NULL); WriteProcessMemory(GameProcess, LPVOID(dst002 + 0x76), "\x90\x90", 2, NULL);
///////////////////////////////////////////////////////////////////////////
// JE --> NOP | Disable server-side verification for duplicate accounts on the server // JE --> NOP | Disable server-side verification for duplicate accounts on the server
WriteProcessMemory(GameProcess, LPVOID(dst003 + 0x23A), "\x90\x90", 2, NULL); WriteProcessMemory(GameProcess, LPVOID(dst003 + 0x23A), "\x90\x90", 2, NULL);
///////////////////////////////////////////////////////////////////////////
// JA --> JMP | Prevent FairFight anti-cheat from initializing on the server // JA --> JMP | Prevent FairFight anti-cheat from initializing on the server
WriteProcessMemory(GameProcess, LPVOID(dst004 + 0x72), "\xE9\xE4\x00\x00\x00\x00", 6, NULL); WriteProcessMemory(GameProcess, LPVOID(dst004 + 0x72), "\xE9\xE4\x00\x00\x00\x00", 6, NULL);
} }

View File

@ -22,30 +22,32 @@
class CGameConsole class CGameConsole
{ {
private: private:
char InputBuf[256]; ///////////////////////////////////////////////////////////////////////////
ImVector<const char*> Commands; char InputBuf[256] = { 0 };
ImVector<char*> History; ImVector<const char*> Commands;
int HistoryPos; // -1: new line, 0..History.Size-1 browsing history. ImVector<char*> History;
ImGuiTextFilter Filter; int HistoryPos = -1;
bool AutoScroll; ImGuiTextFilter Filter;
bool ScrollToBottom; bool AutoScroll = true;
bool ScrollToBottom = false;
public: public:
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Init
CGameConsole() CGameConsole()
{ {
ClearLog(); ClearLog();
memset(InputBuf, 0, sizeof(InputBuf)); memset(InputBuf, 0, sizeof(InputBuf));
HistoryPos = -1; HistoryPos = -1;
AutoScroll = true; AutoScroll = true;
ScrollToBottom = false; ScrollToBottom = false;
Commands.push_back("HELP"); Commands.push_back("HELP");
Commands.push_back("HISTORY"); Commands.push_back("HISTORY");
Commands.push_back("CLEAR"); Commands.push_back("CLEAR");
Commands.push_back("CLASSIFY"); Commands.push_back("CLASSIFY");
AddLog("[DEBUG] THREAD ID: %ld\n", g_dThreadId);
AddLog("[DEBUG] THREAD ID: %ld\n", g_dThreadId);
} }
~CGameConsole() ~CGameConsole()
{ {
@ -53,9 +55,8 @@ public:
for (int i = 0; i < History.Size; i++) { free(History[i]); } for (int i = 0; i < History.Size; i++) { free(History[i]); }
} }
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Helpers // Helpers
static int Stricmp(const char* s1, const char* s2) static int Stricmp(const char* s1, const char* s2)
{ {
int d; int d;
@ -65,7 +66,6 @@ public:
} }
return d; return d;
} }
static int Strnicmp(const char* s1, const char* s2, int n) static int Strnicmp(const char* s1, const char* s2, int n)
{ {
int d = 0; while (n > 0 && (d = toupper(*s2) - toupper(*s1)) == 0 && *s1) int d = 0; while (n > 0 && (d = toupper(*s2) - toupper(*s1)) == 0 && *s1)
@ -74,7 +74,6 @@ public:
} }
return d; return d;
} }
static char* Strdup(const char* s) static char* Strdup(const char* s)
{ {
IM_ASSERT(s); size_t len = strlen(s) + 1; void* buf = malloc(len); IM_ASSERT(buf); if (buf != NULL) IM_ASSERT(s); size_t len = strlen(s) + 1; void* buf = malloc(len); IM_ASSERT(buf); if (buf != NULL)
@ -82,12 +81,13 @@ public:
return (char*)memcpy(buf, (const void*)s, len); return (char*)memcpy(buf, (const void*)s, len);
} }
} }
static void Strtrim(char* s) static void Strtrim(char* s)
{ {
char* str_end = s + strlen(s); while (str_end > s && str_end[-1] == ' ') str_end--; *str_end = 0; char* str_end = s + strlen(s); while (str_end > s && str_end[-1] == ' ') str_end--; *str_end = 0;
} }
///////////////////////////////////////////////////////////////////////////
// Utility
void ClearLog() void ClearLog()
{ {
for (int i = 0; i < Items.Size; i++) { free(Items[i]); } for (int i = 0; i < Items.Size; i++) { free(Items[i]); }
@ -106,18 +106,24 @@ public:
Items.push_back(Strdup(buf)); Items.push_back(Strdup(buf));
} }
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Draw // Draw
void Draw(const char* title, bool* p_open) void Draw(const char* title, bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(840, 600), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(840, 600), ImGuiCond_FirstUseEver);
ImGui::SetWindowPos(ImVec2(1000, 50), ImGuiCond_FirstUseEver); ImGui::SetWindowPos(ImVec2(-1000, 50), ImGuiCond_FirstUseEver);
if (!ImGui::Begin(title, p_open)) { ImGui::End(); return; } if (!ImGui::Begin(title, p_open))
if (ImGui::BeginPopupContextItem())
{ {
if (ImGui::MenuItem("Close Console")) { *p_open = false; } g_bShowMenu = false;
ImGui::EndPopup(); ImGui::End(); return;
} }
if (*p_open == NULL)
{
g_bShowMenu = false;
}
///////////////////////////////////////////////////////////////////////
if (ImGui::SmallButton("Developer mode")) if (ImGui::SmallButton("Developer mode"))
{ {
ToggleDevCommands(); ToggleDevCommands();
@ -136,21 +142,34 @@ public:
ExecCommand("exec netchan"); ExecCommand("exec netchan");
} }
///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::SmallButton("Clear")) { ClearLog(); } if (ImGui::SmallButton("Clear"))
{
ClearLog();
}
ImGui::SameLine(); ImGui::SameLine();
bool copy_to_clipboard = ImGui::SmallButton("Copy"); bool copy_to_clipboard = ImGui::SmallButton("Copy");
ImGui::Separator(); ImGui::Separator();
if (ImGui::BeginPopup("Options")) { ImGui::Checkbox("Auto-scroll", &AutoScroll); ImGui::EndPopup(); } if (ImGui::BeginPopup("Options"))
if (ImGui::Button("Options")) { ImGui::OpenPopup("Options"); } {
ImGui::Checkbox("Auto-scroll", &AutoScroll); ImGui::EndPopup();
}
if (ImGui::Button("Options"))
{
ImGui::OpenPopup("Options");
}
ImGui::SameLine(); ImGui::SameLine();
Filter.Draw("Filter [\"-incl,-excl\"] [\"error\"]", 180); Filter.Draw("Filter [\"-incl,-excl\"] [\"error\"]", 180);
ImGui::Separator(); ImGui::Separator();
///////////////////////////////////////////////////////////////////////
// Reserve enough left-over height for 1 separator + 1 input text // Reserve enough left-over height for 1 separator + 1 input text
const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), false, ImGuiWindowFlags_HorizontalScrollbar);
///////////////////////////////////////////////////////////////////////
ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), true, ImGuiWindowFlags_None);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 4.f, 6.f });
if (ImGui::BeginPopupContextWindow()) if (ImGui::BeginPopupContextWindow())
{ {
if (ImGui::Selectable("Clear")) if (ImGui::Selectable("Clear"))
@ -165,10 +184,11 @@ public:
const char* item = Items[i]; const char* item = Items[i];
if (!Filter.PassFilter(item)) { continue; } if (!Filter.PassFilter(item)) { continue; }
///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
ImVec4 color; ImVec4 color;
bool has_color = false; bool has_color = false;
///////////////////////////////////////////////////////////////////
// General // General
if (strstr(item, "[INFO]")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; } if (strstr(item, "[INFO]")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; }
if (strstr(item, "[ERROR]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; } if (strstr(item, "[ERROR]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
@ -176,31 +196,37 @@ public:
if (strstr(item, "[WARNING]")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; } if (strstr(item, "[WARNING]")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strncmp(item, "# ", 2) == 0) { color = ImVec4(1.00f, 0.80f, 0.60f, 1.00f); has_color = true; } if (strncmp(item, "# ", 2) == 0) { color = ImVec4(1.00f, 0.80f, 0.60f, 1.00f); has_color = true; }
// Script errors ///////////////////////////////////////////////////////////////////
if (strstr(item, "[CLIENT]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, "[SERVER]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, "[UI]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, "SCRIPT ERROR")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, "SCRIPT COMPILE ERROR")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, " -> ")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
// Script debug
if (strstr(item, "CALLSTACK")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, "LOCALS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, "*FUNCTION")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, "DIAGPRINTS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, " File : ")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
if (strstr(item, "<><>GRX<><>")){ color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
// Callbacks // Callbacks
if (strstr(item, "CodeCallback_")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; } if (strstr(item, "CodeCallback_")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
///////////////////////////////////////////////////////////////////
// Script errors
if (strstr(item, "[CLIENT]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, "[SERVER]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, "[UI]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, "SCRIPT ERROR")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, "SCRIPT COMPILE")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, ".gnut #")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, ".nut #")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, " -> ")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
///////////////////////////////////////////////////////////////////
// Script debug
if (strstr(item, "CALLSTACK")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, "LOCALS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, "*FUNCTION")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, "DIAGPRINTS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, " File : ")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
if (strstr(item, "<><>GRX<><>")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
///////////////////////////////////////////////////////////////////
// Filters // Filters
if (strstr(item, ") -> ")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); has_color = true; } if (strstr(item, ") -> ")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.60f); has_color = true; }
///////////////////////////////////////////////////////////////////
if (has_color) { ImGui::PushStyleColor(ImGuiCol_Text, color); } if (has_color) { ImGui::PushStyleColor(ImGuiCol_Text, color); }
ImGui::TextUnformatted(item); ImGui::TextWrapped(item);
if (has_color) { ImGui::PopStyleColor(); } if (has_color) { ImGui::PopStyleColor(); }
} }
if (copy_to_clipboard) { ImGui::LogFinish(); } if (copy_to_clipboard) { ImGui::LogFinish(); }
@ -208,7 +234,7 @@ public:
if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) { ImGui::SetScrollHereY(1.0f); } if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) { ImGui::SetScrollHereY(1.0f); }
ScrollToBottom = false; ScrollToBottom = false;
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// Style // Style
void SetStyleVar(); void SetStyleVar();
{ {
@ -271,33 +297,34 @@ public:
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.5f); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.5f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_ScrollbarRounding, 1.0f); ImGui::PushStyleVar(ImGuiStyleVar_ScrollbarRounding, 1.0f);
//ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0f); //ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 2.5f); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 2.5f);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 1)); // Tighten spacing ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 1)); // Tighten spacing
} }
///////////////////////////////////////////////////////////////////////
ImGui::PopStyleVar(); ImGui::PopStyleVar();
ImGui::EndChild(); ImGui::EndChild();
ImGui::Separator(); ImGui::Separator();
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// Console // Console
bool reclaim_focus = false; bool reclaim_focus = false;
bool clear_inputbuf = false;
ImGui::PushItemWidth(750); ImGui::PushItemWidth(750);
if (ImGui::IsWindowAppearing()) { ImGui::SetKeyboardFocusHere(); } if (ImGui::IsWindowAppearing()) { ImGui::SetKeyboardFocusHere(); }
ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory; ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
if (ImGui::InputText("##input", InputBuf, IM_ARRAYSIZE(InputBuf), input_text_flags, &TextEditCallbackStub, (void*)this)) if (ImGui::InputText("##input", InputBuf, IM_ARRAYSIZE(InputBuf), input_text_flags, &TextEditCallbackStub, (void*)this))
{ {
char* s = InputBuf; char* s = InputBuf;
if (strstr(InputBuf, "`")) { strcpy(s, ""); }
Strtrim(s); Strtrim(s);
if (s[0]) { ExecCommand(s); } if (s[0]) { ExecCommand(s); }
strcpy(s, ""); strcpy(s, "");
reclaim_focus = true; reclaim_focus = true;
clear_inputbuf = false;
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Submit")) if (ImGui::Button("Submit"))
@ -306,27 +333,19 @@ public:
if (s[0]) { ExecCommand(s); } if (s[0]) { ExecCommand(s); }
strcpy(s, ""); strcpy(s, "");
reclaim_focus = true; reclaim_focus = true;
clear_inputbuf = false;
}
if (GetKeyState(VK_OEM_3) & 0x8000) { clear_inputbuf = true; }
if (clear_inputbuf == true)
{
char* s = InputBuf;
strcpy(s, "");
clear_inputbuf = false;
} }
///////////////////////////////////////////////////////////////////////
// Auto-focus on window apparition // Auto-focus on window apparition
ImGui::SetItemDefaultFocus(); ImGui::SetItemDefaultFocus();
if (reclaim_focus) { ImGui::SetKeyboardFocusHere(-1); }// Auto focus previous widget if (reclaim_focus) { ImGui::SetKeyboardFocusHere(-1); }// Auto focus previous widget
ImGui::End(); ImGui::End();
} }
///////////////////////////////////////////////////////////////////////////
// Exec
void ExecCommand(const char* command_line) void ExecCommand(const char* command_line)
{ {
using namespace std;
ifstream file("convar.txt");
AddLog("# %s\n", command_line); AddLog("# %s\n", command_line);
CommandExecute(NULL, command_line); CommandExecute(NULL, command_line);
@ -344,9 +363,10 @@ public:
} }
History.push_back(Strdup(command_line)); History.push_back(Strdup(command_line));
if (Stricmp(command_line, "CLEAR") == 0)
// Process command TODO: compare command with convar/concommand list else return unknown {
if (Stricmp(command_line, "CLEAR") == 0) { ClearLog(); } ClearLog();
}
else if (Stricmp(command_line, "HELP") == 0) else if (Stricmp(command_line, "HELP") == 0)
{ {
AddLog("Commands:"); AddLog("Commands:");
@ -357,26 +377,12 @@ public:
int first = History.Size - 10; int first = History.Size - 10;
for (int i = first > 0 ? first : 0; i < History.Size; i++) { AddLog("%3d: %s\n", i, History[i]); } for (int i = first > 0 ? first : 0; i < History.Size; i++) { AddLog("%3d: %s\n", i, History[i]); }
} }
//char input[256];
//bool found = false; // On command input, we scroll to bottom even if AutoScroll==false
//while (file.good()) ScrollToBottom = true;
//{
// file >> input;
// if (file.good() && strcmp(input, command_line) == 0)
// {
// bool found = true;
// }
//}
//if (!found)
//{
// AddLog("[WARNING] Unknown command: '%s'\n", command_line);
//}
//// On command input, we scroll to bottom even if AutoScroll==false
//ScrollToBottom = true;
//found = false;
} }
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// History // History
static int TextEditCallbackStub(ImGuiInputTextCallbackData* data) static int TextEditCallbackStub(ImGuiInputTextCallbackData* data)
{ {
@ -384,6 +390,8 @@ public:
return console->TextEditCallback(data); return console->TextEditCallback(data);
} }
///////////////////////////////////////////////////////////////////////////
// Edit
int TextEditCallback(ImGuiInputTextCallbackData* data) int TextEditCallback(ImGuiInputTextCallbackData* data)
{ {
switch (data->EventFlag) switch (data->EventFlag)
@ -428,6 +436,8 @@ public:
} }
}; };
///////////////////////////////////////////////////////////////////////////////
// Entry
void ShowGameConsole(bool* p_open) void ShowGameConsole(bool* p_open)
{ {
static CGameConsole console; static CGameConsole console;

View File

@ -8,7 +8,7 @@
* _utility.cpp * _utility.cpp
*-----------------------------------------------------------------------------*/ *-----------------------------------------------------------------------------*/
///////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
BOOL FileExists(LPCTSTR szPath) BOOL FileExists(LPCTSTR szPath)
{ {
@ -18,7 +18,7 @@ BOOL FileExists(LPCTSTR szPath)
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
} }
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// For getting information about the specified module // For getting information about the specified module
MODULEINFO GetModuleInfo(const char* szModule) MODULEINFO GetModuleInfo(const char* szModule)
{ {
@ -32,7 +32,7 @@ MODULEINFO GetModuleInfo(const char* szModule)
return modinfo; return modinfo;
} }
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// For finding a byte pattern in memory of the game process // For finding a byte pattern in memory of the game process
BOOL Compare(const unsigned char* pData, const unsigned char* szPattern, const char* szMask) BOOL Compare(const unsigned char* pData, const unsigned char* szPattern, const char* szMask)
{ {
@ -62,7 +62,7 @@ DWORD64 FindPattern(const char* szModule, const unsigned char* szPattern, const
return 0; return 0;
} }
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
void DbgPrint(LPCSTR sFormat, ...) void DbgPrint(LPCSTR sFormat, ...)
{ {
@ -80,7 +80,7 @@ void DbgPrint(LPCSTR sFormat, ...)
OutputDebugString(sBuffer); OutputDebugString(sBuffer);
} }
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// For dumping data from a buffer to a file on the disk // For dumping data from a buffer to a file on the disk
void HexDump(const char* szHeader, const char* szFile, const char* szMode, int nFunc, const void* pData, int nSize) void HexDump(const char* szHeader, const char* szFile, const char* szMode, int nFunc, const void* pData, int nSize)
{ {
@ -128,6 +128,6 @@ void HexDump(const char* szHeader, const char* szFile, const char* szMode, int n
} }
} }
} }
///////////////////////////////////////////////////////////////////////////
fclose(sTraceLog); fclose(sTraceLog);
} }

View File

@ -3,8 +3,13 @@
#include <Windows.h> #include <Windows.h>
#include <detours.h> #include <detours.h>
/*-----------------------------------------------------------------------------
* _main.cpp
*-----------------------------------------------------------------------------*/
void PrintLastError() void PrintLastError()
{ {
///////////////////////////////////////////////////////////////////////////
//Get the error message, if any. //Get the error message, if any.
DWORD errorMessageID = ::GetLastError(); DWORD errorMessageID = ::GetLastError();
if (errorMessageID == 0) if (errorMessageID == 0)
@ -27,6 +32,7 @@ bool LaunchR5Apex()
CHAR sCommandDirectory[MAX_PATH]; CHAR sCommandDirectory[MAX_PATH];
LPSTR sCommandLine = sCommandDirectory; LPSTR sCommandLine = sCommandDirectory;
///////////////////////////////////////////////////////////////////////////
// '+exec autoexec -dev -fnf -noplatform' // '+exec autoexec -dev -fnf -noplatform'
fopen_s(&sLaunchParams, "platform\\cfg\\startup_debug.cfg", "r"); fopen_s(&sLaunchParams, "platform\\cfg\\startup_debug.cfg", "r");
@ -39,9 +45,11 @@ bool LaunchR5Apex()
STARTUPINFO StartupInfo = { 0 }; STARTUPINFO StartupInfo = { 0 };
PROCESS_INFORMATION ProcInfo = { 0 }; PROCESS_INFORMATION ProcInfo = { 0 };
///////////////////////////////////////////////////////////////////////////
// Initialize the startup info structure. // Initialize the startup info structure.
StartupInfo.cb = sizeof(STARTUPINFO); StartupInfo.cb = sizeof(STARTUPINFO);
///////////////////////////////////////////////////////////////////////////
// Load command line arguments from a file on the disk. // Load command line arguments from a file on the disk.
if (sLaunchParams) if (sLaunchParams)
{ {
@ -51,10 +59,11 @@ bool LaunchR5Apex()
} }
} }
///////////////////////////////////////////////////////////////////////////
// Format the file paths for the game exe and dll. // Format the file paths for the game exe and dll.
GetCurrentDirectory(MAX_PATH, sGameDirectory); GetCurrentDirectory(MAX_PATH, sGameDirectory);
snprintf(sGameExe, sizeof(sGameExe), "%s\\r5apex.exe", sGameDirectory); snprintf(sGameExe, sizeof(sGameExe), "%s\\r5apex.exe", sGameDirectory);
snprintf(sDevDll, sizeof(sDevDll), "%s\\r5dev.dll", sGameDirectory); snprintf(sDevDll, sizeof(sDevDll), "%s\\r5detours.dll", sGameDirectory);
snprintf(sCommandLine, sizeof(sCommandDirectory), "%s\\r5apex.exe %s", sGameDirectory, sArgumentBuffer); snprintf(sCommandLine, sizeof(sCommandDirectory), "%s\\r5apex.exe %s", sGameDirectory, sArgumentBuffer);
printf("Launching Apex Dev...\n"); printf("Launching Apex Dev...\n");
@ -63,12 +72,14 @@ bool LaunchR5Apex()
printf(" - DLL: %s\n", sDevDll); printf(" - DLL: %s\n", sDevDll);
printf(" - CLI: %s\n", sCommandLine); printf(" - CLI: %s\n", sCommandLine);
///////////////////////////////////////////////////////////////////////////
// Build our list of dlls to inject. // Build our list of dlls to inject.
LPCSTR DllsToInject[1] = LPCSTR DllsToInject[1] =
{ {
sDevDll sDevDll
}; };
///////////////////////////////////////////////////////////////////////////
// Create the game process in a suspended state with our dll. // Create the game process in a suspended state with our dll.
result = DetourCreateProcessWithDllsA( result = DetourCreateProcessWithDllsA(
sGameExe, // lpApplicationName sGameExe, // lpApplicationName
@ -86,16 +97,19 @@ bool LaunchR5Apex()
NULL // pfCreateProcessA NULL // pfCreateProcessA
); );
// Failed to create the game process. ///////////////////////////////////////////////////////////////////////////
// Failed to create the process.
if (!result) if (!result)
{ {
PrintLastError(); PrintLastError();
return false; return false;
} }
///////////////////////////////////////////////////////////////////////////
// Resume the process. // Resume the process.
ResumeThread(ProcInfo.hThread); ResumeThread(ProcInfo.hThread);
///////////////////////////////////////////////////////////////////////////
// Close the process and thread handles. // Close the process and thread handles.
CloseHandle(ProcInfo.hProcess); CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread); CloseHandle(ProcInfo.hThread);
@ -103,9 +117,11 @@ bool LaunchR5Apex()
return true; return true;
} }
///////////////////////////////////////////////////////////////////////////////
// Entry point.
int main(int argc, char* argv[], char* envp[]) int main(int argc, char* argv[], char* envp[])
{ {
LaunchR5Apex(); LaunchR5Apex();
Sleep(1000); Sleep(1000);
return 0; return 0;
} }

View File

@ -51,6 +51,7 @@
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<UseOfMfc>false</UseOfMfc>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
@ -158,8 +159,7 @@
<AdditionalDependencies>detours.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>detours.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
<PostBuildEvent> <PostBuildEvent>
<Command> <Command>del "$(TargetDir)\launcher.exe" &amp;&amp; rename "$(TargetPath)" "launcher.exe"</Command>
</Command>
</PostBuildEvent> </PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>