diff --git a/clicker/clicker.cpp b/clicker/clicker.cpp index 135be83..b1a03d8 100644 --- a/clicker/clicker.cpp +++ b/clicker/clicker.cpp @@ -4,6 +4,7 @@ // TODO: Fix clicker void c_clicker::init() { + // Get rid of the inifite loop while ( true ) { if ( !this->m_is_right_clicking || !this->m_is_left_clicking ) @@ -12,24 +13,21 @@ void c_clicker::init() vars::key::clicker_enabled.i_mode = config.clicker.i_key_type; vars::key::clicker_enabled.i_key = config.clicker.i_clicker_key; - static auto first_click = true; if ( vars::key::clicker_enabled.get() ) { - if ( focus::window_think() && focus::cursor_think() && !focus::is_self_focused() ) + if ( focus::window_think() && focus::cursor_think() ) { // left - // - this->m_is_left_clicking = ( config.clicker.b_enable_left_clicker && vars::key::left_mouse.get() && !vars::key::right_mouse.b_is_down); + this->m_is_left_clicking = ( config.clicker.b_enable_left_clicker && vars::key::is_left_down ); if ( this->m_is_left_clicking ) - this->send_click(input::mouse_button_t::left, config.clicker.f_left_cps, first_click ); + this->send_click(input::mouse_button_t::left, config.clicker.f_left_cps, vars::key::l_is_first_click ); // right - // - this->m_is_right_clicking = ( config.clicker.b_enable_right_clicker && vars::key::right_mouse.get()); + this->m_is_right_clicking = ( config.clicker.b_enable_right_clicker && vars::key::is_right_down); if ( this->m_is_right_clicking ) - this->send_click(input::mouse_button_t::right, config.clicker.f_right_cps, first_click ); + this->send_click(input::mouse_button_t::right, config.clicker.f_right_cps, vars::key::r_is_first_click ); } } } @@ -50,7 +48,6 @@ void c_clicker::send_click(input::mouse_button_t b_button, float f_cps, bool& b_ if ( !config.clicker.b_enable_blatant ) this->m_delay += rng::random_real( -config.clicker.f_default_timer_randomization, config.clicker.f_default_timer_randomization ); - // TODO: Fudeu! if ( b_is_first_click ) { sleep( this->m_delay ); @@ -100,15 +97,15 @@ void c_clicker::update_thread() { log_debug( "Update %.3fms", rate ); - // ~ persistence + // persistence if ( config.clicker.b_enable_persistence ) m_random = rng::random_real( -config.clicker.f_persistence_value, config.clicker.f_persistence_value ); - // ~ cps drops + // cps drops if ( config.clicker.b_enable_cps_drops && config.clicker.i_cps_drop_chance > 0 && ( std::rand() % ( 100 / config.clicker.i_cps_drop_chance ) == 0 ) ) m_random -= config.clicker.f_cps_drop_remove; - // ~ cps spikes + // cps spikes if ( config.clicker.b_enable_cps_spikes && config.clicker.i_cps_spike_chance > 0 && ( std::rand() % ( 100 / config.clicker.i_cps_spike_chance ) == 0 ) ) m_random += config.clicker.f_cps_spike_add; diff --git a/clicker/clicker.vcxproj b/clicker/clicker.vcxproj index 3ad3401..180a382 100644 --- a/clicker/clicker.vcxproj +++ b/clicker/clicker.vcxproj @@ -76,6 +76,7 @@ + diff --git a/clicker/clicker.vcxproj.filters b/clicker/clicker.vcxproj.filters index 4c52573..a5f231d 100644 --- a/clicker/clicker.vcxproj.filters +++ b/clicker/clicker.vcxproj.filters @@ -12,7 +12,7 @@ menu - utils\pch + utils\precompiled utils\imgui\impl\dx9 @@ -35,6 +35,9 @@ utils\imgui + + utils\threads + @@ -59,7 +62,7 @@ utils\vars - utils\pch + utils\precompiled utils\imgui\impl\dx9 @@ -129,9 +132,6 @@ {e03d8ee1-45d8-48e9-908e-5068534f2c83} - - {4b318143-ea30-4b46-875b-edfdf4ad9267} - {40cd9742-07b4-40cf-b1be-d3baf0050cf2} @@ -147,5 +147,8 @@ {64418ae5-488a-44f0-aa10-d31c2dc334ad} + + {4b318143-ea30-4b46-875b-edfdf4ad9267} + \ No newline at end of file diff --git a/clicker/main.cpp b/clicker/main.cpp index e571b19..8af8ca3 100644 --- a/clicker/main.cpp +++ b/clicker/main.cpp @@ -2,22 +2,26 @@ INT WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd ) { - std::atexit( [] { threads::hooks::unhook(); } ); + std::atexit( [] { + // Dispose stuff + threads::destroy(); + } ); + std::srand( std::time( nullptr ) ); // TODO: Custom config folder config.run( "clicker" ); std::vector, std::string>> functions = { - { threads::clicker::spawn, "clicker" }, - { threads::randomization::spawn, "clicker randomization" }, - { threads::hooks::spawn, "hooking" } + {threads::spawn_hooks, "input hooks"}, + {threads::spawn_rand, "randomization"}, + {threads::spawn_clicker, "clicker"} }; for ( auto& [func, name] : functions ) std::thread( func ).detach(); - log_debug( "Main loop started..." ); + log_debug( "Init menu" ); if ( !g_menu.initialize( 550, 350 ) ) { log_err( "Failed to create DX9 device!" ); diff --git a/clicker/menu.cpp b/clicker/menu.cpp index e79fbdc..b1ddf44 100644 --- a/clicker/menu.cpp +++ b/clicker/menu.cpp @@ -169,8 +169,8 @@ void c_menu::on_paint( HWND hwnd, int i_width, int i_height ) ImGui::Separator(); ImGui::Text( "Clicks this session: %d", vars::stats::i_clicks_this_session ); ImGui::Text( "Average CPS: %.2f", vars::stats::f_average_cps ); - ImGui::Text( "Is left button down: %s", vars::key::left_mouse.get() ? ICON_FA_CHECK : ICON_FA_TIMES ); - ImGui::Text( "Is right button down: %s", vars::key::right_mouse.get() ? ICON_FA_CHECK : ICON_FA_TIMES ); + ImGui::Text( "Is left button down: %s", vars::key::is_left_down ? ICON_FA_CHECK : ICON_FA_TIMES ); + ImGui::Text( "Is right button down: %s", vars::key::is_right_down ? ICON_FA_CHECK : ICON_FA_TIMES ); ImGui::Text( "Is hotkey toggled: %s", vars::key::clicker_enabled.get() ? ICON_FA_CHECK : ICON_FA_TIMES ); ImGui::Text( "Is window focused: %s", focus::window_think() ? ICON_FA_CHECK : ICON_FA_TIMES ); ImGui::Text( "Is cursor visible: %s", focus::is_cursor_visible() ? ICON_FA_CHECK : ICON_FA_TIMES ); diff --git a/clicker/threads.cpp b/clicker/threads.cpp new file mode 100644 index 0000000..5a6f7ad --- /dev/null +++ b/clicker/threads.cpp @@ -0,0 +1,101 @@ +#include "pch.hpp" + +#include "threads.hpp" + +DWORD WINAPI threads::spawn_hooks() +{ + oLowLevelKeyboardProc = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, nullptr, 0 ); + if ( !oLowLevelKeyboardProc ) + { + // Failed to setup WH_KEYBOARD_LL + return EXIT_SUCCESS; + } + + oLowLevelMouseProc = SetWindowsHookEx( WH_MOUSE_LL, LowLevelMouseProc, nullptr, 0 ); + if ( !oLowLevelMouseProc ) + { + // Failed to setup WH_MOUSE_LL + return EXIT_SUCCESS; + } + + MSG msg {}; + ZeroMemory( &msg, sizeof( msg ) ); + + while ( msg.message != WM_QUIT ) + { + if ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + continue; + } + + WaitMessage(); + } + + return EXIT_SUCCESS; +} + +LRESULT CALLBACK threads::LowLevelMouseProc( int nCode, WPARAM wParam, LPARAM lParam ) +{ + if ( nCode == HC_ACTION ) + { + auto mi = *( (MSLLHOOKSTRUCT*) lParam ); + + switch ( wParam ) + { + case WM_LBUTTONDOWN: + vars::key::l_is_first_click = true; + vars::key::is_left_down = true; + break; + case WM_LBUTTONUP: + vars::key::is_left_down = false; + break; + case WM_MOUSEMOVE: break; + case WM_MOUSEWHEEL: break; + case WM_MOUSEHWHEEL: break; + case WM_RBUTTONDOWN: + vars::key::r_is_first_click = true; + vars::key::is_right_down = true; + break; + case WM_RBUTTONUP: + vars::key::is_right_down = false; + break; + } + } + + return CallNextHookEx( oLowLevelMouseProc, nCode, wParam, lParam ); +} + +LRESULT CALLBACK threads::LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) +{ + if ( nCode == HC_ACTION ) + { + auto mi = *( (KBDLLHOOKSTRUCT*) lParam ); + + switch ( wParam ) + { + case WM_KEYDOWN: + if ( focus::window_think() ) + { + if ( mi.vkCode == 69 /* E */ ) + vars::key::b_inventory_opened = !vars::key::b_inventory_opened; + + if ( mi.vkCode == VK_ESCAPE ) + vars::key::b_inventory_opened = false; + } + break; + case WM_SYSKEYDOWN: break; + case WM_KEYUP: break; + case WM_SYSKEYUP: break; + } + } + + return CallNextHookEx( oLowLevelKeyboardProc, nCode, wParam, lParam ); +} + +void threads::destroy() +{ + UnhookWindowsHookEx( oLowLevelMouseProc ); + UnhookWindowsHookEx( oLowLevelKeyboardProc ); +} \ No newline at end of file diff --git a/clicker/threads.hpp b/clicker/threads.hpp index 2550ba9..7ff7daf 100644 --- a/clicker/threads.hpp +++ b/clicker/threads.hpp @@ -2,65 +2,16 @@ namespace threads { - namespace clicker - { - inline void spawn() - { - g_clicker->init(); - } - } + // Find a better way to sort this out + inline void spawn_clicker() { g_clicker->init(); } + inline void spawn_rand() { g_clicker->update_thread(); } - namespace randomization - { - inline void spawn() - { - g_clicker->update_thread(); - } - } + inline HHOOK oLowLevelMouseProc = nullptr; + inline HHOOK oLowLevelKeyboardProc = nullptr; - namespace hooks - { - inline HHOOK h_hook; + extern LRESULT CALLBACK LowLevelMouseProc( int nCode, WPARAM wParam, LPARAM lParam ); + extern LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ); - static LRESULT CALLBACK keyboard_callback( int nCode, WPARAM wParam, LPARAM lParam ) - { - static auto* k_hook = (KBDLLHOOKSTRUCT*) ( lParam ); - - if ( wParam == WM_KEYDOWN && nCode == HC_ACTION && ( wParam >= WM_KEYFIRST ) && ( wParam <= WM_KEYLAST ) ) - { - if ( focus::window_think() ) - { - if ( k_hook->vkCode == 69 /* E */ ) - vars::key::b_inventory_opened = !vars::key::b_inventory_opened; - - if ( k_hook->vkCode == VK_ESCAPE ) - vars::key::b_inventory_opened = false; - } - } - - return CallNextHookEx( h_hook, nCode, wParam, lParam ); - } - - inline void spawn() - { - h_hook = SetWindowsHookEx( - WH_KEYBOARD_LL, - keyboard_callback, - nullptr, - NULL - ); - - MSG msg; - while ( GetMessage( &msg, nullptr, 0, 0 ) ) - { - TranslateMessage( &msg ); - DispatchMessage( &msg ); - } - } - - inline void unhook() - { - UnhookWindowsHookEx( h_hook ); - } - } + void destroy(); + DWORD WINAPI spawn_hooks(); } \ No newline at end of file diff --git a/clicker/utils.hpp b/clicker/utils.hpp index ed6034f..ace1e06 100644 --- a/clicker/utils.hpp +++ b/clicker/utils.hpp @@ -4,6 +4,7 @@ namespace string { + // Try to port the whole project to unicode (Hello ImGui?) inline std::string to_utf8( std::wstring wstr ) { if ( wstr.empty() ) @@ -93,32 +94,32 @@ namespace rng namespace input { - // TODO: Melhorar isso tudo + // TODO: Fix this logic enum class mouse_button_t: bool { right, left }; enum class mouse_input_type_t: bool { up, down }; + enum class mouse_side_t: DWORD + { + left = MK_LBUTTON, + right = MK_RBUTTON + }; enum class mouse_type_t : DWORD { - left_up = MOUSEEVENTF_LEFTUP, - left_down = MOUSEEVENTF_LEFTDOWN, + left_up = WM_LBUTTONUP, + left_down = WM_LBUTTONDOWN, - right_up = MOUSEEVENTF_RIGHTUP, - right_down = MOUSEEVENTF_RIGHTDOWN + right_up = WM_RBUTTONUP, + right_down = WM_RBUTTONDOWN }; - inline void send_input(mouse_type_t m_type) + inline void send_input(mouse_type_t m_type, mouse_side_t m_side) { - INPUT ip = {}; - { - ip.type = INPUT_MOUSE; - ip.mi.dwFlags = (DWORD)m_type; - } - - SendInput(1, &ip, sizeof(INPUT)); + // Change to RawInput in the future. + SendMessage( GetForegroundWindow(), (DWORD)m_type, (DWORD)m_side, NULL ); } inline void click(mouse_input_type_t type, mouse_button_t button) { - (bool)(type) ? (bool)(button) ? send_input(mouse_type_t::left_down) : send_input(mouse_type_t::right_down) : (bool)(button) ? send_input(mouse_type_t::left_up) : send_input(mouse_type_t::right_up); + (bool)(type) ? (bool)(button) ? send_input(mouse_type_t::left_down, mouse_side_t::left) : send_input(mouse_type_t::right_down, mouse_side_t::right) : (bool)(button) ? send_input(mouse_type_t::left_up, mouse_side_t::left) : send_input(mouse_type_t::right_up, mouse_side_t::right); } } @@ -137,6 +138,7 @@ namespace focus return title; } + // Can get better? inline bool is_self_focused() { const auto hwnd = GetForegroundWindow(); @@ -149,6 +151,7 @@ namespace focus return ( GetCurrentProcessId() == dw_thread_process_id ); } + // Can get better? inline bool is_cursor_visible() { CURSORINFO ci { sizeof( CURSORINFO ) }; @@ -165,13 +168,17 @@ namespace focus inline bool window_think() { - switch ( config.clicker.i_version_type ) + if ( !focus::is_self_focused() ) { - case 0: - return ( GetForegroundWindow() == FindWindow( L"LWJGL", nullptr ) ); - case 1: - return ( active_window_title().find( string::to_unicode( config.clicker.str_window_title ) ) != std::string::npos ); - default: break; + switch ( config.clicker.i_version_type ) + { + case 0: + return ( GetForegroundWindow() == FindWindow( L"LWJGL", nullptr ) ); + case 1: + return ( active_window_title().find( string::to_unicode( config.clicker.str_window_title ) ) != std::string::npos ); + default: + return {}; + } } return false; @@ -182,13 +189,11 @@ namespace focus if ( config.clicker.b_only_in_game ) { if ( config.clicker.b_work_in_inventory ) - return !is_cursor_visible() || ( vars::key::b_inventory_opened && is_cursor_visible() ); + return !(is_cursor_visible()) || ( vars::key::b_inventory_opened && is_cursor_visible() ); - return !is_cursor_visible(); + return !(is_cursor_visible()); } - else - return is_cursor_visible(); - return false; + return true; } } \ No newline at end of file diff --git a/clicker/vars.hpp b/clicker/vars.hpp index 2ae686b..eb1c323 100644 --- a/clicker/vars.hpp +++ b/clicker/vars.hpp @@ -5,10 +5,14 @@ namespace vars namespace key { inline auto clicker_enabled { keybind( true, config.clicker.i_key_type, config.clicker.i_clicker_key ) }; - inline auto left_mouse { keybind( false, keybind_state_t::hold, VK_LBUTTON ) }; - inline auto right_mouse { keybind( false, keybind_state_t::hold, VK_RBUTTON ) }; inline auto hide_window { keybind( false, keybind_state_t::toggle, config.clicker.i_hide_window_key ) }; + inline auto is_left_down { false }; + inline auto is_right_down { false }; + + inline auto l_is_first_click { false }; + inline auto r_is_first_click { false }; + inline auto b_inventory_opened { false }; }