So I was looking at aimbot yesterday, developing it and while looking at the code i notice you use have a lot of performance lost for doing work that could be handle at once. Since most of this code wasn't made to operate on these types of hacks and stuff like that, they can be optimized for hacks in particular. Lets start from the bottom with VectorAngles. This is where most if not all the optimization happened.
This is your traditional VectorAngles.
Problems:
- Two if statements that practically do the same thing, if forward[2] == 0, there is noway forward[2] can be more than 0
- Math function designed to work on double precision floats or 'double' in c++ which are very tasking on most math libraries when we are not using them at all, we are using floats, and the extra 4bytes is just processor time waster while being carried.
- I see that we are setting the angles[2], the third element in the array of floats to 0, which we do not use in our hacks, so why is it even there since this function clearly was modified already, if we are carry an extra 4 bytes again, that is processor time wasted.
(I did not address the Extra variables in this function because the compiler mostlikely doesnt use them anyways, but that would be an example of coping data to someplace, only so it can be moved somewhere else)
Solutions:
- Remove the second If Statement which clearly is one sided anyways
- Optimize the function for the format we are working with
- Use Function designed to work for single procession floating points
- Use only a float array with 2 elements to shed the extra weight.
Old VectorAngles()
Code:
void VectorAngles(const float* forward, float* angles){
float tmp, yaw, pitch;
if(forward[2] == 0 && forward[0] == 0) // Problem Number 1
{
yaw = 0;
if(forward[2] > 0) // Problem Number 1
pitch = 90;
else
pitch = 270;
} else {
yaw = (atan2(forward[2], -forward[0]) * 180 / M_PI)-90;//Problem number 2
if(yaw < 0)
yaw += 360;
tmp = sqrt(forward[0] * forward[0] + forward[2] * forward[2]); // Problem Number 2
pitch = (atan2(forward[1], tmp) * 180 / M_PI ); // Problem Number 2
if(pitch < 0)
pitch += 360;
}
angles[0] = -pitch;
angles[1] = yaw;
angles[2] = 0;
}
Additional Infomation
- I also removed the use of float pointer, to make the function easier on new programmer who may not understand the it and use a wrong data type, and normalize it to the format i am using. AngleNormalize() function
- I made the function inline this for performance reasons which i will not explain now(Inline function also make it harder to reverse engineer
New VectorAngles()
Code:
inline void VectorAngles(const D3DXVECTOR3 forward, D3DXVECTOR2& angles){
float tmp;
if (forward[2] == 0 && forward[0] == 0)
{
angles[1] = 0;
angles[0] = -90;
}
else
{
angles[1] = AngleNormalize((atan2f(forward[2], -forward[0]) * 180 / M_PI) - 90);
tmp = sqrtf(forward[0] * forward[0] + forward[2] * forward[2]);
angles[0] = AngleNormalize(atan2f(-forward[1], tmp) * 180 / M_PI);
}
}
For the next function it will be AngleNormalize()
Problem:
- AngleNormalize uses 2 while loops to come to a format where you have a range from -180 to 180
Solution:
- I removed the while loops and replaced them with a math equation which should be more efficient for numbers with greater distances away from our range.
Old AngleNormalize()
Code:
float AngleNormalize(FLOAT Angle){
while(Angle < -180) Angle += 360;
while(Angle > 180) Angle -= 360;
return Angle;
}
New AngleNormalize
Code:
__forceinline float AngleNormalize(float x)
{
x = fmod(x + 180, 360);
if (x < 0)
x += 360;
return x - 180;
}
The Function GetAngleToTarget
Problems:
- This function subtracts the camera position from the target position one axis at a time, this problem can be fixed in some compilers but really isn't needed, the type D3DXVECTOR3 can be subtracted as is, and I more trust the developers of D3DX to do this operation for me, because they might be using better opcodes to do this task, maybe they found a way to do it with only one opcode (which is possible and i have reason to believe they use these implementations)
- After having convert get the result from VectorAngles, now have to use an 2 if statements to normalize the function, which will always be true because the old VectorAngles didn't support our format, who knows what those values could be.
- As with the VectorAngles() function this function uses an extra 4 bytes that isn't used for there angles "D3DXVECTOR3& vAngles"
Solutions:
- Trust the Developers of D3DX with their operation (this really is just to save lines of code, you might not get performance out of it)
- We already have an optimized VectorAngles so we no longer need the if statement.
- Use float array with 2 elements or a VECTOR2 type
Old GetAngleToTarget
Code:
void GetAngleToTarget(D3DXVECTOR3 vTargetPos, D3DXVECTOR3 vCameraPos, D3DXVECTOR3& vAngles){
D3DXVECTOR3 vDelta;
vDelta.x = vTargetPos.x - vCameraPos.x;
vDelta.y = vTargetPos.y - vCameraPos.y;
vDelta.z = vTargetPos.z - vCameraPos.z;
VectorAngles((float*)&vDelta, (float*)&vAngles);
if(vAngles.x > 180.0f)
vAngles.x -= 360.0f;
else if(vAngles.x < -180.0f)
vAngles.x += 360.0f;
if(vAngles.y > 180.0f)
vAngles.y -= 360.0f;
else if(vAngles.y < -180.0f)
vAngles.y += 360.0f;
}
Additional Information:
- Because this function have been striped to barely nothing i do not see a reason for it existence anymore and do not use it, but i have this to show u what it would look like.
New GetAngleToTarget
Code:
inline void GetAngleToTarget(D3DXVECTOR3 target, D3DXVECTOR3 camera, D3DXVECTOR2& angles){
D3DXVECTOR3 delta;
delta = target - camera;
VectorAngles(delta, angles);
}
The next function is GetFieldOfView better known as GetAimbotFOV()
Information:
- The problems with this are only because of the functions it uses and how it had to clean up after their mess. Now that these functions are more optimized for the equation isn't much we can truly say about this function, I did shed some line tho.
- I also added an extra parameter so i can actually get the angles it obtained, so i can use them, instead of having to recalculate the angles all over, later in my aimbot
- Because i believe GetAngleToTarget is not required anymore i removed it.
- This function is based on the Hyperion base, and is of the Selene hack manager used in this base so some elements of it will be displayed in this function, you can remove them if u may.
Old GetFieldOfView() / GetAimbotFOV()
Code:
bool cHacks::GetAimbotFOV(FLOAT Angle, D3DXVECTOR3 Camera, D3DXVECTOR3 Target){
Angle /= 2;
D3DXVECTOR3 newAngles(NULL, NULL, NULL);
D3DXVECTOR3 curAngles(NULL, NULL, NULL);
GetAngleToTarget(Target, Camera, newAngles);
newAngles[YAW] = AngleNormalize(newAngles[YAW]);
newAngles[PITCH] = AngleNormalize(newAngles[PITCH]);
curAngles[YAW] = AngleNormalize(D3DXToDegree(pPlayerManager->Yaw));
curAngles[PITCH] = AngleNormalize(D3DXToDegree(pPlayerManager->Pitch));
if( newAngles[YAW] >= (curAngles[YAW] - Angle) &&
newAngles[YAW] <= (curAngles[YAW] + Angle) &&
newAngles[PITCH] >= (curAngles[PITCH] - Angle) &&
newAngles[PITCH] <= (curAngles[PITCH] + Angle))
return TRUE;
return FALSE;
}
New GetFieldOfView() / GetAimbotFOV
Code:
inline bool HackManager::GetFieldOfView(float angle, D3DXVECTOR3 camera, D3DXVECTOR3 target, D3DXVECTOR2& newAngles){
auto pmanager = GetPlayerManager();
if (!pmanager)
return false;
angle /= 2;
VectorAngles(target - camera, newAngles);
auto curAngles = D3DXVECTOR2(AngleNormalize(D3DXToDegree(pmanager->Pitch)),
AngleNormalize(D3DXToDegree(pmanager->Yaw)));
return (newAngles[1] >= (curAngles[1] - angle) &&
newAngles[1] <= (curAngles[1] + angle) &&
newAngles[0] >= (curAngles[0] - angle) &&
newAngles[0] <= (curAngles[0] + angle));
}
Now Last but not least the Structure of Aimbots nowadays. Like i said earlier what you guys generally do is u have functions to calculate which player you want. After you know which character, you go ahead and instead of returning angles you use, you go ahead and return the player index, then to calculate the angles all over again.
Code:
{ if(aimMode == 1) {
index = GetClosestPlayer(VisibleCheck, FOVIndex);
} else if(aimMode == 2) {
index = GetClosestCrosshair(VisibleCheck, FOVIndex);
}
}
if(index != -1) {
pPlayer = (GameClasses::PlayerInfo*)GetPlayerByIndex(ulThis, index,0);
D3DXVECTOR3 Position;
GetAngleToTarget((MyGetObjectMaxPos((int*)pPlayer->obj)), (MyGetObjectMaxPos((int*)pLocal->obj)), Position);
pPlayerManager->Yaw = D3DXToRadian(Position[YAW]);
pPlayerManager->Pitch = D3DXToRadian(Position[PITCH] + bone);
}
So i changed this into angles, I dont use functions like GetClosestPlayer() nor GetClosesCrosshair() because they do the same thing except for what they do with the angles, so i integrated it, but I use angles, as u can see in the GetFieldOfView() function, it have a parameter that allows me to get the angle as you will be able to see in the function below, you will also notice i dont use world to screen, because i just dont like it, so i use nearest to field of view which is highly similar to Nearest to Person, but instead of using WorldToScreen() and then to calculate the nearest, I just use the angles i have, and the diameter from the camera to the person, which doesn't limit the aimbot to people on my screen like world to screen does.
As you all know I am only human, and my functions may have room for improvement as well, if they do feel free to tell me where i went wrong, and if u can think of a better way to do the things in my code that would be easy to understand for the choobs who copy and paste, and also efficient at the same time.