From 66b2bc177853d33f4559eb240fbbca354b173fa2 Mon Sep 17 00:00:00 2001 From: jbzdarkid Date: Tue, 5 Nov 2019 10:01:52 -0800 Subject: All set... time to wire up actual randomizer --- Source/Memory.cpp | 106 +++++++++++++++++++++++++++++++------------------- Source/Memory.h | 15 +++++-- Source/Source.vcxproj | 2 + 3 files changed, 79 insertions(+), 44 deletions(-) (limited to 'Source') diff --git a/Source/Memory.cpp b/Source/Memory.cpp index b0e2e9d..7b4b9c7 100644 --- a/Source/Memory.cpp +++ b/Source/Memory.cpp @@ -2,25 +2,87 @@ #include #include #include +#include #include #undef PROCESSENTRY32 #undef Process32Next +Memory::Memory(const std::wstring& processName) : _processName(processName) { +} + +Memory::~Memory() { + if (_threadActive) { + _threadActive = false; + _thread.join(); + } + if (_handle != nullptr) { + CloseHandle(_handle); + } +} + +void Memory::StartHeartbeat(HWND window, std::chrono::milliseconds beat) { + if (_threadActive) return; + _threadActive = true; + _thread = std::thread([sharedThis = shared_from_this(), window, beat]{ + while (sharedThis->_threadActive) { + sharedThis->Heartbeat(window); + std::this_thread::sleep_for(beat); + } + }); + _thread.detach(); +} + +void Memory::Heartbeat(HWND window) { + if (!_handle && !Initialize()) { + // Couldn't initialize, definitely not running + PostMessage(window, WM_COMMAND, HEARTBEAT, (LPARAM)ProcStatus::NotRunning); + return; + } + + DWORD exitCode = 0; + assert(_handle); + GetExitCodeProcess(_handle, &exitCode); + if (exitCode != STILL_ACTIVE) { + // Process has exited, clean up. + _computedAddresses.clear(); + _handle = NULL; + PostMessage(window, WM_COMMAND, HEARTBEAT, (LPARAM)ProcStatus::NotRunning); + return; + } + +#if GLOBALS == 0x5B28C0 + int currentFrame = ReadData({0x5BE3B0}, 1)[0]; +#elif GLOBALS == 0x62D0A0 + int currentFrame = ReadData({0x63954C}, 1)[0]; +#endif + int frameDelta = currentFrame - _previousFrame; + _previousFrame = currentFrame; + if (frameDelta < 0 && currentFrame < 250) { + PostMessage(window, WM_COMMAND, HEARTBEAT, (LPARAM)ProcStatus::NewGame); + return; + } + + // TODO: Some way to return ProcStatus::Randomized vs ProcStatus::NotRandomized vs ProcStatus::DeRandomized; + + PostMessage(window, WM_COMMAND, HEARTBEAT, (LPARAM)ProcStatus::Running); +} + + [[nodiscard]] -bool Memory::Initialize(const std::wstring& processName) { +bool Memory::Initialize() { // First, get the handle of the process PROCESSENTRY32W entry; entry.dwSize = sizeof(entry); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); while (Process32NextW(snapshot, &entry)) { - if (processName == entry.szExeFile) { + if (_processName == entry.szExeFile) { _handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); break; } } if (!_handle) { - std::cerr << "Couldn't find " << processName.c_str() << ", is it open?" << std::endl; + std::cerr << "Couldn't find " << _processName.c_str() << ", is it open?" << std::endl; return false; } @@ -33,7 +95,7 @@ bool Memory::Initialize(const std::wstring& processName) { for (DWORD i = 0; i < numModules / sizeof(HMODULE); i++) { int length = GetModuleBaseNameW(_handle, moduleList[i], &name[0], static_cast(name.size())); name.resize(length); - if (processName == name) { + if (_processName == name) { _baseAddress = (uintptr_t)moduleList[i]; break; } @@ -45,42 +107,6 @@ bool Memory::Initialize(const std::wstring& processName) { return true; } -ProcStatus Memory::Heartbeat(const std::wstring& processName) { - if (!_handle && !Initialize(processName)) { - // Couldn't initialize, definitely not running - return ProcStatus::NotRunning; - } - - DWORD exitCode = 0; - GetExitCodeProcess(_handle, &exitCode); - if (exitCode != STILL_ACTIVE) { - // Process has exited, clean up. - _computedAddresses.clear(); - _handle = NULL; - return ProcStatus::NotRunning; - } - - int currentFrame = 0x7FFFFFFF; - if (GLOBALS == 0x5B28C0) { - currentFrame = ReadData({0x5BE3B0}, 1)[0]; - } else if (GLOBALS == 0x62D0A0) { - currentFrame = ReadData({0x63954C}, 1)[0]; - } else { - assert(false); - } - if (currentFrame < 80) return ProcStatus::NewGame; - - // TODO: Some way to return ProcStatus::Randomized vs ProcStatus::NotRandomized vs ProcStatus::DeRandomized; - - return ProcStatus::Running; -} - -Memory::~Memory() { - if (_handle != nullptr) { - CloseHandle(_handle); - } -} - void Memory::AddSigScan(const std::vector& scanBytes, const std::function& scanFunc) { _sigScans[scanBytes] = {scanFunc, false}; diff --git a/Source/Memory.h b/Source/Memory.h index d7552c5..c19d92b 100644 --- a/Source/Memory.h +++ b/Source/Memory.h @@ -1,12 +1,14 @@ #pragma once #include #include +#include #include #include // #define GLOBALS 0x5B28C0 #define GLOBALS 0x62D0A0 +#define HEARTBEAT 0x401 enum class ProcStatus { NotRunning, Running, @@ -17,11 +19,11 @@ enum class ProcStatus { // http://stackoverflow.com/q/32798185 // http://stackoverflow.com/q/36018838 // http://stackoverflow.com/q/1387064 -class Memory { +class Memory final : public std::enable_shared_from_this { public: - Memory() = default; - ProcStatus Heartbeat(const std::wstring& processName); + Memory(const std::wstring& processName); ~Memory(); + void StartHeartbeat(HWND window, std::chrono::milliseconds beat = std::chrono::milliseconds(1000)); Memory(const Memory& memory) = delete; Memory& operator=(const Memory& other) = delete; @@ -74,10 +76,15 @@ private: ThrowError(); } - bool Initialize(const std::wstring& processName); + void Heartbeat(HWND window); + bool Initialize(); void ThrowError(); void* ComputeOffset(std::vector offsets); + int _previousFrame = 0; + bool _threadActive = false; + std::thread _thread; + std::wstring _processName; std::map _computedAddresses; uintptr_t _baseAddress = 0; HANDLE _handle = nullptr; diff --git a/Source/Source.vcxproj b/Source/Source.vcxproj index 3e66f83..e7f716c 100644 --- a/Source/Source.vcxproj +++ b/Source/Source.vcxproj @@ -158,9 +158,11 @@ + + -- cgit 1.4.1