Исходник anykeys - плагин для работы со всеми клавишами на клавиатуре в Pawn

routefleeder

Известный
Автор темы
40
27
Всем привет. Хотел бы представить свой простой, но довольно полезный плагин для SAMP сервера. Все же знают что в гейммоде можно работать только с колбеком отлова игровых клавиш (OnPlayerKeyStateChange). Так вот, мой плагин позволяет обрабатывать нажатия абсолютно любых клавиш на клавиатуре, в том числе и двойные комбинации.

Использование:
Для начала вы должны установить .dll/.so бинарник плагина на свой сервер в папку plugins и прописать его в server.cfg,
а так же подключить инклуд anykeys.inc. А у клиента должен быть установлен AnyKeys.asi с репозитория.

Pawn-код:
pawn callback:
#include <anykeys>

public OnPlayerPressKey(playerid, key, lastkey)
{
  if(key == VK_J || key == VK_LSHIFT) // для одиночных нажатий
  {
    new keyCode[144];
    format(keyCode, sizeof(keyCode), "Вы нажали на J или Левый Шифт. Код клавиши: %d", key);
    SendClientMessage(playerid, -1, keyCode);
  }
  else if(key == VK_W && lastkey == VK_LSHIFT) // для комбинаций
  {
    SendClientMessage(playerid, -1, "Обнаружена Shift + W комбинация!");
  }

  return 1;
}

Все дефайны названий клавиш вы можете найти в инклуде плагина и использовать их.

Исходник: https://github.com/routefleeder/anykeys
 

arekaj

Новичок
12
1
с серверным плагином как-будто перебор, мог просто incoming packet принимать
 

swlm

Участник
52
17
На будущее, такая инициализация не безопасная. Лучше использовать обычный хук на инициализацию игры или же сампа, ну а потом уже делать свои действия.
Не безопасная, потому-что ты пытаешься читать данные из другого потока, и как бы не случилась гонка данных..


C++:
void InitAndLoad()
{
    while(*reinterpret_cast<unsigned char*>(GAME_STAGE) != 9)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(100u));
    }
    plugin::Events::gameProcessEvent.after += SafetyKeyHook;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        DisableThreadLibraryCalls(hModule);
        std::thread(InitAndLoad).detach();
    }

    return TRUE;
}
 
  • Нравится
Реакции: routefleeder

routefleeder

Известный
Автор темы
40
27
На будущее, такая инициализация не безопасная. Лучше использовать обычный хук на инициализацию игры или же сампа, ну а потом уже делать свои действия.
Не безопасная, потому-что ты пытаешься читать данные из другого потока, и как бы не случилась гонка данных..


C++:
void InitAndLoad()
{
    while(*reinterpret_cast<unsigned char*>(GAME_STAGE) != 9)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(100u));
    }
    plugin::Events::gameProcessEvent.after += SafetyKeyHook;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        DisableThreadLibraryCalls(hModule);
        std::thread(InitAndLoad).detach();
    }

    return TRUE;
}
Ты имеешь ввиду хукнуть место где игра уже полностью инициализированна, затем восстановить листинг украденными байтами, поскольку мы уже поняли что иницилизация успешно прошла и можно дальше выполнять свои действия?
 

swlm

Участник
52
17
Ты имеешь ввиду хукнуть место где игра уже полностью инициализированна, затем восстановить листинг украденными байтами, поскольку мы уже поняли что иницилизация успешно прошла и можно дальше выполнять свои действия?
Да, именно.