diff --git a/src/esp.rs b/src/esp.rs index 2b92e2e..5c5e6b3 100644 --- a/src/esp.rs +++ b/src/esp.rs @@ -2,13 +2,13 @@ use std::ffi::CString; use std::ptr::null; use std::result::Result::Ok; use std::thread; - +use std::time::Duration; use windows::core::PCSTR; use windows::Win32::{Foundation::RECT, Graphics::Gdi::{FillRect, HBRUSH, HDC}}; use windows::Win32::Foundation::{COLORREF, FALSE, GetLastError, HWND, TRUE}; use windows::Win32::Graphics::Gdi::{CreateCompatibleBitmap, CreateCompatibleDC, CreateSolidBrush, DeleteDC, DeleteObject, GetDC, HBITMAP, InvalidateRect, ReleaseDC, SelectObject, TransparentBlt}; use windows::Win32::System::LibraryLoader::GetModuleHandleA; -use windows::Win32::UI::WindowsAndMessaging::{FindWindowA, GetWindowLongA, GWL_EXSTYLE, SetWindowLongA, WS_EX_TRANSPARENT}; +use windows::Win32::UI::WindowsAndMessaging::{FindWindowA, GetWindowLongA, GWL_EXSTYLE, MSG, PeekMessageA, SetWindowLongA, WM_SIZE, WS_EX_TRANSPARENT}; use crate::aimbot::aimbot; use crate::distance; @@ -81,6 +81,7 @@ unsafe fn esp_cleanup( pub unsafe fn esp_entrypoint() -> Result<(), Box> { + // Initialize module handle AC_CLIENT_EXE_HMODULE = { let ac_client_exe_cstring = CString::new("ac_client.exe").unwrap(); GetModuleHandleA(PCSTR(ac_client_exe_cstring.as_ptr() as *const u8)) @@ -93,11 +94,10 @@ pub unsafe fn esp_entrypoint() -> Result<(), Box> { AC_CLIENT_EXE_HMODULE ); - VIEW_MATRIX = VIEW_MATRIX_ADDR as *mut [f32; 16]; println!("[esp] going to unwrap assaultcube window handle"); let assault_cube_cstring = CString::new("AssaultCube").unwrap(); - println!("[esp]going to unwrap FindWindowA"); + println!("[esp] going to unwrap FindWindowA"); let window_handle_result = FindWindowA(PCSTR(0 as *const u8), PCSTR(assault_cube_cstring.as_ptr() as *const u8)); if window_handle_result.is_err() { @@ -109,16 +109,13 @@ pub unsafe fn esp_entrypoint() -> Result<(), Box> { } // Set window style to WS_EX_TRANSPARENT - //println!("[esp] Set window style to Getwinlong"); let ex_style = GetWindowLongA(GAME_WINDOW_HANDLE, GWL_EXSTYLE); - //println!("[esp] Set window style to Setwinl"); SetWindowLongA(GAME_WINDOW_HANDLE, GWL_EXSTYLE, ex_style | WS_EX_TRANSPARENT.0 as i32); - // Get device context and create a compatible DC println!("[esp] Get device context and create a compatible DC"); let hdc = GetDC(GAME_WINDOW_HANDLE); - let mem_dc = CreateCompatibleDC(hdc); + let mut mem_dc = CreateCompatibleDC(hdc); // Get window dimensions println!("[esp] Get window dimensions"); @@ -127,8 +124,8 @@ pub unsafe fn esp_entrypoint() -> Result<(), Box> { let height = GAME_WINDOW_DIMENSIONS.height; // Create a compatible bitmap for double buffering - println!("[esp] Create a compatible bitmap for double buffering)"); - let mem_bitmap = CreateCompatibleBitmap(hdc, width, height); + println!("[esp] Create a compatible bitmap for double buffering"); + let mut mem_bitmap = CreateCompatibleBitmap(hdc, width, height); SelectObject(mem_dc, mem_bitmap); // Select the bitmap into the DC // Initialize game entity data @@ -144,9 +141,41 @@ pub unsafe fn esp_entrypoint() -> Result<(), Box> { let background_brush = CreateSolidBrush(COLORREF(0x00000000)); // Transparent println!("[esp] Getting into the ESP loop"); - init_mem_patches(); + loop { + // Check for window resize + if GAME_WINDOW_DIMENSIONS.width != get_window_dimensions(GAME_WINDOW_HANDLE).unwrap().width || + GAME_WINDOW_DIMENSIONS.height != get_window_dimensions(GAME_WINDOW_HANDLE).unwrap().height + { + let new_dimensions = get_window_dimensions(GAME_WINDOW_HANDLE)?; + let new_width = new_dimensions.width; + let new_height = new_dimensions.height; + + // Only recreate if dimensions have actually changed + if new_width != GAME_WINDOW_DIMENSIONS.width || new_height != GAME_WINDOW_DIMENSIONS.height { + println!("[esp] Window resized to: {}x{}", new_width, new_height); + + // Cleanup old resources + DeleteObject(mem_bitmap); + DeleteDC(mem_dc); + + // Create a new compatible DC and bitmap with the new dimensions + let hdc = GetDC(GAME_WINDOW_HANDLE); + mem_dc = CreateCompatibleDC(hdc); + mem_bitmap = CreateCompatibleBitmap(hdc, new_width, new_height); + SelectObject(mem_dc, mem_bitmap); // Select the new bitmap into the DC + + // Update current dimensions + GAME_WINDOW_DIMENSIONS.width = new_width; + GAME_WINDOW_DIMENSIONS.height = new_height; + + // Release the device context + ReleaseDC(GAME_WINDOW_HANDLE, hdc); + } + } + + // Update local player and other entities if (AC_CLIENT_EXE_HMODULE + LOCAL_PLAYER_OFFSET) as *const usize != null() && LOCAL_PLAYER.entity_starts_at_addr != *((AC_CLIENT_EXE_HMODULE + LOCAL_PLAYER_OFFSET) as *mut usize) { @@ -157,15 +186,15 @@ pub unsafe fn esp_entrypoint() -> Result<(), Box> { if (AC_CLIENT_EXE_HMODULE + NUMBER_OF_PLAYERS_IN_MATCH_OFFSET) as *const i32 != null() && - *((AC_CLIENT_EXE_HMODULE + NUMBER_OF_PLAYERS_IN_MATCH_OFFSET) - as *const i32) as usize != NUM_PLAYERS_IN_MATCH { + *((AC_CLIENT_EXE_HMODULE + NUMBER_OF_PLAYERS_IN_MATCH_OFFSET) + as *const i32) as usize != NUM_PLAYERS_IN_MATCH { println!("[esp] Number of players in match not found"); NUM_PLAYERS_IN_MATCH = *((AC_CLIENT_EXE_HMODULE + NUMBER_OF_PLAYERS_IN_MATCH_OFFSET) as *const i32) as usize; } if (AC_CLIENT_EXE_HMODULE + ENTITY_LIST_OFFSET) as *const u32 != null() && - *((AC_CLIENT_EXE_HMODULE + ENTITY_LIST_OFFSET) as *const u32) != ENTITY_LIST_PTR { + *((AC_CLIENT_EXE_HMODULE + ENTITY_LIST_OFFSET) as *const u32) != ENTITY_LIST_PTR { println!("[esp] Entity list ptr not found"); ENTITY_LIST_PTR = *((AC_CLIENT_EXE_HMODULE + ENTITY_LIST_OFFSET) as *const u32); } @@ -173,17 +202,18 @@ pub unsafe fn esp_entrypoint() -> Result<(), Box> { if !IS_ESP { println!("[esp] Turning off ESP"); - thread::sleep(std::time::Duration::from_millis(1000)); + thread::sleep(Duration::from_millis(1000)); continue; } + // Clear the memory DC before drawing (set to transparent) - FillRect(mem_dc, &RECT { left: 0, top: 0, right: width, bottom: height }, background_brush); //Graphics::Gdi::CreatePatternBrush(create_transparent_bitmap(width, height))); // Set as fully transparent + FillRect(mem_dc, &RECT { left: 0, top: 0, right: GAME_WINDOW_DIMENSIONS.width, bottom: GAME_WINDOW_DIMENSIONS.height }, background_brush); let mut invalidated_area = RECT { left: 0, top: 0, - right: width, - bottom: height, + right: GAME_WINDOW_DIMENSIONS.width, + bottom: GAME_WINDOW_DIMENSIONS.height, }; // Process each entity @@ -194,7 +224,6 @@ pub unsafe fn esp_entrypoint() -> Result<(), Box> { continue; } let mut feet_screen_pos = Vec2 { x: 0.0, y: 0.0 }; - //if !world_to_screen::world_to_screen(entity.position(), &mut screen, *view_matrix, GAME_WINDOW_DIMENSIONS.width, GAME_WINDOW_DIMENSIONS.height) { if !world_to_screen(entity.position(), &mut feet_screen_pos, *VIEW_MATRIX, GAME_WINDOW_DIMENSIONS.width, GAME_WINDOW_DIMENSIONS.height) { continue; } @@ -202,10 +231,7 @@ pub unsafe fn esp_entrypoint() -> Result<(), Box> { if !world_to_screen(entity.head_position(), &mut head_screen_pos, *VIEW_MATRIX, GAME_WINDOW_DIMENSIONS.width, GAME_WINDOW_DIMENSIONS.height) { continue; } -/* let mut topLeft: Vec2 = Vec2::new(head_screen_pos.x - width as f32, head_screen_pos.y); - let mut topRight: Vec2 = Vec2::new(head_screen_pos.x + width as f32, head_screen_pos.y); - let mut bottomRight: Vec2 = Vec2::new(feet_screen_pos.x + width as f32, feet_screen_pos.y); - let mut bottomLeft: Vec2 = Vec2::new(feet_screen_pos.x - width as f32, feet_screen_pos.y);*/ + // Draw box let distance = distance::distance_3d(LOCAL_PLAYER.position(), entity.position()); let box_width = (GAME_WINDOW_DIMENSIONS.width as f32 / distance) as i32; @@ -217,56 +243,63 @@ pub unsafe fn esp_entrypoint() -> Result<(), Box> { } else { red_brush }; - //aimbot(mem_dc); - if IS_DRAW_FOV - { - draw_circle(hdc, (GAME_WINDOW_DIMENSIONS.width as f32 / 2.0, - GAME_WINDOW_DIMENSIONS.height as f32 / 2.0), - FOV, - COLORREF(0x00FFFFFF)); + + if IS_DRAW_FOV { + draw_circle(hdc, (GAME_WINDOW_DIMENSIONS.width as f32 / 2.0, GAME_WINDOW_DIMENSIONS.height as f32 / 2.0), FOV, COLORREF(0x00FFFFFF)); } + draw_text(mem_dc, feet_screen_pos.x as i32, feet_screen_pos.y as i32, &entity); - draw_border_box(mem_dc, box_brush_color, - box_left, box_top, - box_width, box_height, 5); - draw_scaling_bar(mem_dc, - head_screen_pos.x - 55.0, head_screen_pos.y, - feet_screen_pos.x - 15.0, feet_screen_pos.y, - box_width as f32 * 2.5, - entity.health() as f32, 100.0, - COLORREF(0x0000FF00)); + draw_border_box( + mem_dc, + box_brush_color, + box_left, + box_top, + box_width, + box_height, + 5 + ); + draw_scaling_bar( + mem_dc, + head_screen_pos.x - 55.0, + head_screen_pos.y, + feet_screen_pos.x - 15.0, + feet_screen_pos.y, + box_width as f32 * 2.5, + entity.health() as f32, + 100.0, + COLORREF(0x0000FF00), + ); + // Update the invalidated area to encompass all drawn entities invalidated_area.left = invalidated_area.left.min(box_left); invalidated_area.top = invalidated_area.top.min(box_top); invalidated_area.right = invalidated_area.right.max(box_left + box_width); invalidated_area.bottom = invalidated_area.bottom.max(box_top + box_height); - - - - } - // Invalidate the combined area of all drawn entities if InvalidateRect(GAME_WINDOW_HANDLE, Some(&invalidated_area), TRUE) == FALSE { println!("[esp] InvalidateRect failed {:?}", GetLastError()); } - if TransparentBlt(hdc, 0, 0, width, height, - mem_dc, 0, 0, width, height, + + // Perform the transparent blit + if TransparentBlt(hdc, 0, 0, GAME_WINDOW_DIMENSIONS.width, GAME_WINDOW_DIMENSIONS.height, + mem_dc, 0, 0, GAME_WINDOW_DIMENSIONS.width, GAME_WINDOW_DIMENSIONS.height, 0x00000000) == FALSE { println!("[esp] TransparentBlt failed {:?}", GetLastError()); } + // Sleep to reduce CPU usage - thread::sleep(std::time::Duration::from_millis(5)); + thread::sleep(Duration::from_millis(5)); } +/* + // Cleanup resources at the end of the loop + esp_cleanup(GAME_WINDOW_HANDLE, hdc, mem_dc, mem_bitmap, red_brush, green_brush, background_brush) + .expect("[esp] Failed to deallocate hdcs, brushes, and bitmaps."); - - // Cleanup -/* esp_cleanup(GAME_WINDOW_HANDLE, hdc, mem_dc, mem_bitmap, - red_brush, green_brush, background_brush) - .expect("[esp] Failed to deallocate hdcs, brushes and bitmaps."); Ok(())*/ } +