Help Help with SAMP Player Pools.

slep2.0

Member
Joined
Jun 15, 2025
Messages
5
Reaction score
0
Hey, I'm trying to create an int function that will return a ped from a player ID supplied.
I do have the struct of the pool, however I don't have the memory address, or the knowledge to how to get it. I did try to go to this offset the user Parazitas sent in one of the threads.

samp.dll + 0x26EA0C + 0x3DE + 0x4
However when I tried to access it in ghidra, or in x32dbg I was met with an empty result, it might be because of my inexprience but i don't know really.
If you can help me with building the function from scratch, thank you.
Here are my resources: (taken from s0beit)
struct SampPlayerPool // This is taken from s0beit.
{
//uint32_t ulMaxPlayerID;
int iLocalPlayerScore;
uint16_t sLocalPlayerID;
void* pVTBL_txtHandler;
std::string strLocalPlayerName;
int iLocalPlayerPing;
struct stLocalPlayer* pLocalPlayer;
int iIsListed[SAMP_MAX_PLAYERS];
BOOL bSavedCheckCollision[SAMP_MAX_PLAYERS];
struct stRemotePlayer* pRemotePlayer[SAMP_MAX_PLAYERS];
int largestID;
};

SampPlayerPool* g_Players = nullptr;
I'm guessing to myself we would need to iterate over the pool samp fills with, access the sLocalPlayerId and check with the input that was given.
 

Parazitas

God
Staff member
Joined
Jan 2, 2017
Messages
3,344
Solutions
7
Reaction score
952
Location
Lithuania
BTW, I am using DK22Pac plugin-sdk, so I have access to gta's san andreas player ped, pools, and other stuff.
gta is not same as samp..
Actor handle by id:

More stuff
 

slep2.0

Member
Joined
Jun 15, 2025
Messages
5
Reaction score
0
You are able to manipulate gta's memory that samp uses, like your own ped, vehicles, i'm guessing it will just send an RPC to the server
Thank you very much though, please keep this thread open as I might have more questions :D
 

slep2.0

Member
Joined
Jun 15, 2025
Messages
5
Reaction score
0
Hey, Parazitas, I've pretty sure i've done this wrong, can you tell?

CPlayerPed getSampPedFromId(short id) { if (!sampBase) { return; } // Using UINT32_T means we read 4 bytes, as thats a 32bit app max size per register. uintptr_t addr1 = sampBase + static_cast<uintptr_t>(0x21A0F8); // SAMP_INFO_OFFSET uint32_t val1 = *reinterpret_cast<uint32_t*>(addr1); uintptr_t addr2 = val1 + static_cast<uintptr_t>(0x3CD); // SAMP_pPOOLS_OFFSET uint32_t val2 = *reinterpret_cast<uint32_t*>(addr2); uintptr_t addr3 = val2 + static_cast<uintptr_t>(0x18); // SAMP_PPOOL_PLAYER_OFFSET uint32_t val3 = *reinterpret_cast<uint32_t*>(addr3); id *= 0x4; // PLAYER_ID times 4 id += 0x2E; // SAMP_REMOTEPLAYER_OFFSET val3 += id; uint32_t val4 = *reinterpret_cast<uint32_t*>(val3); if (val4 > 0) { val4 += 0x44; // SAMP_REMOTEPLAYERDATA_HANDLE_OFFSET uint32_t val5 = *reinterpret_cast<uint32_t*>(val4); if (val5 > 0) { return *reinterpret_cast<CPlayerPed*>(val5); } else { return; } } else { return; } }
 

Parazitas

God
Staff member
Joined
Jan 2, 2017
Messages
3,344
Solutions
7
Reaction score
952
Location
Lithuania
Why did you skipped 2 steps and went stright to handle offset? :D

Finish code yourself...
C++:
CPlayerPed getSampPedFromId(short ID) {
    if (!sampBase) {
        return;
    }
    // Using UINT32_T means we read 4 bytes, as thats a 32bit app max size per register.
    uintptr_t SAMP_INFO_POINTER_OFFSET = sampBase + static_cast<uintptr_t>(0x21A0F8); // SAMP_INFO_OFFSET
    
    uint32_t SAMP_INFO_POINTER = *reinterpret_cast<uint32_t*>(SAMP_INFO_POINTER_OFFSET);
    
    uintptr_t SAMP_POOLS_POINTER_OFFSET = SAMP_INFO_POINTER + static_cast<uintptr_t>(0x3CD); // SAMP_POOLS_OFFSET
    
    uint32_t SAMP_POOLS_POINTER = *reinterpret_cast<uint32_t*>(SAMP_POOLS_POINTER_OFFSET);
    
    uintptr_t SAMP_PPOOL_PLAYER_POINTER_OFFSET = SAMP_POOLS_POINTER + static_cast<uintptr_t>(0x18); // SAMP_PPOOL_PLAYER_OFFSET
    
    uint32_t SAMP_PPOOL_PLAYER_POINTER = *reinterpret_cast<uint32_t*>(SAMP_PPOOL_PLAYER_POINTER_OFFSET);
    
    ID *= 0x4; // PLAYER_ID times 4
    ID += 0x2E; // SAMP_REMOTEPLAYER_OFFSET

    SAMP_PPOOL_PLAYER_POINTER += ID;
    uint32_t SAMP_REMOTEPLAYER = *reinterpret_cast<uint32_t*>(SAMP_PPOOL_PLAYER_POINTER);

    if (SAMP_REMOTEPLAYER > 0) {
        SAMP_REMOTEPLAYER += 0x0; // SAMP_REMOTEPLAYERDATA_OFFSET 
        uint32_t SAMP_REMOTEPLAYERDATA_OFFSET = *reinterpret_cast<uint32_t*>(SAMP_REMOTEPLAYER);
        
        if (SAMP_REMOTEPLAYERDATA_OFFSET > 0) {
            SAMP_REMOTEPLAYERDATA_OFFSET += 0x0; // SAMP_REMOTEPLAYERDATA_ACTOR_OFFSET 
        uint32_t SAMP_REMOTEPLAYERDATA_ACTOR_OFFSET = *reinterpret_cast<uint32_t*>(SAMP_REMOTEPLAYERDATA_OFFSET);
        
        if (SAMP_REMOTEPLAYERDATA_ACTOR_OFFSET > 0) {
            SAMP_REMOTEPLAYERDATA_ACTOR_OFFSET += 0x44; // SAMP_REMOTEPLAYERDATA_HANDLE_OFFSET 
        uint32_t SAMP_REMOTEPLAYERDATA_HANDLE_OFFSET  = *reinterpret_cast<uint32_t*>(SAMP_REMOTEPLAYERDATA_ACTOR_OFFSET);
            return *reinterpret_cast<CPlayerPed*>(SAMP_REMOTEPLAYERDATA_HANDLE_OFFSET );
            // etc... many false returns...
 
Top