Другое С/С++ Вопрос - Ответ

Smeruxa

smeruxa.ru
Проверенный
1,431
789
Это потому что CPlayerPed это класс только для локального игрока. В этом методе получается
C++:
CEntity* CPlayerPed::m_p3rdPersonMouseTarget
Посмотреть вложение 275142
И от него уже рисуется треугольник. Можно в теории переписать метод для рисования по CPed других педов
Вот такой вариант попробовал, он работает в случае, если играют анимации, откуда этот эффект взялся - я без понятия, случайно выявил (прыгал и забирался по стенке)
Т.е. рисует треугольник, видимо есть какой-то случай, вызывающий это
C++:
CPlayerPed* l = static_cast<CPlayerPed*>(FindPlayerPed());
l->m_pPlayerTargettedPed = CPools::GetPed(sampapi::v037r1::RefNetGame()->GetPlayerPool()->GetAt(nearId)->m_pPlayer->m_pPed->m_handle);
l->DrawTriangleForMouseRecruitPed();
Может чего-то не хватает, какого-то флага/стейта
 
Последнее редактирование:

Musaigen

ihatemyself
Проверенный
1,708
1,601
Вот такой вариант попробовал, он работает в случае, если играют анимации, откуда этот эффект взялся - я без понятия, случайно выявил (прыгал и забирался по стенке)
Т.е. рисует треугольник, видимо есть какой-то случай, вызывающий это
C++:
CPlayerPed* l = static_cast<CPlayerPed*>(FindPlayerPed());
l->m_pPlayerTargettedPed = CPools::GetPed(sampapi::v037r1::RefNetGame()->GetPlayerPool()->GetAt(nearId)->m_pPlayer->m_pPed->m_handle);
l->DrawTriangleForMouseRecruitPed();
Может чего-то не хватает, какого-то флага/стейта
Нет никакого флага или стейта, таргетный пед сразу чистится по адресам 0x609EE3 и 0x60BA52, если ты не в прицеле.
 
Последнее редактирование:
  • Нравится
Реакции: вайега52

swlm

Участник
52
18
Вопрос по поводу RakClient.h
Как правильно работать с Receive? То-есть, как правильно получать пакеты исходящие от сервера?
Вопрос в том, где это делать? В игровом цикле? Нужна ли какая-то задержка?

RakNet:
virtual Packet* Receive(void);
P.S. Прикол в том, что когда я использую Receive, то как будто я перехватываю пакет, и дальше уже никакие пакеты от клиента на сервер не идут.
 
Последнее редактирование:

вайега52

Налуашил состояние
Модератор
2,995
3,124
Вопрос по поводу RakClient.h
Как правильно работать с Receive? То-есть, как правильно получать пакеты исходящие от сервера?
Вопрос в том, где это делать? В игровом цикле? Нужна ли какая-то задержка?

RakNet:
virtual Packet* Receive(void);
P.S. Прикол в том, что когда я использую Receive, то как будто я перехватываю пакет, и дальше уже никакие пакеты от клиента на сервер не идут.
Ты это делаешь внутри своего самп клиента или хукаешь самп.длл?

Если второй вариант, то тебе надо хукать вызов RakClient::Receive - вызывать оригинал, сохранять результат (полученный пакет), обрабатывать его, если это нужный тебе пакет и уже в зависимости от нужд возвращать из Хука либо nullptr (самп его не прочитает), либо результат вызова оригинала
 

swlm

Участник
52
18
Ты это делаешь внутри своего самп клиента или хукаешь самп.длл?

Если второй вариант, то тебе надо хукать вызов RakClient::Receive - вызывать оригинал, сохранять результат (полученный пакет), обрабатывать его, если это нужный тебе пакет и уже в зависимости от нужд возвращать из Хука либо nullptr (самп его не прочитает), либо результат вызова оригинала
P.S. Я это делал в своём самп-клиенте.

