#include "jumbot.h"
static float AngleNormalize360(float angle) {
return (float) ((360.0 / 65536) * ((int) (angle * (65536 / 360.0)) & 65535));
}
static float AngleNormalize180(float angle) {
angle = AngleNormalize360(angle);
if (angle > 180.0) {
angle -= 360;
}
return angle;
}
static float AngleDelta(float angle1, float angle2) {
return AngleNormalize180(angle1 - angle2);
}
static inline float rad2deg(double a) {
return (float) ((a * 180.0f) / M_PI);
}
* Adjusts view angle.
*/
static void jumbot_angle() {
float accelCoef = *jumbot.groundEntityNum != ENTITYNUM_NONE ? 10.0f : 1.0f;
usercmd_t cmd;
int cmd_num = jumbot.syscall(CG_GETCURRENTCMDNUMBER);
jumbot.syscall(CG_GETUSERCMD, cmd_num, &cmd);
float velSize = (float) sqrt(jumbot.velocity->x * jumbot.velocity->x + jumbot.velocity->y * jumbot.velocity->y);
if ((MIN_SPEED - MIN_SPEED / 125.0f * accelCoef) / velSize * 1.1 > 1) {
return;
}
float perAngle = AngleNormalize180(rad2deg(acos((MIN_SPEED - MIN_SPEED / 125.0f * accelCoef) / velSize * 1.1)));
float velAngle = rad2deg(atan2(jumbot.velocity->y, jumbot.velocity->x));
float accelAngle = rad2deg(atan2(-cmd.rightmove, cmd.forwardmove));
float viewXAccel = jumbot.view->x + accelAngle;
if (cmd.forwardmove == 0) {
if (cmd.rightmove > 0) {
*jumbot.mouseX = (float) (*jumbot.mouseX - AngleDelta(viewXAccel, velAngle - perAngle) - MOUSE_SAFE_PAD);
}
else if (cmd.rightmove < 0) {
*jumbot.mouseX = (float) (*jumbot.mouseX - AngleDelta(viewXAccel, velAngle + perAngle) + MOUSE_SAFE_PAD);
}
} else if (cmd.forwardmove > 0) {
if (cmd.rightmove > 0) {
*jumbot.mouseX = (float) (*jumbot.mouseX - AngleDelta(viewXAccel, velAngle - perAngle) - MOUSE_SAFE_PAD);
}
else if (cmd.rightmove < 0) {
*jumbot.mouseX = (float) (*jumbot.mouseX - AngleDelta(viewXAccel, velAngle + perAngle) + MOUSE_SAFE_PAD);
}
} else if (cmd.forwardmove < 0) {
if (cmd.rightmove > 0) {
*jumbot.mouseX = (float) (*jumbot.mouseX - AngleDelta(viewXAccel, velAngle + perAngle) + MOUSE_SAFE_PAD);
}
else if (cmd.rightmove < 0) {
*jumbot.mouseX = (float) (*jumbot.mouseX - AngleDelta(jumbot.view->x + accelAngle, velAngle - perAngle) - MOUSE_SAFE_PAD);
}
}
}
* Automatically jump when touching ground.
*/
static void jumbot_autojump() {
if (*jumbot.groundEntityNum != ENTITYNUM_NONE) {
*(int *) ADDR_KEY_UP = TRUE;
} else {
*(int *) ADDR_KEY_UP = FALSE;
}
}
* Hooked vmMain.
*/
static int jumbot_CG_vmMain(int command, int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int aa, int ab) {
int ret;
switch (command) {
case CG_INIT:
jumbot.syscall(CG_ADDCOMMAND, CMD_JUMBOT_ON);
jumbot.syscall(CG_ADDCOMMAND, CMD_JUMBOT_OFF);
jumbot.syscall(CG_ADDCOMMAND, CMD_AUTOJUMP_ON);
jumbot.syscall(CG_ADDCOMMAND, CMD_AUTOJUMP_OFF);
unsigned int offset = (unsigned int) jumbot.cgame + jumbot.mod->offset;
jumbot.velocity = (struct vector3 *) (OFFSET_VELOCITY + offset);
jumbot.view = (struct vector2 *) (OFFSET_VIEW + offset);
jumbot.groundEntityNum = (int *) (OFFSET_GROUND_ENTITY_NUM + offset);
jumbot.mouseX = (float *) ADDR_MOUSE_X;
break;
case CG_CONSOLE_COMMAND:
const char *cmd = Cmd_Argv(0);
if (!strcmp(cmd, CMD_JUMBOT_ON)) {
jumbot.enabled = TRUE;
return TRUE;
} else if (!strcmp(cmd, CMD_JUMBOT_OFF)) {
jumbot.enabled = FALSE;
return TRUE;
} else if (!strcmp(cmd, CMD_AUTOJUMP_ON)) {
jumbot.autojump = TRUE;
return TRUE;
} else if (!strcmp(cmd, CMD_AUTOJUMP_OFF)) {
*(int *) ADDR_KEY_UP = FALSE;
jumbot.autojump = FALSE;
return TRUE;
}
break;
}
if (jumbot.ETPro) {
*(void **) ETPRO_AC2_VM_LOCATION = (void *) ETPRO_AC2_VM_ORIG;
ret = jumbot.cg_vmMain(command, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab);
*(void **) ETPRO_AC2_VM_LOCATION = jumbot_CG_vmMain;
} else {
ret = jumbot.cg_vmMain(command, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab);
}
if (command == CG_DRAW_ACTIVE_FRAME) {
if (jumbot.enabled) {
jumbot_angle();
}
if (jumbot.autojump) {
jumbot_autojump();
}
}
return ret;
}
* ETPro checksum circumvention.
*/
static void jumbot_ETPro_AC(void *a, void *b, void *c, int checksum, void *e, char *orig_guid) {
jumbot.ETPro_AC(a, b, c, ETPRO_AC_CHECKSUM, e, orig_guid);
}
* Tricks ETPro into thinking that we haven't hooked our vmMain.
*/
static void* jumbot_ETPro_AC2(DWORD a) {
*(void **) ETPRO_AC2_VM_LOCATION = (void *) ETPRO_AC2_VM_ORIG;
void *p = jumbot.ETPro_AC2(a);
*(void **) ETPRO_AC2_VM_LOCATION = jumbot_CG_vmMain;
*(int *) ETPRO_AC2_SECURITY = 0;
return p;
}
* Catches syscall pointer.
*/
static void jumbot_CG_dllEntry(int(*syscallptr)(int arg, ...)) {
jumbot.syscall = syscallptr;
jumbot.cg_dllEntry(syscallptr);
}
* CGame load & ETPro AC detours.
*/
static HINSTANCE __stdcall jumbot_LoadLibraryA(LPCSTR lpLibName) {
HMODULE ret = jumbot.LoadLibraryA(lpLibName);
if (strstr(lpLibName, "cgame_mp_x86.dll")) {
jumbot.ETPro = FALSE;
jumbot.mod = NULL;
jumbot.cgame = NULL;
if (ETPRO_AC_LOCATION && strstr(lpLibName, "etpro\\cgame_mp_x86.dll")) {
jumbot.ETPro = TRUE;
jumbot.ETPro_AC = (void (*)(void *, void *, void *, int, void *, char *)) DetourFunction((PBYTE) ETPRO_AC_LOCATION, (PBYTE) jumbot_ETPro_AC);
jumbot.ETPro_AC2 = (void* (*)(DWORD)) DetourFunction((PBYTE) ETPRO_AC2_LOCATION, (PBYTE) jumbot_ETPro_AC2);
}
char string[128];
for (int i = 0; i < sizeof(mods) / sizeof(mods[0]); i++) {
memset(string, 0, sizeof(string));
strcat(string, "\\");
strcat(string, mods[i].name);
strcat(string, "\\cgame_mp_x86.dll");
if (strstr(lpLibName, string)) {
jumbot.mod = &mods[i];
jumbot.cgame = ret;
}
}
}
return ret;
}
* Hooks vmMain & dllEntry.
*/
static FARPROC __stdcall jumbot_GetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
FARPROC ret = jumbot.GetProcAddress(hModule, lpProcName);
if (hModule == jumbot.cgame) {
if (!strcmp(lpProcName, "vmMain")) {
jumbot.cg_vmMain = (int(*)(int, ...)) ret;
ret = (void*) jumbot_CG_vmMain;
} else if (!strcmp(lpProcName, "dllEntry")) {
jumbot.cg_dllEntry = (void(*)(int(*)(int, ...))) ret;
ret = (void*) jumbot_CG_dllEntry;
}
}
return ret;
}
* DLL entry point.
*/
static BOOL __stdcall DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
if (reason == DLL_PROCESS_ATTACH) {
jumbot.LoadLibraryA = (void *) DetourFunction((void *) LoadLibraryA, (void *) jumbot_LoadLibraryA);
jumbot.GetProcAddress = (void *) DetourFunction((void *) GetProcAddress, (void *) jumbot_GetProcAddress);
Cmd_Argv = (char* (*)(int)) ADDR_COM_ARGV;
}
return TRUE;
}