diff --git a/memory-external/classes/auto_updater.cpp b/memory-external/classes/auto_updater.cpp index 18002e4..146fd17 100644 --- a/memory-external/classes/auto_updater.cpp +++ b/memory-external/classes/auto_updater.cpp @@ -19,8 +19,6 @@ namespace updater { std::tm commit_date = {}; std::istringstream(last_commit_date) >> std::get_time(&commit_date, "%Y-%m-%dT%H:%M:%SZ"); - auto currentTime = std::chrono::system_clock::now(); - std::chrono::system_clock::time_point commitTimePoint = std::chrono::system_clock::from_time_t(std::mktime(&commit_date)); if (file_good("offsets.json")) { @@ -31,7 +29,7 @@ namespace updater { // Check if the local file is older than the last GitHub commit if (lastModifiedClockTime < commitTimePoint) { std::cout << "[updater] Local file is older than the last GitHub commit." << std::endl; - + char response; if (!automatic_update) { std::cout << "[updater] Do you want to download the latest offsets? (y/n): "; @@ -47,7 +45,7 @@ namespace updater { std::cout << "[updater] Error: Failed to download file, try downloading manually from " << raw_updated_offets << "\n" << std::endl; } } - + } else { std::cout << "[updater] Local file is up to date.\n" << std::endl; diff --git a/memory-external/classes/auto_updater.hpp b/memory-external/classes/auto_updater.hpp index f46d094..70e8fb4 100644 --- a/memory-external/classes/auto_updater.hpp +++ b/memory-external/classes/auto_updater.hpp @@ -27,13 +27,13 @@ namespace updater { extern bool read(); extern void save(); - inline std::string github_repo_api = "https://api.github.com/repos/IMXNOOBX/cs2-external-esp/commits"; - inline std::string raw_updated_offets = "https://github.com/IMXNOOBX/cs2-external-esp/raw/main/offsets/offsets.json"; + const inline std::string github_repo_api = "https://api.github.com/repos/IMXNOOBX/cs2-external-esp/commits"; + const inline std::string raw_updated_offets = "https://github.com/IMXNOOBX/cs2-external-esp/raw/main/offsets/offsets.json"; namespace offsets { - inline std::ptrdiff_t dwLocalPlayer = 0x187AC48; - inline std::ptrdiff_t dwEntityList = 0x178D8E8; - inline std::ptrdiff_t dwViewMatrix = 0x187B730; + inline std::ptrdiff_t dwLocalPlayer = 0x1877CF8; + inline std::ptrdiff_t dwEntityList = 0x178A808; + inline std::ptrdiff_t dwViewMatrix = 0x18787E0; inline std::ptrdiff_t m_iPawnArmor = 0x80c; inline std::ptrdiff_t dwPawnHealth = 0x808; diff --git a/memory-external/classes/config.cpp b/memory-external/classes/config.cpp index 4e2f1fd..a424e7b 100644 --- a/memory-external/classes/config.cpp +++ b/memory-external/classes/config.cpp @@ -26,16 +26,53 @@ namespace config { automatic_update = data["automatic_update"]; if (data["render_distance"].is_number()) render_distance = data["render_distance"]; - if (data["show_distance"].is_boolean()) - show_distance = data["show_distance"]; - if (data["show_armor"].is_boolean()) - show_armor = data["show_armor"]; - if (data["rainbow"].is_boolean()) - rainbow = data["rainbow"]; - if (data["rainbow_speed"].is_number()) - rainbow_speed = data["rainbow_speed"]; - if (data["head_tracker"].is_boolean()) - head_tracker = data["head_tracker"]; + if (data["flag_render_distance"].is_number()) + flag_render_distance = data["flag_render_distance"]; + if (data["show_extra_flags"].is_boolean()) + show_extra_flags = data["show_extra_flags"]; + + if (data.find("esp_box_color_team") != data.end()) { + esp_box_color_team = { + data["esp_box_color_team"][0].get(), + data["esp_box_color_team"][1].get(), + data["esp_box_color_team"][2].get() + }; + } + + if (data.find("esp_box_color_enemy") != data.end()) { + esp_box_color_enemy = { + data["esp_box_color_enemy"][0].get(), + data["esp_box_color_enemy"][1].get(), + data["esp_box_color_enemy"][2].get() + }; + } + + if (data.find("esp_name_color") != data.end()) { + esp_name_color = { + data["esp_name_color"][0].get(), + data["esp_name_color"][1].get(), + data["esp_name_color"][2].get() + }; + } + + if (data.find("esp_distance_color") != data.end()) { + esp_distance_color = { + data["esp_distance_color"][0].get(), + data["esp_distance_color"][1].get(), + data["esp_distance_color"][2].get() + }; + } + + //if (data["show_distance"].is_boolean()) + // show_distance = data["show_distance"]; + //if (data["show_armor"].is_boolean()) + // show_armor = data["show_armor"]; + //if (data["rainbow"].is_boolean()) + // rainbow = data["rainbow"]; + //if (data["rainbow_speed"].is_number()) + // rainbow_speed = data["rainbow_speed"]; + //if (data["head_tracker"].is_boolean()) + // head_tracker = data["head_tracker"]; return true; } @@ -46,12 +83,20 @@ namespace config { data["team_esp"] = team_esp; data["automatic_update"] = automatic_update; data["render_distance"] = render_distance; - data["show_distance"] = show_distance; - data["show_armor"] = show_armor; - data["rainbow"] = rainbow; - data["rainbow_speed"] = rainbow_speed; - data["head_tracker"] = head_tracker; - + data["flag_render_distance"] = flag_render_distance; + data["show_extra_flags"] = show_extra_flags; + + data["esp_box_color_team"] = { esp_box_color_team.r, esp_box_color_team.g, esp_box_color_team.b }; + data["esp_box_color_enemy"] = { esp_box_color_enemy.r, esp_box_color_enemy.g, esp_box_color_enemy.b }; + data["esp_name_color"] = { esp_name_color.r, esp_name_color.g, esp_name_color.b }; + data["esp_distance_color"] = { esp_distance_color.r, esp_distance_color.g, esp_distance_color.b }; + + //data["show_distance"] = show_distance; + //data["show_armor"] = show_armor; + //data["rainbow"] = rainbow; + //data["rainbow_speed"] = rainbow_speed; + //data["head_tracker"] = head_tracker; + std::ofstream output(file_path); output << std::setw(4) << data << std::endl; output.close(); diff --git a/memory-external/classes/config.hpp b/memory-external/classes/config.hpp index 7916717..02af005 100644 --- a/memory-external/classes/config.hpp +++ b/memory-external/classes/config.hpp @@ -5,6 +5,18 @@ using json = nlohmann::json; +struct RGB { + int r; + int g; + int b; + + // Conversion function from RGB to COLORREF + operator COLORREF() const { + return RGB(r, g, b); + } +}; + + namespace config { const std::string file_path = "config.json"; @@ -13,10 +25,18 @@ namespace config { inline bool automatic_update = false; inline bool team_esp = false; - inline float render_distance = -1.f; - inline bool show_distance = false; - inline bool show_armor = false; - inline bool head_tracker = false; - inline bool rainbow = false; - inline float rainbow_speed = 0.001f; + inline float render_distance = -1.f; + inline int flag_render_distance = 200; + inline bool show_extra_flags = false; + + //inline bool show_distance = false; + //inline bool show_armor = false; + //inline bool head_tracker = false; + //inline bool rainbow = false; + //inline float rainbow_speed = 0.001f; + + inline RGB esp_box_color_team = { 75, 175, 75 }; + inline RGB esp_box_color_enemy = { 175, 75, 75 }; + inline RGB esp_name_color = { 75, 75, 175 }; + inline RGB esp_distance_color = { 75, 75, 175 }; } diff --git a/memory-external/classes/vector.hpp b/memory-external/classes/vector.hpp index 730acdd..cc28660 100644 --- a/memory-external/classes/vector.hpp +++ b/memory-external/classes/vector.hpp @@ -99,6 +99,14 @@ struct Vector3 return { x, y, w }; } + float calculate_distance(const Vector3& point) const { + float dx = point.x - x; + float dy = point.y - y; + float dz = point.z - z; + + return std::sqrt(dx * dx + dy * dy + dz * dz); + } + // struct data float x, y, z; }; \ No newline at end of file diff --git a/memory-external/hacks/hack.hpp b/memory-external/hacks/hack.hpp index a7eb2f6..b70f7d4 100644 --- a/memory-external/hacks/hack.hpp +++ b/memory-external/hacks/hack.hpp @@ -5,275 +5,217 @@ #include "../classes/render.hpp" #include "../classes/config.hpp" + + namespace hack { std::shared_ptr process; ProcessModule base_module; - float CalculateDistance(const Vector3& point1, const Vector3& point2) { - float dx = point2.x - point1.x; - float dy = point2.y - point1.y; - float dz = point2.z - point1.z; + //const float pi = 3.14159265358979323846f; - return std::sqrt(dx * dx + dy * dy + dz * dz); - } + void loop() { + const uintptr_t localPlayer = process->read(base_module.base + updater::offsets::dwLocalPlayer); + if (!localPlayer) + return; - void loop() { - const uintptr_t localPlayer = process->read(base_module.base + updater::offsets::dwLocalPlayer); - if (!localPlayer) - return; + const int localTeam = process->read(localPlayer + updater::offsets::m_iTeamNum); + const view_matrix_t view_matrix = process->read(base_module.base + updater::offsets::dwViewMatrix); + const Vector3 localOrigin = process->read(localPlayer + updater::offsets::m_vecOrigin); + const uintptr_t entity_list = process->read(base_module.base + updater::offsets::dwEntityList); - const int localTeam = process->read(localPlayer + updater::offsets::m_iTeamNum); - const view_matrix_t view_matrix = process->read(base_module.base + updater::offsets::dwViewMatrix); - const Vector3 localOrigin = process->read(localPlayer + updater::offsets::m_vecOrigin); - const uintptr_t entity_list = process->read(base_module.base + updater::offsets::dwEntityList); + int playerIndex = 0; + uintptr_t list_entry; - int playerIndex = 1; - uintptr_t list_entry; + /** + * Loop through all the players in the entity list + * + * (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; - /** - * Loop through all the players in the entity list - * - * (This could have been done by getting a entity list count from the engine, but I'm too lazy to do that) - **/ - while (true) { - 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; - const uintptr_t player = process->read(list_entry + 120 * (playerIndex & 0x1FF)); - if (!player) { - playerIndex++; - continue; - } - const int playerHealth = process->read(player + updater::offsets::dwPawnHealth); - const int playerArmor = process->read(player + updater::offsets::m_iPawnArmor); - if (playerHealth <= 0 || playerHealth > 100) { - playerIndex++; - continue; - } + const int playerHealth = process->read(player + updater::offsets::dwPawnHealth); + const int playerArmor = process->read(player + updater::offsets::m_iPawnArmor); + if (playerHealth <= 0 || playerHealth > 100) + 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)) { - playerIndex++; - continue; - } - const std::uint32_t playerPawn = process->read(player + updater::offsets::dwPlayerPawn); + /** + * 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 uintptr_t list_entry2 = process->read(entity_list + 0x8 * ((playerPawn & 0x7FFF) >> 9) + 16); - if (!list_entry2) { - playerIndex++; - continue; - } - const uintptr_t pCSPlayerPawn = process->read(list_entry2 + 120 * (playerPawn & 0x1FF)); - if (!pCSPlayerPawn) { - playerIndex++; - continue; - } + const std::uint32_t playerPawn = process->read(player + updater::offsets::dwPlayerPawn); - if (config::team_esp && (pCSPlayerPawn == localPlayer)) { - playerIndex++; - continue; - } + const uintptr_t list_entry2 = process->read(entity_list + 0x8 * ((playerPawn & 0x7FFF) >> 9) + 16); + if (!list_entry2) + continue; - std::string playerName = "Invalid Name"; - const DWORD64 playerNameAddress = process->read(player + updater::offsets::dwSanitizedName); - if (playerNameAddress) { - char buf[256]; - process->read_raw(playerNameAddress, buf, sizeof(buf)); - playerName = std::string(buf); - } + const uintptr_t pCSPlayerPawn = process->read(list_entry2 + 120 * (playerPawn & 0x1FF)); + if (!pCSPlayerPawn) + continue; - const Vector3 origin = process->read(pCSPlayerPawn + updater::offsets::m_vecOrigin); - const Vector3 head = { origin.x, origin.y, origin.z + 75.f }; - const Vector3 head2 = { origin.x + 10, origin.y + 10, origin.z + 75.f }; - const Vector3 localOrigin = process->read(localPlayer + updater::offsets::m_vecOrigin); + if (config::team_esp && (pCSPlayerPawn == localPlayer)) + continue; - if (config::render_distance != -1 && (localOrigin - origin).length2d() > config::render_distance) { - playerIndex++; - continue; - } - const Vector3 screenPos = origin.world_to_screen(view_matrix); - const Vector3 screenHead = head.world_to_screen(view_matrix); + std::string playerName = "Invalid Name"; + const DWORD64 playerNameAddress = process->read(player + updater::offsets::dwSanitizedName); - const float height = screenPos.y - screenHead.y; - const float width = height / 2.4f; + if (playerNameAddress) { + char buf[256]; + process->read_raw(playerNameAddress, buf, sizeof(buf)); + playerName = std::string(buf); + } - const float height2 = (screenPos.y - screenHead.y) / 8; - const float width2 = (height / 2.4f) / 4; + const Vector3 origin = process->read(pCSPlayerPawn + updater::offsets::m_vecOrigin); + const Vector3 head = { origin.x, origin.y, origin.z + 75.f }; + const Vector3 head2 = { origin.x + 10, origin.y + 10, origin.z + 75.f }; + const Vector3 localOrigin = process->read(localPlayer + updater::offsets::m_vecOrigin); - if (screenPos.z >= 0.01f) { - const COLORREF boxColor = RGB(175, 75, 75); - const COLORREF healthBarColor = RGB(255 - playerHealth, 55 + playerHealth * 2, 75); + if (config::render_distance != -1 && (localOrigin - origin).length2d() > config::render_distance) + continue; - const float pi = 3.14159265358979323846f; - // Get the current time - DWORD currentTime = GetTickCount(); + if ((localOrigin - origin).length2d() < 5) + continue; - // Calculate the sinusoidal values for RGB colors - float red = (sin(config::rainbow_speed * currentTime + 0) * 127.5f + 127.5f); // 0 phase shift - float green = (sin(config::rainbow_speed * currentTime + 2 * pi / 3) * 127.5f + 127.5f); // 2*pi/3 phase shift - float blue = (sin(config::rainbow_speed * currentTime + 4 * pi / 3) * 127.5f + 127.5f); // 4*pi/3 phase shift - // Convert the floating point values to integers for RGB color creation - COLORREF rainbowColor = RGB(static_cast(red), static_cast(green), static_cast(blue)); + const Vector3 screenPos = origin.world_to_screen(view_matrix); + const Vector3 screenHead = head.world_to_screen(view_matrix); - float distance = CalculateDistance(localOrigin, origin); - // Round the distance to the nearest integer - int roundedDistance = std::round(distance / 10); + const float height = screenPos.y - screenHead.y; + const float width = height / 2.4f; - if (config::rainbow) { - render::DrawBorderBox( - g::hdcBuffer, - screenHead.x - width / 2, - screenHead.y, - width, - height, - (localTeam == playerTeam ? rainbowColor : rainbowColor) - ); - } - else - { - render::DrawBorderBox( - g::hdcBuffer, - screenHead.x - width / 2, - screenHead.y, - width, - height, - (localTeam == playerTeam ? RGB(75, 175, 75) : RGB(175, 75, 75)) - ); - } + const float head_height = (screenPos.y - screenHead.y) / 8; + const float head_width = (height / 2.4f) / 4; - render::DrawBorderBox( - g::hdcBuffer, - screenHead.x - (width / 2 + 5), - screenHead.y + (height * (100 - playerHealth) / 100), - 2, - height - (height * (100 - playerHealth) / 100), - RGB( - (255 - playerHealth), - (55 + playerHealth * 2), - 75 - ) - ); + if (screenPos.z >= 0.01f) { + float distance = localOrigin.calculate_distance(origin); + int roundedDistance = std::round(distance / 10); - if (config::head_tracker) - { - if (roundedDistance > 35) - { - render::DrawFilledBox( - g::hdcBuffer, - screenHead.x - (width2 / 2), - (screenHead.y + 10 - (roundedDistance / 80)) - (height2 / 2), - width2, - height2, - rainbowColor - ); - } - else if (roundedDistance > 5) - { - render::DrawFilledBox( - g::hdcBuffer, - screenHead.x - (width2 / 2), - screenHead.y + 25 - (height2 / 2), - width2, - height2, - rainbowColor - ); - } - } + render::DrawBorderBox( + g::hdcBuffer, + screenHead.x - width / 2, + screenHead.y, + width, + height, + (localTeam == playerTeam ? config::esp_box_color_team : config::esp_box_color_enemy) + ); - if (config::rainbow) - { - render::RenderText( - g::hdcBuffer, - screenHead.x + (width / 2 + 5), - screenHead.y, - playerName.c_str(), - rainbowColor, - 10 - ); - } - else - { - render::RenderText( - g::hdcBuffer, - screenHead.x + (width / 2 + 5), - screenHead.y, - playerName.c_str(), - RGB(75, 75, 175), - 10 - ); - } + render::DrawBorderBox( + g::hdcBuffer, + screenHead.x - (width / 2 + 5), + screenHead.y + (height * (100 - playerHealth) / 100), + 2, + height - (height * (100 - playerHealth) / 100), + RGB( + (255 - playerHealth), + (55 + playerHealth * 2), + 75 + ) + ); - render::RenderText( - g::hdcBuffer, - screenHead.x + (width / 2 + 5), - screenHead.y + 10, - (std::to_string(playerHealth) + "hp").c_str(), - RGB( - (255 - playerHealth), - (55 + playerHealth * 2), - 75 - ), - 10 - ); + render::RenderText( + g::hdcBuffer, + screenHead.x + (width / 2 + 5), + screenHead.y, + playerName.c_str(), + config::esp_name_color, + 10 + ); - if (config::show_armor) - { - render::RenderText( - g::hdcBuffer, - screenHead.x + (width / 2 + 5), - screenHead.y + 21, - (std::to_string(playerArmor) + "armor").c_str(), - RGB( - (255 - playerArmor), - (55 + playerArmor * 2), - 75 - ), - 10 - ); - } + /** + * I know is not the best way but a simple way to not saturate the screen with a ton of information + */ + if (roundedDistance > config::flag_render_distance) + continue; - if (config::show_distance) - { - if (config::rainbow) - { - render::RenderText( - g::hdcBuffer, - screenHead.x + (width / 2 + 5), - screenHead.y + 32, - (std::to_string(roundedDistance) + "m away").c_str(), - rainbowColor, - 10 - ); - } - else - { - render::RenderText( - g::hdcBuffer, - screenHead.x + (width / 2 + 5), - screenHead.y + 32, - (std::to_string(roundedDistance) + "m away").c_str(), - RGB(75, 75, 175), - 10 - ); - } - } - } - playerIndex++; - } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } + render::RenderText( + g::hdcBuffer, + screenHead.x + (width / 2 + 5), + screenHead.y + 10, + (std::to_string(playerHealth) + "hp").c_str(), + RGB( + (255 - playerHealth), + (55 + playerHealth * 2), + 75 + ), + 10 + ); + + if (config::show_extra_flags) + { + render::RenderText( + g::hdcBuffer, + screenHead.x + (width / 2 + 5), + screenHead.y + 21, + (std::to_string(playerArmor) + "armor").c_str(), + RGB( + (255 - playerArmor), + (55 + playerArmor * 2), + 75 + ), + 10 + ); + + render::RenderText( + g::hdcBuffer, + screenHead.x + (width / 2 + 5), + screenHead.y + 32, + (std::to_string(roundedDistance) + "m away").c_str(), + config::esp_distance_color, + 10 + ); + } + + /** + * Great idea by @ifBars that will be implemented later on + */ + /* + if (config::head_tracker) + { + if (roundedDistance > 35) + { + render::DrawFilledBox( + g::hdcBuffer, + screenHead.x - (head_width / 2), + (screenHead.y + 10 - (roundedDistance / 80)) - (head_height / 2), + head_width, + head_height, + (localTeam == playerTeam ? RGB(75, 175, 75) : RGB(175, 75, 75)) + ); + } + else if (roundedDistance > 5) + { + render::DrawFilledBox( + g::hdcBuffer, + screenHead.x - (head_width / 2), + screenHead.y + 25 - (head_height / 2), + head_width, + head_height, + (localTeam == playerTeam ? RGB(75, 175, 75) : RGB(175, 75, 75)) + ); + } + } + */ + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } } diff --git a/memory-external/main.cpp b/memory-external/main.cpp index 007d2fa..76e7990 100644 --- a/memory-external/main.cpp +++ b/memory-external/main.cpp @@ -137,10 +137,11 @@ int main() { //SetActiveWindow(hack::process->hwnd_); #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 rainbow boxes & names\n\t[F8] enable/disable player distances\n\t[F9] enable/disable player armor\n\t[F10] enable/disable player head tracker\n\t[fin] Unload esp.\n" << std::endl; + 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 - std::cout << "\n[settings] In Game keybinds:\n\t[F5] enable/disable Team ESP\n\t[fin] Unload esp\n" << std::endl; + std::cout << "\n[settings] In Game keybinds:\n\t[F5] enable/disable Team ESP\n\t[F7] enable/disable extra flags\n\t[end] Unload esp\n" << std::endl; #endif + std::cout << "[settings] Make sure you check the config for additional settings!" << std::endl; // Message loop MSG msg; @@ -152,13 +153,7 @@ int main() { #ifndef _UC if (GetAsyncKeyState(VK_F6) & 0x8000) { config::automatic_update = !config::automatic_update; config::save(); Beep(700, 100); } #endif - if (GetAsyncKeyState(VK_F7) & 0x8000) { config::rainbow = !config::rainbow; config::save(); Beep(700, 100); }; - - if (GetAsyncKeyState(VK_F8) & 0x8000) { config::show_distance = !config::show_distance; config::save(); Beep(700, 100); }; - - if (GetAsyncKeyState(VK_F9) & 0x8000) { config::show_armor = !config::show_armor; config::save(); Beep(700, 100); }; - - if (GetAsyncKeyState(VK_F10) & 0x8000) { config::head_tracker = !config::head_tracker; config::save(); Beep(700, 100); }; + if (GetAsyncKeyState(VK_F7) & 0x8000) { config::show_extra_flags = !config::show_extra_flags; config::save(); Beep(700, 100); }; TranslateMessage(&msg); DispatchMessage(&msg);