Offsets for players

Crash129

New member
Joined
Dec 25, 2013
Messages
2
Reaction score
0
Hello,

How are the players stored in the SAMP process? Are they just a multi dimensional array? Currently trying to write an external aimbot for SAMP, but I'm struggling with finding the memory addresses for the player positions/health/names.
 

Opcode.eXe

Expert
Joined
Feb 18, 2013
Messages
1,492
Reaction score
236
Location
( ͡° ͜ʖ ͡°)
On http://www.gtamodding.com/?title=Memory_Addresses_%28SA%29
you can find some memory adresses for example to get the current player you're aiming at with the green marker on the head:

0xB6F3B8 = Pointer to Target.
+ 0x79C [dword] = Targetted CPed.


and then you can read the position of the Cped with:

CPed +0x14 = Pointer to XYZ position structure (and rotation)

    (CPed+0x14) +0x0 to +0x2C = [dword] Is the rotation matrix
    (CPed+0x14) +0x30 = [dword] XPos
    (CPed+0x14) +0x34 = [dword] YPos
    (CPed+0x14) +0x38 = [dword] ZPos

and for the health/names you can take a look into the mod_sa source code^^
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,127
Solutions
1
Reaction score
158
here's some code which could be helpful to you (btw the bad side is that GetModuleHandleA() probably won't work if the code isn't executed within the process so you'd have inject it)
Code:
#define SAMP_INFO  0x21A0F8 
#define SAMP_SETTINGS  0x3C5
#define SAMP_POOLS 0x3cd

DWORD* pInfo = NULL;
DWORD* pPools = NULL;
DWORD* pPlayerPool = NULL;

DWORD myCped = *(DWORD*)0xB6F5F0;
DWORD myMatrix = *(DWORD*)(myCped + 0x14);

void InitializeSamp()
{
	SampDLL = (DWORD)GetModuleHandleA("samp.dll");
	while(!SampDLL)
	{
		Sleep(500);
	}	
	pInfo = (DWORD*)(SampDLL+SAMP_INFO);
	pPools = (DWORD*)(*pInfo + SAMP_POOLS);
	pPlayerPool = (DWORD*)(*pPools + 24);
}

void Players::Update()
{
	//int memAddrNum=1;
	for(DWORD i = 0; i < 4016; i += 4)
	{
		int iIsPlayerListed = *(int*)(*pPlayerPool + 4062 + i);
		if(iIsPlayerListed > 0x00) //g_Players->iIsListed[i/4]
		{
			DWORD* pRP = (DWORD*)(*pPlayerPool + 46 + i);//pRP is pRemotePlayer to avoid mixing data (because it's a global variable) (at least it was in my code...)
			DWORD* pRPData = (DWORD*)(*pRP + 0);
			DWORD dwLastStreamedInTick = *(DWORD*)(*pRPData + 457);
			short id = *(short*)(*pRPData + 171); 	
			//if(!(memAddrNum == player[id].memAddrNum))//to know when to reset name
			//{
				//player[id].memAddrNum = memAddrNum;
				player[id].name = "";
				player[id].iNameLen = *(int*)(*pRP + 28); //28
				for(int j=0;j<player[id].iNameLen;j++)
				{
					if(player[id].iNameLen > 15)
					{
						player[id].name += *(char*)(*(DWORD*)(*pRP + 12) + j);
					}
					else
					{
						player[id].name += *(char*)(*pRP + 12 + j);
					}
				}

			//}
			//if not streamed in		
			player[id].score = *(int*)(*pRP + 36);
			player[id].isStreamedIn = false;
			player[id].isOnScreen = false;
			player[id].color = samp_color_get(id);

			

			if(dwLastStreamedInTick == 0)
			{
				//if streamed in
				player[id].isStreamedIn = true;
				player[id].teamID = *(unsigned char*)(*pRPData + 8);
				player[id].score = *(int*)(*pRP + 36);
				player[id].hp = *(float*)(*pRPData + 444);
				player[id].armor = *(float*)(*pRPData + 440);

				if(*(int*)(*pRPData + 9) == 19)
				{
					player[id].isDriving = true;
					player[id].pos[0] = *(float*)(*pRPData + 147); 
					player[id].pos[1] = *(float*)(*pRPData + 151); 
					player[id].pos[2] = *(float*)(*pRPData + 155);
				}
				else
				{
					player[id].isDriving = false;
					player[id].pos[0] = *(float*)(*pRPData + 123); 
					player[id].pos[1] = *(float*)(*pRPData + 127); 
					player[id].pos[2] = *(float*)(*pRPData + 131);
				}
			}
			else//if not streamed in
			{

			}
		}
		memAddrNum++; // i don't remember exactly why i used this but probably to avoid constantly checking player names (if offset in memory changed then check name again or something like that)
	}//end of "for all players" loop
	ResetPersonalizedTextures();//IsStillOnScreen[] indicates which are still on screen 


	//here update my dude a.k.a. $Player_Actor
	UpdateMyPlayer();
}



void UpdateMyPlayer()
{

	/*
	player[1004].iNameLen = g_Players->iLocalPlayerNameLen;
	
	for(int j=0;j<player[1004].iNameLen;j++)
	{
		if(player[1004].iNameLen > 15)
		{
			player[1004].name += (char*)(*(DWORD*)(g_Players->pszLocalPlayerName)+j);//not sure about this
			//(char*)(*(DWORD*)(*pRP + 12) + j);
		}
		else
		{
			player[1004].name += g_Players->szLocalPlayerName[j];
			//*(char*)(*pRP + 12 + j);
		}
	}
	*/

	
	if(*(int*)(myCped + 0x534)== 0)//running state
	{
		player[1004].isDriving = true;
	}
	else
	{
		player[1004].isDriving = false;
	}
		
	player[1004].hp = *(float*)(myCped + 0x540);
	player[1004].armor = *(float*)(myCped + 0x544);
	player[1004].color = samp_color_get(myID);

	player[1004].pos[0] = *(float*)(myMatrix + 0x30);
	player[1004].pos[1] =  *(float*)(myMatrix + 0x34);
	player[1004].pos[2] =  *(float*)(myMatrix + 0x38);

	player[1004].isOnScreen = false;
}


you could check "Cplayers" and "samp" files inside attached archive for a more handy way, btw there are also some functions which could be used for the aimbot, like this from "Csprite.cpp" file:
Code:
float angle = GetCameraXAngle() - GetAngleBetween2Players(1004, playerID);//1004 stands for your dude
angle -= 180.0f;
if(angle < 0.0f){angle += 360.0f;}
 

Attachments

  • src.rar
    52.2 KB · Views: 71
Top