diff --git a/.circleci/config.yml b/.circleci/config.yml index 2b8eef88..367ed6b7 100755 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: build: docker: - - image: registry.gitlab.com/nullworks/cathook-ci-docker/ubuntu-cat-dependencies:build + - image: nullworks/cathook-docker-ci:latest steps: - checkout - run: diff --git a/TODO b/TODO index 4e54f9e6..15f7c56a 100755 --- a/TODO +++ b/TODO @@ -23,12 +23,10 @@ MAX -> MIN priority // // // // // // No Trigger Mediguns // // -More projectile weapons aimbot (wrap assassin, wrangler, stickybomb, airstrike) // // +More projectile weapons aimbot (wrap assassin, wrangler, airstrike) // // // // // // -Make building aimbot compensate for gravity on projectile weapons // // // // -add Spectator Silent for projectile weapons // // // // // // // // @@ -57,10 +55,9 @@ fullbright toggle // // FLAG ESP? // // // // ESP Icons // // -ESP Distance sort // // -Show sapped buildings in ESP // // // // +ESP Distance sort // // // // carrying esp // // -Spy Cam // // +Spy Cam // // // // //------------------------------------------------------------------------------------------------------------------// // // // diff --git a/data/menu/nullifiedcat/misc/Misc2.xml b/data/menu/nullifiedcat/misc/Misc2.xml index c99a8fcf..856a3693 100755 --- a/data/menu/nullifiedcat/misc/Misc2.xml +++ b/data/menu/nullifiedcat/misc/Misc2.xml @@ -1,5 +1,6 @@ + \ No newline at end of file diff --git a/data/menu/nullifiedcat/misc/sandwich.xml b/data/menu/nullifiedcat/misc/sandwich.xml new file mode 100644 index 00000000..f60a5247 --- /dev/null +++ b/data/menu/nullifiedcat/misc/sandwich.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/include/core/netvars.hpp b/include/core/netvars.hpp index 986d5be4..258003ed 100755 --- a/include/core/netvars.hpp +++ b/include/core/netvars.hpp @@ -66,6 +66,7 @@ public: offset_t m_hBuilder; offset_t m_iObjectType; offset_t m_bMiniBuilding; + offset_t m_bHasSapper; offset_t m_bBuilding; offset_t m_iTeleState; offset_t m_flTeleRechargeTime; diff --git a/include/hooks/HookTools.hpp b/include/hooks/HookTools.hpp index 2722213e..4318cf4d 100644 --- a/include/hooks/HookTools.hpp +++ b/include/hooks/HookTools.hpp @@ -5,6 +5,7 @@ #include "core/profiler.hpp" #include #include "config.h" +#include "memory" class HookedFunction; namespace HookTools @@ -30,6 +31,9 @@ class HookedFunction std::function m_func; int m_priority; std::string m_name; +#if ENABLE_PROFILER + ProfilerSection section = ProfilerSection("UNNAMED_FUNCTIONS"); +#endif void init(HookedFunctions_types type, std::string name, int priority, std::function func) { @@ -44,11 +48,17 @@ class HookedFunction case HF_Paint: m_name = "PAINT_"; break; + default: + m_name = "UNDEFINED_"; + break; } m_name.append(name); m_priority = priority; m_func = func; m_type = type; +#if ENABLE_PROFILER + section.m_name = m_name; +#endif HookTools::GetHookedFunctions().push_back(this); } @@ -59,7 +69,6 @@ public: if (m_type == type) { #if ENABLE_PROFILER - static ProfilerSection section(m_name); ProfilerNode node(section); #endif m_func(); diff --git a/include/prediction.hpp b/include/prediction.hpp index 812faae9..96ee3a8b 100644 --- a/include/prediction.hpp +++ b/include/prediction.hpp @@ -17,6 +17,8 @@ Vector SimpleLatencyPrediction(CachedEntity *ent, int hb); bool PerformProjectilePrediction(CachedEntity *target, int hitbox); +Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, + float gravity); Vector ProjectilePrediction(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod); Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, diff --git a/include/visual/colors.hpp b/include/visual/colors.hpp index a6fc93b4..df598905 100644 --- a/include/visual/colors.hpp +++ b/include/visual/colors.hpp @@ -125,19 +125,19 @@ constexpr rgba_t empty = FromRGBA8(0, 0, 0, 0); constexpr rgba_t FromHSL(float h, float s, float v) { - if (s <= 0.0) + if (s <= 0.0f) { // < is bogus, just shuts up warnings return rgba_t{ v, v, v, 1.0f }; } float hh = h; - if (hh >= 360.0) - hh = 0.0; - hh /= 60.0; + if (hh >= 360.0f) + hh = 0.0f; + hh /= 60.0f; long i = long(hh); float ff = hh - i; - float p = v * (1.0 - s); - float q = v * (1.0 - (s * ff)); - float t = v * (1.0 - (s * (1.0 - ff))); + float p = v * (1.0f - s); + float q = v * (1.0f - (s * ff)); + float t = v * (1.0f - (s * (1.0f - ff))); switch (i) { @@ -149,7 +149,6 @@ constexpr rgba_t FromHSL(float h, float s, float v) return rgba_t{ p, v, t, 1.0f }; case 3: return rgba_t{ p, q, v, 1.0f }; - break; case 4: return rgba_t{ t, p, v, 1.0f }; case 5: diff --git a/src/PlayerTools.cpp b/src/PlayerTools.cpp index b002a36a..838fe3bd 100644 --- a/src/PlayerTools.cpp +++ b/src/PlayerTools.cpp @@ -133,7 +133,7 @@ std::optional forceEspColorSteamId(unsigned id) } #endif - return std::nullopt; + return std::nullopt; } std::optional forceEspColor(CachedEntity *entity) { diff --git a/src/core/netvars.cpp b/src/core/netvars.cpp index 75865a33..24ec6624 100644 --- a/src/core/netvars.cpp +++ b/src/core/netvars.cpp @@ -124,6 +124,8 @@ void NetVars::Init() this->m_bBuilding = gNetvars.get_offset("DT_BaseObject", "m_hBuilding"); this->m_iObjectType = gNetvars.get_offset("DT_BaseObject", "m_iObjectType"); + this->m_bHasSapper = + gNetvars.get_offset("DT_BaseObject", "m_bHasSapper"); this->m_bMiniBuilding = gNetvars.get_offset("DT_BaseObject", "m_bMiniBuilding"); this->m_iTeleState = diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp index 1cdaa51a..ef6b0c8f 100644 --- a/src/hacks/Aimbot.cpp +++ b/src/hacks/Aimbot.cpp @@ -76,10 +76,16 @@ static settings::Float fovcircle_opacity{ "aimbot.fov-circle.opacity", "0.7" }; namespace hacks::shared::aimbot { +bool shouldBacktrack() +{ + return *enable && *backtrackAimbot; +} + bool IsBacktracking() { - return !(!aimkey || !aimkey.isKeyDown()) && *enable && *backtrackAimbot; + return !(!aimkey || !aimkey.isKeyDown()) && shouldBacktrack(); } + // Current Entity int target_eid{ 0 }; CachedEntity *target = 0; @@ -107,18 +113,14 @@ void CreateMove() // Auto-Unzoom if (auto_unzoom) - { if (g_pLocalPlayer->holding_sniper_rifle && g_pLocalPlayer->bZoomed && zoomTime.test_and_set(3000)) - { current_user_cmd->buttons |= IN_ATTACK2; - } - } + if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFMinigun)) - { if (auto_spin_up && !zoomTime.check(3000)) current_user_cmd->buttons |= IN_ATTACK2; - } + // We do this as we need to pass whether the aimkey allows aiming to both // the find target and aiming system. If we just call the func than toggle // aimkey would break so we save it to a var to use it twice @@ -208,7 +210,9 @@ void CreateMove() // flNextPrimaryAttack meme // target_eid = target_entity->m_IDX; - if (only_can_shoot) + if (only_can_shoot && + g_pLocalPlayer->weapon()->m_iClassID() != CL_CLASS(CTFMinigun) && + g_pLocalPlayer->weapon()->m_iClassID() != CL_CLASS(CTFLaserPointer)) { // Handle Compound bow @@ -434,8 +438,7 @@ bool IsTargetStateGood(CachedEntity *entity) { PROF_SECTION(PT_aimbot_targetstatecheck); - if (hacks::shared::backtrack::isBacktrackEnabled && - entity->m_Type() != ENTITY_PLAYER) + if (shouldBacktrack() && entity->m_Type() != ENTITY_PLAYER) return false; // Checks for Players if (entity->m_Type() == ENTITY_PLAYER) @@ -695,7 +698,7 @@ void Aim(CachedEntity *entity) auto hitboxmin = entity->hitboxes.GetHitbox(cd.hitbox)->min; auto hitboxmax = entity->hitboxes.GetHitbox(cd.hitbox)->max; auto hitboxcenter = entity->hitboxes.GetHitbox(cd.hitbox)->center; - if (hacks::shared::backtrack::isBacktrackEnabled) + if (shouldBacktrack()) { hitboxcenter = hacks::shared::backtrack::headPositions @@ -766,7 +769,7 @@ void Aim(CachedEntity *entity) if (silent && !slow_aim) g_pLocalPlayer->bUseSilentAngles = true; - if (hacks::shared::backtrack::isBacktrackEnabled) + if (shouldBacktrack()) { auto i = hacks::shared::backtrack::headPositions [hacks::shared::backtrack::iBestTarget] @@ -821,8 +824,9 @@ void DoAutoshoot() float chargebegin = *((float *) ((unsigned) RAW_ENT(LOCAL_W) + 3152)); float chargetime = g_GlobalVars->curtime - chargebegin; - // Release Sticky if > chargetime - if ((chargetime >= (float) sticky_autoshoot) && begansticky > 3) + // Release Sticky if > chargetime, 3.85 is the max second chargetime, + // but we want a percent so here we go + if ((chargetime >= 3.85f * *sticky_autoshoot) && begansticky > 3) { current_user_cmd->buttons &= ~IN_ATTACK; hacks::shared::antiaim::SetSafeSpace(3); @@ -879,6 +883,8 @@ void DoAutoshoot() if (attack) current_user_cmd->buttons |= IN_ATTACK; + if (LOCAL_W->m_iClassID() == CL_CLASS(CTFLaserPointer)) + current_user_cmd->buttons |= IN_ATTACK2; hacks::shared::antiaim::SetSafeSpace(1); } @@ -891,7 +897,7 @@ const Vector &PredictEntity(CachedEntity *entity) if (cd.predict_tick == tickcount) return result; - if (!hacks::shared::backtrack::isBacktrackEnabled || projectile_mode) + if (!shouldBacktrack() || projectile_mode) { // Players @@ -922,7 +928,8 @@ const Vector &PredictEntity(CachedEntity *entity) } else if (entity->m_Type() == ENTITY_BUILDING) { - result = GetBuildingPosition(entity); + result = BuildingPrediction(entity, GetBuildingPosition(entity), + cur_proj_speed, cur_proj_grav); // Other } else @@ -1135,7 +1142,7 @@ bool VischeckPredictedEntity(CachedEntity *entity) // Update info cd.vcheck_tick = tickcount; - if (!hacks::shared::backtrack::isBacktrackEnabled || projectile_mode) + if (!shouldBacktrack() || projectile_mode) cd.visible = IsEntityVectorVisible(entity, PredictEntity(entity)); else cd.visible = IsVectorVisible( diff --git a/src/hacks/CMakeLists.txt b/src/hacks/CMakeLists.txt index 7112faf7..9aa35914 100755 --- a/src/hacks/CMakeLists.txt +++ b/src/hacks/CMakeLists.txt @@ -7,6 +7,7 @@ if(NOT LagbotMode) target_sources(cathook PRIVATE "${CMAKE_CURRENT_LIST_DIR}/Achievement.cpp" "${CMAKE_CURRENT_LIST_DIR}/Aimbot.cpp" + "${CMAKE_CURRENT_LIST_DIR}/MiscAimbot.cpp" "${CMAKE_CURRENT_LIST_DIR}/Announcer.cpp" "${CMAKE_CURRENT_LIST_DIR}/AntiAim.cpp" "${CMAKE_CURRENT_LIST_DIR}/AntiAntiAim.cpp" diff --git a/src/hacks/ESP.cpp b/src/hacks/ESP.cpp index 79797c79..7902123f 100644 --- a/src/hacks/ESP.cpp +++ b/src/hacks/ESP.cpp @@ -1039,12 +1039,15 @@ void _FASTCALL ProcessEntity(CachedEntity *ent) ? "Teleporter" : (classid == CL_CLASS(CObjectSentrygun) ? "Sentry Gun" : "Dispenser")); - int level = CE_INT(ent, netvar.iUpgradeLevel); - int IsMini = CE_INT(ent, netvar.m_bMiniBuilding); + int level = CE_INT(ent, netvar.iUpgradeLevel); + bool IsMini = CE_BYTE(ent, netvar.m_bMiniBuilding); + bool IsSapped = CE_BYTE(ent, netvar.m_bHasSapper); if (!IsMini) AddEntityString(ent, format("LV ", level, ' ', name)); else AddEntityString(ent, format("Mini ", name)); + if (IsSapped) + AddEntityString(ent, "*Sapped*"); if (classid == CL_CLASS(CObjectTeleporter)) { float next_teleport = diff --git a/src/hacks/KillSay.cpp b/src/hacks/KillSay.cpp index 0c85864c..64c69708 100644 --- a/src/hacks/KillSay.cpp +++ b/src/hacks/KillSay.cpp @@ -25,14 +25,14 @@ const std::string tf_classes_killsay[] = { "class", "scout", "sniper", const std::string tf_teams_killsay[] = { "RED", "BLU" }; -static std::string lastmsg = ""; +static std::string lastmsg{}; TextFile file{}; std::string ComposeKillSay(IGameEvent *event) { const std::vector *source = nullptr; - switch ((int) killsay_mode) + switch (*killsay_mode) { case 1: source = &file.lines; @@ -46,8 +46,10 @@ std::string ComposeKillSay(IGameEvent *event) case 4: source = &builtin_nonecore_mlg; break; + default: + break; } - if (!source || source->size() == 0) + if (!source || source->empty()) return ""; if (!event) return ""; @@ -58,18 +60,18 @@ std::string ComposeKillSay(IGameEvent *event) if (g_IEngine->GetPlayerForUserID(kid) != g_IEngine->GetLocalPlayer()) return ""; std::string msg = source->at(rand() % source->size()); - while (msg == lastmsg) - { + // checks if the killsays.txt file is not 1 line. 100% sure it's going + // to crash if it is. + while (msg == lastmsg && source->size() > 1) msg = source->at(rand() % source->size()); - } lastmsg = msg; - player_info_s info; + player_info_s info{}; g_IEngine->GetPlayerInfo(g_IEngine->GetPlayerForUserID(vid), &info); ReplaceString(msg, "%name%", std::string(info.name)); CachedEntity *ent = ENTITY(g_IEngine->GetPlayerForUserID(vid)); int clz = g_pPlayerResource->GetClass(ent); ReplaceString(msg, "%class%", tf_classes_killsay[clz]); - player_info_s infok; + player_info_s infok{}; g_IEngine->GetPlayerInfo(g_IEngine->GetPlayerForUserID(kid), &infok); ReplaceString(msg, "%killer%", std::string(infok.name)); ReplaceString(msg, "%team%", tf_teams_killsay[ent->m_iTeam() - 2]); @@ -87,10 +89,8 @@ class KillSayEventListener : public IGameEventListener2 if (!killsay_mode) return; std::string message = hacks::shared::killsay::ComposeKillSay(event); - if (message.size()) - { + if (!message.empty()) chat_stack::Say(message, false); - } } }; @@ -123,7 +123,7 @@ const std::vector builtin_default = { "You must really like that respawn timer, %name%.", "If your main is %class%, you should give up.", - "Hey %name%, i see you can't play %class%. Try quitting the game." + "Hey %name%, i see you can't play %class%. Try quitting the game.", "%team% is filled with spergs", "%name%@gmail.com to vacreview@valvesoftware.com\nFOUND CHEATER", "\n☐ Not rekt\n ☑ Rekt\n ☑ Really Rekt\n ☑ Tyrannosaurus Rekt" diff --git a/src/hacks/MiscAimbot.cpp b/src/hacks/MiscAimbot.cpp new file mode 100644 index 00000000..bf29559f --- /dev/null +++ b/src/hacks/MiscAimbot.cpp @@ -0,0 +1,116 @@ +// +// Created by bencat07 on 28.09.18. +// + +#include "common.hpp" +#include +#include +#include +static settings::Bool enable{ "sandwichaim.enable", "false" }; +static settings::Button aimkey{ "sandwichaim.aimkey", "" }; +static settings::Int aimkey_mode{ "sandwichaim.aimkey-mode", "0" }; + +float sandwich_speed = 350.0f; +float grav = 0.25f; +std::pair FindBestEnt(bool teammate, bool Predict, bool zcheck) +{ + CachedEntity *bestent = nullptr; + float bestscr = FLT_MAX; + Vector predicted{}; + for (int i = 0; i < g_IEngine->GetMaxClients(); i++) + { + CachedEntity *ent = ENTITY(i); + if (CE_BAD(ent) || !(ent->m_bAlivePlayer()) || + (teammate && ent->m_iTeam() != LOCAL_E->m_iTeam()) || ent == LOCAL_E) + continue; + if (!teammate && ent->m_iTeam() == LOCAL_E->m_iTeam()) + continue; + if (!ent->hitboxes.GetHitbox(1)) + continue; + Vector target{}; + if (Predict) + target = ProjectilePrediction(ent, 1, sandwich_speed, grav, + PlayerGravityMod(ent)); + else + target = ent->hitboxes.GetHitbox(1)->center; + if (!IsEntityVectorVisible(ent, target)) + continue; + if (zcheck && (ent->m_vecOrigin().z - LOCAL_E->m_vecOrigin().z) > 80.0f) + continue; + float scr = ent->m_flDistance(); + if (g_pPlayerResource->GetClass(ent) == tf_medic) + scr *= 0.1f; + if (scr < bestscr) + { + bestent = ent; + predicted = target; + bestscr = scr; + } + } + return {bestent, predicted}; +} +static HookedFunction + SandwichAim(HookedFunctions_types::HF_CreateMove, "SandwichAim", 1, []() { + if (!*enable) + return; + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) + return; + if (aimkey) + { + switch (*aimkey_mode) + { + case 1: + if (!aimkey.isKeyDown()) + return; + break; + case 2: + if (aimkey.isKeyDown()) + return; + break; + default: + break; + } + } + if (LOCAL_W->m_iClassID() != CL_CLASS(CTFLunchBox)) + return; + Vector Predict; + CachedEntity *bestent = nullptr; + std::pair result{}; + result = FindBestEnt(true, true, false); + bestent = result.first; + Predict = result.second; + if (bestent) + { + Vector tr = Predict - g_pLocalPlayer->v_Eye; + Vector angles; + VectorAngles(tr, angles); + // Clamping is important + fClampAngle(angles); + current_user_cmd->viewangles = angles; + current_user_cmd->buttons |= IN_ATTACK2; + g_pLocalPlayer->bUseSilentAngles = true; + } + }); +static settings::Bool charge_aim{ "chargeaim.enable", "false"}; +static HookedFunction ChargeAimbot(HookedFunctions_types::HF_CreateMove, "ChargeAim", 1, [](){ + if (!*charge_aim) + return; + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) + return; + if (!HasCondition(LOCAL_E)) + return; + std::pair result{}; + result = FindBestEnt(false, false, true); + CachedEntity *bestent = result.first; + if (bestent && result.second.IsValid()) + { + Vector tr = result.second - g_pLocalPlayer->v_Eye; + Vector angles; + VectorAngles(tr, angles); + // Clamping is important + fClampAngle(angles); + current_user_cmd->viewangles = angles; + current_user_cmd->buttons |= IN_ATTACK2; + g_pLocalPlayer->bUseSilentAngles = true; + } +}); \ No newline at end of file diff --git a/src/hacks/NavBot.cpp b/src/hacks/NavBot.cpp index d1432c2a..bbab58d5 100644 --- a/src/hacks/NavBot.cpp +++ b/src/hacks/NavBot.cpp @@ -182,9 +182,9 @@ CachedEntity *NearestEnemy() return bestent; return nullptr; } -Timer cdr{}; -Timer cd2{}; -Timer cd3{}; +Timer ammo_health_cooldown{}; +Timer init_timer{}; +Timer nav_cooldown{}; Timer engi_spot_cd{}; Timer nav_enemy_cd{}; std::vector preferred_sniper_spots; @@ -217,9 +217,9 @@ void initonce() for (int i = 0; i < afkTicks.size(); i++) afkTicks[i].update(); priority_spots.clear(); - cdr.update(); - cd2.update(); - cd3.update(); + ammo_health_cooldown.update(); + init_timer.update(); + nav_cooldown.update(); engi_spot_cd.update(); sniper_spots.clear(); preferred_sniper_spots.clear(); @@ -451,7 +451,7 @@ static HookedFunction if (*stay_near && nav_enemy_cd.test_and_set(1000) && (!HasLowAmmo()) & (!HasLowHealth())) NavToEnemy(); - if (HasLowHealth() && cdr.test_and_set(5000)) + if (HasLowHealth() && ammo_health_cooldown.test_and_set(5000)) { CachedEntity *med = nearestHealth(); if (CE_GOOD(med)) @@ -461,7 +461,7 @@ static HookedFunction nav::NavTo(med->m_vecOrigin(), true, true, 7); } } - if (HasLowAmmo() && cdr.test_and_set(5000)) + if (HasLowAmmo() && ammo_health_cooldown.test_and_set(5000)) { CachedEntity *ammo = nearestAmmo(); if (CE_GOOD(ammo)) @@ -488,7 +488,7 @@ static HookedFunction g_GlobalVars->curtime) { waittime = 1000; - cd3.update(); + nav_cooldown.update(); if (nav::priority == 1337) nav::clearInstructions(); nav::NavTo(GetBuildingPosition(ent), false, false); @@ -499,20 +499,20 @@ static HookedFunction { if (!nav::ReadyForCommands && !spy_mode && !heavy_mode && !engi_mode) - cd3.update(); + nav_cooldown.update(); if (target_sentry && NavToSentry(3)) return; bool isready = (spy_mode || heavy_mode || engi_mode) ? true : nav::ReadyForCommands; - if (isready && cd3.test_and_set(waittime)) + if (isready && nav_cooldown.test_and_set(waittime)) { waittime = /*(spy_mode || heavy_mode || engi_mode) ? 100 : 2000*/ 0; if (!spy_mode && !heavy_mode && !engi_mode) { - cd3.update(); - if (cd2.test_and_set(5000)) + nav_cooldown.update(); + if (init_timer.test_and_set(5000)) Init(); if (!NavToSniperSpot(5)) waittime = 1; @@ -522,7 +522,7 @@ static HookedFunction CachedEntity *tar = NearestEnemy(); if (CE_BAD(tar) && last_tar == -1 && nav::ReadyForCommands) { - if (cd2.test_and_set(5000)) + if (init_timer.test_and_set(5000)) Init(); if (!NavToSniperSpot(4)) waittime = 1; @@ -535,25 +535,36 @@ static HookedFunction if (!nav::NavTo(tar->m_vecOrigin(), false)) last_tar = -1; } - else { - auto unsorted_ticks = hacks::shared::backtrack::headPositions[tar->m_IDX]; - std::vector sorted_ticks; - for (int i = 0; i < 66; i++) { - if (hacks::shared::backtrack::ValidTick(unsorted_ticks[i], tar)) + else + { + auto unsorted_ticks = hacks::shared::backtrack:: + headPositions[tar->m_IDX]; + std::vector + sorted_ticks; + for (int i = 0; i < 66; i++) + { + if (hacks::shared::backtrack::ValidTick( + unsorted_ticks[i], tar)) sorted_ticks.push_back(unsorted_ticks[i]); } - if (sorted_ticks.empty()) { + if (sorted_ticks.empty()) + { if (!nav::NavTo(tar->m_vecOrigin(), false)) last_tar = -1; return; } - std::sort(sorted_ticks.begin(), sorted_ticks.end(), - [](const hacks::shared::backtrack::BacktrackData &a, - const hacks::shared::backtrack::BacktrackData &b) { - return a.tickcount > b.tickcount; - }); + std::sort( + sorted_ticks.begin(), sorted_ticks.end(), + [](const hacks::shared::backtrack::BacktrackData + &a, + const hacks::shared::backtrack::BacktrackData + &b) { + return a.tickcount > b.tickcount; + }); - if (!sorted_ticks[5].tickcount || nav::NavTo(sorted_ticks[5].entorigin, false, false)) + if (!sorted_ticks[5].tickcount || + nav::NavTo(sorted_ticks[5].entorigin, false, + false)) if (!nav::NavTo(tar->m_vecOrigin(), false)) last_tar = -1; } @@ -563,7 +574,7 @@ static HookedFunction else { // Init things - if (cd2.test_and_set(5000)) + if (init_timer.test_and_set(5000)) Init(); // If No spots set just return if (nest_spots.empty()) @@ -674,7 +685,7 @@ static HookedFunction else if (sniper_spots.size() && nav::ReadyForCommands) { - if (cd2.test_and_set(5000)) + if (init_timer.test_and_set(5000)) Init(); if (!NavToSniperSpot(1)) waittime = 1; diff --git a/src/hitrate.cpp b/src/hitrate.cpp index 89aa68ff..b81bff91 100644 --- a/src/hitrate.cpp +++ b/src/hitrate.cpp @@ -165,8 +165,7 @@ class HurtListener : public IGameEventListener public: virtual void FireGameEvent(KeyValues *event) { - if (strcmp("player_hurt", event->GetName()) && - strcmp("player_death", event->GetName())) + if (strcmp("player_hurt", event->GetName())) return; if (g_IEngine->GetPlayerForUserID(event->GetInt("attacker")) == g_IEngine->GetLocalPlayer()) @@ -174,9 +173,7 @@ public: if (CE_GOOD(LOCAL_W) && (LOCAL_W->m_iClassID() == CL_CLASS(CTFSniperRifle) || LOCAL_W->m_iClassID() == CL_CLASS(CTFSniperRifleDecap))) - OnHit(strcmp("player_death", event->GetName()) - ? event->GetBool("crit") - : true); + OnHit(event->GetBool("crit")); } } }; diff --git a/src/hooks/CreateMove.cpp b/src/hooks/CreateMove.cpp index dd66909f..6a3e2082 100644 --- a/src/hooks/CreateMove.cpp +++ b/src/hooks/CreateMove.cpp @@ -26,7 +26,8 @@ static settings::Bool engine_pred{ "misc.engine-prediction", "false" }; static settings::Bool debug_projectiles{ "debug.projectiles", "false" }; static settings::Int semiauto{ "misc.semi-auto", "0" }; static settings::Int fakelag_amount{ "misc.fakelag", "0" }; -static settings::Bool auto_disguise{ "misc.autodisguise", "true" }; +static settings::Bool auto_disguise{ "misc.autodisguise", "false" }; +static settings::Bool fuckmode{ "misc.fuckmode", "false" }; class CMoveData; #if LAGBOT_MODE @@ -142,9 +143,7 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, { if (CE_GOOD(LOCAL_W) && minigun_jump && LOCAL_W->m_iClassID() == CL_CLASS(CTFMinigun)) - { CE_INT(LOCAL_W, netvar.iWeaponState) = 0; - } } #endif ret = original::CreateMove(this_, input_sample_time, cmd); @@ -201,6 +200,12 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, ipc::UpdateServerAddress(); #endif } + if (*fuckmode) + { + static int prevbuttons = 0; + current_user_cmd->buttons |= prevbuttons; + prevbuttons |= current_user_cmd->buttons; + } hooked_methods::CreateMove(); if (nolerp) diff --git a/src/hooks/DispatchUserMessage.cpp b/src/hooks/DispatchUserMessage.cpp index e0b8b645..5d71ba27 100644 --- a/src/hooks/DispatchUserMessage.cpp +++ b/src/hooks/DispatchUserMessage.cpp @@ -21,7 +21,15 @@ static bool retrun = false; static Timer sendmsg{}; static Timer gitgud{}; -std::string clear( 200, '\n' ); +// Using repeated char causes crash on some systems. Suboptimal solution. +const static std::string clear( + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); std::string lastfilter{}; std::string lastname{}; @@ -60,7 +68,7 @@ DEFINE_HOOKED_METHOD(DispatchUserMessage, bool, void *this_, int type, { if (!isHackActive()) return original::DispatchUserMessage(this_, type, buf); - if (retrun && gitgud.test_and_set(300)) + if (retrun && type != 47 && gitgud.test_and_set(300)) { PrintChat("\x07%06X%s\x01: %s", 0xe05938, lastname.c_str(), lastfilter.c_str()); @@ -96,16 +104,14 @@ DEFINE_HOOKED_METHOD(DispatchUserMessage, bool, void *this_, int type, std::string message{}; for (i = 0; i < 3; i++) { - int starcount = 0; while ((c = data[j++]) && (loop_index < s)) { loop_index++; if (clean_chat) + { if ((c == '\n' || c == '\r') && (i == 1 || i == 2)) - { - data[j - 1] = '*'; - starcount++; - } + data[j - 1] = '\0'; + } if (i == 1) name.push_back(c); if (i == 2) @@ -178,7 +184,7 @@ DEFINE_HOOKED_METHOD(DispatchUserMessage, bool, void *this_, int type, if (boost::contains(message2, filter) && !filtered) { filtered = true; - chat_stack::Say(". " + clear, true); + chat_stack::Say("." + clear, true); retrun = true; lastfilter = format(filter); lastname = format(name); diff --git a/src/hooks/visual/DrawModelExecute.cpp b/src/hooks/visual/DrawModelExecute.cpp index 3e7ea0fa..e8047549 100644 --- a/src/hooks/visual/DrawModelExecute.cpp +++ b/src/hooks/visual/DrawModelExecute.cpp @@ -55,17 +55,11 @@ DEFINE_HOOKED_METHOD(DrawModelExecute, void, IVModelRender *this_, { IClientEntity *ent = unk->GetIClientEntity(); if (ent) - { if (ent->entindex() == spectator_target) - { return; - } - } if (ent && !effect_chams::g_EffectChams.drawing && effect_chams::g_EffectChams.ShouldRenderChams(ent)) - { return; - } } return original::DrawModelExecute(this_, state, info, bone); diff --git a/src/ipc.cpp b/src/ipc.cpp index ca4f3b5d..9b6a440b 100644 --- a/src/ipc.cpp +++ b/src/ipc.cpp @@ -150,7 +150,7 @@ CatCommand debug_get_ingame_ipc( int count = 0; unsigned highest = 0; std::vector botlist{}; - for (unsigned i = 1; 0 < cat_ipc::max_peers; i++) + for (unsigned i = 1; i < cat_ipc::max_peers; i++) { if (!ipc::peer->memory->peer_data[i].free) { diff --git a/src/playerlist.cpp b/src/playerlist.cpp index e76bdb2e..cefe42bf 100644 --- a/src/playerlist.cpp +++ b/src/playerlist.cpp @@ -192,6 +192,8 @@ CatCommand pl_set_state( continue; std::string currname(info.name); std::replace(currname.begin(), currname.end(), ' ', '-'); + std::replace_if(currname.begin(), currname.end(), + [](char x) { return !isprint(x); }, '*'); if (currname.find(name) != 0) continue; id = i; @@ -258,6 +260,8 @@ static int cat_pl_set_state_completionCallback( continue; std::string name(info.name); std::replace(name.begin(), name.end(), ' ', '-'); + std::replace_if(name.begin(), name.end(), + [](char x) { return !isprint(x); }, '*'); names.push_back(name); } std::sort(names.begin(), names.end()); diff --git a/src/prediction.cpp b/src/prediction.cpp index 06ef1818..72d0eb38 100644 --- a/src/prediction.cpp +++ b/src/prediction.cpp @@ -256,7 +256,66 @@ Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, result.y - origin.y, result.z - origin.z);*/ return result; } +Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, + float gravity) +{ + if (!vec.z || CE_BAD(building)) + return Vector(); + Vector result = vec; + // if (not debug_pp_extrapolate) { + //} else { + // result = SimpleLatencyPrediction(ent, hb); + // + //} + float latency = g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) + + g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_INCOMING); + if (speed == 0.0f) + return Vector(); + trace::filter_no_player.SetSelf(RAW_ENT(building)); + float dtg = DistanceToGround(vec); + // TODO ProjAim + float medianTime = g_pLocalPlayer->v_Eye.DistTo(result) / speed; + float range = 1.5f; + float currenttime = medianTime - range; + if (currenttime <= 0.0f) + currenttime = 0.01f; + float besttime = currenttime; + float mindelta = 65536.0f; + Vector bestpos = result; + int maxsteps = 300; + for (int steps = 0; steps < maxsteps; + steps++, currenttime += ((float) (2 * range) / (float) maxsteps)) + { + Vector curpos = result; + curpos += 0 * currenttime; + if (debug_pp_extrapolate) + { + curpos += 0 * currenttime * latency; + } + if (dtg > 0.0f) + { + curpos.z -= currenttime * currenttime * 400.0f * 0; + if (curpos.z < result.z - dtg) + curpos.z = result.z - dtg; + } + float rockettime = g_pLocalPlayer->v_Eye.DistTo(curpos) / speed; + if (debug_pp_rockettimeping) + rockettime += + g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING); + if (fabs(rockettime - currenttime) < mindelta) + { + besttime = currenttime; + bestpos = curpos; + mindelta = fabs(rockettime - currenttime); + } + } + if (debug_pp_rockettimeping) + besttime += g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING); + bestpos.z += (400 * besttime * besttime * gravity); + // S = at^2/2 ; t = sqrt(2S/a)*/ + return bestpos; +} Vector ProjectilePrediction(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod) { diff --git a/src/projlogging.cpp b/src/projlogging.cpp index 4f213533..d7cbb503 100644 --- a/src/projlogging.cpp +++ b/src/projlogging.cpp @@ -8,9 +8,9 @@ #include "projlogging.hpp" #include "common.hpp" +Vector prevloc[2048]{}; namespace projectile_logging { - void Update() { for (int i = 1; i < HIGHEST_ENTITY; i++) @@ -18,13 +18,31 @@ void Update() CachedEntity *ent = ENTITY(i); if (CE_BAD(ent)) continue; - if (ent->m_Type() == ENTITY_PROJECTILE) + const model_t *model = RAW_ENT(ent)->GetModel(); + bool issandwich = false; + if (model && tickcount % 33 == 0) { - int owner = CE_INT(ent, 0x894) & 0xFFF; + std::string model_name(g_IModelInfo->GetModelName(model)); + if (model_name.find("plate") != std::string::npos) + { + issandwich = true; + Vector abs_orig = RAW_ENT(ent)->GetAbsOrigin(); + float movement = prevloc[i].DistTo(abs_orig); + logging::Info("Sandwich movement: %f", movement); + prevloc[i] = abs_orig; + } + } + if (ent->m_Type() == ENTITY_PROJECTILE || issandwich) + { + /*int owner = CE_INT(ent, 0x894) & 0xFFF; if (owner != LOCAL_W->m_IDX) - continue; + continue;*/ if (tickcount % 20 == 0) { + Vector abs_orig = RAW_ENT(ent)->GetAbsOrigin(); + float movement = prevloc[i].DistTo(abs_orig); + logging::Info("movement: %f", movement); + prevloc[i] = abs_orig; const Vector &v = ent->m_vecVelocity; const Vector &a = ent->m_vecAcceleration; Vector eav; diff --git a/src/votelogger.cpp b/src/votelogger.cpp index c539e74f..e8522611 100644 --- a/src/votelogger.cpp +++ b/src/votelogger.cpp @@ -9,9 +9,9 @@ #include #include -static settings::Bool requeue{ "hack.requeue-on-kick", "false" }; -static settings::Bool vote_kicky{ "hack.autovote.yes", "false" }; -static settings::Bool vote_kickn{ "hack.autovote.no", "false" }; +static settings::Bool vote_kicky{ "votelogger.autovote.yes", "false" }; +static settings::Bool vote_kickn{ "votelogger.autovote.no", "false" }; +static settings::Bool party_say{ "votelogger.partysay", "true" }; namespace votelogger { @@ -29,9 +29,8 @@ void dispatchUserMessage(bf_read &buffer, int type) { // TODO: Add always vote no/vote no on friends. Cvar is "vote option2" was_local_player = false; - auto caller = (unsigned char) buffer.ReadByte(); - // unknown - buffer.ReadByte(); + int team = buffer.ReadByte(); + int caller = buffer.ReadByte(); char reason[64]; char name[64]; buffer.ReadString(reason, 64, false, nullptr); @@ -41,9 +40,12 @@ void dispatchUserMessage(bf_read &buffer, int type) eid >>= 1; unsigned steamID = 0; - player_info_s info{}; - if (g_IEngine->GetPlayerInfo(eid, &info)) - steamID = info.friendsID; + // info is the person getting kicked, + // info2 is the person calling the kick. + player_info_s info{}, info2{}; + if (!g_IEngine->GetPlayerInfo(eid, &info)) + break; + steamID = info.friendsID; if (eid == LOCAL_E->m_IDX) was_local_player = true; if (*vote_kickn) @@ -58,14 +60,32 @@ void dispatchUserMessage(bf_read &buffer, int type) playerlist::AccessData(info.friendsID).state == playerlist::k_EState::DEFAULT) g_IEngine->ClientCmd_Unrestricted("vote option1"); + if (*party_say) + { + if (g_IEngine->GetPlayerInfo(caller, &info2)) + { + // because tf2 is stupid and doesn't have escape characters, + // use the greek question marks instead. big brain. + // Clang-format why, TODO: Don't use format func + g_IEngine->ExecuteClientCmd( + format("say_party [CAT] votekick called: ", + boost::replace_all_copy((std::string) info2.name, + ";", ";"), + " => ", + boost::replace_all_copy((std::string) info.name, ";", + ";"), + " (", reason, ")") + .c_str()); + } + } logging::Info("Vote called to kick %s [U:1:%u] for %s", name, steamID, reason); break; } case 47: logging::Info("Vote passed"); - if (was_local_player && requeue) - tfmm::startQueue(); + // if (was_local_player && requeue) + // tfmm::startQueue(); break; case 48: logging::Info("Vote failed");