ASI chat_on_t | Чат на клавишу T (рус. E)

#SameLine

Активный
417
37
прив
не знаю зачем калкор сделал открытие чата через событие WM_CHAR, но этот плагин позволяет исправить эту фигню. благодаря этому чат будет нормально открываться на всех раскладках
какая разница между уже имеющимися аналогами? плагин делает работу такой, какая она была изначально задумана, что позволяет, например, не открывать чат если в инпут имгуи/мимгуи вводится что-либо
ну и ещё поддержка р1, р3-1, р4-2 на месте, без зависимости от клео/сф/муна
аналога на луа нет, а если будет то окажется нестабильным
C++:
rtdhook_call* mainloop_hook = nullptr;
bool open_input = false;

enum SampVersion {
    SAMP_NOT_LOADED,
    SAMP_UNKNOWN,
    SAMP_037_R1,
    SAMP_037_R3_1,
    SAMP_037_R4_2
};

uintptr_t samp_get_base()
{
    return reinterpret_cast<uintptr_t>(GetModuleHandleA("samp.dll"));
}

SampVersion samp_get_version()
{
    static SampVersion samp_ver = SampVersion::SAMP_NOT_LOADED;
    if (samp_ver <= SampVersion::SAMP_UNKNOWN)
    {
        auto base = samp_get_base();
        if (base == 0) return SampVersion::SAMP_NOT_LOADED;

        auto* ntHeader = reinterpret_cast<IMAGE_NT_HEADERS*>(base + reinterpret_cast<IMAGE_DOS_HEADER*>(base)->e_lfanew);

        auto ep = ntHeader->OptionalHeader.AddressOfEntryPoint;
        switch (ep)
        {
        case 0x31DF13:
            samp_ver = SampVersion::SAMP_037_R1;
            break;
        case 0xCC4D0:
            samp_ver = SampVersion::SAMP_037_R3_1;
            break;
        case 0xCBCB0:
            samp_ver = SampVersion::SAMP_037_R4_2;
            break;
        default:
            samp_ver = SampVersion::SAMP_UNKNOWN;
#ifdef _DEBUG
            assert(0);
#endif
        }
    }

    return samp_ver;
}

LRESULT CALLBACK handle_wndproc(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    if (Msg == WM_KEYDOWN && wParam == 0x54) // T key
    {
        open_input = true; // Lazy to lock CInput WM_CHAR
        return 0;
    }
    return CallWindowProcA(lpPrevWndFunc, hWnd, Msg, wParam, lParam);
}

void mainloop()
{
    static bool once = false;
    static SampVersion version = SAMP_NOT_LOADED;
    if (!once && *reinterpret_cast<uintptr_t*>(0x00C8D4C0) == 9 && samp_get_base() != 0)
    {
        once = true;
        version = samp_get_version();
        if (version >= SAMP_037_R1)
        {
            uintptr_t override_mem = 0;
            uintptr_t hook_ptr = 0;
            switch (version)
            {
            case SAMP_037_R3_1:
                override_mem = 0x0613CB;
                hook_ptr = 0x0613CB + 1;
                break;
            case SAMP_037_R4_2:
                override_mem = 0x061B3B;
                hook_ptr = 0x061B3B + 1;
                break;
            case SAMP_037_R1:
                hook_ptr = 0x05E02B;
                break;
            }
            if (override_mem)
            {
                DWORD old_protection;
                VirtualProtect((LPVOID)(samp_get_base() + override_mem), 2, PAGE_EXECUTE_READWRITE, &old_protection);
                *reinterpret_cast<uint16_t*>(samp_get_base() + override_mem) = 0xE890;
                VirtualProtect((LPVOID)(samp_get_base() + override_mem), 2, old_protection, &old_protection);
            }
            if (hook_ptr)
            {
                auto* hook = new rtdhook_call(samp_get_base() + hook_ptr, &handle_wndproc);
                hook->install();
            }
        }
    }
    if (open_input)
    {
        static uintptr_t func_ptr = 0;
        if (!func_ptr)
        {
            switch (version)
            {
            case SAMP_037_R3_1:
                func_ptr = 0x060E20;
                break;
            case SAMP_037_R4_2:
                func_ptr = 0x61590;
                break;
            case SAMP_037_R1:
                func_ptr = 0x5DA80;
                break;
            }
        }
        if (func_ptr)
            reinterpret_cast<int(*)(WPARAM)>(samp_get_base() + func_ptr)('T');
        open_input = false;
    }
    reinterpret_cast<void(*)()>(mainloop_hook->getHookedFunctionAddress())();
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  fdwReason,
                       LPVOID lpReserved
                     )
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        mainloop_hook = new rtdhook_call(0x53E968, &mainloop);
        mainloop_hook->install();
    }
    return TRUE;
}
и даже уберет хуйню чтоб при вводе input imgui / mimgui зажатии шрифта ты в игре прыгаешь?
 

N08I40K

Известный
224
106
и даже уберет хуйню чтоб при вводе input imgui / mimgui зажатии шрифта ты в игре прыгаешь?
А не проще поменять в настройках игры пробел и шифт местами? Это же жесть как не удобно прыгать на шифт и бегать на пробел.
 

PanSeek

t.me/dailypanseek
Всефорумный модератор
899
1,745
Причем тут скрипт от @Double Tap Inside, если задумка этого плагина совсем в другом. Плагин находится в разделе "Фиксы", это уже как минимум дает Вам знать, что это исправление существующей проблемы в SA/MP без прочих плюшек-финти-флюшек.
 

ARMOR

kjor32 is legend
Модератор
4,845
6,064
@#Northn Добавь пожалуйста ещё поддержку R5.

Вот даже адреса:
C++:
override_mem = 0x61B3B
hook_ptr = 0x61B3B + 1
func_ptr = 0x61590
DLLEntyPoint = 0xCBC90

UP: Добавил сам, держите кому надо, ничего кроме поддержки R5 не добавлял:
 

Вложения

  • chat_on_t.asi
    81 KB · Просмотры: 18
Последнее редактирование: