From d706955846e071c1fc874a018fdfcd0c6e15af17 Mon Sep 17 00:00:00 2001 From: tucucu Date: Sun, 5 Nov 2023 21:06:17 +0100 Subject: [PATCH 1/5] move memory read to its own thread --- memory-external/classes/vector.hpp | 34 +---- memory-external/hacks/hack.hpp | 172 ++++-------------------- memory-external/hacks/reader.cpp | 172 ++++++++++++++++++++++++ memory-external/hacks/reader.hpp | 64 +++++++++ memory-external/main.cpp | 54 ++++---- memory-external/memory-external.vcxproj | 2 + 6 files changed, 297 insertions(+), 201 deletions(-) create mode 100644 memory-external/hacks/reader.cpp create mode 100644 memory-external/hacks/reader.hpp diff --git a/memory-external/classes/vector.hpp b/memory-external/classes/vector.hpp index cc28660..64c5377 100644 --- a/memory-external/classes/vector.hpp +++ b/memory-external/classes/vector.hpp @@ -1,17 +1,9 @@ #pragma once +#ifndef _VECTOR_ESP_ +#define _VECTOR_ESP_ #include #include -#include "globals.hpp" - -struct view_matrix_t { - float* operator[ ](int index) { - return matrix[index]; - } - - float matrix[4][4]; -}; - struct Vector3 { // constructor @@ -80,25 +72,6 @@ struct Vector3 return x == 0.f && y == 0.f && z == 0.f; } - Vector3 world_to_screen(view_matrix_t matrix) const { - float _x = matrix[0][0] * x + matrix[0][1] * y + matrix[0][2] * z + matrix[0][3]; - float _y = matrix[1][0] * x + matrix[1][1] * y + matrix[1][2] * z + matrix[1][3]; - - float w = matrix[3][0] * x + matrix[3][1] * y + matrix[3][2] * z + matrix[3][3]; - - float inv_w = 1.f / w; - _x *= inv_w; - _y *= inv_w; - - float x = g::gameBounds.right * .5f; - float y = g::gameBounds.bottom * .5f; - - x += 0.5f * _x * g::gameBounds.right + 0.5f; - y -= 0.5f * _y * g::gameBounds.bottom + 0.5f; - - return { x, y, w }; - } - float calculate_distance(const Vector3& point) const { float dx = point.x - x; float dy = point.y - y; @@ -109,4 +82,5 @@ struct Vector3 // struct data float x, y, z; -}; \ No newline at end of file +}; +#endif \ No newline at end of file diff --git a/memory-external/hacks/hack.hpp b/memory-external/hacks/hack.hpp index 988a924..37f53bb 100644 --- a/memory-external/hacks/hack.hpp +++ b/memory-external/hacks/hack.hpp @@ -1,48 +1,20 @@ #include #include -#include "../memory/memory.hpp" -#include "../classes/globals.hpp" +#include "reader.hpp" #include "../classes/render.hpp" #include "../classes/config.hpp" +#include "../classes/globals.hpp" namespace hack { - std::shared_ptr process; - ProcessModule base_client; - ProcessModule base_engine; void loop() { - const view_matrix_t view_matrix = process->read(base_client.base + updater::offsets::dwViewMatrix); - const uintptr_t entity_list = process->read(base_client.base + updater::offsets::dwEntityList); - - const uintptr_t localPlayer = process->read(base_client.base + updater::offsets::dwLocalPlayer); - if (!localPlayer) - return; - - const int localTeam = process->read(localPlayer + updater::offsets::m_iTeamNum); - const std::uint32_t localPlayerPawn = process->read(localPlayer + updater::offsets::m_hPlayerPawn); - if (!localPlayerPawn) - return; - - const uintptr_t localList_entry2 = process->read(entity_list + 0x8 * ((localPlayerPawn & 0x7FFF) >> 9) + 16); - const uintptr_t localpCSPlayerPawn = process->read(localList_entry2 + 120 * (localPlayerPawn & 0x1FF)); - if (!localpCSPlayerPawn) - return; - - const Vector3 localOrigin = process->read(localpCSPlayerPawn + updater::offsets::m_vecOrigin); - - bool c4IsPlanted = process->read(base_client.base + updater::offsets::dwPlantedC4 - 0x8); - if (c4IsPlanted) + if (g_game.isC4Planted) { - const uintptr_t planted_c4 = process->read(process->read(base_client.base + updater::offsets::dwPlantedC4)); - - const uintptr_t c4Node = process->read(planted_c4 + updater::offsets::m_pGameSceneNode); - - const Vector3 c4Origin = process->read(c4Node + updater::offsets::m_vecAbsOrigin); - - const Vector3 c4ScreenPos = c4Origin.world_to_screen(view_matrix); + Vector3 c4Origin = g_game.c4.get_origin(); + const Vector3 c4ScreenPos = g_game.world_to_screen(&c4Origin); if (c4ScreenPos.z >= 0.01f) { - float c4Distance = localOrigin.calculate_distance(c4Origin); + float c4Distance = g_game.localOrigin.calculate_distance(c4Origin); float c4RoundedDistance = std::round(c4Distance / 500.f); float height = 10 - c4RoundedDistance; @@ -76,71 +48,10 @@ namespace hack { * * (This could have been done by getting a entity list count from the engine, but I'm too lazy to do that) **/ - while (true) { - playerIndex++; - list_entry = process->read(entity_list + (8 * (playerIndex & 0x7FFF) >> 9) + 16); - if (!list_entry) - break; - - const uintptr_t player = process->read(list_entry + 120 * (playerIndex & 0x1FF)); - if (!player) - continue; - - /** - * Skip rendering your own character and teammates - * - * If you really want you can exclude your own character from the check but - * since you are in the same team as yourself it will be excluded anyway - **/ - const int playerTeam = process->read(player + updater::offsets::m_iTeamNum); - if (config::team_esp && (playerTeam == localTeam)) - continue; - - const std::uint32_t playerPawn = process->read(player + updater::offsets::m_hPlayerPawn); - - const uintptr_t list_entry2 = process->read(entity_list + 0x8 * ((playerPawn & 0x7FFF) >> 9) + 16); - if (!list_entry2) - continue; - - const uintptr_t pCSPlayerPawn = process->read(list_entry2 + 120 * (playerPawn & 0x1FF)); - if (!pCSPlayerPawn) - continue; - - const int playerHealth = process->read(pCSPlayerPawn + updater::offsets::m_iHealth); - const int playerArmor = process->read(pCSPlayerPawn + updater::offsets::m_ArmorValue); - if (playerHealth <= 0 || playerHealth > 100) - continue; - - if (config::team_esp && (pCSPlayerPawn == localPlayer)) - continue; - - std::string playerName = "Invalid Name"; - const DWORD64 playerNameAddress = process->read(player + updater::offsets::m_sSanitizedPlayerName); - if (playerNameAddress) { - char buf[256]; - process->read_raw(playerNameAddress, buf, sizeof(buf)); - playerName = std::string(buf); - } - - const Vector3 origin = process->read(pCSPlayerPawn + updater::offsets::m_vecOrigin); - const Vector3 head = { origin.x, origin.y, origin.z + 75.f }; - - if (origin.x == localOrigin.x && origin.y == localOrigin.y && origin.z == localOrigin.z) - continue; - - const uintptr_t gamescene = process->read(pCSPlayerPawn + 0x310); - const uintptr_t bonearray = process->read(gamescene + 0x160 + 0x80); - const Vector3 headPos = process->read(bonearray + 6 * 32); - - if (config::render_distance != -1 && (localOrigin - origin).length2d() > config::render_distance) - continue; - - if (origin.x == 0 && origin.y == 0) - continue; - - const Vector3 screenPos = origin.world_to_screen(view_matrix); - const Vector3 screenHead = head.world_to_screen(view_matrix); - const Vector3 screenHeadPos = headPos.world_to_screen(view_matrix); + for (auto player = g_game.players.begin(); player < g_game.players.end(); player++) { + const Vector3 screenPos = g_game.world_to_screen(&player->origin); + const Vector3 screenHead = g_game.world_to_screen(&player->head); + const Vector3 screenHeadPos = g_game.world_to_screen(&player->skull); if (screenPos.z >= 0.01f) { const float height = screenPos.y - screenHead.y; @@ -148,7 +59,7 @@ namespace hack { const float head_height = (screenHeadPos.y - screenHeadPos.y) / 8; const float head_width = (head_height / 2.4f) / 4; - float distance = localOrigin.calculate_distance(origin); + float distance = g_game.localOrigin.calculate_distance(player->origin); int roundedDistance = std::round(distance / 10.f); render::DrawCircle( @@ -165,27 +76,27 @@ namespace hack { screenHead.y, width, height, - (localTeam == playerTeam ? config::esp_box_color_team : config::esp_box_color_enemy) + (g_game.localTeam == player->team ? config::esp_box_color_team : config::esp_box_color_enemy) ); render::DrawBorderBox( g::hdcBuffer, screenHead.x - (width / 2 + 10), - screenHead.y + (height * (100 - playerArmor) / 100), + screenHead.y + (height * (100 - player->armor) / 100), 2, - height - (height * (100 - playerArmor) / 100), + height - (height * (100 - player->armor) / 100), RGB(0, 185, 255) ); render::DrawBorderBox( g::hdcBuffer, screenHead.x - (width / 2 + 5), - screenHead.y + (height * (100 - playerHealth) / 100), + screenHead.y + (height * (100 - player->health) / 100), 2, - height - (height * (100 - playerHealth) / 100), + height - (height * (100 - player->health) / 100), RGB( - (255 - playerHealth), - (55 + playerHealth * 2), + (255 - player->health), + (55 + player->health * 2), 75 ) ); @@ -194,7 +105,7 @@ namespace hack { g::hdcBuffer, screenHead.x + (width / 2 + 5), screenHead.y, - playerName.c_str(), + player->name.c_str(), config::esp_name_color, 10 ); @@ -209,10 +120,10 @@ namespace hack { g::hdcBuffer, screenHead.x + (width / 2 + 5), screenHead.y + 10, - (std::to_string(playerHealth) + "hp").c_str(), + (std::to_string(player->health) + "hp").c_str(), RGB( - (255 - playerHealth), - (55 + playerHealth * 2), + (255 - player->health), + (55 + player->health * 2), 75 ), 10 @@ -222,10 +133,10 @@ namespace hack { g::hdcBuffer, screenHead.x + (width / 2 + 5), screenHead.y + 20, - (std::to_string(playerArmor) + "armor").c_str(), + (std::to_string(player->armor) + "armor").c_str(), RGB( - (255 - playerArmor), - (55 + playerArmor * 2), + (255 - player->armor), + (55 + player->armor * 2), 75 ), 10 @@ -233,36 +144,11 @@ namespace hack { if (config::show_extra_flags) { - /* - * Reading values for extra flags is now seperated from the other reads - * This removes unnecessary memory reads, improving performance when not showing extra flags - */ - const bool isDefusing = process->read(pCSPlayerPawn + updater::offsets::m_bIsDefusing); - const uintptr_t playerMoneyServices = process->read(player + updater::offsets::m_pInGameMoneyServices); - const int32_t money = process->read(playerMoneyServices + updater::offsets::m_iAccount); - const float flashAlpha = process->read(pCSPlayerPawn + updater::offsets::m_flFlashOverlayAlpha); - - const auto clippingWeapon = process->read(pCSPlayerPawn + updater::offsets::m_pClippingWeapon); - const auto weaponData = process->read(clippingWeapon + 0x360); - const auto weaponNameAddress = process->read(weaponData + updater::offsets::m_szName); - std::string weaponName = "Invalid Weapon Name"; - - if (!weaponNameAddress) { - weaponName = "Invalid Weapon Name"; - } - else { - char buf[32]; - process->read_raw(weaponNameAddress, buf, sizeof(buf)); - weaponName = std::string(buf); - if (weaponName.compare(0, 7, "weapon_") == 0) - weaponName = weaponName.substr(7, weaponName.length()); // Remove weapon_ prefix - } - render::RenderText( g::hdcBuffer, screenHead.x + (width / 2 + 5), screenHead.y + 30, - weaponName.c_str(), + player->weapon.c_str(), config::esp_distance_color, 10 ); @@ -280,12 +166,12 @@ namespace hack { g::hdcBuffer, screenHead.x + (width / 2 + 5), screenHead.y + 50, - ("$" + std::to_string(money)).c_str(), + ("$" + std::to_string(player->money)).c_str(), RGB(0, 125, 0), 10 ); - if (flashAlpha > 100) + if (player->flashAlpha > 100) { render::RenderText( g::hdcBuffer, @@ -297,7 +183,7 @@ namespace hack { ); } - if (isDefusing) + if (player->is_defusing) { const std::string defuText = "Player is defusing"; render::RenderText( diff --git a/memory-external/hacks/reader.cpp b/memory-external/hacks/reader.cpp new file mode 100644 index 0000000..805bc17 --- /dev/null +++ b/memory-external/hacks/reader.cpp @@ -0,0 +1,172 @@ +#include "reader.hpp" +#include +#include "../classes/auto_updater.hpp" +#include "../classes/config.hpp" + +// CC4 +uintptr_t CC4::get_planted() { + return g_game.process->read(g_game.process->read(g_game.base_client.base + updater::offsets::dwPlantedC4)); +} + +uintptr_t CC4::get_node() { + return g_game.process->read(get_planted() + updater::offsets::m_pGameSceneNode); +} + +Vector3 CC4::get_origin() { + return g_game.process->read(get_node() + updater::offsets::m_vecAbsOrigin); +} + +// CGame +void CGame::init() { + std::cout << "[cs2] Waiting for cs2.exe..." << std::endl; + + process = std::make_shared(); + while (!process->AttachProcessHj("cs2.exe")) + std::this_thread::sleep_for(std::chrono::seconds(1)); + + std::cout << "[cs2] Attached to cs2.exe\n" << std::endl; + + do { + base_client = process->GetModule("client.dll"); + base_engine = process->GetModule("engine2.dll"); + if (base_client.base == 0 || base_engine.base == 0) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + std::cout << "[cs2] Failed to find module client.dll/engine2.dll, waiting for the game to load it..." << std::endl; + } + } while (base_client.base == 0 || base_engine.base == 0); + + GetClientRect(g_game.process->hwnd_, &game_bounds); + + buildNumber = process->read(base_engine.base + updater::offsets::dwBuildNumber); +} + +void CGame::loop() { + inGame = false; + isC4Planted = false; + + localPlayer = process->read(base_client.base + updater::offsets::dwLocalPlayer); + if (!localPlayer) return; + + localPlayerPawn = process->read(localPlayer + updater::offsets::m_hPlayerPawn); + if (!localPlayerPawn) return; + + entity_list = process->read(base_client.base + updater::offsets::dwEntityList); + + const uintptr_t localList_entry2 = process->read(entity_list + 0x8 * ((localPlayerPawn & 0x7FFF) >> 9) + 16); + const uintptr_t localpCSPlayerPawn = process->read(localList_entry2 + 120 * (localPlayerPawn & 0x1FF)); + if (!localpCSPlayerPawn) return; + + view_matrix = process->read(base_client.base + updater::offsets::dwViewMatrix); + + localTeam = process->read(localPlayer + updater::offsets::m_iTeamNum); + localOrigin = process->read(localpCSPlayerPawn + updater::offsets::m_vecOrigin); + isC4Planted = process->read(g_game.base_client.base + updater::offsets::dwPlantedC4 - 0x8); + + inGame = true; + int playerIndex = 0; + std::vector list; + + while (true) { + playerIndex++; + uintptr_t list_entry = process->read(entity_list + (8 * (playerIndex & 0x7FFF) >> 9) + 16); + if (!list_entry) break; + + CPlayer player; + + player.entity = process->read(list_entry + 120 * (playerIndex & 0x1FF)); + if (!player.entity) continue; + + /** + * Skip rendering your own character and teammates + * + * If you really want you can exclude your own character from the check but + * since you are in the same team as yourself it will be excluded anyway + **/ + player.team = process->read(player.entity + updater::offsets::m_iTeamNum); + if (config::team_esp && (player.team == localTeam)) continue; + + const std::uint32_t playerPawn = process->read(player.entity + updater::offsets::m_hPlayerPawn); + + const uintptr_t list_entry2 = process->read(entity_list + 0x8 * ((playerPawn & 0x7FFF) >> 9) + 16); + if (!list_entry2) continue; + + player.pCSPlayerPawn = process->read(list_entry2 + 120 * (playerPawn & 0x1FF)); + if (!player.pCSPlayerPawn) continue; + + player.health = process->read(player.pCSPlayerPawn + updater::offsets::m_iHealth); + player.armor = process->read(player.pCSPlayerPawn + updater::offsets::m_ArmorValue); + if (player.health <= 0 || player.health > 100) continue; + + if (config::team_esp && (player.pCSPlayerPawn == localPlayer)) continue; + + player.name = read_string(player.entity + updater::offsets::m_sSanitizedPlayerName); + + player.origin = process->read(player.pCSPlayerPawn + updater::offsets::m_vecOrigin); + player.head = { player.origin.x, player.origin.y, player.origin.z + 75.f }; + + if (player.origin.x == localOrigin.x && player.origin.y == localOrigin.y && player.origin.z == localOrigin.z) + continue; + + if (config::render_distance != -1 && (localOrigin - player.origin).length2d() > config::render_distance) continue; + if (player.origin.x == 0 && player.origin.y == 0) continue; + + const uintptr_t gamescene = process->read(player.pCSPlayerPawn + 0x310); + const uintptr_t bonearray = process->read(gamescene + 0x160 + 0x80); + player.skull = process->read(bonearray + 6 * 32); + + if (config::show_extra_flags) { + /* + * Reading values for extra flags is now seperated from the other reads + * This removes unnecessary memory reads, improving performance when not showing extra flags + */ + player.is_defusing = process->read(player.pCSPlayerPawn + updater::offsets::m_bIsDefusing); + + const uintptr_t playerMoneyServices = process->read(player.entity + updater::offsets::m_pInGameMoneyServices); + player.money = process->read(playerMoneyServices + updater::offsets::m_iAccount); + + player.flashAlpha = process->read(player.pCSPlayerPawn + updater::offsets::m_flFlashOverlayAlpha); + + const auto clippingWeapon = process->read(player.pCSPlayerPawn + updater::offsets::m_pClippingWeapon); + const auto weaponData = process->read(clippingWeapon + 0x360); + std::string weaponName = read_string(weaponData + updater::offsets::m_szName); + if (weaponName.compare(0, 7, "weapon_") == 0) + player.weapon = weaponName.substr(7, weaponName.length()); // Remove weapon_ prefix + else + player.weapon = "Invalid Weapon Name"; + } + + list.push_back(player); + } + + players.clear(); + players.assign(list.begin(), list.end()); +} + +std::string CGame::read_string(uintptr_t addr) { + const DWORD64 address = g_game.process->read(addr); + if (address) { + char buffer[256]; + process->read_raw(address, buffer, sizeof(buffer)); + return std::string(buffer); + } + return "invalid"; +} + +Vector3 CGame::world_to_screen(Vector3* v) { + float _x = view_matrix[0][0] * v->x + view_matrix[0][1] * v->y + view_matrix[0][2] * v->z + view_matrix[0][3]; + float _y = view_matrix[1][0] * v->x + view_matrix[1][1] * v->y + view_matrix[1][2] * v->z + view_matrix[1][3]; + + float w = view_matrix[3][0] * v->x + view_matrix[3][1] * v->y + view_matrix[3][2] * v->z + view_matrix[3][3]; + + float inv_w = 1.f / w; + _x *= inv_w; + _y *= inv_w; + + float x = game_bounds.right * .5f; + float y = game_bounds.bottom * .5f; + + x += 0.5f * _x * game_bounds.right + 0.5f; + y -= 0.5f * _y * game_bounds.bottom + 0.5f; + + return { x, y, w }; +} diff --git a/memory-external/hacks/reader.hpp b/memory-external/hacks/reader.hpp new file mode 100644 index 0000000..c7f38fe --- /dev/null +++ b/memory-external/hacks/reader.hpp @@ -0,0 +1,64 @@ +#pragma once +#include "../memory/memory.hpp" +#include "../classes/vector.hpp" + +struct view_matrix_t { + float* operator[ ](int index) { + return matrix[index]; + } + + float matrix[4][4]; +}; + +class CC4 { +public: + uintptr_t get_planted(); + uintptr_t get_node(); + Vector3 get_origin(); +}; + +class CPlayer { +public: + uintptr_t entity; + int team; + uintptr_t pCSPlayerPawn; + int health; + int armor; + std::string name; + Vector3 origin; + Vector3 head; + Vector3 skull; + bool is_defusing; + int32_t money; + float flashAlpha; + std::string weapon; +}; + +class CGame +{ +public: + std::shared_ptr process; + ProcessModule base_client; + ProcessModule base_engine; + RECT game_bounds; + uintptr_t buildNumber; + bool inGame; + Vector3 localOrigin; + bool isC4Planted; + int localTeam; + CC4 c4; + std::vector players = {}; + void init(); + void loop(); + Vector3 world_to_screen(Vector3* v); +private: + view_matrix_t view_matrix; + uintptr_t entity_list; + uintptr_t localPlayer; + std::uint32_t localPlayerPawn; + uintptr_t localList_entry2; + uintptr_t localpCSPlayerPawn; + std::string read_string(uintptr_t addr); +}; + +inline CGame g_game; \ No newline at end of file diff --git a/memory-external/main.cpp b/memory-external/main.cpp index 99d9bd7..e65a652 100644 --- a/memory-external/main.cpp +++ b/memory-external/main.cpp @@ -5,11 +5,14 @@ #include "memory/memory.hpp" #include "classes/vector.hpp" +#include "hacks/reader.hpp" #include "hacks/hack.hpp" #include "classes/globals.hpp" #include "classes/render.hpp" #include "classes/auto_updater.hpp" +bool finish = false; + LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) @@ -39,7 +42,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) FillRect(g::hdcBuffer, &ps.rcPaint, (HBRUSH)GetStockObject(WHITE_BRUSH)); - if (GetForegroundWindow() == hack::process->hwnd_) { + if (GetForegroundWindow() == g_game.process->hwnd_) { //render::RenderText(g::hdcBuffer, 10, 10, "cs2 | ESP", RGB(75, 175, 175), 15); hack::loop(); } @@ -62,13 +65,18 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) return 0; } +void read_thread() { + while (!finish) { + g_game.loop(); + std::this_thread::sleep_for(std::chrono::milliseconds(2)); + } +} + int main() { SetConsoleTitle("cs2-external-esp"); std::cout << "[info] Github Repository: https://github.com/IMXNOOBX/cs2-external-esp" << std::endl; std::cout << "[info] Unknowncheats thread: https://www.unknowncheats.me/forum/counter-strike-2-releases/600259-cs2-external-esp.html\n" << std::endl; - hack::process = std::make_shared(); - std::cout << "[config] Reading configuration." << std::endl; if (config::read()) std::cout << "[updater] Sucessfully read configuration file\n" << std::endl; @@ -79,30 +87,15 @@ int main() { updater::check_and_update(config::automatic_update); #endif - std::cout << "[cs2] Waiting for cs2.exe..." << std::endl; - - while (!hack::process->AttachProcessHj("cs2.exe")) - std::this_thread::sleep_for(std::chrono::seconds(1)); - - std::cout << "[cs2] Attached to cs2.exe\n" << std::endl; - std::cout << "[updater] Reading offsets from file offsets.json." << std::endl; if (updater::read()) std::cout << "[updater] Sucessfully read offsets file\n" << std::endl; else std::cout << "[updater] Error reading offsets file, reseting to the default state\n" << std::endl; - do { - hack::base_client = hack::process->GetModule("client.dll"); - hack::base_engine = hack::process->GetModule("engine2.dll"); - if (hack::base_client.base == 0 || hack::base_engine.base == 0) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - std::cout << "[cs2] Failed to find module client.dll/engine2.dll, waiting for the game to load it..." << std::endl; - } - } while (hack::base_client.base == 0 || hack::base_engine.base == 0); + g_game.init(); - const uintptr_t buildNumber = hack::process->read(hack::base_engine.base + updater::offsets::dwBuildNumber); - if (buildNumber != updater::build_number) { + if (g_game.buildNumber != updater::build_number) { std::cout << "[cs2] Build number doesnt match, the game has been updated and this esp most likely wont work." << std::endl; std::cout << "[warn] If the esp doesnt work, consider updating offsets manually in the file offsets.json" << std::endl; std::cout << "[cs2] Press any key to continue" << std::endl; @@ -114,10 +107,10 @@ int main() { std::cout << "[overlay] Waiting to focus game to create the overlay..." << std::endl; std::cout << "[overlay] Make sure your game is in \"Full Screen Windowed\"" << std::endl; - while (GetForegroundWindow() != hack::process->hwnd_) { + while (GetForegroundWindow() != g_game.process->hwnd_) { std::this_thread::sleep_for(std::chrono::seconds(1)); - hack::process->UpdateHWND(); - ShowWindow(hack::process->hwnd_, TRUE); + g_game.process->UpdateHWND(); + ShowWindow(g_game.process->hwnd_, TRUE); } std::cout << "[overlay] Creating window overlay..." << std::endl; @@ -126,13 +119,13 @@ int main() { wc.lpfnWndProc = WndProc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.hbrBackground = WHITE_BRUSH; - wc.hInstance = reinterpret_cast(GetWindowLongA(hack::process->hwnd_, (-6))); // GWL_HINSTANCE)); + wc.hInstance = reinterpret_cast(GetWindowLongA(g_game.process->hwnd_, (-6))); // GWL_HINSTANCE)); wc.lpszMenuName = " "; wc.lpszClassName = " "; RegisterClassExA(&wc); - GetClientRect(hack::process->hwnd_, &g::gameBounds); + GetClientRect(g_game.process->hwnd_, &g::gameBounds); // Create the window HINSTANCE hInstance = NULL; @@ -146,6 +139,9 @@ int main() { ShowWindow(hWnd, TRUE); //SetActiveWindow(hack::process->hwnd_); + // Launch game memory reading thread + std::thread read(read_thread); + #ifndef _UC std::cout << "\n[settings] In Game keybinds:\n\t[F5] enable/disable Team ESP\n\t[F6] enable/disable automatic updates\n\t[F7] enable/disable extra flags\n\t[end] Unload esp.\n" << std::endl; #else @@ -155,9 +151,9 @@ int main() { // Message loop MSG msg; - while (GetMessage(&msg, NULL, 0, 0)) + while (GetMessage(&msg, NULL, 0, 0) && !finish) { - if (GetAsyncKeyState(VK_END) & 0x8000) break; + if (GetAsyncKeyState(VK_END) & 0x8000) finish = true; if (GetAsyncKeyState(VK_F5) & 0x8000) { config::team_esp = !config::team_esp; config::save(); Beep(700, 100); }; #ifndef _UC @@ -171,6 +167,8 @@ int main() { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } + read.detach(); + Beep(700, 100); Beep(700, 100); std::cout << "[overlay] Destroying overlay window." << std::endl; @@ -180,7 +178,7 @@ int main() { DestroyWindow(hWnd); std::cout << "[cs2] Deataching from process" << std::endl; - hack::process->Close(); + g_game.process->Close(); #ifdef NDEBUG std::cout << "[cs2] Press any key to close" << std::endl; diff --git a/memory-external/memory-external.vcxproj b/memory-external/memory-external.vcxproj index 7aeb126..00259c5 100644 --- a/memory-external/memory-external.vcxproj +++ b/memory-external/memory-external.vcxproj @@ -213,6 +213,7 @@ + @@ -224,6 +225,7 @@ + From be7f0c28561b201f6d3b92f3de38fd5ad56704ba Mon Sep 17 00:00:00 2001 From: tucucu Date: Sun, 5 Nov 2023 21:25:51 +0100 Subject: [PATCH 2/5] game closing and code cleanup --- memory-external/hacks/reader.cpp | 11 ++++++++--- memory-external/hacks/reader.hpp | 1 + memory-external/main.cpp | 3 +-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/memory-external/hacks/reader.cpp b/memory-external/hacks/reader.cpp index 805bc17..20154d2 100644 --- a/memory-external/hacks/reader.cpp +++ b/memory-external/hacks/reader.cpp @@ -35,11 +35,16 @@ void CGame::init() { } } while (base_client.base == 0 || base_engine.base == 0); - GetClientRect(g_game.process->hwnd_, &game_bounds); + GetClientRect(process->hwnd_, &game_bounds); buildNumber = process->read(base_engine.base + updater::offsets::dwBuildNumber); } +void CGame::close() { + std::cout << "[cs2] Deatachig from process" << std::endl; + process->Close(); +} + void CGame::loop() { inGame = false; isC4Planted = false; @@ -60,7 +65,7 @@ void CGame::loop() { localTeam = process->read(localPlayer + updater::offsets::m_iTeamNum); localOrigin = process->read(localpCSPlayerPawn + updater::offsets::m_vecOrigin); - isC4Planted = process->read(g_game.base_client.base + updater::offsets::dwPlantedC4 - 0x8); + isC4Planted = process->read(base_client.base + updater::offsets::dwPlantedC4 - 0x8); inGame = true; int playerIndex = 0; @@ -143,7 +148,7 @@ void CGame::loop() { } std::string CGame::read_string(uintptr_t addr) { - const DWORD64 address = g_game.process->read(addr); + const DWORD64 address = process->read(addr); if (address) { char buffer[256]; process->read_raw(address, buffer, sizeof(buffer)); diff --git a/memory-external/hacks/reader.hpp b/memory-external/hacks/reader.hpp index c7f38fe..5cf69fc 100644 --- a/memory-external/hacks/reader.hpp +++ b/memory-external/hacks/reader.hpp @@ -50,6 +50,7 @@ public: std::vector players = {}; void init(); void loop(); + void close(); Vector3 world_to_screen(Vector3* v); private: view_matrix_t view_matrix; diff --git a/memory-external/main.cpp b/memory-external/main.cpp index e65a652..2c1129e 100644 --- a/memory-external/main.cpp +++ b/memory-external/main.cpp @@ -177,8 +177,7 @@ int main() { DestroyWindow(hWnd); - std::cout << "[cs2] Deataching from process" << std::endl; - g_game.process->Close(); + g_game.close(); #ifdef NDEBUG std::cout << "[cs2] Press any key to close" << std::endl; From 41e1aaeea55d70d9baa14076f3345e60f34dc873 Mon Sep 17 00:00:00 2001 From: IMXNOOBX Date: Thu, 9 Nov 2023 17:37:15 +0100 Subject: [PATCH 3/5] Updated "offset updater action" to make a pr now --- .github/workflows/update_offsets.yml | 37 ++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/.github/workflows/update_offsets.yml b/.github/workflows/update_offsets.yml index 57f082a..47d6b86 100644 --- a/.github/workflows/update_offsets.yml +++ b/.github/workflows/update_offsets.yml @@ -35,13 +35,30 @@ jobs: echo "Repository has no updates" exit 0 - - name: Commit and push changes - if: steps.run-python-script.outcome == 'success' - run: | - git config --global user.email ${{ secrets.GIT_USER_EMAIL }} - git config --global user.name ${{ secrets.GIT_USER_NAME }} - git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} - git add offsets/offsets.json - git commit -m "Automatically updated offsets from https://github.com/a2x/cs2-dumper" - git push - shell: bash + # - name: Commit and push changes + # if: steps.run-python-script.outcome == 'success' + # run: | + # git config --global user.email ${{ secrets.GIT_USER_EMAIL }} + # git config --global user.name ${{ secrets.GIT_USER_NAME }} + # git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} + # git add offsets/offsets.json + # git commit -m "Automatically updated offsets from https://github.com/a2x/cs2-dumper" + # git push + # shell: bash + - name: Create Pull Request + id: cpr + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: Automatically updated offsets a2x/cs2-dumper + author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> + signoff: false + branch: offset-update + delete-branch: true + title: 'Automatically updated offsets' + body: | + Offsets Updated + - Automatically updated offsets from [cs2-dumper](https://github.com/a2x/cs2-dumper) + labels: | + update-offsets + reviewers: IMXNOOBX \ No newline at end of file From 8c97730594d6b57027a94d933124c7d9f3193373 Mon Sep 17 00:00:00 2001 From: IMXNOOBX Date: Thu, 9 Nov 2023 18:52:05 +0100 Subject: [PATCH 4/5] Fixed merge issue. im getting dumber day to day :c --- memory-external/hacks/hack.hpp | 34 ++++++-------------------------- memory-external/hacks/reader.cpp | 9 ++++++--- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/memory-external/hacks/hack.hpp b/memory-external/hacks/hack.hpp index 03a5661..9d10dd0 100644 --- a/memory-external/hacks/hack.hpp +++ b/memory-external/hacks/hack.hpp @@ -51,25 +51,6 @@ namespace hack { for (auto player = g_game.players.begin(); player < g_game.players.end(); player++) { const Vector3 screenPos = g_game.world_to_screen(&player->origin); const Vector3 screenHead = g_game.world_to_screen(&player->head); - const Vector3 screenHeadPos = g_game.world_to_screen(&player->skull); - - const Vector3 origin = process->read(pCSPlayerPawn + updater::offsets::m_vecOrigin); - const Vector3 head = { origin.x, origin.y, origin.z + 75.f }; - - if (origin.x == localOrigin.x && origin.y == localOrigin.y && origin.z == localOrigin.z) - continue; - - - - if (config::render_distance != -1 && (localOrigin - origin).length2d() > config::render_distance) - continue; - - if (origin.x == 0 && origin.y == 0) - continue; - - const Vector3 screenPos = origin.world_to_screen(view_matrix); - const Vector3 screenHead = head.world_to_screen(view_matrix); - if (screenPos.z >= 0.01f) { const float height = screenPos.y - screenHead.y; @@ -78,18 +59,16 @@ namespace hack { float distance = g_game.localOrigin.calculate_distance(player->origin); int roundedDistance = std::round(distance / 10.f); - if (config::show_head_tracker) - { - const uintptr_t gamescene = process->read(pCSPlayerPawn + 0x310); - const uintptr_t bonearray = process->read(gamescene + 0x160 + 0x80); - const Vector3 headPos = process->read(bonearray + 6 * 32); - const Vector3 screenHeadPos = headPos.world_to_screen(view_matrix); + if (config::show_head_tracker) { + const Vector3 screenHeadPos = g_game.world_to_screen(&player->skull); + const float head_height = (screenHeadPos.y - screenHeadPos.y) / 8; + const float head_width = (head_height / 2.4f) / 4; render::DrawCircle( g::hdcBuffer, screenHeadPos.x, screenHeadPos.y, - width / 5, + 5, config::esp_box_color_enemy ); } @@ -194,7 +173,7 @@ namespace hack { RGB(0, 125, 0), 10 ); - + if (player->flashAlpha > 100) { render::RenderText( @@ -226,4 +205,3 @@ namespace hack { } } - diff --git a/memory-external/hacks/reader.cpp b/memory-external/hacks/reader.cpp index 20154d2..f7dab94 100644 --- a/memory-external/hacks/reader.cpp +++ b/memory-external/hacks/reader.cpp @@ -115,9 +115,12 @@ void CGame::loop() { if (config::render_distance != -1 && (localOrigin - player.origin).length2d() > config::render_distance) continue; if (player.origin.x == 0 && player.origin.y == 0) continue; - const uintptr_t gamescene = process->read(player.pCSPlayerPawn + 0x310); - const uintptr_t bonearray = process->read(gamescene + 0x160 + 0x80); - player.skull = process->read(bonearray + 6 * 32); + if (config::show_head_tracker) { + const uintptr_t gamescene = process->read(player.pCSPlayerPawn + 0x310); + const uintptr_t bonearray = process->read(gamescene + 0x160 + 0x80); + player.skull = process->read(bonearray + 6 * 32); + } + if (config::show_extra_flags) { /* From 1a6cd6fc82ce007e784f88984d6b7f4426c0da83 Mon Sep 17 00:00:00 2001 From: IMXNOOBX <69653071+IMXNOOBX@users.noreply.github.com> Date: Fri, 10 Nov 2023 09:26:47 +0100 Subject: [PATCH 5/5] Update hack.hpp changed head width to `width / 5` --- memory-external/hacks/hack.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/memory-external/hacks/hack.hpp b/memory-external/hacks/hack.hpp index 9d10dd0..1da4705 100644 --- a/memory-external/hacks/hack.hpp +++ b/memory-external/hacks/hack.hpp @@ -68,7 +68,7 @@ namespace hack { g::hdcBuffer, screenHeadPos.x, screenHeadPos.y, - 5, + width / 5, config::esp_box_color_enemy ); }