Merge branch 'master' of https://github.com/nullifiedcat/cathook into move-data

This commit is contained in:
nullifiedcat 2017-08-16 12:06:00 +03:00
commit 6aea71b55d
7 changed files with 375 additions and 174 deletions

View File

@ -424,6 +424,7 @@
"tauntslide_tf2",
"tauntslide",
"flashlight",
"request_balance_spam",
{
"type": "list",
"name": "Remove Conditions",

View File

@ -147,3 +147,4 @@ void Invalidate() {
}
}

View File

@ -14,8 +14,10 @@ namespace hacks { namespace shared { namespace bunnyhop {
// Var for user settings
CatVar enabled(CV_SWITCH, "bhop_enabled", "0", "Bunnyhop", "Enable Bunnyhop. All extra features like autojump and perfect jump limit were temporary removed.");
//CatVar perfect_jump_limit(CV_INT, "bhop_enabled", "0", "Bunnyhop", "Enable Bunnyhop. All extra features like autojump and perfect jump limit were temporary removed.");
int iTicksLastJump = 0;
static int ticks_last_jump = 0;
//static int perfect_jumps = 0;
// Function called by game for movement
void CreateMove() {
@ -26,26 +28,22 @@ void CreateMove() {
// Check if there is usercommands
if (!g_pUserCmd->command_number) return;
// Check if local player is airborne, if true then return
//if (CE_INT(g_pLocalPlayer->entity, netvar.movetype) == MOVETYPE_FLY) return;
// Grab netvar for flags from the local player
int flags = CE_INT(g_pLocalPlayer->entity, netvar.iFlags);
// var for "if on ground" from the flags netvar
bool ground = (flags & (1 << 0));
bool ground = CE_INT(g_pLocalPlayer->entity, netvar.iFlags) & (1 << 0);
// Var for if the player is pressing jump
bool jump = (g_pUserCmd->buttons & IN_JUMP);
// Check if player is not on the ground and player is holding their jump key
if (!ground && jump) {
// If the ticks since last jump are greater or equal to 7, then force the player to stop jumping
// If the ticks since last jump are greater or equal to 9, then force the player to stop jumping
// The bot disables jump untill player hits the ground or lets go of jump
if (iTicksLastJump++ >= 9) g_pUserCmd->buttons = g_pUserCmd->buttons &~ IN_JUMP;
if (ticks_last_jump++ >= 9) {
g_pUserCmd->buttons = g_pUserCmd->buttons &~ IN_JUMP;
}
}
// If the players jump cmd has been used, then we reset our var
if (!jump) iTicksLastJump = 0;
if (!jump) ticks_last_jump = 0;
// Finish the function with return
return;

View File

@ -50,11 +50,25 @@ CatVar proj_esp(CV_SWITCH, "esp_proj", "1", "Projectile ESP", "Projectile ESP");
CatVar entity_model(CV_SWITCH, "esp_model_name", "0", "Model name ESP", "Model name esp (DEBUG ONLY)");
CatVar item_weapon_spawners(CV_SWITCH, "esp_weapon_spawners", "1", "Show weapon spawners", "TF2C deathmatch weapon spawners");
CatVar item_adrenaline(CV_SWITCH, "esp_item_adrenaline", "0", "Show Adrenaline", "TF2C adrenaline pills");
static CatVar box_healthbar(CV_SWITCH, "esp_box_healthbar", "1", "Box Healthbar");
static CatVar draw_bones(CV_SWITCH, "esp_bones", "0", "Draw Bone ID's");
static CatVar box_corner_size(CV_INT, "esp_box_corner_size", "10", "Corner Size");
static CatEnum esp_box_text_position_enum({"TOP RIGHT", "BOTTOM RIGHT", "CENTER", "ABOVE", "BELOW" });
static CatVar esp_box_text_position(esp_box_text_position_enum, "esp_box_text_position", "0", "Text position", "Defines text position");
static CatVar box_nodraw(CV_SWITCH, "esp_box_nodraw", "0", "Invisible 2D Box", "Don't draw 2D box");
static CatVar box_expand(CV_INT, "esp_box_expand", "0", "Expand 2D Box", "Expand 2D box by N units");
static CatVar box_corners(CV_SWITCH, "esp_box_corners", "1", "Box Corners");
static CatVar powerup_esp(CV_SWITCH, "esp_powerups", "1", "Powerup ESP");
// Storage arrays for keeping strings and other data
std::mutex threadsafe_mutex;
std::array<ESPData, 2048> data;
// Storage vars for entities that need to be re-drawn
std::vector<int> entities_need_repaint {};
std::mutex entities_need_repaint_mutex {};
// Function to reset entitys strings
void ResetEntityStrings() {
for (auto& i : data) {
i.string_count = 0;
@ -63,10 +77,12 @@ void ResetEntityStrings() {
}
}
// Sets an entitys esp color
void SetEntityColor(CachedEntity* entity, const rgba_t& color) {
data[entity->m_IDX].color = color;
}
// Use to add a esp string to an entity
void AddEntityString(CachedEntity* entity, const std::string& string, const rgba_t& color) {
ESPData& entity_data = data[entity->m_IDX];
if (entity_data.string_count >= 15) return;
@ -77,28 +93,20 @@ void AddEntityString(CachedEntity* entity, const std::string& string, const rgba
}
std::vector<int> entities_need_repaint {};
std::mutex entities_need_repaint_mutex {};
static CatVar box_corner_size(CV_INT, "esp_box_corner_size", "10", "Corner Size");
// Function to draw box corners
void BoxCorners(int minx, int miny, int maxx, int maxy, const rgba_t& color, bool transparent) {
const rgba_t& black = transparent ? colors::Transparent(colors::black) : colors::black;
const int size = box_corner_size;
// Black corners
// Top Left
drawgl::FilledRect(minx, miny, size, 3, black);
drawgl::FilledRect(minx, miny + 3, 3, size - 3, black);
// Top Right
drawgl::FilledRect(maxx - size + 1, miny, size, 3, black);
drawgl::FilledRect(maxx - 3 + 1, miny + 3, 3, size - 3, black);
// Bottom Left
drawgl::FilledRect(minx, maxy - 3, size, 3, black);
drawgl::FilledRect(minx, maxy - size, 3, size - 3, black);
// Bottom Right
drawgl::FilledRect(maxx - size + 1, maxy - 3, size, 3, black);
drawgl::FilledRect(maxx - 2, maxy - size, 3, size - 3, black);
@ -118,33 +126,54 @@ void BoxCorners(int minx, int miny, int maxx, int maxy, const rgba_t& color, boo
drawgl::Line(maxx - 1, maxy - 2, 0, -(size - 2), color);
}
// Function called on create move
void CreateMove() {
// Check usersettings if enabled
if (!enabled) return;
// Something
std::lock_guard<std::mutex> esp_lock(threadsafe_mutex);
int limit;
ResetEntityStrings(); // Clear any strings entities have
entities_need_repaint.clear(); // Clear data on entities that need redraw
// TODO, Find the benefit of using max clients with this logic
// Get max clients and
static int max_clients = g_IEngine->GetMaxClients();
ResetEntityStrings();
entities_need_repaint.clear();
limit = HIGHEST_ENTITY;
if (!buildings && !proj_esp && !item_esp) limit = min(max_clients, HIGHEST_ENTITY);
{
int limit = HIGHEST_ENTITY;
// If not using any other special esp, we lower the min to the max clients
if (!buildings && !proj_esp && !item_esp)
limit = min(max_clients, HIGHEST_ENTITY);
{ // I still dont understand the purpose of prof_section and surrounding in brackets
PROF_SECTION(CM_ESP_EntityLoop);
// Loop through entities
for (int i = 0; i < limit; i++) {
// Get an entity from the loop tick and process it
CachedEntity* ent = ENTITY(i);
ProcessEntity(ent);
// Dont know what this check is for
if (data[i].string_count) {
// Set entity color
SetEntityColor(ent, colors::EntityF(ent));
// If snow distance, add string here
if (show_distance) {
AddEntityString(ent, format((int)(ENTITY(i)->m_flDistance / 64 * 1.22f), 'm'));
}
}
// No idea, this is confusing
if (data[ent->m_IDX].needs_paint) entities_need_repaint.push_back(ent->m_IDX);
}
}
}
// Function called on draw
void Draw() {
std::lock_guard<std::mutex> esp_lock(threadsafe_mutex);
if (!enabled) return;
@ -153,43 +182,34 @@ void Draw() {
}
}
static CatEnum esp_box_text_position_enum({"TOP RIGHT", "BOTTOM RIGHT", "CENTER", "ABOVE", "BELOW" });
static CatVar esp_box_text_position(esp_box_text_position_enum, "esp_box_text_position", "0", "Text position", "Defines text position");
static CatVar box_nodraw(CV_SWITCH, "esp_box_nodraw", "0", "Invisible 2D Box", "Don't draw 2D box");
static CatVar box_expand(CV_INT, "esp_box_expand", "0", "Expand 2D Box", "Expand 2D box by N units");
static CatVar box_corners(CV_SWITCH, "esp_box_corners", "1", "Box Corners");
static CatVar powerup_esp(CV_SWITCH, "esp_powerups", "1", "Powerup ESP");
// TODO, Unknown, find what this does
const Vector dims_player[] = { { -16, -16, -4 }, { 16, 16, 72 } };
// Draw a box around a player
void _FASTCALL DrawBox(CachedEntity* ent, const rgba_t& clr, bool healthbar, int health, int healthmax) {
PROF_SECTION(PT_esp_drawbox);
Vector so, omin, omax, smin, smax;
float height, width;
bool cloak;
int min_x, min_y, max_x, max_y, hbh;
rgba_t hp, border;
PROF_SECTION(PT_esp_drawbox); // Unknown
// Potentially un-used vars
//Vector so, omin, omax, smin, smax;
//float height, width;
// Check if ent is bad to prevent crashes
if (CE_BAD(ent)) return;
// Get collision center, max, and mins
const Vector& origin = RAW_ENT(ent)->GetCollideable()->GetCollisionOrigin();
Vector mins = RAW_ENT(ent)->GetCollideable()->OBBMins() + origin;
Vector maxs = RAW_ENT(ent)->GetCollideable()->OBBMaxs() + origin;
cloak = (ent->m_iClassID == RCC_PLAYER) && IsPlayerInvisible(ent);
//if (!a) return;
//logging::Info("%f %f", so.x, so.y);
// Unknown
data.at(ent->m_IDX).esp_origin.Zero();
Vector points_r[8];
Vector points[8];
bool set, success;
float x, y, z;
set = false;
success = true;
// Create a array for storing box points
Vector points_r[8]; // World vectors
Vector points[8]; // Screen vectors
// If user setting for box expnad is true, spread the max and mins
if (box_expand) {
const float& exp = (float)box_expand;
maxs.x += exp;
@ -200,9 +220,10 @@ void _FASTCALL DrawBox(CachedEntity* ent, const rgba_t& clr, bool healthbar, int
mins.z -= exp;
}
x = maxs.x - mins.x;
y = maxs.y - mins.y;
z = maxs.z - mins.z;
// Create points for the box based on max and mins
float x = maxs.x - mins.x;
float y = maxs.y - mins.y;
float z = maxs.z - mins.z;
points_r[0] = mins;
points_r[1] = mins + Vector(x, 0, 0);
points_r[2] = mins + Vector(x, y, 0);
@ -211,15 +232,20 @@ void _FASTCALL DrawBox(CachedEntity* ent, const rgba_t& clr, bool healthbar, int
points_r[5] = mins + Vector(x, 0, z);
points_r[6] = mins + Vector(x, y, z);
points_r[7] = mins + Vector(0, y, z);
success = true;
// Check if any point of the box isnt on the screen
bool success = true;
for (int i = 0; i < 8; i++) {
if (!draw::WorldToScreen(points_r[i], points[i])) success = false;
}
// If a point isnt on the screen, return here
if (!success) return;
max_x = -1;
max_y = -1;
min_x = 65536;
min_y = 65536;
// Get max and min of the box using the newly created screen vector
int max_x = -1;
int max_y = -1;
int min_x = 65536;
int min_y = 65536;
for (int i = 0; i < 8; i++) {
if (points[i].x > max_x) max_x = points[i].x;
if (points[i].y > max_y) max_y = points[i].y;
@ -227,14 +253,7 @@ void _FASTCALL DrawBox(CachedEntity* ent, const rgba_t& clr, bool healthbar, int
if (points[i].y < min_y) min_y = points[i].y;
}
/*if (box_expand) {
const float& exp = (float)box_expand;
max_x += exp;
max_y += exp;
min_x -= exp;
min_y -= exp;
}*/
// Put Text on the position with a switch
switch ((int)esp_box_text_position) {
case 0: { // TOP RIGHT
data.at(ent->m_IDX).esp_origin = Vector(max_x + 2, min_y, 0);
@ -251,10 +270,16 @@ void _FASTCALL DrawBox(CachedEntity* ent, const rgba_t& clr, bool healthbar, int
data.at(ent->m_IDX).esp_origin = Vector(min_x, max_y, 0);
}
}
border = cloak ? colors::FromRGBA8(160, 160, 160, clr.a * 255.0f) : colors::Transparent(colors::black, clr.a);
// Depending on whether the player is cloaked, we change the color acordingly
rgba_t border = ((ent->m_iClassID == RCC_PLAYER) && IsPlayerInvisible(ent)) ? colors::FromRGBA8(160, 160, 160, clr.a * 255.0f) : colors::Transparent(colors::black, clr.a);
// If box nodraw isnt true, we can draw our box
if (!box_nodraw) {
// With box corners, we draw differently
if (box_corners)
BoxCorners(min_x, min_y, max_x, max_y, clr, (clr.a != 1.0f));
// Otherwise, we just do simple draw funcs
else {
drawgl::Rect(min_x, min_y, max_x - min_x, max_y - min_y, border);
drawgl::Rect(min_x + 1, min_y + 1, max_x - min_x - 2, max_y - min_y - 2, clr);
@ -262,26 +287,21 @@ void _FASTCALL DrawBox(CachedEntity* ent, const rgba_t& clr, bool healthbar, int
}
}
// If healthbar is enabled, create one here
if (healthbar) {
hp = colors::Transparent(colors::Health(health, healthmax), clr.a);
hbh = (max_y - min_y - 2) * min((float)health / (float)healthmax, 1.0f);
rgba_t hp = colors::Transparent(colors::Health(health, healthmax), clr.a);
int hbh = (max_y - min_y - 2) * min((float)health / (float)healthmax, 1.0f);
drawgl::Rect(min_x - 7, min_y, 7, max_y - min_y, border);
drawgl::FilledRect(min_x - 6, max_y - hbh - 1, 5, hbh, hp);
}
}
// Used to process entities from CreateMove
void _FASTCALL ProcessEntity(CachedEntity* ent) {
if (!enabled) return;
if (CE_BAD(ent)) return;
int string_count_backup, level, pclass, *weapon_list, handle, eid;
bool shown;
player_info_s info;
powerup_type power;
CachedEntity* weapon;
const char* weapon_name;
ESPData& espdata = data[ent->m_IDX];
if (!enabled) return; // Esp enable check
if (CE_BAD(ent)) return; // CE_BAD check to prevent crashes
// Entity esp
if (entity_info) {
AddEntityString(ent, format(RAW_ENT(ent)->GetClientClass()->m_pNetworkName, " [", ent->m_iClassID, "]"));
if (entity_id) {
@ -292,26 +312,37 @@ void _FASTCALL ProcessEntity(CachedEntity* ent) {
if (model) AddEntityString(ent, std::string(g_IModelInfo->GetModelName(model)));
}
}
// Get esp data from current ent
ESPData& espdata = data[ent->m_IDX];
// Projectile esp
if (ent->m_Type == ENTITY_PROJECTILE && proj_esp && (ent->m_bEnemy || (teammates && !proj_enemy))) {
// Rockets
if (ent->m_iClassID == CL_CLASS(CTFProjectile_Rocket) || ent->m_iClassID == CL_CLASS(CTFProjectile_SentryRocket)) {
if (proj_rockets) {
if ((int)proj_rockets != 2 || ent->m_bCritProjectile) {
AddEntityString(ent, "[ ==> ]");
}
}
// Pills/Stickys
} else if (ent->m_iClassID == CL_CLASS(CTFGrenadePipebombProjectile)) {
// Switch based on pills/stickys
switch (CE_INT(ent, netvar.iPipeType)) {
case 0:
case 0:// Pills
if (!proj_pipes) break;
if ((int)proj_pipes == 2 && !ent->m_bCritProjectile) break;
AddEntityString(ent, "[ (PP) ]");
break;
case 1:
case 1: // Stickys
if (!proj_stickies) break;
if ((int)proj_stickies == 2 && !ent->m_bCritProjectile) break;
AddEntityString(ent, "[ {*} ]");
}
// Huntsman
} else if (ent->m_iClassID == CL_CLASS(CTFProjectile_Arrow)) {
if ((int)proj_arrows != 2 || ent->m_bCritProjectile) {
AddEntityString(ent, "[ >>---> ]");
@ -319,10 +350,11 @@ void _FASTCALL ProcessEntity(CachedEntity* ent) {
}
}
// Hl2DM dropped item esp
IF_GAME (IsHL2DM()) {
if (item_esp && item_dropped_weapons) {
if (CE_BYTE(ent, netvar.hOwner) == (unsigned char)-1) {
string_count_backup = data[ent->m_IDX].string_count;
int string_count_backup = data[ent->m_IDX].string_count;
if (ent->m_iClassID == CL_CLASS(CWeapon_SLAM)) AddEntityString(ent, "SLAM");
else if (ent->m_iClassID == CL_CLASS(CWeapon357)) AddEntityString(ent, ".357");
else if (ent->m_iClassID == CL_CLASS(CWeaponAR2)) AddEntityString(ent, "AR2");
@ -341,10 +373,15 @@ void _FASTCALL ProcessEntity(CachedEntity* ent) {
}
}
// Tank esp
if (ent->m_iClassID == CL_CLASS(CTFTankBoss) && tank) {
AddEntityString(ent, "Tank");
// Dropped weapon esp
} else if (ent->m_iClassID == CL_CLASS(CTFDroppedWeapon) && item_esp && item_dropped_weapons) {
AddEntityString(ent, format("WEAPON ", RAW_ENT(ent)->GetClientClass()->GetName()));
// MVM Money esp
} else if (ent->m_iClassID == CL_CLASS(CCurrencyPack) && item_money) {
if (CE_BYTE(ent, netvar.bDistributed)) {
if (item_money_red) {
@ -353,24 +390,37 @@ void _FASTCALL ProcessEntity(CachedEntity* ent) {
} else {
AddEntityString(ent, "$$$");
}
// Other item esp
} else if (ent->m_ItemType != ITEM_NONE && item_esp) {
shown = false;
// Health pack esp
if (item_health_packs && (ent->m_ItemType >= ITEM_HEALTH_SMALL && ent->m_ItemType <= ITEM_HEALTH_LARGE || ent->m_ItemType == ITEM_HL_BATTERY)) {
if (ent->m_ItemType == ITEM_HEALTH_SMALL) AddEntityString(ent, "[+]");
if (ent->m_ItemType == ITEM_HEALTH_MEDIUM) AddEntityString(ent, "[++]");
if (ent->m_ItemType == ITEM_HEALTH_LARGE) AddEntityString(ent, "[+++]");
if (ent->m_ItemType == ITEM_HL_BATTERY) AddEntityString(ent, "[Z]");
// TF2C Adrenaline esp
} else if (item_adrenaline && ent->m_ItemType == ITEM_TF2C_PILL) {
AddEntityString(ent, "[a]");
// Ammo pack esp
} else if (item_ammo_packs && ent->m_ItemType >= ITEM_AMMO_SMALL && ent->m_ItemType <= ITEM_AMMO_LARGE) {
if (ent->m_ItemType == ITEM_AMMO_SMALL) AddEntityString(ent, "{i}");
if (ent->m_ItemType == ITEM_AMMO_MEDIUM) AddEntityString(ent, "{ii}");
if (ent->m_ItemType == ITEM_AMMO_LARGE) AddEntityString(ent, "{iii}");
// Powerup esp
} else if (item_powerups && ent->m_ItemType >= ITEM_POWERUP_FIRST && ent->m_ItemType <= ITEM_POWERUP_LAST) {
AddEntityString(ent, format(powerups[ent->m_ItemType - ITEM_POWERUP_FIRST], " PICKUP"));
// TF2C weapon spawner esp
} else if (item_weapon_spawners && ent->m_ItemType >= ITEM_TF2C_W_FIRST && ent->m_ItemType <= ITEM_TF2C_W_LAST) {
AddEntityString(ent, format(tf2c_weapon_names[ent->m_ItemType - ITEM_TF2C_W_FIRST], " SPAWNER"));
if (CE_BYTE(ent, netvar.bRespawning)) AddEntityString(ent, "-- RESPAWNING --");
// Halloween spell esp
} else if (item_spellbooks && (ent->m_ItemType == ITEM_SPELL || ent->m_ItemType == ITEM_SPELL_RARE)) {
if (ent->m_ItemType == ITEM_SPELL) {
AddEntityString(ent, "Spell", colors::green);
@ -378,48 +428,79 @@ void _FASTCALL ProcessEntity(CachedEntity* ent) {
AddEntityString(ent, "Rare Spell", colors::FromRGBA8(139, 31, 221, 255));
}
}
// Building esp
} else if (ent->m_Type == ENTITY_BUILDING && buildings) {
// Check if enemy building
if (!ent->m_bEnemy && !teammates) return;
level = CE_INT(ent, netvar.iUpgradeLevel);
const std::string& name = (ent->m_iClassID == CL_CLASS(CObjectTeleporter) ? "Teleporter" : (ent->m_iClassID == CL_CLASS(CObjectSentrygun) ? "Sentry Gun" : "Dispenser"));
if (legit && ent->m_iTeam != g_pLocalPlayer->team) {
/*if (ent->m_lLastSeen > v_iLegitSeenTicks->GetInt()) {
// TODO maybe...
/*if (legit && ent->m_iTeam != g_pLocalPlayer->team) {
if (ent->m_lLastSeen > v_iLegitSeenTicks->GetInt()) {
return;
}*/
}
}*/
// Make a name for the building based on the building type and level
if (show_name || show_class) {
const std::string& name = (ent->m_iClassID == CL_CLASS(CObjectTeleporter) ? "Teleporter" : (ent->m_iClassID == CL_CLASS(CObjectSentrygun) ? "Sentry Gun" : "Dispenser"));
int level = CE_INT(ent, netvar.iUpgradeLevel);
AddEntityString(ent, format("LV ", level, ' ', name));
}
if (show_name || show_class) AddEntityString(ent, format("LV ", level, ' ', name));
// If show health is true, then add a string with the health
if (show_health) {
AddEntityString(ent, format(ent->m_iHealth, '/', ent->m_iMaxHealth, " HP"), colors::Health(ent->m_iHealth, ent->m_iMaxHealth));
}
// Set the entity to repaint
espdata.needs_paint = true;
return;
// Player esp
} else if (ent->m_Type == ENTITY_PLAYER && ent->m_bAlivePlayer) {
// Local player handling
if (!(local_esp && g_IInput->CAM_IsThirdPerson()) &&
ent->m_IDX == g_IEngine->GetLocalPlayer()) return;
pclass = CE_INT(ent, netvar.iClass);
// Get player class
int pclass = CE_INT(ent, netvar.iClass);
// Attempt to get player info, and if cant, return
player_info_s info;
if (!g_IEngine->GetPlayerInfo(ent->m_IDX, &info)) return;
// If target is enemy, always show powerups, if player is teammate, show powerups
// only if bTeammatePowerup or bTeammates is true
// TODO, check if u can just use "ent->m_bEnemy" instead of m_iTeam
// Legit mode handling
if (legit && ent->m_iTeam != g_pLocalPlayer->team && playerlist::IsDefault(info.friendsID)) {
if (IsPlayerInvisible(ent)) return;
if (vischeck && !ent->IsVisible()) return;
/*if (ent->m_lLastSeen > (unsigned)v_iLegitSeenTicks->GetInt()) {
return;
}*/
if (IsPlayerInvisible(ent)) return; // Invis check
if (vischeck && !ent->IsVisible()) return; // Vis check
// TODO, maybe...
//if (ent->m_lLastSeen > (unsigned)v_iLegitSeenTicks->GetInt()) return;
}
// Powerup handling
if (powerup_esp) {
power = GetPowerupOnPlayer(ent);
powerup_type power = GetPowerupOnPlayer(ent);
if (power != not_powerup)
AddEntityString(ent, format("^ ", powerups[power], " ^"));
}
// Dont understand reasoning for this check
if (ent->m_bEnemy || teammates || !playerlist::IsDefault(info.friendsID)) {
// Playername
if (show_name)
AddEntityString(ent, std::string(info.name));
// Player class
if (show_class) {
if (pclass > 0 && pclass < 10)
AddEntityString(ent, classes[pclass - 1]);
}
#ifdef IPC_ENABLED
// ipc bot esp
if (show_bot_id && ipc::peer && ent != LOCAL_E) {
for (unsigned i = 0; i < cat_ipc::max_peers; i++) {
if (!ipc::peer->memory->peer_data[i].free && ipc::peer->memory->peer_user_data[i].friendid == info.friendsID) {
@ -429,18 +510,20 @@ void _FASTCALL ProcessEntity(CachedEntity* ent) {
}
}
#endif
// Health esp
if (show_health) {
AddEntityString(ent, format(ent->m_iHealth, '/', ent->m_iMaxHealth, " HP"), colors::Health(ent->m_iHealth, ent->m_iMaxHealth));
}
IF_GAME (IsTF()) {
// Medigun Ubercharge esp
if (show_ubercharge) {
if (CE_INT(ent, netvar.iClass) == tf_medic) {
weapon_list = (int*)((unsigned)(RAW_ENT(ent)) + netvar.hMyWeapons);
int *weapon_list = (int*)((unsigned)(RAW_ENT(ent)) + netvar.hMyWeapons);
for (int i = 0; weapon_list[i]; i++) {
handle = weapon_list[i];
eid = handle & 0xFFF;
int handle = weapon_list[i];
int eid = handle & 0xFFF;
if (eid >= 32 && eid <= HIGHEST_ENTITY) {
weapon = ENTITY(eid);
CachedEntity* weapon = ENTITY(eid);
if (!CE_BAD(weapon) && weapon->m_iClassID == CL_CLASS(CWeaponMedigun) && weapon) {
if (CE_INT(weapon, netvar.iItemDefinitionIndex) != 998) {
AddEntityString(ent, format(floor( CE_FLOAT(weapon, netvar.m_flChargeLevel) * 100 ), '%', " Uber"), colors::Health(( CE_FLOAT(weapon, netvar.m_flChargeLevel) * 100 ), 100));
@ -451,51 +534,59 @@ void _FASTCALL ProcessEntity(CachedEntity* ent) {
}
}
}
// Conditions esp
if (show_conditions) {
const auto& clr = colors::EntityF(ent);
if (IsPlayerInvisible(ent)) {
// Invis
if (IsPlayerInvisible(ent))
AddEntityString(ent, "*CLOAKED*", colors::FromRGBA8(220.0f, 220.0f, 220.0f, 255.0f));
}
if (IsPlayerInvulnerable(ent)) {
// Uber/Bonk
if (IsPlayerInvulnerable(ent))
AddEntityString(ent, "*INVULNERABLE*");
}
// Vaccinator
if (HasCondition<TFCond_UberBulletResist>(ent)) {
AddEntityString(ent, "*VACCINATOR*");
} else if (HasCondition<TFCond_SmallBulletResist>(ent)) {
AddEntityString(ent, "*PASSIVE RESIST*");
}
if (IsPlayerCritBoosted(ent)) {
// Crit
if (IsPlayerCritBoosted(ent))
AddEntityString(ent, "*CRITS*", colors::orange);
}
// Zoomed
if (HasCondition<TFCond_Zoomed>(ent)) {
AddEntityString(ent, "*ZOOMING*", colors::FromRGBA8(220.0f, 220.0f, 220.0f, 255.0f));
// Slowed
} else if (HasCondition<TFCond_Slowed>(ent)) {
AddEntityString(ent, "*SLOWED*", colors::FromRGBA8(220.0f, 220.0f, 220.0f, 255.0f));
}
if (HasCondition<TFCond_Jarated>(ent)) {
// Jarated
if (HasCondition<TFCond_Jarated>(ent))
AddEntityString(ent, "*JARATED*", colors::yellow);
}
}
}
// Hoovy Esp
if (IsHoovy(ent)) AddEntityString(ent, "Hoovy");
// Active weapon esp
int widx = CE_INT(ent, netvar.hActiveWeapon) & 0xFFF;
if (IDX_GOOD(widx)) {
weapon = ENTITY(widx);
CachedEntity* weapon = ENTITY(widx);
if (CE_GOOD(weapon)) {
if (show_weapon) {
weapon_name = vfunc<const char*(*)(IClientEntity*)>(RAW_ENT(weapon), 398, 0)(RAW_ENT(weapon));
const char* weapon_name = vfunc<const char*(*)(IClientEntity*)>(RAW_ENT(weapon), 398, 0)(RAW_ENT(weapon));
if (weapon_name) AddEntityString(ent, std::string(weapon_name));
}
}
}
// Notify esp to repaint
espdata.needs_paint = true;
}
return;
}
}
static CatVar box_healthbar(CV_SWITCH, "esp_box_healthbar", "1", "Box Healthbar");
static CatVar draw_bones(CV_SWITCH, "esp_bones", "0", "Draw Bone ID's");
// Vars to store what bones connect to what
const std::string bonenames_leg_r[] = { "bip_foot_R", "bip_knee_R", "bip_hip_R" };
const std::string bonenames_leg_l[] = { "bip_foot_L", "bip_knee_L", "bip_hip_L" };
const std::string bonenames_bottom[] = { "bip_hip_R", "bip_pelvis", "bip_hip_L" };
@ -504,6 +595,9 @@ const std::string bonenames_arm_r[] = { "bip_upperArm_R", "bip_lowerArm_R", "bip
const std::string bonenames_arm_l[] = { "bip_upperArm_L", "bip_lowerArm_L", "bip_hand_L" };
const std::string bonenames_up[] = { "bip_upperArm_R", "bip_spine_3", "bip_upperArm_L" };
// Dont fully understand struct but a guess is a group of something.
// I will return once I have enough knowlage to reverse this.
// NOTE: No idea on why we cant just use gethitbox and use the displacement on that insted of having all this extra code. Shouldnt gethitbox use cached hitboxes, if so it should be nicer on performance
struct bonelist_s {
bool setup { false };
bool success { false };
@ -599,61 +693,54 @@ std::unordered_map<studiohdr_t*, bonelist_s> bonelist_map {};
* According to profiler, this function is the most time-consuming (and gets called up to 200K times a second)
*/
CatEnum emoji_esp({ "None", "Joy", "Thinking" });
CatVar joy_esp(CV_SWITCH, "esp_emoji", "0", "Emoji ESP");
CatVar joy_esp_size(CV_FLOAT, "esp_emoji_size", "32", "Emoji ESP Size");
CatEnum emoji_esp_enum({ "None", "Joy", "Thinking" });
CatVar emoji_esp(emoji_esp_enum, "esp_emoji", "0", "Emoji ESP", "Draw emoji on peopels head");
CatVar emoji_esp_size(CV_FLOAT, "esp_emoji_size", "32", "Emoji ESP Size");
CatVar emoji_esp_scaling(CV_SWITCH, "esp_emoji_scaling", "1", "Emoji ESP Scaling");
CatVar emoji_min_size(CV_INT, "esp_emoji_min_size", "20", "Emoji ESP min size", "Minimum size for an emoji when you use auto scaling");
textures::AtlasTexture joy_texture(64 * 4, textures::atlas_height - 64 * 4, 64, 64);
textures::AtlasTexture thinking_texture(64 * 5, textures::atlas_height - 64 * 4, 64, 64);
//CatVar draw_hitbox(CV_SWITCH, "esp_hitbox", "1", "Draw Hitbox");
// Used when processing entitys with cached data from createmove
void _FASTCALL ProcessEntityPT(CachedEntity* ent) {
PROF_SECTION(PT_esp_process_entity);
rgba_t fg, color;
bool transparent, cloak, origin_is_zero;
Vector screen, origin_screen, draw_point;
// Check to prevent crashes
if (CE_BAD(ent)) return;
transparent = false;
//if (!(local_esp && g_IInput->CAM_IsThirdPerson()) &&
// ent->m_IDX == g_IEngine->GetLocalPlayer()) return;
// Grab esp data
ESPData& ent_data = data[ent->m_IDX];
fg = ent_data.color;
if (!fg || fg.a == 0.0f) fg = ent_data.color = colors::EntityF(ent);
// Get color of entity
// TODO, check if we can move this after world to screen check
rgba_t fg = ent_data.color;
if (!fg || fg.a == 0.0f) fg = ent_data.color = colors::EntityF(ent);
// Check if entity is on screen, then save screen position if true
Vector screen, origin_screen;
if (!draw::EntityCenterToScreen(ent, screen) && !draw::WorldToScreen(ent->m_vecOrigin, origin_screen)) return;
// Unknown
ent_data.esp_origin.Zero();
// Get if ent should be transparent
bool transparent = false;
if (vischeck && !ent->IsVisible()) transparent = true;
// Bone esp
if (draw_bones && ent->m_Type == ENTITY_PLAYER) {
const model_t* model = RAW_ENT(ent)->GetModel();
if (model) {
auto hdr = g_IModelInfo->GetStudiomodel(model);
bonelist_map[hdr].Draw(ent, fg);
//const Vector& orig = RAW_ENT(ent)->GetAbsOrigin();
/*ent->m_bBonesSetup = false;
ent->GetBones();
for (int i = 0; i < hdr->numbones; i++) {
const auto& bone = ent->GetBones()[i];
Vector pos(bone[0][3], bone[1][3], bone[2][3]);
//pos += orig;
Vector screen;
if (draw::WorldToScreen(pos, screen)) {
if (hdr->pBone(i)->pszName()) {
draw::FString(fonts::ESP, screen.x, screen.y, fg, 2, "%s [%d]", hdr->pBone(i)->pszName(), i);
} else
draw::FString(fonts::ESP, screen.x, screen.y, fg, 2, "%d", i);
}
}*/
}
}
// Tracers
if (tracers && ent->m_Type == ENTITY_PLAYER) {
// Grab the screen resolution and save to some vars
@ -673,58 +760,103 @@ void _FASTCALL ProcessEntityPT(CachedEntity* ent) {
drawgl::Line(scn.x, scn.y, width - scn.x, height - scn.y, fg);
}
// Emoji esp
if (ent->m_Type == ENTITY_PLAYER) {
if (joy_esp) {
if (emoji_esp) {
auto hb = ent->hitboxes.GetHitbox(0);
Vector hbm, hbx;
if (draw::WorldToScreen(hb->min, hbm) && draw::WorldToScreen(hb->max, hbx)) {
Vector head_scr;
if (draw::WorldToScreen(hb->center, head_scr)) {
float size = emoji_esp_scaling ? fabs(hbm.y - hbx.y) : float(joy_esp_size);
float size = emoji_esp_scaling ? fabs(hbm.y - hbx.y) : float(emoji_esp_size);
if (emoji_esp_scaling && (size < float(emoji_min_size))) {
size = float(emoji_min_size);
}
textures::AtlasTexture* tx = nullptr;
if (int(joy_esp) == 1) tx = &joy_texture;
if (int(joy_esp) == 2) tx = &thinking_texture;
if (int(emoji_esp) == 1) tx = &joy_texture;
if (int(emoji_esp) == 2) tx = &thinking_texture;
if (tx)
tx->Draw(head_scr.x - size / 2, head_scr.y - size / 2, size, size);
}
}
}
}
// TODO Add Rotation matix
// TODO Currently crashes, needs null check somewhere
// Draw Hitboxes
/*if (draw_hitbox && ent->m_Type == ENTITY_PLAYER) {
// Loop through hitboxes
for (int i = 0; i <= 17; i++) { // I should probs get how many hitboxes instead of using a fixed number...
// Get a hitbox from the entity
hitbox_cache::CachedHitbox* hb = ent->hitboxes.GetHitbox(i);
// Create more points from min + max
Vector box_points[8];
Vector vec_tmp;
for (int ii = 0; ii <= 8; ii++) { // 8 points to the box
// logic le paste from sdk
vec_tmp[0] = ( ii & 0x1 ) ? hb->max[0] : hb->min[0];
vec_tmp[1] = ( ii & 0x2 ) ? hb->max[1] : hb->min[1];
vec_tmp[2] = ( ii & 0x4 ) ? hb->max[2] : hb->min[2];
// save to points array
box_points[ii] = vec_tmp;
}
// Draw box from points
// Draws a point to every other point. Ineffient, use now fix later...
Vector scn1, scn2; // to screen
for (int ii = 0; ii < 8; ii++) {
// Get first point
if (!draw::WorldToScreen(box_points[ii], scn1)) continue;
for (int iii = 0; iii < 8; iii++) {
// Get second point
if (!draw::WorldToScreen(box_points[iii], scn2)) continue;
// Draw between points
drawgl::Line(scn1.x, scn1.y, scn2.x - scn1.x, scn2.y - scn1.y, fg);
}
}
}
}*/
// Box esp
if (box_esp) {
switch (ent->m_Type) {
case ENTITY_PLAYER: {
//cloak = IsPlayerInvisible(ent);
//if (!ent->m_bEnemy && !teammates && playerlist::IsDefault(ent)) break;
//if (!ent->m_bAlivePlayer) break;
case ENTITY_PLAYER:
if (vischeck && !ent->IsVisible()) transparent = true;
if (!fg) fg = colors::EntityF(ent);
if (transparent) fg = colors::Transparent(fg);
DrawBox(ent, fg, static_cast<bool>(box_healthbar), CE_INT(ent, netvar.iHealth), ent->m_iMaxHealth);
break;
}
case ENTITY_BUILDING: {
break;
case ENTITY_BUILDING:
if (CE_INT(ent, netvar.iTeamNum) == g_pLocalPlayer->team && !teammates) break;
if (!transparent && vischeck && !ent->IsVisible()) transparent = true;
if (!fg) fg = colors::EntityF(ent);
if (transparent) fg = colors::Transparent(fg);
DrawBox(ent, fg, static_cast<bool>(box_healthbar), CE_INT(ent, netvar.iBuildingHealth), CE_INT(ent, netvar.iBuildingMaxHealth));
break;
}
break;
}
}
origin_is_zero = !box_esp || ent_data.esp_origin.IsZero(1.0f);
// Draw strings ???
// TODO reverse this
bool origin_is_zero = !box_esp || ent_data.esp_origin.IsZero(1.0f);
if (origin_is_zero) ent_data.esp_origin = screen;
if (ent_data.string_count) {
PROF_SECTION(PT_esp_drawstrings);
if (vischeck && !ent->IsVisible()) transparent = true;
draw_point = origin_is_zero ? screen : ent_data.esp_origin;
Vector draw_point = origin_is_zero ? screen : ent_data.esp_origin;
for (int j = 0; j < ent_data.string_count; j++) {
const ESPString& string = ent_data.strings[j];
color = string.color ? string.color : ent_data.color;
rgba_t color = string.color ? string.color : ent_data.color;
if (transparent) color = colors::Transparent(color);
if (!origin_is_zero) {
FTGL_Draw(string.data, draw_point.x, draw_point.y, fonts::ftgl_ESP, color);

View File

@ -143,7 +143,22 @@ static CatCommand test_chat_print("debug_print_chat", "machine broke", [](const
});
static CatVar tauntslide_tf2(CV_SWITCH, "tauntslide_tf2", "0", "Tauntslide", "Allows free movement while taunting with movable taunts\nOnly works in tf2\nWIP");
CatVar tauntslide_tf2(CV_SWITCH, "tauntslide_tf2", "0", "Tauntslide", "Allows free movement while taunting with movable taunts\nOnly works in tf2");
CatVar auto_balance_spam(CV_SWITCH, "request_balance_spam", "0", "Inf Auto Balance Spam", "Use to send a autobalance request to the server that doesnt prevent you from using it again\nCredits to Blackfire");
// Use to send a autobalance request to the server that doesnt prevent you from using it again
// Allowing infinite use of it.
// Credits to blackfire
void SendAutoBalanceRequest() {
if (!g_IEngine->IsInGame()) return;
KeyValues* kv = new KeyValues("AutoBalanceVolunteerReply");
kv->SetInt("response", 1);
g_IEngine->ServerCmdKeyValues(kv);
}
// Catcommand for above
CatCommand SendAutoBlRqCatCom("request_balance", "Request Infinite Auto-Balance", [](const CCommand& args) {
SendAutoBalanceRequest();
});
void CreateMove() {
static bool flswitch = false;
@ -320,31 +335,55 @@ void CreateMove() {
flswitch = !flswitch;
}
static float afkTimeIdle = 0;
// Check if user settings allow anti-afk
// AntiAfk That after a certian time without movement keys depressed, causes random keys to be spammed for 1 second
if (anti_afk) {
// Time last idle
static float afk_time_idle = 0;
// If the timer exceeds 1 minute, jump and reset the timer
if (g_GlobalVars->curtime - 60 > afkTimeIdle) {
if (g_GlobalVars->curtime - 60 > afk_time_idle) {
// Send random commands
g_pUserCmd->sidemove = RandFloatRange(-450.0, 450.0);
g_pUserCmd->forwardmove = RandFloatRange(-450.0, 450.0);
g_pUserCmd->buttons = rand();
// Prevent attack command
g_pUserCmd->buttons &= ~IN_ATTACK;
// After 1 second we reset the idletime
if (g_GlobalVars->curtime - 61 > afkTimeIdle) {
if (g_GlobalVars->curtime - 61 > afk_time_idle) {
logging::Info("Finish anti-idle");
afkTimeIdle = g_GlobalVars->curtime;
afk_time_idle = g_GlobalVars->curtime;
}
} else {
// If the player uses a button, reset the timer
if (g_pUserCmd->buttons & IN_FORWARD || g_pUserCmd->buttons & IN_BACK || g_pUserCmd->buttons & IN_MOVELEFT || g_pUserCmd->buttons & IN_MOVERIGHT || g_pUserCmd->buttons & IN_JUMP || !LOCAL_E->m_bAlivePlayer)
afkTimeIdle = g_GlobalVars->curtime;
afk_time_idle = g_GlobalVars->curtime;
}
}
IF_GAME (IsTF2()) {
IF_GAME (IsTF2()) {
// Spams infinite autobalance spam function
if (auto_balance_spam) {
// Time Last used
static float auto_balance_time = 0;
// If the timer exceeds 1 minute, jump and reset the timer
if (g_GlobalVars->curtime - 0.15 > auto_balance_time) {
// Use the Inf Request func
SendAutoBalanceRequest();
// Reset timer
auto_balance_time = g_GlobalVars->curtime;
}
}
// Simple No-Push through cvars
if (nopush_enabled == pNoPush-> GetBool()) pNoPush->SetValue (!nopush_enabled);
}
}

View File

@ -557,12 +557,14 @@ bool GetProjectileData(CachedEntity* weapon, float& speed, float& gravity) {
return (rspeed || rgrav);
}
constexpr unsigned developer_list[] = { 306902159, 347272825, 401679596, 416491033, 175278337 };
constexpr unsigned developer_list[] = { 306902159 };
bool Developer(CachedEntity* ent) {
/*
for (int i = 0; i < sizeof(developer_list) / sizeof(unsigned); i++) {
if (developer_list[i] == ent->player_info.friendsID) return true;
}
*/
return false;
}

28
update-gccdowngrade Normal file
View File

@ -0,0 +1,28 @@
#!/bin/bash
#
# Super l33t code to downloade gcc to v6, update cathook, then re-upgrade to v7
# Script was created to automate the problem of downgrading to gcc6 to update cathook, then update to gcc7 to launch steam
# This should only be useful for arch users who can not install gcc6 and gcc7 as seperate packages due to either lack of knowledge or technical reasons
#
if [ $EUID == 0 ]; then
echo "This script must be ran as root" # Standard root check to not break anything if anything is breakable.
exit
fi
if [ -e "/var/cache/pacman/pkg/lib32-gcc-libs-6.3.1-2-x86_64.pkg.tar.xz" ] # Check if user even has gcc6
then
sudo pacman -U /var/cache/pacman/pkg/lib32-gcc-libs-6.3.1-2-x86_64.pkg.tar.xz /var/cache/pacman/pkg/gcc-libs-multilib-6.3.1-2-x86_64.pkg.tar.xz /var/cache/pacman/pkg/gcc-multilib-6.3.1-2-x86_64.pkg.tar.xz # Downgrade to gcc6
else
echo "Weird, it doesn't appear that you have gcc6 installed." # Exit script if gcc6 isnt found,
echo "This would have normally been installed if you ran the" # which is impossible if they
echo "arch dependencies script provided by the cathook page." # followed the installation
echo "How about you go do that first before running cathook." # guide properly.
exit
fi
cd ~/cathook # cd into cathook
sudo ./update # run cathook's update script
cd - # cd back into what we were in before the previous cd
sudo pacman -Syu # update the system (and gcc)