I am actually quite new to C++, although I have previously programmed in Java. Do you see any ways I can improve readability, maintainability and performance, and make it more object-oriented?
/*
Control + 0 = enable aimbot
*/
#include "stdafx.h"
#include <math.h>
const float pi = 3.14159265358979f;
/*
* I am using int* as if it were the same thing as int**, int***, etc.
* Another more elegant looking method is to use int as if it were int*, int**, etc
* but it is more prone to undefined behaviour and I am more likely to get away with the first method.
* See: http://stackoverflow.com/questions/16256158/dereferencing-a-double-level-pointer-results-in-different-behaviour-from-derefer
*/
int* getClosestPointer(int** basePointer, int offsets[], int levels) {
for (int i = 0; i < levels; i++) {
basePointer = (int**) (*basePointer + offsets[i] / sizeof(int));
}
return (int*) basePointer;
}
/*
[Player base] = A
[A + 34] = X
[A + 38] = Y
[A + 3C] = Z
[A + 40] = Crosshair X
[A + 44] = Crosshair Y
[A + F4] = HP
[A + 154] = Grenades
*/
int playerBaseXOffsets[] = { 0x34 };
int playerBaseYOffsets[] = { 0x38 };
int playerBaseZOffsets[] = { 0x3C };
int playerBaseCXOffsets[] = { 0x40 };
int playerBaseCYOffsets[] = { 0x44 };
int playerBaseHPOffsets[] = { 0xF4 };
int playerBaseAmmoOffsets[] = { 0x368, 0x14, 0 };
int playerBaseGrenadesOffsets[] = { 0x154 };
typedef struct Player {
int** basePointer;
float* xPointer;
float* yPointer;
float* zPointer;
float* cXPointer;
float* cYPointer;
int* hpPointer;
int* ammoPointer;
int* grenadesPointer;
Player() {
}
Player(int** basePtr) {
basePointer = basePtr;
xPointer = (float*) getClosestPointer(basePointer, playerBaseXOffsets, sizeof(playerBaseXOffsets) / sizeof(playerBaseXOffsets[0]));
yPointer = (float*) getClosestPointer(basePointer, playerBaseYOffsets, sizeof(playerBaseYOffsets) / sizeof(playerBaseYOffsets[0]));
zPointer = (float*) getClosestPointer(basePointer, playerBaseZOffsets, sizeof(playerBaseZOffsets) / sizeof(playerBaseZOffsets[0]));
cXPointer = (float*) getClosestPointer(basePointer, playerBaseCXOffsets, sizeof(playerBaseCXOffsets) / sizeof(playerBaseCXOffsets[0]));
cYPointer = (float*) getClosestPointer(basePointer, playerBaseCYOffsets, sizeof(playerBaseCYOffsets) / sizeof(playerBaseCYOffsets[0]));
hpPointer = getClosestPointer(basePointer, playerBaseHPOffsets, sizeof(playerBaseHPOffsets) / sizeof(playerBaseHPOffsets[0]));
ammoPointer = getClosestPointer(basePointer, playerBaseAmmoOffsets, sizeof(playerBaseAmmoOffsets) / sizeof(playerBaseAmmoOffsets[0]));
grenadesPointer = getClosestPointer(basePointer, playerBaseGrenadesOffsets, sizeof(playerBaseGrenadesOffsets) / sizeof(playerBaseGrenadesOffsets[0]));
}
} Player;
Player players[32] = { };
/* Pythagorean's theorem (flavour for 3D) */
float getDistanceBetween(Player one, Player two) {
return sqrt(
(*(one.xPointer)-*(two.xPointer))*(*(one.xPointer)-*(two.xPointer))
+ (*(one.yPointer)-*(two.yPointer))*(*(one.yPointer)-*(two.yPointer))
+ (*(one.zPointer)-*(two.zPointer))*(*(one.zPointer)-*(two.zPointer))
);
}
int getNumberOfPlayers() {
return *((int*) ((UINT) GetModuleHandleW(0) + 0xE4E10));
}
Player* getClosestTarget() {
float smallestDistance;
int index = -1;
for (int i = 1; i < getNumberOfPlayers(); i++) {
if (*(players[i].hpPointer) > 0) {
float tempDistance = getDistanceBetween(players[0], players[i]);
if (index == -1 || tempDistance < smallestDistance) {
smallestDistance = tempDistance;
index = i;
}
}
}
if (index == -1) {
return NULL;
} else {
return &players[index];
}
}
/* Gets the crosshair horizontal angle in degrees. */
float getCX(Player me, Player target) {
float deltaX = *(target.xPointer) - *(me.xPointer);
float deltaY = *(me.yPointer) - *(target.yPointer);
if (*(target.xPointer) > *(me.xPointer) && *(target.yPointer) < *(me.yPointer)) {
return atanf(deltaX/deltaY) * 180.0f / pi;
} else if(*(target.xPointer) > *(me.xPointer) && *(target.yPointer) > *(me.yPointer)) {
return atanf(deltaX/deltaY) * 180.0f / pi + 180.0f;
} else if(*(target.xPointer) < *(me.xPointer) && *(target.yPointer) > *(me.yPointer)) {
return atanf(deltaX/deltaY) * 180.0f / pi - 180.0f;
} else {
return atanf(deltaX/deltaY) * 180.0f / pi + 360.0f;
}
}
/* Gets the crosshair vertical angle in degrees. */
float getCY(Player me, Player target) {
float deltaZ = *(target.zPointer) - *(me.zPointer);
float dist = getDistanceBetween(me, target);
return asinf(deltaZ/dist) * 180.0f / pi;
}
int main() {
bool aimbotEnabled = false;
Player* closestTargetPointer = NULL;
// [Base + DF73C] = Player 1 base
players[0] = Player((int**) ((UINT) GetModuleHandleW(0) + 0xDF73C));
int** extraPlayersBase = *((int***) ((UINT) GetModuleHandleW(0) + 0xE5F00));
while (true) {
// [Base + E5F00] = A
// [A + 0,4,8...] = Player 2/3/4... base
for (int i = 0; i < getNumberOfPlayers() - 1; i++) {
players[i + 1] = Player(extraPlayersBase + i * 4 / sizeof(int*));
}
if (GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState('0')) {
aimbotEnabled = !aimbotEnabled;
Sleep(500);
}
if (aimbotEnabled) {
closestTargetPointer = getClosestTarget();
if (closestTargetPointer != NULL) {
*(players[0].cXPointer) = getCX(players[0], *closestTargetPointer);
*(players[0].cYPointer) = getCY(players[0], *closestTargetPointer);
}
}
Sleep(10);
}
}
DWORD WINAPI Main(LPVOID lpParam) {
main();
return S_OK;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hModule);
CreateThread(NULL, 0, &Main, NULL, 0, NULL);
}
return TRUE;
}
getCX
there is some pieces of repeated code. I think it's best to eliminate it, maybe use another function. Otherwise looks good for me - but I'm not good in C and/or WinAPI. \$\endgroup\$