Спасибо. Я так и думал, что нужно хукать вызов RakClient::Receive.
А теперь вопрос, как правильно хукать вызов RakClient::Receive?
Посмотрел в IDA PRO (sampr3.idb)
Я так понимаю, там нужно мутить что-то с RakClientInterface_vtbl?
Получать указатель на RakClientInterface, а потом с помощью оффсетов хукать функцию Receive?
 
Последнее редактирование:

вайега52

Налуашил состояние
Модератор
2,995
3,124
P.S. Я это делал в своём самп-клиенте.

Спасибо. Я так и думал, что нужно хукать вызов RakClient::Receive.
А теперь вопрос, как правильно хукать вызов RakClient::Receive?
Посмотрел в IDA PRO (sampr3.idb)
Я так понимаю, там нужно мутить что-то с RakClientInterface_vtbl?
Получать указатель на RakClientInterface, а потом с помощью оффсетов хукать функцию Receive?
в структуре CNetGame есть указатель на RakClientInterface (pNetGame + 0x2C на R3), можешь от туда его получить и изменять указатель на метод внутри самой вмт. Либо же можешь найти адрес самой функции и хукать ее (samp.dll + 0x34AC0 на R3)
 

вайега52

Налуашил состояние
Модератор
2,995
3,124
как полностью отключить pause mune ( esc )? пробовал отключить рендер по итогу при esc экран черный и выйти из esc не получалось
Из самого простого - хукнуть WNDPROC и не пропускать сообщение для VK_ESCAPE
 
  • Нравится
Реакции: tanksoftik

swlm

Участник
52
18
в структуре CNetGame есть указатель на RakClientInterface (pNetGame + 0x2C на R3), можешь от туда его получить и изменять указатель на метод внутри самой вмт. Либо же можешь найти адрес самой функции и хукать ее (samp.dll + 0x34AC0 на R3)
Вот, смотри, я сделал вот так:


C++:
bool Hooks::HookReceive() {
    void** vtable = reinterpret_cast<void**>(AVSSync::getRakClientIntf());
    if (!vtable) {
        return false;
    }

    void* receiveAddr = vtable[9];

    MH_STATUS createStatus = MH_CreateHook(receiveAddr, &HookedReceive, reinterpret_cast<void**>(&originalReceive));
    if (createStatus != MH_OK) {
        return false;
    }

    MH_STATUS enableStatus = MH_EnableHook(receiveAddr);
    if (enableStatus != MH_OK) {
        return false;
    }

    std::cout << "Receive hooked successfully!" << std::endl;
    return true;
}

Это правильно? getRakClientIntf() возвращает указатель на RakClientInterface*
 

вайега52

Налуашил состояние
Модератор
2,995
3,124
Вот, смотри, я сделал вот так:


C++:
bool Hooks::HookReceive() {
    void** vtable = reinterpret_cast<void**>(AVSSync::getRakClientIntf());
    if (!vtable) {
        return false;
    }

    void* receiveAddr = vtable[9];

    MH_STATUS createStatus = MH_CreateHook(receiveAddr, &HookedReceive, reinterpret_cast<void**>(&originalReceive));
    if (createStatus != MH_OK) {
        return false;
    }

    MH_STATUS enableStatus = MH_EnableHook(receiveAddr);
    if (enableStatus != MH_OK) {
        return false;
    }

    std::cout << "Receive hooked successfully!" << std::endl;
    return true;
}

Это правильно? getRakClientIntf() возвращает указатель на RakClientInterface*
Ты на какой версии сампа? Если р3, то receiveAddr - samp.dll должен совпадать 0x34AC0
 

swlm

Участник
52
18
Во, сделал так:
И хук заработал, только как теперь работать с пакетами, когда я пытаюсь получить что-то из пакета, происходит краш.


