Skip to content

Commit

Permalink
add rtldg/bunnyhopape stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
rtldg committed Nov 22, 2023
1 parent 2182828 commit 237454d
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 19 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Detours
Debug
Release
.vs
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
## RawInput2
## RawInput2BunnyhopAPE

An external software that ports [momentum mod's](https://momentum-mod.org/) ``m_rawinput 2`` behaviour. This option provides mouse interpolation which will ["line up with the tickrate properly without needing to have a specific framerate"](https://discord.com/channels/235111289435717633/356398721790902274/997026787995435088) (rio). The code for this isn't public and was reverse engineered from the game.


### Because juggling exe's & CS:S launch options is annoying:

Includes **BunnyhopAPE** from [alkatrazbhop](https://github.com/alkatrazbhop/BunnyhopAPE) -> [yupi2](https://github.com/yupi2/BunnyhopAPE) -> [rtldg](https://github.com/rtldg/BunnyhopAPE)
- autohop prediction
- auto-starting CS:S with `-insecure`
- Now with auto-detecting the steam library path!
- fullscreen hook thing

### Usage
* Launch the game in ``-insecure`` mode. (It wont work otherwise!)
* Run the application.
* Make sure to set ``m_rawinput 2`` in game for it to take effect.
* `F5` to toggle autohop prediction
* `F6` to toggle the fullscreen hook thing which keeps the game open in fullscreen when you alt-tab (which is nice if you have two monitors)

### Building requirements
* [Microsoft Detours](https://github.com/microsoft/Detours)
145 changes: 128 additions & 17 deletions RawInput2/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
#include <stdio.h>
#include "utils.h"
Expand Down Expand Up @@ -204,6 +206,20 @@ BOOL IsProcessRunning(DWORD processID)
return ret == WAIT_TIMEOUT;
}

// https://stackoverflow.com/questions/10866311/getmessage-with-a-timeout/10866328#10866328
BOOL GetMessageWithTimeout(MSG* msg, UINT to)
{
BOOL res;
UINT_PTR timerId = SetTimer(NULL, NULL, to, NULL);
res = GetMessage(msg, NULL, 0, 0);
KillTimer(NULL, timerId);
if (!res)
return FALSE;
if (msg->message == WM_TIMER && msg->hwnd == NULL && msg->wParam == timerId)
return FALSE; //TIMEOUT! You could call SetLastError() or something...
return TRUE;
}

DWORD InjectionEntryPoint(DWORD processID)
{
LoadLibraryA("VCRUNTIME140.dll");
Expand All @@ -224,6 +240,20 @@ DWORD InjectionEntryPoint(DWORD processID)

//ConMsg("Plat_FloatTime: %.5f\n", Plat_FloatTime());

BYTE nopBuffer[6] = { 0x90,0x90,0x90,0x90,0x90,0x90 };
BYTE jumpPredOriginalBytes[6];
auto jumpPred = reinterpret_cast<void*>(FindPattern("client.dll", "85 C0 8B 46 08 0F 84 ? FF FF FF F6 40 28 02 0F 85 ? FF FF FF") + 15);
memcpy(jumpPredOriginalBytes, jumpPred, 6);
DWORD jumpPredOriginalProtect;
VirtualProtect(jumpPred, 6, PAGE_EXECUTE_READWRITE, &jumpPredOriginalProtect);
memcpy(jumpPred, nopBuffer, 6);

auto pReleaseVideo = reinterpret_cast<void*>(FindPattern("engine.dll", "56 8B F1 8B 06 8B 40 ? FF D0 84 C0 75 ? 8B 06") + 12);
auto pFUCKD3D9 = reinterpret_cast<void*>(FindPattern("d3d9.dll", "0F 84 ? ? ? ? 6A 07 FF B3"));
DWORD pReleaseVideoOriginalProtect, pFUCKD3D9OriginalProtect;
VirtualProtect(pReleaseVideo, 1, PAGE_EXECUTE_READWRITE, &pReleaseVideoOriginalProtect);
VirtualProtect(pFUCKD3D9, 2, PAGE_EXECUTE_READWRITE, &pFUCKD3D9OriginalProtect);

DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)oGetRawMouseAccumulators, Hooked_GetRawMouseAccumulators);
Expand All @@ -233,12 +263,55 @@ DWORD InjectionEntryPoint(DWORD processID)
DetourAttach(&(PVOID&)oIn_SetSampleTime, Hooked_IN_SetSampleTime);
DetourTransactionCommit();

bool jumpPredPatched = true;
bool fullScreenPatched = false;

RegisterHotKey(NULL, 1, MOD_NOREPEAT, VK_F5);
RegisterHotKey(NULL, 2, MOD_NOREPEAT, VK_F6);

while (IsProcessRunning(processID))
//while(FindWindowA(NULL, "CS:S RawInput2") != 0)
{
Sleep(1000);
MSG msg;
if (GetMessageWithTimeout(&msg, 200))
{
if (msg.message == WM_HOTKEY && msg.wParam == 1)
{
if (jumpPredPatched)
memcpy(jumpPred, jumpPredOriginalBytes, 6);
else
memcpy(jumpPred, nopBuffer, 6);
jumpPredPatched = !jumpPredPatched;
}
else if (msg.message == WM_HOTKEY && msg.wParam == 2)
{
if (fullScreenPatched)
{
memcpy(pReleaseVideo, "\x75", 1);
memcpy(pFUCKD3D9, "\x0F\x84", 2);
}
else
{
memcpy(pReleaseVideo, "\xEB", 1);
memcpy(pFUCKD3D9, "\x90\xE9", 2);
}
fullScreenPatched = !fullScreenPatched;
}
}

//Sleep(55);
}

UnregisterHotKey(NULL, 1);
UnregisterHotKey(NULL, 2);

memcpy(pReleaseVideo, "\x75", 1);
memcpy(pFUCKD3D9, "\x0F\x84", 2);
VirtualProtect(pReleaseVideo, 1, pReleaseVideoOriginalProtect, &pReleaseVideoOriginalProtect);
VirtualProtect(pFUCKD3D9, 2, pFUCKD3D9OriginalProtect, &pFUCKD3D9OriginalProtect);
memcpy(jumpPred, jumpPredOriginalBytes, 6);
VirtualProtect(jumpPred, 6, jumpPredOriginalProtect, &jumpPredOriginalProtect);

DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)oGetRawMouseAccumulators, Hooked_GetRawMouseAccumulators);
Expand Down Expand Up @@ -302,21 +375,54 @@ void PEInjector(DWORD processID, DWORD Func(DWORD))
CreateRemoteThread(targetProcess, NULL, 0, (LPTHREAD_START_ROUTINE)((DWORD_PTR)Func + deltaImageBase), (LPVOID)GetCurrentProcessId(), 0, NULL);
}

