получить id локального игрока

RedHolms

Известный
Автор темы
Проверенный
617
360
Задача казалось бы простая, но в CNetGame.m_localinfo.m_nId хранится мусор) Так же пробовал samp'овской функцией искать ID по педу, возвращало тоже самое
И да, мне нужно без SF, чистый самп
 
Решение
up

Решение
я тупич масштаба миллиард, брал адрес, прибавлял оффсет и брал полученный адрес как ID (надо было кастить к поинтеру и брать значения с поинтера)
в коде нагляднее:
C++:
short id = idk + 0x1; // как я брал
short id = *(short*)(idk + 0x1); // как надо
догадался спустя 3 дня, класс)

sizeoftrickster

…And Megadeth For All?
Проверенный
121
436
Могу предложить вариант:

C++:
// Вначале получаем указатель на структуру SAMP или stSAMP, CNetGame, pSAMP, вообщем как удобнее
pSAMP = *reinterpret_cast<void **>( samp.dll + 0x21A0F8 );
// Потом из структуры сампа получаем указатель на структуру игровых пулов
ppPools = reinterpret_cast<void **>( (size_t)pSAMP + 0x3CD );
// Потом из структуры игровых пулов в структуре самп получаем указатель на структуру игроков
ppPlayer = reinterpret_cast<void**>( (size_t)pPools + 0x18 );
// В итоге, из структуры игроков получаем ник и ид ЛОКАЛЬНОГО игрока. Смотри: https://gitlab.com/prime-hack/samp/plugins/templates/samp/-/blob/master/SAMP by SR_team
pLocalPlayerNickname = reinterpret_cast<void*>( (size_t)pPlayerPool + 0xA );
pLocalPlayerId = reinterpret_cast<short*>( (size_t)pPlayerPool + 0x4 );

short SAMP::PlayerPool::GetLocalPlayerId() {
    if (pLocalPlayerId) return *pLocalPlayerId;
    return -1;
}

std::string SAMP::PlayerPool::GetLocalPlayerNickname() {
    struct msvc_string {
        union {
            char  szString[0x10];
            char* pszString;
        };
        std::size_t length;
        std::size_t allocated;
    };
    auto string = *reinterpret_cast<msvc_string*>(pLocalPlayerNickname);
    if (string.allocated < 0x10) return { string.szString, string.length };
    return { string.pszString, string.length };
}

Еще один вариант, через pack и pop

C++:
#pragma pack(push, 1)
// Сюда структуры, сами структуры можно посмотреть: https://github.com/BlastHackNet/mod_s0beit_sa-1/blob/master/src/samp.h
struct stSAMP
{
    void                    *pUnk0;
    struct stServerInfo            *pServerInfo;
    uint8_t                    byteSpace[24];
    char                    szIP[257];
    char                    szHostname[259];
    bool                    bNametagStatus; // changes by /nametagstatus
    uint32_t                ulPort;
    uint32_t                ulMapIcons[100];
    int                        iLanMode;
    int                        iGameState;
    uint32_t                ulConnectTick;
    struct stServerPresets    *pSettings;
    void                    *pRakClientInterface;
    struct stSAMPPools        *pPools;
};
#pragma pack(pop)
 
  • Нравится
Реакции: RedHolms

RedHolms

Известный
Автор темы
Проверенный
617
360
г
Могу предложить вариант:

C++:
// Вначале получаем указатель на структуру SAMP или stSAMP, CNetGame, pSAMP, вообщем как удобнее
pSAMP = *reinterpret_cast<void **>( samp.dll + 0x21A0F8 );
// Потом из структуры сампа получаем указатель на структуру игровых пулов
ppPools = reinterpret_cast<void **>( (size_t)pSAMP + 0x3CD );
// Потом из структуры игровых пулов в структуре самп получаем указатель на структуру игроков
ppPlayer = reinterpret_cast<void**>( (size_t)pPools + 0x18 );
// В итоге, из структуры игроков получаем ник и ид ЛОКАЛЬНОГО игрока. Смотри: https://gitlab.com/prime-hack/samp/plugins/templates/samp/-/blob/master/SAMP by SR_team
pLocalPlayerNickname = reinterpret_cast<void*>( (size_t)pPlayerPool + 0xA );
pLocalPlayerId = reinterpret_cast<short*>( (size_t)pPlayerPool + 0x4 );

short SAMP::PlayerPool::GetLocalPlayerId() {
    if (pLocalPlayerId) return *pLocalPlayerId;
    return -1;
}

std::string SAMP::PlayerPool::GetLocalPlayerNickname() {
    struct msvc_string {
        union {
            char  szString[0x10];
            char* pszString;
        };
        std::size_t length;
        std::size_t allocated;
    };
    auto string = *reinterpret_cast<msvc_string*>(pLocalPlayerNickname);
    if (string.allocated < 0x10) return { string.szString, string.length };
    return { string.pszString, string.length };
}

Еще один вариант, через pack и pop

C++:
#pragma pack(push, 1)
// Сюда структуры, сами структуры можно посмотреть: https://github.com/BlastHackNet/mod_s0beit_sa-1/blob/master/src/samp.h
struct stSAMP
{
    void                    *pUnk0;
    struct stServerInfo            *pServerInfo;
    uint8_t                    byteSpace[24];
    char                    szIP[257];
    char                    szHostname[259];
    bool                    bNametagStatus; // changes by /nametagstatus
    uint32_t                ulPort;
    uint32_t                ulMapIcons[100];
    int                        iLanMode;
    int                        iGameState;
    uint32_t                ulConnectTick;
    struct stServerPresets    *pSettings;
    void                    *pRakClientInterface;
    struct stSAMPPools        *pPools;
};
#pragma pack(pop)
это и есть получение ID из CNetGame.m_localinfo.m_nId
 

RedHolms

Известный
Автор темы
Проверенный
617
360
up

Решение
я тупич масштаба миллиард, брал адрес, прибавлял оффсет и брал полученный адрес как ID (надо было кастить к поинтеру и брать значения с поинтера)
в коде нагляднее:
C++:
short id = idk + 0x1; // как я брал
short id = *(short*)(idk + 0x1); // как надо
догадался спустя 3 дня, класс)
 
Последнее редактирование:
  • Ха-ха
Реакции: qdIbp