Бегаем с открытой менюхой аки про

Бегаем с открытой менюхой аки про

Тема в разделе C/C++ создана пользователем panzerfaust
panzerfaust Автор темы
Всем привет, очень часто вижу как юные пастеры делают что-то подобное:

C++:
if (wParam == 'W' || wParam == 'A' || wParam == 'S' || wParam == 'D') {
    return orig_wndproc(hWnd, uMsg, wParam, lParam);
}

что в корне неверно. Например, если у юзера стоят бинды на ESDF, то данный код очень сильно насрет в штаны. Поэтому, как говорится, смотри и учись:

1. Хукаем wndproc всеми мыслимыми и немыслимыми способами
2. Находим волшебную глобальную переменную m_bEnabled
C++:
//-----------------------------------------------------------------------------
// Handles input messages
//-----------------------------------------------------------------------------
LRESULT CInputSystem::WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
#if !defined( POSIX ) && !defined( USE_SDL )

    if ( !m_bEnabled )
        return ChainWindowMessage( hwnd, uMsg, wParam, lParam );

3. Генерим сигнатуру на эту переменную:
dX3U3QR.png


4. Находим волшебную таблицу соотношения VirtualKeyCode -> ButtonCode_t
C++:
ButtonCode_t ButtonCode_VirtualKeyToButtonCode( int keyCode )
{
    if ( keyCode < 0 || keyCode >= sizeof( s_pVirtualKeyToButtonCode ) / sizeof( s_pVirtualKeyToButtonCode[0] ) )
    {
        Assert( false );
        return KEY_NONE;
    }
    return s_pVirtualKeyToButtonCode[keyCode];
}
(а так же не забываем эту функцию, еще пригодится)

5. Точно так же достаем ее сигнатуру (идентично шагу 3)
6. Суем код этой функции себе в чит (если, конечно, делать нечего как мне. Проще будет просто сделать сигнатуру этой функции и сунуть себе в читло, а далее вызывать)

А теперь самое интересное:

C++:
// wndproc

// определяем m_bEnabled как референс
static auto& enabled = sig_scan("redacted", "redacted").get<bool>();

// выполняем wndproc меню, если имгуи то будет что-то похожее
// обязательно нужно тут инвертировать результат, дабы игра не реагировала на кнопки
enabled = !ImGui_ImplWin32_WndProc(msg, wparam, lparam);

// далее, проверяем тип смски
if (msg == WM_KEYDOWN || msg == WM_KEYUP)
{
    // получаем binding нашей супер-кнопки
    const auto binding = sdk::engine_client->binding_for_key(sdk::virtual_key_to_button_code(wparam));
    
    // проверяем, есть ли такой биндинг
    if (binding)
    {
        // хешируем любым удобным способом, либо по-старинке if-else сравниваем строку
        // а затем чекаем бинды
        switch (util::fnv1a(binding))
        {
            case FNV("+forward"):
            case FNV("+back"):
            case FNV("+moveleft"):
            case FNV("+moveright"):
            case FNV("+jump"):
            case FNV("+duck"):
            case FNV("+walk"):
                // включаем обратно инпут у игры
                enabled = true;
                break;
        }
    }
}

// и уже после всех этих нехитрых манипуляций, вызываем ориг функцию
return HK_ORIG(dx_wnd_proc, wnd, msg, wparam, lparam);

И вот таким нехитрым способом ваш уровень программирование возрастет на 5 единиц.
Сигнатуры не прикрепляю, найти их крайне просто.

Сверху