C++:
bool Hooks::HookReceive() {
    Packet* __fastcall HookedReceive(RakClientInterface__vtable* thisPtr, void* edx) {
        Packet* packet = originalReceive(thisPtr);

        return packet;
    }


    HMODULE sampModule = GetModuleHandleA("samp.dll");
    if (!sampModule) {
        return false;
    }

    // Получаем указатель на рак клиент
    RakClientInterface** rakclient = reinterpret_cast<RakClientInterface**>(AVSSync::getRakClientIntf());
    if (!rakclient) {
        return false;
    }

    DWORD* vTable = *reinterpret_cast<DWORD**>(rakclient);
    LPVOID target = reinterpret_cast<LPVOID>(vTable[8]);

    MH_STATUS createStatus = MH_CreateHook(target, &HookedReceive, reinterpret_cast<void**>(&originalReceive));
    if (createStatus != MH_OK) {
        return false;
    }

    MH_STATUS enableStatus = MH_EnableHook(target);
    if (enableStatus != MH_OK) {
        return false;
    }

    std::cout << "Receive hooked successfully!" << std::endl;
    return true;
}

Ты на какой версии сампа? Если р3, то receiveAddr - samp.dll должен совпадать 0x34AC0
На R3, но нет, не совпадает: 0x5CAF637A
 
Последнее редактирование:

AdCKuY_DpO4uLa

Адский дрочер
Друг
369
821
 

swlm

Участник
52
18
ладно, сделаю тогда на функцию сразу...
 

вайега52

Налуашил состояние
Модератор
2,995
3,124
получить что-то из пакета, происходит краш.
Потому-что эта функция вызывается в бесконечном цикле игры и не морозит основной поток, т.е. если нет пакета для получения, возвращается nullptr (под капотом там обычное получение пакета из потокобезопасной очереди, которая пополняется внутри ракпира). Делай проверку на nullptr и должно работать
 

swlm

Участник
52
18
Потому-что эта функция вызывается в бесконечном цикле игры и не морозит основной поток, т.е. если нет пакета для получения, возвращается nullptr (под капотом там обычное получение пакета из потокобезопасной очереди, которая пополняется внутри ракпира). Делай проверку на nullptr и должно работать
Да, сяб, проверил и всё работает.

Получается этот вариант хука правильный?
C++:
bool Hooks::HookReceive() {
    HMODULE sampModule = GetModuleHandleA("samp.dll");
    if (!sampModule) {
        return false;
    }

    // Получаем указатель на рак клиент
    RakClientInterface** rakclient = reinterpret_cast<RakClientInterface**>(AVSSync::getRakClientIntf());
    if (!rakclient) {
        return false;
    }

    DWORD* vTable = *reinterpret_cast<DWORD**>(rakclient);
    LPVOID target = reinterpret_cast<LPVOID>(vTable[8]);

    MH_STATUS createStatus = MH_CreateHook(target, &HookedReceive, reinterpret_cast<void**>(&originalReceive));
    if (createStatus != MH_OK) {
        return false;
    }

    MH_STATUS enableStatus = MH_EnableHook(target);
    if (enableStatus != MH_OK) {
        return false;
    }

    std::cout << "Receive hooked successfully!" << std::endl;
    return true;
}
 
  • Нравится
Реакции: вайега52

вайега52

Налуашил состояние
Модератор
2,995
3,124
Да, сяб, проверил и всё работает.

Получается этот вариант хука правильный?
C++:
bool Hooks::HookReceive() {
    HMODULE sampModule = GetModuleHandleA("samp.dll");
    if (!sampModule) {
        return false;
    }

    // Получаем указатель на рак клиент
    RakClientInterface** rakclient = reinterpret_cast<RakClientInterface**>(AVSSync::getRakClientIntf());
    if (!rakclient) {
        return false;
    }

    DWORD* vTable = *reinterpret_cast<DWORD**>(rakclient);
    LPVOID target = reinterpret_cast<LPVOID>(vTable[8]);

    MH_STATUS createStatus = MH_CreateHook(target, &HookedReceive, reinterpret_cast<void**>(&originalReceive));
    if (createStatus != MH_OK) {
        return false;
    }

    MH_STATUS enableStatus = MH_EnableHook(target);
    if (enableStatus != MH_OK) {
        return false;
    }

    std::cout << "Receive hooked successfully!" << std::endl;
    return true;
}
Если указатель на ракклиент верный, то да по сути (я минхуком не пользовался, не знаю,умеет ли он в вмт)
 
  • Нравится
Реакции: swlm