//Сredits: https://github.com/alkatrazbhop/BunnyhopAPE
int main()
// Assumes the libraryfolders.vdf is "well formed"
std::string GetCSSPath()
{
SetConsoleTitle("CS:S RawInput2");

DWORD processID;
printf("Waiting for CS:S to start...");
while (1)
HKEY key;
RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Valve\\Steam", &key);
char buf[256];
DWORD size = sizeof(buf) / sizeof(buf[0]);
RegQueryValueExA(key, "InstallPath", 0, NULL, (BYTE*)buf, &size);
auto steampath = std::string(buf);

std::ifstream libraryfolders(steampath + "\\steamapps\\libraryfolders.vdf");
std::string line, css_path, library_path;
while (std::getline(libraryfolders, line))
{
processID = GetPIDByName("hl2.exe");
if (processID) break;
Sleep(1000);
#define PPPPP "\t\t\"path\"\t\t\""
if (line.rfind(PPPPP, 0) == 0)
{
library_path = line.substr(sizeof(PPPPP) - 1, line.size() - sizeof(PPPPP));
}
if (line.rfind("\t\t\t\"240\"", 0) == 0)
{
css_path = library_path;
break;
}
}
if (css_path != "")
css_path += "\\steamapps\\common\\Counter-Strike Source\\";
return css_path;
}

HANDLE g_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
//Сredits: https://github.com/alkatrazbhop/BunnyhopAPE
int main()
{
SetConsoleTitle("CS:S RawInput2 + BunnyhopAPE");

auto css_path = GetCSSPath();
auto css_exe = css_path + "hl2.exe";
#if 1
char launch_options[] = "-steam -game cstrike -insecure -novid -console";
#else
char launch_options[] = "-steam -game cstrike -insecure -novid";
#endif
PROCESS_INFORMATION pi = {};
STARTUPINFOA si = {};
CreateProcessA(css_exe.c_str(), launch_options, NULL, NULL, FALSE, 0, NULL, css_path.c_str(), &si, &pi);

HANDLE g_hProcess = pi.hProcess;
DWORD processID = pi.dwProcessId;

while (1)
{
Expand All @@ -331,16 +437,21 @@ int main()
ReadProcessMemory(g_hProcess, pCmdLine, &pCmdLine, sizeof(DWORD), NULL);
ReadProcessMemory(g_hProcess, pCmdLine, &pCmdLine, sizeof(DWORD), NULL);
ReadProcessMemory(g_hProcess, pCmdLine, cmdLine, 255, NULL);
CloseHandle(g_hProcess);
if (!strstr(cmdLine, " -insecure"))
Error("-insecure key is missing!");

system("cls");
printf("Set \"m_rawinput 2\" in game for it to take effect.\n");
printf("Set \"m_rawinput 2\" in game for it to take effect\n\nPress F5 to toggle BunnyhopAPE autobhop prediction (on by default)\nPress F6 to toggle the fullscreen hook (you probably don't want this)\n");

PEInjector(processID, InjectionEntryPoint);


while (_getch() != VK_RETURN) {}
return false;
while (1)
{
if (WaitForSingleObject(g_hProcess, 0) != WAIT_TIMEOUT)
return 0;
if (_kbhit() && _getch() != VK_RETURN)
return 0;
Sleep(500);
}
return 0;
}

0 comments on commit 237454d

Please sign in to comment.