diff --git a/CMakeLists.txt b/CMakeLists.txt index f19c8fa3..535196e1 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ set(DataPath "/opt/cathook/data" CACHE FILEPATH "Data location") set(VACBypass 0 CACHE BOOL "Textmode VAC bypass") set(Textmode 0 CACHE BOOL "Various textmode-only features for bots") set(EnableTextmodeStdin 0 CACHE BOOL "Textmode Stdin -> Console bridge (EXPERIMENTAL)") -set(EnableWarnings 1 CACHE BOOL "Enable compile warnings") +set(EnableWarnings 0 CACHE BOOL "Enable compile warnings") set(EnableNullGraphics 0 CACHE BOOL "Enable experimental textmode hooks (CRASHES)") set(EnableOnlineFeatures 0 CACHE BOOL "Enable online features (WIP)") @@ -87,7 +87,7 @@ configure_file(include/version.h.in ${CMAKE_SOURCE_DIR}/include/version.h @ONLY) #set_target_properties(cathook PROPERTIES COMPILE_FLAGS "-m32 -msse -msse2 -msse3 -fexceptions" LINK_FLAGS "-m32 -fno-gnu-unique -fexceptions -DNDEBUG") set(CMAKE_CXX_FLAGS "-m32 -msse -msse2 -msse3 -fexceptions -fno-gnu-unique -DNDEBUG") -set(CMAKE_CXX_FLAGS_DEBUG "-Og -g -ggdb -rdynamic") +set(CMAKE_CXX_FLAGS_DEBUG "-Og -rdynamic -ggdb") set(CMAKE_CXX_FLAGS_RELEASE "-O3") diff --git a/README.md b/README.md index 05cd3628..a3aac775 100755 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ and a lot of useful features, including * Follow Bots * Working crit hack (does not work right now (works right now)) -[FULL LIST OF FEATURES HERE](https://github.com/nullworks/cathook/wiki/List-of-features) (list might be outdated) +[FULL LIST OF FEATURES HERE](https://github.com/nullworks/cathook/wiki/Feature-List-and-explanations) (list might be outdated) # INSTALLATION diff --git a/attach b/attach index f75f3be2..eda46450 100755 --- a/attach +++ b/attach @@ -58,3 +58,5 @@ rm $FILENAME sudo killall -18 steamwebhelper sudo killall -18 steam + +sudo ./scripts/auto-updater & diff --git a/attach-gdb b/attach-gdb new file mode 100755 index 00000000..8245fbf5 --- /dev/null +++ b/attach-gdb @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +line=$(pidof hl2_linux) +arr=($line) +inst=$1 +if [ $# == 0 ]; then + inst=0 +fi + +if [ ${#arr[@]} == 0 ]; then + echo TF2 isn\'t running! + exit +fi + +if [ $inst -gt ${#arr[@]} ] || [ $inst == ${#arr[@]} ]; then + echo wrong index! + exit +fi + +proc=${arr[$inst]} + +echo Running instances: "${arr[@]}" +echo Attaching to "$proc" + +#sudo ./detach $inst bin/libcathook.so + +#if grep -q "$(realpath bin/libcathook.so)" /proc/"$proc"/maps; then +# echo already loaded +# exit +#fi + +# pBypass for crash dumps being sent +# You may also want to consider using -nobreakpad in your launch options. +sudo rm -rf /tmp/dumps # Remove if it exists +sudo mkdir /tmp/dumps # Make it as root +sudo chmod 000 /tmp/dumps # No permissions + +FILENAME="/tmp/.gl$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1)" + +cp "bin/libcathook.so" "$FILENAME" + +echo loading "$FILENAME" to "$proc" + +sudo killall -19 steam +sudo killall -19 steamwebhelper + +gdb -n -q -batch \ + -ex "attach $proc" \ + -ex "set \$dlopen = (void*(*)(char*, int)) dlopen" \ + -ex "call \$dlopen(\"$FILENAME\", 1)" \ + -ex "call dlerror()" \ + -ex 'print (char *) $2' \ + -ex "catch syscall exit exit_group" \ + -ex "detach" \ + -ex "quit" + +sudo killall -18 steamwebhelper +sudo killall -18 steam + +sudo ./scripts/auto-updater & + +gdb -n -q -batch \ + -ex "attach $proc" \ + -ex "continue" \ + -ex "backtrace" + +rm $FILENAME diff --git a/attach-libnamed.sh b/attach-libnamed.sh index ed33e5c5..cd4f7be1 100755 --- a/attach-libnamed.sh +++ b/attach-libnamed.sh @@ -61,3 +61,5 @@ sudo gdb -n -q -batch \ -ex "quit" sudo rm "/lib/i386-linux-gnu/${FILENAME}" + +sudo ./scripts/auto-updater & diff --git a/data/dominatesay.txt b/data/dominatesay.txt new file mode 100644 index 00000000..e47d78b8 --- /dev/null +++ b/data/dominatesay.txt @@ -0,0 +1,11 @@ +replace this file with actual dominatesay. +usable macros: +%team% %class% %killer% %name% %myteam% %myclass% %dominum% \n + +examples: + +%name% is getting dominated. no big surprise. +%team% actually sucks i already have %dominum% dominations wtf? +%name%, quit playing %class% dude. i'm already dominating you. +lmao adding %name% to my list of idiots +%dominum% dominations lol diff --git a/data/menu/nullifiedcat/catbot.xml b/data/menu/nullifiedcat/catbot.xml index b0de2d0c..2f8ed4ca 100755 --- a/data/menu/nullifiedcat/catbot.xml +++ b/data/menu/nullifiedcat/catbot.xml @@ -64,13 +64,11 @@ - - + - - + diff --git a/external/libglez b/external/libglez index 9457ea15..caca15cd 160000 --- a/external/libglez +++ b/external/libglez @@ -1 +1 @@ -Subproject commit 9457ea150e041689c6f38f5720b4d571cf64a943 +Subproject commit caca15cd63545b43798fc8872611a2e5f78d4668 diff --git a/include/core/netvars.hpp b/include/core/netvars.hpp index 258003ed..8e7b98d0 100755 --- a/include/core/netvars.hpp +++ b/include/core/netvars.hpp @@ -11,15 +11,8 @@ class IClientEntity; -// Fix clang gay -#if defined(__clang__) #define NET_VAR(entity, offset, type) \ (*(reinterpret_cast(reinterpret_cast(entity) + (offset)))) -#elif defined(__GNUC__) || defined(__GNUG__) -#define NET_VAR(entity, offset, type) \ - (*(reinterpret_cast(reinterpret_cast(entity) + \ - (offset)))) -#endif #define NET_INT(entity, offset) NET_VAR(entity, offset, int) @@ -73,6 +66,7 @@ public: offset_t m_flTeleCurrentRechargeDuration; offset_t m_iTeleTimesUsed; offset_t m_flTeleYawToExit; + offset_t m_bMatchBuilding; offset_t iPipeType; offset_t iBuildingHealth; offset_t iBuildingMaxHealth; diff --git a/include/hacks/Backtrack.hpp b/include/hacks/Backtrack.hpp index cd8f22db..c34bb116 100644 --- a/include/hacks/Backtrack.hpp +++ b/include/hacks/Backtrack.hpp @@ -62,6 +62,7 @@ extern circular_buf sequences; extern BacktrackData headPositions[32][66]; extern bool isBacktrackEnabled; +extern bool Vischeck_Success; float getLatency(); int getTicks(); bool ValidTick(BacktrackData &i, CachedEntity *ent); diff --git a/include/hacks/CMakeLists.txt b/include/hacks/CMakeLists.txt index df18df8e..9a265591 100755 --- a/include/hacks/CMakeLists.txt +++ b/include/hacks/CMakeLists.txt @@ -27,6 +27,7 @@ target_sources(cathook PRIVATE "${CMAKE_CURRENT_LIST_DIR}/FollowBot.hpp" "${CMAKE_CURRENT_LIST_DIR}/hacklist.hpp" "${CMAKE_CURRENT_LIST_DIR}/KillSay.hpp" + "${CMAKE_CURRENT_LIST_DIR}/DominateSay.hpp" "${CMAKE_CURRENT_LIST_DIR}/Killstreak.hpp" "${CMAKE_CURRENT_LIST_DIR}/LightESP.hpp" "${CMAKE_CURRENT_LIST_DIR}/Misc.hpp" diff --git a/include/hacks/DominateSay.hpp b/include/hacks/DominateSay.hpp new file mode 100644 index 00000000..92e01f2d --- /dev/null +++ b/include/hacks/DominateSay.hpp @@ -0,0 +1,20 @@ +/* + * DominateSay.h + * + * Created on: Oct 30, 2017 + */ + +#pragma once + +#include "common.hpp" + +namespace hacks::shared::dominatesay +{ + +void init(); +void shutdown(); +void reload(); + +extern const std::vector builtin_default; +extern const std::vector jp_anime; +} // namespace hacks::shared::dominatesay diff --git a/include/hacks/NavBot.hpp b/include/hacks/NavBot.hpp index 329a50fc..8da26ba5 100644 --- a/include/hacks/NavBot.hpp +++ b/include/hacks/NavBot.hpp @@ -1,26 +1,13 @@ +// +// Created by bencat07 on 17.08.18. +// +#pragma once + #include "common.hpp" - -namespace hacks::shared::NavBot +#include "config.h" +namespace hacks::tf2::NavBot { - -// Main Functions -void Init(bool from_LevelInit); - -// Helper -bool CanPath(); -bool HasLowHealth(); -bool HasLowAmmo(); -CachedEntity *nearestHealth(); -CachedEntity *nearestAmmo(); -CachedEntity *nearestEnemy(); -CachedEntity *nearestTeleporter(); -Vector GetClosestValidByDist(CachedEntity *ent, float mindist, float maxdist, bool near); -void UpdateSlot(); -void Jump(); - -// Path -bool NavToSniperSpot(int priority); -bool NavToNearestEnemy(); -bool NavToBacktrackTick(int priority); - -} // namespace hacks::shared::NavBot +void Init(); +void initonce(); +extern Vector Best_Spot; +} // namespace hacks::tf2::NavBot diff --git a/include/hacks/hacklist.hpp b/include/hacks/hacklist.hpp index 1c360aaa..9a3031d8 100755 --- a/include/hacks/hacklist.hpp +++ b/include/hacks/hacklist.hpp @@ -46,6 +46,7 @@ #include "Misc.hpp" #include "Trigger.hpp" #include "KillSay.hpp" +#include "DominateSay.hpp" #include "UberSpam.hpp" #include "Achievement.hpp" #endif diff --git a/include/helpers.hpp b/include/helpers.hpp index ee20e429..4c1debd2 100755 --- a/include/helpers.hpp +++ b/include/helpers.hpp @@ -71,6 +71,7 @@ weaponmode GetWeaponMode(); void FixMovement(CUserCmd &cmd, Vector &viewangles); void VectorAngles(Vector &forward, Vector &angles); +void AngleVectors2(const QAngle &angles, Vector *forward); extern std::mutex trace_lock; bool IsEntityVisible(CachedEntity *entity, int hb); bool IsEntityVectorVisible(CachedEntity *entity, Vector endpos); @@ -124,6 +125,14 @@ void WhatIAmLookingAt(int *result_eindex, Vector *result_pos); void Patch(void *address, void *patch, size_t length); +inline Vector GetAimAtAngles(Vector origin, Vector target) +{ + Vector angles, tr; + tr = (target - origin); + VectorAngles(tr, angles); + fClampAngle(angles); + return angles; +} void AimAt(Vector origin, Vector target, CUserCmd *cmd); void AimAtHitbox(CachedEntity *ent, int hitbox, CUserCmd *cmd); bool IsProjectileCrit(CachedEntity *ent); diff --git a/include/visual/EffectChams.hpp b/include/visual/EffectChams.hpp index ab9f4148..474cbb67 100644 --- a/include/visual/EffectChams.hpp +++ b/include/visual/EffectChams.hpp @@ -27,7 +27,9 @@ public: init = false; } - inline virtual void SetParameters(KeyValues *params){} + inline virtual void SetParameters(KeyValues *params) + { + } virtual void Render(int x, int y, int w, int h); diff --git a/include/visual/EffectGlow.hpp b/include/visual/EffectGlow.hpp index a1d24760..51268ee1 100644 --- a/include/visual/EffectGlow.hpp +++ b/include/visual/EffectGlow.hpp @@ -17,7 +17,8 @@ class EffectGlow : public IScreenSpaceEffect { public: virtual void Init(); - inline virtual void Shutdown(){ + inline virtual void Shutdown() + { mat_unlit.Shutdown(); mat_unlit_z.Shutdown(); mat_blit.Shutdown(); @@ -27,7 +28,9 @@ public: mat_blur_y.Shutdown(); } - inline virtual void SetParameters(KeyValues *params){} + inline virtual void SetParameters(KeyValues *params) + { + } virtual void Render(int x, int y, int w, int h); diff --git a/attach-backtrace-scramble.sh b/scripts/attach-backtrace-scramble.sh similarity index 100% rename from attach-backtrace-scramble.sh rename to scripts/attach-backtrace-scramble.sh diff --git a/scripts/auto-updater b/scripts/auto-updater new file mode 100755 index 00000000..13b5fe28 --- /dev/null +++ b/scripts/auto-updater @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +LOCKFILE=/tmp/chupdater.lock +if [ -e ${LOCKFILE} ] && ps -p `cat ${LOCKFILE}` >/dev/null; then + echo -e "\033[1;31m \n \nAuto Updater: Auto Updater already running in the background\n\033[0m" + exit 1 +fi + +# make sure the lockfile is removed when we exit and then claim it +trap "rm -f ${LOCKFILE}; exit" INT TERM EXIT +echo $$ > ${LOCKFILE} + +echo -e "\033[1;34m \n \nAuto Updater: Updating cathook in the background\n\033[0m" + +sudo -u $LOGNAME bash -c 'git fetch && git pull origin >/dev/null && git submodule update --init --recursive >/dev/null' || { echo -e "\033[1;31m \n \nAuto Updater: Failed to pull from github!\n\033[0m"; exit 1; } + +pushd build >/dev/null || exit 1 + +if [ $(id -u) -eq 0 ]; then + cmake --build . --target data >/dev/null || { echo -e "\033[1;31m \n \nAuto Updater:Failed to update /opt/cathook/data directory\n\033[0m"; exit 1; } +fi + +sudo -u $LOGNAME bash -c 'cmake .. >/dev/null && nice -n 10 cmake --build . --target cathook -- -j 1 >/dev/null' || { echo -e "\033[1;31m \n \nAuto Updater: Failed to compile cathook\n\033[0m"; exit 1; } + +rm -f ${LOCKFILE} + +popd >/dev/null + +echo -e "\n\n\033[1;34mAuto Updater: Cathook updated successfully\033[0m" && exit 0 diff --git a/src/core/netvars.cpp b/src/core/netvars.cpp index 24ec6624..2cb7bb15 100644 --- a/src/core/netvars.cpp +++ b/src/core/netvars.cpp @@ -138,6 +138,9 @@ void NetVars::Init() gNetvars.get_offset("DT_ObjectTeleporter", "m_iTimesUsed"); this->m_flTeleYawToExit = gNetvars.get_offset("DT_ObjectTeleporter", "m_flYawToExit"); + this->m_bMatchBuilding = + gNetvars.get_offset("DT_ObjectTeleporter", "m_bMatchBuilding"); + ; this->iPipeType = gNetvars.get_offset("DT_TFProjectile_Pipebomb", "m_iType"); this->iBuildingHealth = diff --git a/src/hack.cpp b/src/hack.cpp index 308f14bd..81fadd19 100644 --- a/src/hack.cpp +++ b/src/hack.cpp @@ -5,22 +5,14 @@ * Author: nullifiedcat */ -// The code below was obtained from: -// http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes/1925461#1925461 -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#ifndef __USE_GNU #define __USE_GNU -#endif - #include #include #include -#include #include -#include -#include +#include +#include +#include #include #include "hack.hpp" #include "common.hpp" @@ -33,6 +25,7 @@ #include "copypasted/CDumper.hpp" #include "version.h" +#include /* * Credits to josh33901 aka F1ssi0N for butifel F1Public and Darkstorm 2015 @@ -105,85 +98,56 @@ void hack::ExecuteCommand(const std::string command) hack::command_stack().push(command); } -/* This structure mirrors the one found in /usr/include/asm/ucontext.h */ -typedef struct _sig_ucontext +void my_signal_handler(int signum) { - unsigned long uc_flags; - struct ucontext *uc_link; - stack_t uc_stack; - struct sigcontext uc_mcontext; - sigset_t uc_sigmask; -} sig_ucontext_t; + namespace st = boost::stacktrace; + ::signal(signum, SIG_DFL); + passwd *pwd = getpwuid(getuid()); + std::ofstream out( + strfmt("/tmp/cathook-%s-%d-segfault.log", pwd->pw_name, getpid()) + .get()); -void crit_err_hdlr(int sig_num, siginfo_t *info, void *ucontext) -{ - void *array[50]; - void *caller_address; - char **messages; - int size, i; - sig_ucontext_t *uc; + Dl_info info; + if (!dladdr(reinterpret_cast(SetCanshootStatus), &info)) + return; + unsigned int baseaddr = (unsigned int) info.dli_fbase; - uc = (sig_ucontext_t *) ucontext; - -/* Get the address at the time the signal was raised */ -#if defined(__i386__) // gcc specific - caller_address = (void *) uc->uc_mcontext.eip; // EIP: x86 specific -#elif defined(__x86_64__) // gcc specific - caller_address = (void *) uc->uc_mcontext.rip; // RIP: x86_64 specific -#else -#error Unsupported architecture. // TODO: Add support for other arch. -#endif - - fprintf(stderr, "\n"); - FILE *backtraceFile; - - // In this example we write the stacktrace to a file. However, we can also - // just fprintf to stderr (or do both). - passwd *pwd = getpwuid(getuid()); - backtraceFile = fopen( - strfmt("/tmp/cathook-%s-%d-segfault.log", pwd->pw_name, getpid()).get(), - "w"); - - if (sig_num == SIGSEGV) - fprintf(backtraceFile, "signal %d (%s), address is %p from %p\n", - sig_num, strsignal(sig_num), info->si_addr, - (void *) caller_address); - else - fprintf(backtraceFile, "signal %d (%s)\n", sig_num, strsignal(sig_num)); - - size = backtrace(array, 50); - /* overwrite sigaction with caller's address */ - array[1] = caller_address; - messages = backtrace_symbols(array, size); - /* skip first stack frame (points here) */ - for (i = 1; i < size && messages != NULL; ++i) + for (auto i : st::stacktrace()) { - fprintf(backtraceFile, "[bt]: (%d) %s\n", i, messages[i]); + unsigned int offset = (unsigned int) (i.address()) - baseaddr; + Dl_info info2; + out << (void *)offset; + if (!dladdr(i.address(), &info2)) + { + out << std::endl; + continue; + } + out << " " << info2.dli_fname << ": "; + if (info2.dli_sname) + { + int status = -4; + char *realname = + abi::__cxa_demangle(info2.dli_sname, 0, 0, &status); + if (status == 0) + { + out << realname << std::endl; + free(realname); + } + else + out << info2.dli_sname << std::endl; + } + else + out << "Not found!" << std ::endl; } - fclose(backtraceFile); - free(messages); - - std::abort(); - exit(EXIT_FAILURE); + out.close(); + ::raise(SIGABRT); } -void installSignal(int __sig) -{ - struct sigaction sigact; - sigact.sa_sigaction = crit_err_hdlr; - sigact.sa_flags = SA_RESTART | SA_SIGINFO; - if (sigaction(__sig, &sigact, (struct sigaction *) NULL) != 0) - { - fprintf(stderr, "error setting signal handler for %d (%s)\n", __sig, - strsignal(__sig)); - exit(EXIT_FAILURE); - } -} void hack::Initialize() { - signal(SIGPIPE, SIG_IGN); - installSignal(SIGSEGV); + ::signal(SIGSEGV, &my_signal_handler); + //::signal(SIGABRT, &my_signal_handler); time_injected = time(nullptr); /*passwd *pwd = getpwuid(getuid()); char *logname = strfmt("/tmp/cathook-game-stdout-%s-%u.log", pwd->pw_name, @@ -339,6 +303,7 @@ free(logname);*/ #if not LAGBOT_MODE // FIXME [MP] hacks::shared::killsay::init(); + hacks::shared::dominatesay::init(); hacks::shared::announcer::init(); hacks::tf2::killstreak::init(); #endif @@ -431,6 +396,7 @@ void hack::Shutdown() #if not LAGBOT_MODE logging::Info("Shutting down killsay..."); hacks::shared::killsay::shutdown(); + hacks::shared::dominatesay::shutdown(); hacks::shared::announcer::shutdown(); #endif logging::Info("Success.."); diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp index 49deb390..0bbce3a6 100644 --- a/src/hacks/Aimbot.cpp +++ b/src/hacks/Aimbot.cpp @@ -1,4 +1,4 @@ -/* +/* * HAimbot.cpp * * Created on: Oct 9, 2016 @@ -83,7 +83,7 @@ bool shouldBacktrack() bool IsBacktracking() { - return !(!aimkey || !aimkey.isKeyDown()) && shouldBacktrack(); + return (aimkey ? aimkey.isKeyDown() : true) && shouldBacktrack(); } // Current Entity @@ -118,7 +118,9 @@ void CreateMove() current_user_cmd->buttons |= IN_ATTACK2; if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFMinigun)) - if (auto_spin_up && CE_INT(g_pLocalPlayer->weapon(), netvar.m_iClip1) != 0 && !zoomTime.check(1000)) + if (auto_spin_up && + CE_INT(g_pLocalPlayer->weapon(), netvar.m_iAmmo + 4) != 0 && + !zoomTime.check(1000)) current_user_cmd->buttons |= IN_ATTACK2; // We do this as we need to pass whether the aimkey allows aiming to both @@ -406,7 +408,7 @@ CachedEntity *RetrieveBestTarget(bool aimkey_state) break; case 4: // Distance Priority (Furthest Away) scr = calculated_data_array[i].aim_position.DistTo( - g_pLocalPlayer->v_Eye); + g_pLocalPlayer->v_Eye); break; case 6: // Health Priority (Highest) scr = ent->m_iHealth() * 4; @@ -428,7 +430,9 @@ CachedEntity *RetrieveBestTarget(bool aimkey_state) else if (hacks::shared::backtrack::iBestTarget != -1) { target_highest_ent = ENTITY(hacks::shared::backtrack::iBestTarget); - foundTarget = true; + if (!IsTargetStateGood(target_highest_ent)) + target_highest_ent = nullptr; + foundTarget = true; } // Save the ent for future use with target lock @@ -813,7 +817,7 @@ void DoAutoshoot() begancharge) { current_user_cmd->buttons &= ~IN_ATTACK; - hacks::shared::antiaim::SetSafeSpace(3); + hacks::shared::antiaim::SetSafeSpace(5); begancharge = false; // Pull string if charge isnt enough } @@ -836,7 +840,7 @@ void DoAutoshoot() if ((chargetime >= 3.85f * *sticky_autoshoot) && begansticky > 3) { current_user_cmd->buttons &= ~IN_ATTACK; - hacks::shared::antiaim::SetSafeSpace(3); + hacks::shared::antiaim::SetSafeSpace(5); begansticky = 0; } // Else just keep charging @@ -1149,20 +1153,17 @@ bool VischeckPredictedEntity(CachedEntity *entity) // Retrieve predicted data AimbotCalculatedData_s &cd = calculated_data_array[entity->m_IDX]; if (cd.vcheck_tick == tickcount) - return cd.visible; + { + if (!shouldBacktrack() || projectile_mode) + return cd.visible; + } // Update info cd.vcheck_tick = tickcount; if (!shouldBacktrack() || projectile_mode) cd.visible = IsEntityVectorVisible(entity, PredictEntity(entity)); else - cd.visible = IsVectorVisible( - g_pLocalPlayer->v_Eye, - hacks::shared::backtrack::headPositions - [entity->m_IDX][hacks::shared::backtrack::BestTick] - .hitboxes[cd.hitbox] - .center, - true); + cd.visible = hacks::shared::backtrack::Vischeck_Success; return cd.visible; } @@ -1277,7 +1278,7 @@ float EffectiveTargetingRange() if (GetWeaponMode() == weapon_melee) return (float) re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W)); if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFFlameThrower)) - return 185.0f; // Pyros only have so much untill their flames hit + return 310.0f; // Pyros only have so much until their flames hit return (float) max_range; } diff --git a/src/hacks/AntiBackstab.cpp b/src/hacks/AntiBackstab.cpp index 96b8f671..f668f293 100644 --- a/src/hacks/AntiBackstab.cpp +++ b/src/hacks/AntiBackstab.cpp @@ -66,19 +66,36 @@ CachedEntity *ClosestSpy() continue; if (CE_BYTE(ent, netvar.iLifeState)) continue; + bool ispyro = false; + bool isheavy = false; if (CE_INT(ent, netvar.iClass) != tf_class::tf_spy) - continue; + { + if (CE_INT(ent, netvar.iClass) != tf_class::tf_pyro && CE_INT(ent, netvar.iClass) != tf_class::tf_heavy) + continue; + int idx = CE_INT(ent, netvar.hActiveWeapon) & 0xFFF; + if (IDX_BAD(idx)) + continue; + CachedEntity *pyro_weapon = ENTITY(idx); + int widx = CE_INT(pyro_weapon, netvar.iItemDefinitionIndex); + if (widx != 40 && widx != 1146 && widx != 656) + continue; + if (widx == 656) + isheavy = true; + ispyro = true; + } if (CE_INT(ent, netvar.iTeamNum) == g_pLocalPlayer->team) continue; if (IsPlayerInvisible(ent)) continue; dist = ent->m_flDistance(); - if (fabs(GetAngle(ent)) > (float) angle) + if (fabs(GetAngle(ent)) > (float) angle || (ispyro && !isheavy && fabs(GetAngle(ent)) > 90.0f) || (isheavy && fabs(GetAngle(ent)) > 132.0f)) { break; // logging::Info("Backstab???"); } - if (dist < (float) distance && (dist < closest_dist || !closest_dist)) + if ((((!ispyro && dist < (float) distance)) || + (ispyro && !isheavy && dist < 314.0f) || (isheavy && dist < 120.0f)) && + (dist < closest_dist || !closest_dist)) { closest_dist = dist; closest = ent; @@ -97,8 +114,14 @@ void CreateMove() spy = ClosestSpy(); if (spy) { - noaa = true; - current_user_cmd->viewangles.x = 160.0f; + noaa = true; + if (current_user_cmd->buttons & IN_ATTACK) + return; + const Vector &A = LOCAL_E->m_vecOrigin(); + const Vector &B = spy->m_vecOrigin(); + diff = (A - B); + if (diff.y < 0 || CE_INT(spy, netvar.iClass) == tf_class::tf_heavy) + current_user_cmd->viewangles.x = 180.0f; if (silent) g_pLocalPlayer->bUseSilentAngles = true; if (sayno) diff --git a/src/hacks/AutoBackstab.cpp b/src/hacks/AutoBackstab.cpp index 5d1b345f..2fabb147 100644 --- a/src/hacks/AutoBackstab.cpp +++ b/src/hacks/AutoBackstab.cpp @@ -19,17 +19,6 @@ namespace backtrack = hacks::shared::backtrack; static settings::Bool enable{ "autobackstab.enable", "0" }; static settings::Bool silent{ "autobackstab.silent", "1" }; void testingFunc(); -void AngleVectors2(const QAngle &angles, Vector *forward) -{ - float sp, sy, cp, cy; - - SinCos(DEG2RAD(angles[YAW]), &sy, &cy); - SinCos(DEG2RAD(angles[PITCH]), &sp, &cp); - - forward->x = cp * cy; - forward->y = cp * sy; - forward->z = -sp; -} // Not required anymore, keeping for future reference Vector rotateVector(Vector center, float radianAngle, Vector p) @@ -233,7 +222,6 @@ void CreateMove() current_user_cmd->buttons |= IN_ATTACK; if (silent) g_pLocalPlayer->bUseSilentAngles = true; - logging::Info("Success on tick %i", j); return; } } diff --git a/src/hacks/AutoDeadringer.cpp b/src/hacks/AutoDeadringer.cpp index 4e58ec31..a7c5ff57 100644 --- a/src/hacks/AutoDeadringer.cpp +++ b/src/hacks/AutoDeadringer.cpp @@ -28,7 +28,7 @@ bool IsProjectile(CachedEntity *ent) int NearbyEntities() { int ret = 0; - if (CE_BAD(LOCAL_E)) + if (CE_BAD(LOCAL_E) || CE_BAD(LOCAL_W)) return ret; for (int i = 0; i < HIGHEST_ENTITY; i++) { @@ -48,7 +48,7 @@ void CreateMove() { if (!enable) return; - if (CE_BAD(LOCAL_E)) + if (CE_BAD(LOCAL_E) || CE_BAD(LOCAL_W)) return; if (g_pLocalPlayer->clazz != tf_spy) return; diff --git a/src/hacks/AutoHeal.cpp b/src/hacks/AutoHeal.cpp index 989cd35e..882c4563 100644 --- a/src/hacks/AutoHeal.cpp +++ b/src/hacks/AutoHeal.cpp @@ -232,7 +232,7 @@ bool IsProjectile(CachedEntity *ent) int NearbyEntities() { int ret = 0; - if (CE_BAD(LOCAL_E)) + if (CE_BAD(LOCAL_E) || CE_BAD(LOCAL_W)) return ret; for (int i = 0; i < HIGHEST_ENTITY; i++) { diff --git a/src/hacks/Backtrack.cpp b/src/hacks/Backtrack.cpp index e8f31490..048f6f3d 100644 --- a/src/hacks/Backtrack.cpp +++ b/src/hacks/Backtrack.cpp @@ -32,6 +32,7 @@ BacktrackData headPositions[32][66]{}; int highesttick[32]{}; int lastincomingsequencenumber = 0; bool isBacktrackEnabled = false; +bool Vischeck_Success = false; circular_buf sequences{ 2048 }; void UpdateIncomingSequences() @@ -88,7 +89,7 @@ void Run() } isBacktrackEnabled = true; - if (CE_BAD(LOCAL_E)) + if (CE_BAD(LOCAL_E) || CE_BAD(LOCAL_W)) return; if (g_Settings.bInvalid) return; @@ -307,8 +308,10 @@ void EmptyBacktrackData(BacktrackData &i) // This func is internal only std::pair getBestEntBestTick() { - int bestEnt = -1; - int bestTick = -1; + int bestEnt = -1; + int bestTick = -1; + bool vischeck_priority = false; + Vischeck_Success = false; if (GetWeaponMode() == weapon_melee) { float bestDist = 9999.0f; @@ -328,11 +331,25 @@ std::pair getBestEntBestTick() headPositions[i][j] .hitboxes.at(spine_3) .center.DistTo(g_pLocalPlayer->v_Eye); - if (dist < bestDist && dist > *mindistance) + if (dist > bestDist && vischeck_priority) + continue; + bool Vischeck_suceeded = IsVectorVisible( + g_pLocalPlayer->v_Eye, + headPositions[i][j].hitboxes.at(0).center, + true); + if (((dist < bestDist) || + (Vischeck_suceeded && !vischeck_priority)) && + dist > *mindistance && + (vischeck_priority ? Vischeck_suceeded : true)) { bestEnt = i; bestTick = j; bestDist = dist; + if (Vischeck_suceeded) + { + Vischeck_Success = true; + vischeck_priority = true; + } } } } @@ -358,6 +375,7 @@ std::pair getBestEntBestTick() g_pLocalPlayer->v_OrigViewangles, g_pLocalPlayer->v_Eye, headPositions[i][j].hitboxes.at(head).center); + Vischeck_Success = true; if (bestFov > FOVDistance) { bestFov = FOVDistance; diff --git a/src/hacks/CMakeLists.txt b/src/hacks/CMakeLists.txt index 9aa35914..ec152c61 100755 --- a/src/hacks/CMakeLists.txt +++ b/src/hacks/CMakeLists.txt @@ -26,6 +26,7 @@ if(NOT LagbotMode) "${CMAKE_CURRENT_LIST_DIR}/Backtrack.cpp" "${CMAKE_CURRENT_LIST_DIR}/FollowBot.cpp" "${CMAKE_CURRENT_LIST_DIR}/KillSay.cpp" + "${CMAKE_CURRENT_LIST_DIR}/DominateSay.cpp" "${CMAKE_CURRENT_LIST_DIR}/Killstreak.cpp" "${CMAKE_CURRENT_LIST_DIR}/LightESP.cpp" "${CMAKE_CURRENT_LIST_DIR}/Misc.cpp" diff --git a/src/hacks/CatBot.cpp b/src/hacks/CatBot.cpp index f91a8eb1..0c6195ec 100644 --- a/src/hacks/CatBot.cpp +++ b/src/hacks/CatBot.cpp @@ -301,7 +301,7 @@ static HookedFunction cm(HF_CreateMove, "catbot", 5, []() { if (g_Settings.bInvalid) return; - if (CE_BAD(LOCAL_E)) + if (CE_BAD(LOCAL_E) || CE_BAD(LOCAL_W)) return; if (*auto_crouch) diff --git a/src/hacks/DominateSay.cpp b/src/hacks/DominateSay.cpp new file mode 100644 index 00000000..9f28ee01 --- /dev/null +++ b/src/hacks/DominateSay.cpp @@ -0,0 +1,141 @@ +/* + * DominateSay.cpp + * + * Created on: October 30, 2018 + */ + +#include +#include +#include "common.hpp" + +static settings::Int dominatesay_mode{ "dominatesay.mode", "0" }; +static settings::String filename{ "dominatesay.file", "dominatesay.txt" }; + +static CatCommand reload_command("dominatesay_reload", "Reload dominatesays", + []() { + hacks::shared::dominatesay::reload(); + }); + +namespace hacks::shared::dominatesay +{ + +const std::string tf_classes_dominatesay[] = { "class", "scout", "sniper", + "soldier", "demoman", "medic", + "heavy", "pyro", "spy", + "engineer" }; + +const std::string tf_teams_dominatesay[] = { "RED", "BLU" }; + +static std::string lastmsg{}; + +TextFile file{}; + +std::string ComposeDominateSay(IGameEvent *event) +{ + const std::vector *source = nullptr; + switch (*dominatesay_mode) + { + case 1: + source = &file.lines; + break; + case 2: + source = &builtin_default; + break; + case 3: + source = &jp_anime; + break; + default: + break; + } + if (!source || source->empty()) + return ""; + if (!event) + return ""; + int vid = event->GetInt("dominated"); + int kid = event->GetInt("dominator"); + int dnum = event->GetInt("dominations"); + + // this is actually impossible but just in case. + if (g_IEngine->GetPlayerForUserID(kid) != g_IEngine->GetLocalPlayer()) + return ""; + + std::string msg = source->at(rand() % source->size()); + + while (msg == lastmsg && source->size() > 1) + msg = source->at(rand() % source->size()); + lastmsg = msg; + 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_dominatesay[clz]); + player_info_s infok{}; + g_IEngine->GetPlayerInfo(g_IEngine->GetPlayerForUserID(kid), &infok); + + ReplaceString(msg, "%dominum%", std::to_string(dnum)); + ReplaceString(msg, "%killer%", std::string(infok.name)); + ReplaceString(msg, "%team%", tf_teams_dominatesay[ent->m_iTeam() - 2]); + ReplaceString(msg, "%myteam%", + tf_teams_dominatesay[LOCAL_E->m_iTeam() - 2]); + ReplaceString(msg, "%myclass%", + tf_classes_dominatesay[g_pPlayerResource->GetClass(LOCAL_E)]); + ReplaceString(msg, "\\n", "\n"); + return msg; +} + +class DominateSayEventListener : public IGameEventListener2 +{ + void FireGameEvent(IGameEvent *event) override + { + if (!dominatesay_mode) + return; + std::string message = + hacks::shared::dominatesay::ComposeDominateSay(event); + if (!message.empty()) + chat_stack::Say(message, false); + } +}; + +static DominateSayEventListener listener{}; + +void reload() +{ + file.Load(*filename); +} + +void init() +{ + g_IEventManager2->AddListener(&listener, (const char *) "player_domination", + false); +} + +void shutdown() +{ + g_IEventManager2->RemoveListener(&listener); +} + +// a much better default dominatesay would be appreciated. +const std::vector builtin_default = { + "dominating %name%! (%dominum% dominations)", + "%name%, getting tapped?", + "%killer% is dominating the server with %dominum% dominations!", +}; + +// same goes to this one +const std::vector jp_anime = { + "Get d-dominated %name%-senpai >:3", + "g- gomenasai! %name%-san!", + "Wow! hey hey hey H~ ey !!! I found you again~~!", + "%name%-san please don't get mad at me.. ><", + // https://youtu.be/sW3RT0tF020?t=207 + "kore kara mo douzo yoroshiku ne.", + "konna watashi dakedo waratte yurushite ne.", + "zutto taisetsu ni shite ne.", + "eikyuu hoshou no watashi dakara.", +}; + +} // namespace hacks::shared::dominatesay diff --git a/src/hacks/ESP.cpp b/src/hacks/ESP.cpp index 8f507557..480a1541 100644 --- a/src/hacks/ESP.cpp +++ b/src/hacks/ESP.cpp @@ -252,7 +252,7 @@ static HookedFunction // Check usersettings if enabled if (!*enable) return; - if (CE_BAD(LOCAL_E)) + if (CE_BAD(LOCAL_E) || CE_BAD(LOCAL_W)) return; // Something std::lock_guard esp_lock(threadsafe_mutex); diff --git a/src/hacks/FollowBot.cpp b/src/hacks/FollowBot.cpp index fa7d7d9c..fa134332 100644 --- a/src/hacks/FollowBot.cpp +++ b/src/hacks/FollowBot.cpp @@ -208,7 +208,7 @@ static HookedFunction init(); // We need a local player to control - if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || CE_BAD(LOCAL_W)) { follow_target = 0; return; @@ -231,7 +231,8 @@ static HookedFunction } if (CE_GOOD(ENTITY(follow_target)) && navtime.test_and_set(2000)) { - if (nav::navTo(ENTITY(follow_target)->m_vecOrigin(), 5, true, false)) + if (nav::navTo(ENTITY(follow_target)->m_vecOrigin(), 5, true, + false)) { navtimeout.update(); } @@ -264,180 +265,184 @@ static HookedFunction // Target Selection { - if (steamid && - ((follow_target && - ENTITY(follow_target)->player_info.friendsID != steamid) || - !follow_target)) - { - // Find a target with the steam id, as it is prioritized - auto ent_count = g_IEngine->GetMaxClients(); - for (int i = 0; i < ent_count; i++) + if (steamid && + ((follow_target && + ENTITY(follow_target)->player_info.friendsID != steamid) || + !follow_target)) { - auto entity = ENTITY(i); - if (CE_BAD(entity)) // Exist + dormant - continue; - if (i == follow_target) - continue; - if (entity->m_Type() != ENTITY_PLAYER) - continue; - if (steamid != entity->player_info.friendsID) // steamid check - continue; - - if (!entity->m_bAlivePlayer()) // Dont follow dead players - continue; - bool found = false; - if (corneractivate) + // Find a target with the steam id, as it is prioritized + auto ent_count = g_IEngine->GetMaxClients(); + for (int i = 0; i < ent_count; i++) { - Vector indirectOrigin = VischeckCorner( - LOCAL_E, entity, *follow_activation / 2, - true); // get the corner location that the - // future target is visible from - std::pair corners; - if (!indirectOrigin.z && - entity->m_IDX == lastent) // if we couldn't find it, run - // wallcheck instead - { - corners = - VischeckWall(LOCAL_E, entity, - float(follow_activation) / 2, true); - if (!corners.first.z || !corners.second.z) - continue; - // addCrumbs(LOCAL_E, corners.first); - // addCrumbs(entity, corners.second); - addCrumbPair(LOCAL_E, entity, corners); - found = true; - } - if (indirectOrigin.z) - { - addCrumbs(entity, indirectOrigin); - found = true; - } - } - else - { - if (VisCheckEntFromEnt(LOCAL_E, entity)) - found = true; - } - if (isNavBotCM && !found) - { - if (!nav::navTo(entity->m_vecOrigin())) + auto entity = ENTITY(i); + if (CE_BAD(entity)) // Exist + dormant continue; - navtimeout.update(); - found = true; + if (i == follow_target) + continue; + if (entity->m_Type() != ENTITY_PLAYER) + continue; + if (steamid != + entity->player_info.friendsID) // steamid check + continue; + + if (!entity->m_bAlivePlayer()) // Dont follow dead players + continue; + bool found = false; + if (corneractivate) + { + Vector indirectOrigin = VischeckCorner( + LOCAL_E, entity, *follow_activation / 2, + true); // get the corner location that the + // future target is visible from + std::pair corners; + if (!indirectOrigin.z && + entity->m_IDX == + lastent) // if we couldn't find it, run + // wallcheck instead + { + corners = VischeckWall(LOCAL_E, entity, + float(follow_activation) / 2, + true); + if (!corners.first.z || !corners.second.z) + continue; + // addCrumbs(LOCAL_E, corners.first); + // addCrumbs(entity, corners.second); + addCrumbPair(LOCAL_E, entity, corners); + found = true; + } + if (indirectOrigin.z) + { + addCrumbs(entity, indirectOrigin); + found = true; + } + } + else + { + if (VisCheckEntFromEnt(LOCAL_E, entity)) + found = true; + } + if (isNavBotCM && !found) + { + if (!nav::navTo(entity->m_vecOrigin())) + continue; + navtimeout.update(); + found = true; + } + if (!found) + continue; + follow_target = entity->m_IDX; + break; } - if (!found) - continue; - follow_target = entity->m_IDX; - break; } } - } // If we dont have a follow target from that, we look again for someone // else who is suitable { - if ((!follow_target || change || - (ClassPriority(ENTITY(follow_target)) < 6 && - ENTITY(follow_target)->player_info.friendsID != steamid)) && - roambot) - { - // Try to get a new target - auto ent_count = - followcart ? HIGHEST_ENTITY : g_IEngine->GetMaxClients(); - for (int i = 0; i < ent_count; i++) + if ((!follow_target || change || + (ClassPriority(ENTITY(follow_target)) < 6 && + ENTITY(follow_target)->player_info.friendsID != steamid)) && + roambot) { - auto entity = ENTITY(i); - if (CE_BAD(entity)) // Exist + dormant - continue; - if (!followcart) + // Try to get a new target + auto ent_count = + followcart ? HIGHEST_ENTITY : g_IEngine->GetMaxClients(); + for (int i = 0; i < ent_count; i++) + { + auto entity = ENTITY(i); + if (CE_BAD(entity)) // Exist + dormant + continue; + if (!followcart) + if (entity->m_Type() != ENTITY_PLAYER) + continue; + if (entity == LOCAL_E) // Follow self lol + continue; + if (entity->m_bEnemy()) + continue; + if (afk && afkTicks[i].check( + int(afktime))) // don't follow target that + // was determined afk + continue; + if (IsPlayerDisguised(entity) || IsPlayerInvisible(entity)) + continue; + if (!entity->m_bAlivePlayer()) // Dont follow dead players + continue; + if (follow_activation && + entity->m_flDistance() > (float) follow_activation) + continue; + const model_t *model = + ENTITY(follow_target)->InternalEntity()->GetModel(); + // FIXME follow cart/point + /*if (followcart && model && + (lagexploit::pointarr[0] || lagexploit::pointarr[1] || + lagexploit::pointarr[2] || lagexploit::pointarr[3] || + lagexploit::pointarr[4]) && + (model == lagexploit::pointarr[0] || + model == lagexploit::pointarr[1] || + model == lagexploit::pointarr[2] || + model == lagexploit::pointarr[3] || + model == lagexploit::pointarr[4])) + follow_target = entity->m_IDX;*/ if (entity->m_Type() != ENTITY_PLAYER) continue; - if (entity == LOCAL_E) // Follow self lol - continue; - if (entity->m_bEnemy()) - continue; - if (afk && - afkTicks[i].check(int(afktime))) // don't follow target that - // was determined afk - continue; - if (IsPlayerDisguised(entity) || IsPlayerInvisible(entity)) - continue; - if (!entity->m_bAlivePlayer()) // Dont follow dead players - continue; - if (follow_activation && - entity->m_flDistance() > (float) follow_activation) - continue; - const model_t *model = - ENTITY(follow_target)->InternalEntity()->GetModel(); - // FIXME follow cart/point - /*if (followcart && model && - (lagexploit::pointarr[0] || lagexploit::pointarr[1] || - lagexploit::pointarr[2] || lagexploit::pointarr[3] || - lagexploit::pointarr[4]) && - (model == lagexploit::pointarr[0] || - model == lagexploit::pointarr[1] || - model == lagexploit::pointarr[2] || - model == lagexploit::pointarr[3] || - model == lagexploit::pointarr[4])) - follow_target = entity->m_IDX;*/ - if (entity->m_Type() != ENTITY_PLAYER) - continue; - // favor closer entitys - if (follow_target && - ENTITY(follow_target)->m_flDistance() < - entity->m_flDistance()) // favor closer entitys - continue; - // check if new target has a higher priority than current target - if (ClassPriority(ENTITY(follow_target)) >= - ClassPriority(ENTITY(i))) - continue; - bool found = false; - if (corneractivate) - { - Vector indirectOrigin = VischeckCorner( - LOCAL_E, entity, *follow_activation / 2, - true); // get the corner location that the - // future target is visible from - std::pair corners; - if (!indirectOrigin.z && - entity->m_IDX == lastent) // if we couldn't find it, run - // wallcheck instead - { - corners = - VischeckWall(LOCAL_E, entity, - float(follow_activation) / 2, true); - if (!corners.first.z || !corners.second.z) - continue; - // addCrumbs(LOCAL_E, corners.first); - // addCrumbs(entity, corners.second); - addCrumbPair(LOCAL_E, entity, corners); - found = true; - } - if (indirectOrigin.z) - { - addCrumbs(entity, indirectOrigin); - found = true; - } - } - else - { - if (VisCheckEntFromEnt(LOCAL_E, entity)) - found = true; - } - if (isNavBotCM && !found) - { - if (!nav::navTo(entity->m_vecOrigin())) + // favor closer entitys + if (follow_target && + ENTITY(follow_target)->m_flDistance() < + entity->m_flDistance()) // favor closer entitys continue; - navtimeout.update(); - found = true; + // check if new target has a higher priority than current + // target + if (ClassPriority(ENTITY(follow_target)) >= + ClassPriority(ENTITY(i))) + continue; + bool found = false; + if (corneractivate) + { + Vector indirectOrigin = VischeckCorner( + LOCAL_E, entity, *follow_activation / 2, + true); // get the corner location that the + // future target is visible from + std::pair corners; + if (!indirectOrigin.z && + entity->m_IDX == + lastent) // if we couldn't find it, run + // wallcheck instead + { + corners = VischeckWall(LOCAL_E, entity, + float(follow_activation) / 2, + true); + if (!corners.first.z || !corners.second.z) + continue; + // addCrumbs(LOCAL_E, corners.first); + // addCrumbs(entity, corners.second); + addCrumbPair(LOCAL_E, entity, corners); + found = true; + } + if (indirectOrigin.z) + { + addCrumbs(entity, indirectOrigin); + found = true; + } + } + else + { + if (VisCheckEntFromEnt(LOCAL_E, entity)) + found = true; + } + if (isNavBotCM && !found) + { + if (!nav::navTo(entity->m_vecOrigin())) + continue; + navtimeout.update(); + found = true; + } + if (!found) + continue; + // ooooo, a target + follow_target = i; + afkTicks[i].update(); // set afk time to 0 } - if (!found) - continue; - // ooooo, a target - follow_target = i; - afkTicks[i].update(); // set afk time to 0 } } - } lastent++; if (lastent > g_IEngine->GetMaxClients()) lastent = 0; diff --git a/src/hacks/Misc.cpp b/src/hacks/Misc.cpp index 535aeefe..28a1f129 100644 --- a/src/hacks/Misc.cpp +++ b/src/hacks/Misc.cpp @@ -22,7 +22,7 @@ #include "hack.hpp" -static settings::Bool render_zoomed{ "visuals.render-local-zoomed", "false" }; +static settings::Bool render_zoomed{ "visual.render-local-zoomed", "false" }; static settings::Bool anti_afk{ "misc.anti-afk", "false" }; static settings::Bool auto_strafe{ "misc.autostrafe", "false" }; static settings::Bool tauntslide{ "misc.tauntslide-tf2c", "false" }; diff --git a/src/hacks/MiscAimbot.cpp b/src/hacks/MiscAimbot.cpp index 64a195a4..81ba89d1 100644 --- a/src/hacks/MiscAimbot.cpp +++ b/src/hacks/MiscAimbot.cpp @@ -3,12 +3,15 @@ // #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" }; +#include "settings/Bool.hpp" +#include "settings/Int.hpp" +#include "settings/Key.hpp" +#include "PlayerTools.hpp" +#include "hacks/Trigger.hpp" + +static settings::Bool sandwichaim_enabled{ "sandwichaim.enable", "false" }; +static settings::Button sandwichaim_aimkey{ "sandwichaim.aimkey", "" }; +static settings::Int sandwichaim_aimkey_mode{ "sandwichaim.aimkey-mode", "0" }; float sandwich_speed = 350.0f; float grav = 0.25f; @@ -32,6 +35,9 @@ std::pair FindBestEnt(bool teammate, bool Predict, continue; if (!ent->hitboxes.GetHitbox(1)) continue; + if (!teammate && player_tools::shouldTarget(ent) != + player_tools::IgnoreReason::DO_NOT_IGNORE) + continue; Vector target{}; if (Predict) target = ProjectilePrediction(ent, 1, sandwich_speed, grav, @@ -151,21 +157,21 @@ void DoSlowAim(Vector &input_angle) } static HookedFunction - SandwichAim(HookedFunctions_types::HF_CreateMove, "SandwichAim", 1, []() { - if (!*enable) + SandwichAim(HookedFunctions_types::HF_CreateMove, "SandwichAim", 5, []() { + if (!*sandwichaim_enabled) return; - if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || CE_BAD(LOCAL_W)) return; - if (aimkey) + if (sandwichaim_aimkey) { - switch (*aimkey_mode) + switch (*sandwichaim_aimkey_mode) { case 1: - if (!aimkey.isKeyDown()) + if (!sandwichaim_aimkey.isKeyDown()) return; break; case 2: - if (aimkey.isKeyDown()) + if (sandwichaim_aimkey.isKeyDown()) return; break; default: @@ -202,7 +208,7 @@ static HookedFunction return; if (charge_key && !charge_key.isKeyDown()) return; - if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || CE_BAD(LOCAL_W)) return; if (!HasCondition(LOCAL_E)) return; @@ -221,18 +227,64 @@ static HookedFunction charge_aimbotted = true; } }); + static settings::Bool charge_control{ "chargecontrol.enable", "false" }; -static settings::Int charge_int{ "chargecontrol.strength", "1" }; +static settings::Float charge_float{ "chargecontrol.strength", "3.0f" }; static HookedFunction ChargeControl( - HookedFunctions_types::HF_CreateMove, "ChargeControl", 1, []() { + HookedFunctions_types::HF_CreateMove, "chargecontrol", 5, []() { if (!*charge_control || charge_aimbotted) return; - if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || CE_BAD(LOCAL_W)) return; if (!HasCondition(LOCAL_E)) return; float offset = 0.0f; - if (current_user_cmd->mousedx > 1 || current_user_cmd->mousedx < -1) - offset = -(current_user_cmd->mousedx / 100 * *charge_int); + if (current_user_cmd->buttons & IN_MOVELEFT) + offset = *charge_float; + if (current_user_cmd->buttons & IN_MOVERIGHT) + offset = -*charge_float; current_user_cmd->viewangles.y += offset; }); + +static settings::Bool autosapper_enabled("autosapper.enabled", "false"); +static settings::Bool autosapper_silent("autosapper.silent", "true"); + +static HookedFunction SapperAimbot(HF_CreateMove, "sapperaimbot", 5, []() { + if (!autosapper_enabled) + return; + if (CE_BAD(LOCAL_E) || CE_BAD(LOCAL_W) || !g_pLocalPlayer->holding_sapper) + return; + + CachedEntity *target = nullptr; + float fov = FLT_MAX; + float range = re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W)); + for (int i = 0; i < entity_cache::max; i++) + { + CachedEntity *ent = ENTITY(i); + if (CE_BAD(ent)) + continue; + if (ent->m_Type() != ENTITY_BUILDING) + continue; + if (!ent->m_bEnemy()) + continue; + if (CE_BYTE(ent, netvar.m_bHasSapper)) + continue; + if (GetBuildingPosition(ent).DistTo(g_pLocalPlayer->v_Eye) > range) + continue; + float new_fov = GetFov(g_pLocalPlayer->v_OrigViewangles, + g_pLocalPlayer->v_Eye, GetBuildingPosition(ent)); + if (fov <= new_fov) + continue; + + fov = new_fov; + target = ent; + } + if (target) + { + AimAt(g_pLocalPlayer->v_Eye, GetBuildingPosition(target), + current_user_cmd); + if (autosapper_silent) + g_pLocalPlayer->bUseSilentAngles = true; + current_user_cmd->buttons |= IN_ATTACK; + } +}); diff --git a/src/hacks/NavBot.cpp b/src/hacks/NavBot.cpp index e1054492..ca873b7f 100644 --- a/src/hacks/NavBot.cpp +++ b/src/hacks/NavBot.cpp @@ -1,192 +1,30 @@ +// +// Created by bencat07 on 17.08.18. +// +#include +#include #include "common.hpp" -#include "NavBot.hpp" -#include "Backtrack.hpp" -#include "PlayerTools.hpp" #include "navparser.hpp" -#include "settings/Bool.hpp" -#include "settings/Float.hpp" -#include "HookedMethods.hpp" +#include "FollowBot.hpp" +#include "NavBot.hpp" +#include "PlayerTools.hpp" -// Rvars +namespace hacks::tf2::NavBot +{ static settings::Bool enable{ "navbot.enable", "false" }; -static settings::Bool sniper_mode{ "navbot.sniper-mode", "true" }; +static settings::Bool spy_mode{ "navbot.spy-mode", "false" }; static settings::Bool heavy_mode{ "navbot.heavy-mode", "false" }; static settings::Bool scout_mode{ "navbot.scout-mode", "false" }; -static settings::Float jump_trigger{ "navbot.jump-distance", "500.0f" }; -static settings::Bool spy_mode{ "navbot.spy-mode", "false" }; -static settings::Bool stay_near{ "navbot.stay-near", "true" }; -static settings::Bool path_health{ "navbot.path-health", "true" }; -static settings::Bool path_ammo{ "navbot.path-ammo", "true" }; -static settings::Bool pick_optimal_slot{ "navbot.best-slot", "true" }; -static settings::Bool take_tele{ "navbot.take-teleporter", "false" }; - -// Timers -static Timer general_cooldown{}; -static Timer init_cooldown{}; -static Timer path_health_cooldown{}; -static Timer path_ammo_cooldown{}; -static Timer refresh_nearest_target{}; -static Timer refresh_nearest_valid_vector{}; -static Timer nav_to_nearest_enemy_cooldown{}; -static Timer slot_timer{}; -static Timer non_sniper_sniper_nav_cooldown{}; -static Timer jump_cooldown{}; -static Timer teleporter_cooldown{}; -static Timer teleporter_find_cooldown{}; -static Timer nav_timeout{}; - -// Vectors -static std::vector default_spots{}; -static std::vector preferred_spots{}; - -// Unordered_maps -static std::unordered_map preferred_spots_priority{}; - -static bool inited = false; - -namespace hacks::shared::NavBot -{ - -// Main Functions -void Init(bool from_LevelInit) -{ - if (!*enable) - { - inited = false; - return; - } - if (from_LevelInit) - { - inited = false; - default_spots.clear(); - preferred_spots.clear(); - preferred_spots_priority.clear(); - } - if (!nav::prepare()) - return; - if (!from_LevelInit) - { - default_spots.clear(); - preferred_spots.clear(); - preferred_spots_priority.clear(); - } - inited = true; - for (auto &i : nav::navfile.get()->m_areas) - { - if (!i.m_hidingSpots.empty()) - for (auto &j : i.m_hidingSpots) - default_spots.push_back(&j.m_pos); - if (i.m_attributeFlags & NAV_MESH_NO_HOSTAGES) - preferred_spots.push_back(&i.m_center); - } -} - -static HookedFunction - CreateMove(HookedFunctions_types::HF_CreateMove, "NavBot", 18, []() { - // Master Switch - - if (!*enable) - return; - - // init pls - if (!inited) - { - if (init_cooldown.test_and_set(10000)) - Init(false); - return; - } - // no nav file loaded/inited - if (!nav::prepare()) - return; - // Timeout boys - if (!nav_timeout.check(2000)) - return; - - if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) - return; - // Health and ammo have highest priority, but the stay near priorities has to be this high to override anything else - if (nav::curr_priority == 1337 && (HasLowAmmo() || HasLowHealth())) - nav::clearInstructions(); - - // Get health if low - if (path_health && HasLowHealth() && - path_health_cooldown.test_and_set(500)) - { - CachedEntity *health = nearestHealth(); - if (CE_GOOD(health)) - nav::navTo(health->m_vecOrigin(), 7, false, false); - } - - // Get Ammo if low on ammo - if (path_ammo && HasLowAmmo() && path_ammo_cooldown.test_and_set(500)) - { - CachedEntity *ammo = nearestAmmo(); - if (CE_GOOD(ammo)) - nav::navTo(ammo->m_vecOrigin(), 6, false, false); - } - // Stop pathing for ammo/Health if problem resolved - if ((!HasLowAmmo() && nav::curr_priority == 6) || ( nav::curr_priority == 7 && !HasLowHealth())) - nav::clearInstructions(); - - // Take Teleporter - if (*take_tele && nav::curr_priority != 6 && nav::curr_priority != 7 && teleporter_cooldown.test_and_set(200)) - { - CachedEntity *ent = nearestTeleporter(); - if (CE_GOOD(ent) && ent->m_flDistance() <= 300.0f) - if (nav::navTo(ent->m_vecOrigin(), 4, false, false)) - return; - - } - // If Zoning enabled then zone enemy - if (stay_near && nav_to_nearest_enemy_cooldown.test_and_set(100) && !*spy_mode) - NavToNearestEnemy(); - - // Prevent path spam on sniper bots - if (CanPath()) - { - if (sniper_mode) - NavToSniperSpot(5); - else if ((*heavy_mode || scout_mode) && nav_to_nearest_enemy_cooldown.test_and_set(100)) - { - if (!NavToNearestEnemy() && non_sniper_sniper_nav_cooldown.test_and_set(10000)) - NavToSniperSpot(5); - } - else if (*spy_mode && nav_to_nearest_enemy_cooldown.test_and_set(100)) - if (!NavToBacktrackTick(5) && non_sniper_sniper_nav_cooldown.test_and_set(10000)) - NavToSniperSpot(5); - } - if (*pick_optimal_slot) - UpdateSlot(); - if (*scout_mode) - Jump(); - }); - -// Helpers - -bool CanPath() -{ - if (nav::curr_priority == 4 || nav::curr_priority == 6 || nav::curr_priority == 7) - return false; - if ((*heavy_mode || *spy_mode || *scout_mode) && general_cooldown.test_and_set(100)) - return true; - else if (sniper_mode) - { - if (nav::ReadyForCommands && general_cooldown.test_and_set(100)) - return true; - return false; - } - return false; -} - -bool HasLowHealth() -{ - return float(LOCAL_E->m_iHealth()) / float(LOCAL_E->m_iMaxHealth()) < 0.64; -} +static settings::Bool primary_only{ "navbot.primary-only", "true" }; +static settings::Int jump_distance{ "navbot.jump-distance", "500" }; +static settings::Bool target_sentry{ "navbot.target-sentry", "true" }; +static settings::Bool stay_near{ "navbot.stay-near", "false" }; +static settings::Bool take_tele{ "navbot.take-teleporters", "true" }; bool HasLowAmmo() { int *weapon_list = - (int *) ((unsigned) (RAW_ENT(LOCAL_E)) + netvar.hMyWeapons); + (int *) ((uint64_t)(RAW_ENT(LOCAL_E)) + netvar.hMyWeapons); if (g_pLocalPlayer->holding_sniper_rifle && CE_INT(LOCAL_E, netvar.m_iAmmo + 4) <= 5) return true; @@ -206,6 +44,29 @@ bool HasLowAmmo() return false; } +bool HasLowHealth() +{ + return float(LOCAL_E->m_iHealth()) / float(LOCAL_E->m_iMaxHealth()) < 0.64; +} + +CachedEntity *nearestSentry() +{ + float bestscr = FLT_MAX; + CachedEntity *bestent = nullptr; + for (int i = 0; i < HIGHEST_ENTITY; i++) + { + CachedEntity *ent = ENTITY(i); + if (CE_BAD(ent) || ent->m_iClassID() != CL_CLASS(CObjectSentrygun) || + ent->m_iTeam() == LOCAL_E->m_iTeam()) + continue; + if (ent->m_flDistance() < bestscr) + { + bestscr = ent->m_flDistance(); + bestent = ent; + } + } + return bestent; +} CachedEntity *nearestHealth() { float bestscr = FLT_MAX; @@ -227,7 +88,6 @@ CachedEntity *nearestHealth() } return bestent; } - CachedEntity *nearestAmmo() { float bestscr = FLT_MAX; @@ -249,110 +109,224 @@ CachedEntity *nearestAmmo() } return bestent; } - -static int last_target = -1; -CachedEntity *nearestEnemy() +int last_tar = -1; +CachedEntity *NearestEnemy() { - if (refresh_nearest_target.test_and_set(3000)) + if (last_tar != -1 && CE_GOOD(ENTITY(last_tar)) && + ENTITY(last_tar)->m_bAlivePlayer() && + ENTITY(last_tar)->m_iTeam() != LOCAL_E->m_iTeam()) + return ENTITY(last_tar); + float bestscr = FLT_MAX; + CachedEntity *bestent = nullptr; + for (int i = 0; i < g_IEngine->GetMaxClients(); i++) { - CachedEntity *best_tar = nullptr; - float best_dist = FLT_MAX; - for (int i = 0; i < g_IEngine->GetMaxClients(); i++) + CachedEntity *ent = ENTITY(i); + if (CE_BAD(ent) || ent->m_Type() != ENTITY_PLAYER) + continue; + if (player_tools::shouldTarget(ent) != + player_tools::IgnoreReason::DO_NOT_IGNORE) + continue; + if (ent == LOCAL_E || !ent->m_bAlivePlayer() || + ent->m_iTeam() == LOCAL_E->m_iTeam()) + continue; + float scr = ent->m_flDistance(); + if (g_pPlayerResource->GetClass(ent) == tf_engineer || + g_pPlayerResource->GetClass(ent) == tf_heavy) + scr *= 5.0f; + if (g_pPlayerResource->GetClass(ent) == tf_pyro) + scr *= 7.0f; + if (scr < bestscr) { - CachedEntity *ent = ENTITY(i); - if (CE_BAD(ent) || !ent->m_bAlivePlayer() || !ent->m_bEnemy() || - ent == LOCAL_E || - player_tools::shouldTarget(ent) != - player_tools::IgnoreReason::DO_NOT_IGNORE) - continue; - if (ent->m_vecOrigin().DistTo(LOCAL_E->m_vecOrigin()) < best_dist) - { - best_dist = ent->m_vecOrigin().DistTo(LOCAL_E->m_vecOrigin()); - best_tar = ent; - } + bestscr = scr; + bestent = ent; } - if (CE_GOOD(best_tar)) + } + if (CE_BAD(bestent)) + last_tar = -1; + else + last_tar = bestent->m_IDX; + return bestent; +} + +CNavArea *FindNearestValidByDist(Vector vec, float mindist, float maxdist, + bool nearest) +{ + float best_scr = nearest ? FLT_MAX : 0.0f; + CNavArea *best_area = nullptr; + for (auto &i : nav::navfile->m_areas) + { + float score = i.m_center.DistTo(vec); + if (score > maxdist || score < mindist) + continue; + Vector tovischeck = i.m_center; + tovischeck.z += 48.0f; + if (!IsVectorVisible(vec, tovischeck, false)) + continue; + if (!nav::isSafe(&i)) + continue; + if (nearest) { - last_target = best_tar->m_IDX; - return best_tar; + if (score < best_scr) + { + best_scr = score; + best_area = &i; + } } else { - last_target = -1; - return nullptr; - } - } - else - { - if (last_target == -1) - return nullptr; - else - { - CachedEntity *ent = ENTITY(last_target); - if (CE_BAD(ent) || !ent->m_bAlivePlayer() || !ent->m_bEnemy() || - ent == LOCAL_E || - player_tools::shouldTarget(ent) != - player_tools::IgnoreReason::DO_NOT_IGNORE) + if (score > best_scr) { - last_target = -1; - return nullptr; + best_scr = score; + best_area = &i; } - else - return ent; } } + return best_area; } -static Vector cached_vector{0.0f, 0.0f, 0.0f}; -static Vector empty{0.0f, 0.0f, 0.0f}; -Vector GetClosestValidByDist(CachedEntity *ent, float mindist, float maxdist, bool near) +static Timer ammo_health_cooldown{}; +static Timer init_timer{}; +static Timer nav_cooldown{}; +static Timer engi_spot_cd{}; +static Timer nav_enemy_cd{}; +static Timer jump_cooldown{}; +static std::vector preferred_sniper_spots; +static std::vector sniper_spots; +static std::vector nest_spots; +Vector Best_Spot{ 0.0f, 0.0f, 0.0f }; +void Init() { - if (refresh_nearest_valid_vector.test_and_set(100)) + sniper_spots.clear(); + preferred_sniper_spots.clear(); + nest_spots.clear(); + for (auto &area : nav::navfile->m_areas) { - if (CE_BAD(ent)) - return empty; - - Vector best_area{0.0f, 0.0f, 0.0f}; - float best_dist = near ? FLT_MAX : 0.0f; - for (auto &i : nav::navfile->m_areas) - { - if (!nav::isSafe(&i)) - continue; - Vector center = i.m_center; - float dist = center.DistTo(ent->m_vecOrigin()); - - // Check if wihin the range specified - if (dist > maxdist || dist < mindist) - continue; - - // We want to be standing the closest to them possible, besides as a sniper - if ((near && dist > best_dist) || (!near && dist < best_dist)) - continue; - - // Anti stuck in ground stuff - Vector zcheck = center; - zcheck.z += 48; - - // Anti stuck in ground - Vector zent = ent->m_vecOrigin(); - zent += 48; - if (!IsVectorVisible(zcheck, zent, false)) - continue; - best_area = i.m_center; - best_dist = dist; - } - if (best_area.IsValid() && best_area.z ) - { - cached_vector = best_area; - return best_area; - } - return empty; + if (area.m_attributeFlags & NAV_MESH_NO_HOSTAGES) + preferred_sniper_spots.push_back(area.m_center); + if (area.m_attributeFlags & NAV_MESH_RUN) + nest_spots.push_back(area.m_center); + for (auto hide : area.m_hidingSpots) + if (hide.IsGoodSniperSpot() || hide.IsIdealSniperSpot() || + hide.IsExposed()) + sniper_spots.push_back(hide.m_pos); } - // We Want a bit of caching - else - return cached_vector; + logging::Info("Sniper spots: %d, Manual Sniper Spots: %d, Sentry Spots: %d", + sniper_spots.size(), preferred_sniper_spots.size(), + nest_spots.size()); +} +static std::unordered_map disabled_spot{}; +static std::unordered_map disabled_cooldown{}; +std::unordered_map priority_spots; +void initonce() +{ + priority_spots.clear(); + ammo_health_cooldown.update(); + init_timer.update(); + nav_cooldown.update(); + engi_spot_cd.update(); + sniper_spots.clear(); + preferred_sniper_spots.clear(); + disabled_cooldown.clear(); + disabled_spot.clear(); + return; } +static Timer spot_timer{}; +#define retnull \ + { \ + Best_Spot = { 0.0f, 0.0f, 0.0f }; \ + return; \ + } + +struct ent_info +{ + Vector origin{}; + int team{}; + int clazz{}; + int idx{}; +}; + +void UpdateBestSpot() +{ + if (!spot_timer.test_and_set(10000)) + return; + if (CE_BAD(LOCAL_E) || CE_BAD(LOCAL_W)) + retnull; + int ent_count = 0; + std::unordered_map stored_pos; + for (int i = 0; i < g_IEngine->GetMaxClients(); i++) + { + CachedEntity *ent = ENTITY(i); + if (CE_BAD(ent) || !ent->m_bAlivePlayer()) + continue; + stored_pos[i].origin = ent->m_vecOrigin(); + stored_pos[i].team = ent->m_iTeam(); + stored_pos[i].clazz = g_pPlayerResource->GetClass(ent); + stored_pos[i].idx = i; + } + // Get dist from each ent to another + std::unordered_map, float, + boost::hash>> + distances; + for (auto &i : stored_pos) + for (auto &j : stored_pos) + distances[{ i.second.idx, j.second.idx }] = + i.second.origin.DistTo(j.second.origin); + Vector prefferred_spot{}; + float score_max = FLT_MAX; + bool must_be_enemy = false; + for (auto &i : distances) + { + // Mark self :thinking: + if (stored_pos[i.first.first].idx == LOCAL_E->m_IDX || + stored_pos[i.first.second].idx == LOCAL_E->m_IDX) + continue; + // Not for us + if (stored_pos[i.first.first].team != stored_pos[i.first.second].team) + continue; + Vector pos1 = stored_pos[i.first.first].origin; + Vector pos2 = stored_pos[i.first.second].origin; + + // Bot please don't get stuck midair thanks + if (fabsf(pos1.z - pos2.z) > 70) + continue; + + // Get Pos inbetween the two coords. + Vector estimated_pos = (pos1 + pos2) / 2; + bool enemy = stored_pos[i.first.first].team != LOCAL_E->m_iTeam(); + if (must_be_enemy && !enemy) + continue; + // Prevent lag thru vischecks + if (must_be_enemy && !enemy) + if ((!i.second || (i.second > score_max && !score_max))) + continue; + // Vischecks.club + if (!IsVectorVisible(pos1, estimated_pos, true) || + !IsVectorVisible(pos2, estimated_pos, true)) + continue; + + // Distance check thing + if ((i.second && (i.second < score_max || !score_max )) || (enemy && !must_be_enemy)) + { + score_max = i.second; + if (enemy) + must_be_enemy = true; + prefferred_spot = estimated_pos; + } + } + if (!prefferred_spot.IsZero()) + Best_Spot = prefferred_spot; + else + retnull; + +} +static CatCommand update_spot_debug{"navbot_debug_spotupdate", "debug", [](){ + UpdateBestSpot(); +}}; +static CatCommand nav_best_spot{"navbot_debug_navbest", "debug", [](){ + nav::navTo(Best_Spot); +}}; +Timer slot_timer{}; void UpdateSlot() { if (!slot_timer.test_and_set(1000)) @@ -373,209 +347,453 @@ void UpdateSlot() } } } - -void Jump() +enum BuildingNum { - CachedEntity *ent = nearestEnemy(); - if (CE_BAD(ent)) - return; - if (ent->m_flDistance() < *jump_trigger && jump_cooldown.test_and_set(200)) - current_user_cmd->buttons |= IN_JUMP; -} - -static int teleporter = -1; -CachedEntity *nearestTeleporter() + DISPENSER = 0, + TELEPORT_ENT, + SENTRY, + TELEPORT_EXT, +}; +std::vector GetBuildings() { - if (teleporter_find_cooldown.test_and_set(1000)) + float bestscr = FLT_MAX; + std::vector buildings; + for (int i = 0; i < HIGHEST_ENTITY; i++) { - float closest = FLT_MAX; - CachedEntity *tele = nullptr; - for (int i = 0; i < HIGHEST_ENTITY; i++) + CachedEntity *ent = ENTITY(i); + if (CE_BAD(ent)) + continue; + if (ent->m_Type() != ENTITY_BUILDING) + continue; + if ((CE_INT(ent, netvar.m_hBuilder) & 0xFFF) != + g_pLocalPlayer->entity_idx) + continue; + if (ent->m_vecOrigin().DistTo(LOCAL_E->m_vecOrigin()) < bestscr) { - CachedEntity *ent = ENTITY(i); - if (CE_BAD(ent) || ent->m_bEnemy() || ent->m_iClassID() != CL_CLASS(CObjectTeleporter)) - continue; - if (CE_FLOAT(ent, netvar.m_flTeleYawToExit) && CE_FLOAT(ent, netvar.m_flTeleRechargeTime) && CE_FLOAT(ent, netvar.m_flTeleRechargeTime) < g_GlobalVars->curtime) - { - float score = ent->m_flDistance(); - if (score < closest) - { - tele = ent; - closest = score; - nav_timeout.update(); - } - } + buildings.push_back(i); + bestscr = ent->m_vecOrigin().DistTo(LOCAL_E->m_vecOrigin()); } - if (tele) - teleporter = tele->m_IDX; - return tele; } - else - { - if (teleporter == -1) - return nullptr; - CachedEntity *ent = ENTITY(teleporter); - if (CE_BAD(ent) || ent->m_bEnemy() || ent->m_iClassID() != CL_CLASS(CObjectTeleporter)) - { - teleporter = -1; - return nullptr; - } - return ent; - } - // Wtf Call the police - return nullptr; + return buildings; } - -// Navigation -bool NavToSniperSpot(int priority) +int cost[4] = { 100, 50, 130, 50 }; +int GetBestBuilding(int metal) { - // Already pathing currently and priority is below the wanted, so just - // return - if (priority < nav::curr_priority) + bool hasSentry = false; + bool hasDispenser = false; + if (!GetBuildings().empty()) + for (auto build : GetBuildings()) + { + CachedEntity *building = ENTITY(build); + if (building->m_iClassID() == CL_CLASS(CObjectSentrygun)) + hasSentry = true; + if (building->m_iClassID() == CL_CLASS(CObjectDispenser)) + hasDispenser = true; + } + if (metal >= cost[SENTRY] && !hasSentry) + return SENTRY; + else if (metal >= cost[DISPENSER] && !hasDispenser) + return DISPENSER; + if (hasSentry && hasDispenser) + return 3; + return -1; +} +int GetClosestBuilding() +{ + float bestscr = FLT_MAX; + int BestBuilding = -1; + for (int i = 0; i < HIGHEST_ENTITY; i++) + { + CachedEntity *ent = ENTITY(i); + if (CE_BAD(ent)) + continue; + if (ent->m_Type() != ENTITY_BUILDING) + continue; + if ((CE_INT(ent, netvar.m_hBuilder) & 0xFFF) != + g_pLocalPlayer->entity_idx) + continue; + if (ent->m_vecOrigin().DistTo(LOCAL_E->m_vecOrigin()) < bestscr) + { + BestBuilding = i; + bestscr = ent->m_vecOrigin().DistTo(LOCAL_E->m_vecOrigin()); + } + } + return BestBuilding; +} +int GetClosestTeleporter() +{ + float bestscr = FLT_MAX; + int BestBuilding = -1; + for (int i = 0; i < HIGHEST_ENTITY; i++) + { + CachedEntity *ent = ENTITY(i); + if (CE_BAD(ent)) + continue; + if (ent->m_iClassID() != CL_CLASS(CObjectTeleporter)) + continue; + if (ent->m_vecOrigin().DistTo(LOCAL_E->m_vecOrigin()) < bestscr) + { + BestBuilding = i; + bestscr = ent->m_vecOrigin().DistTo(LOCAL_E->m_vecOrigin()); + } + } + return BestBuilding; +} +bool NavToSentry(int priority) +{ + CachedEntity *Sentry = nearestSentry(); + if (CE_BAD(Sentry)) + return false; + CNavArea *area = FindNearestValidByDist(GetBuildingPosition(Sentry), + 1100.0f, 2000.0f, false); + if (!area) + return false; + if (nav::navTo(area->m_center, priority, true, false)) return true; - // Preferred yay or nay? - bool use_preferred = preferred_spots.empty() ? false : true; - if (!use_preferred && default_spots.empty()) - return false; + return false; +} +static Vector lastgoal{ 0, 0, 0 }; +int lastent = -1; - std::vector *sniper_spots = - use_preferred ? &preferred_spots : &default_spots; - - // Wtf Nullptr! - if (!sniper_spots) - return false; - if (use_preferred) +bool NavToEnemy() +{ + if (*stay_near) { - // Store Lowest Matches for later, will be useful - std::vector matches{}; - - // Priority INT_MAX, not like you'll exceed it anyways lol - int lowest_priority = INT_MAX; - for (unsigned i = 0; i < sniper_spots->size(); i++) + if (lastent != -1) { - if (preferred_spots_priority[i] < lowest_priority) + CachedEntity *ent = ENTITY(lastent); + if (CE_BAD(ent) || !ent->m_bAlivePlayer() || + ent->m_iTeam() == LOCAL_E->m_iTeam()) { - lowest_priority = preferred_spots_priority[i]; - matches.clear(); - matches.push_back(i); - } - else if (preferred_spots_priority[i] == lowest_priority) - matches.push_back(i); - } - if (!matches.empty()) - { - // Cant exceed.club - float min_dist = FLT_MAX; - - // Best Spot to nav to - int best_spot = -1; - - for (auto idx : matches) - { - Vector *match = sniper_spots->at(matches.at(0)); - - // Score of the match - float score = match->DistTo(LOCAL_E->m_vecOrigin()); - - if (score < min_dist) + lastent = -1; + if (lastgoal.x > 1.0f || lastgoal.x < -1.0f) { - min_dist = score; - best_spot = idx; + nav::navTo(lastgoal, 1337, true, false); + return true; } } + else + { + CNavArea *area = nullptr; + if (!*heavy_mode && !*scout_mode) + area = FindNearestValidByDist(ent->m_vecOrigin(), 300, 6000, + false); + else + area = FindNearestValidByDist(ent->m_vecOrigin(), 200, 1000, + true); + if (area) + { + nav::navTo(area->m_center, 1337, true, false); + lastgoal = area->m_center; + lastent = ent->m_IDX; + return true; + } + else if ((lastgoal.x > 1.0f || lastgoal.x < -1.0f) && + lastgoal.DistTo(LOCAL_E->m_vecOrigin()) > 200.0f) + { + nav::navTo(lastgoal, 1337, true, false); + lastgoal = { 0, 0, 0 }; + return true; + } + else + { + lastgoal = { 0, 0, 0 }; + lastent = -1; + } + } + } - // return if no spot found - if (best_spot == -1) - return false; - // Make spot less important - preferred_spots_priority[best_spot]++; - // Nav to Spot - return nav::navTo(*sniper_spots->at(best_spot), priority); + auto ent = NearestEnemy(); + if (CE_GOOD(ent)) + { + CNavArea *area = nullptr; + if (!*heavy_mode && !*scout_mode) + area = FindNearestValidByDist(ent->m_vecOrigin(), 200, 2000, + false); + else + area = + FindNearestValidByDist(ent->m_vecOrigin(), 200, 1000, true); + if (area) + { + nav::navTo(area->m_center, 1337, true, false); + lastgoal = area->m_center; + lastent = ent->m_IDX; + return true; + } + else if ((lastgoal.x > 1.0f || lastgoal.x < -1.0f) && + lastgoal.DistTo(LOCAL_E->m_vecOrigin()) > 200.0f) + { + nav::navTo(lastgoal, 1337, true, false); + lastgoal = { 0, 0, 0 }; + return true; + } + else + { + lastgoal = { 0, 0, 0 }; + lastent = -1; + } + } + else if ((lastgoal.x > 1.0f || lastgoal.x < -1.0f) && + lastgoal.DistTo(LOCAL_E->m_vecOrigin()) > 200.0f) + { + nav::navTo(lastgoal, 1337, true, false); + lastgoal = { 0, 0, 0 }; + return true; + } + else + { + lastgoal = { 0, 0, 0 }; + lastent = -1; } } - else - { - // Get Random Sniper Spot - unsigned index = unsigned(std::rand()) % sniper_spots->size(); - Vector *random_spot = sniper_spots->at(index); - - // Nav to Spot - return nav::navTo(*random_spot, priority); - } -} -bool CanNavToNearestEnemy() -{ - if (HasLowAmmo() || HasLowHealth()) - return false; - return true; -} -bool NavToNearestEnemy() -{ - CachedEntity *ent = nearestEnemy(); - if (CE_BAD(ent)) - return false; - if (nav::curr_priority == 6 || nav::curr_priority == 7 || nav::curr_priority == 4) - return false; - float min_dist = 800.0f; - float max_dist = 4000.0f; - bool stay_near = *sniper_mode ? false : true; - if (*heavy_mode || *scout_mode) - { - min_dist = 100.0f; - max_dist = 1000.0f; - } - Vector to_nav = GetClosestValidByDist(ent, min_dist, max_dist, stay_near); - if (to_nav.z) - return nav::navTo(to_nav, 1337, false, false); return false; } -bool NavToBacktrackTick(int priority) +bool NavToSniperSpot(int priority) { - CachedEntity *ent = nearestEnemy(); - if (CE_BAD(ent)) + Vector random_spot{}; + if (!sniper_spots.size() && !preferred_sniper_spots.size()) return false; - // Health and ammo are more important - if (nav::curr_priority == 6 || nav::curr_priority == 7) - return false; - // Just backtrack data - auto unsorted_ticks = hacks::shared::backtrack:: - headPositions[ent->m_IDX]; - // Vector needed for later - std::vector - sorted_ticks; - - // Only use good ticks - for (int i = 0; i < 66; i++) + bool use_preferred = !preferred_sniper_spots.empty(); + auto snip_spot = use_preferred ? preferred_sniper_spots : sniper_spots; + bool toret = false; + if (use_preferred) { - if (hacks::shared::backtrack::ValidTick( - unsorted_ticks[i], ent)) - sorted_ticks.push_back(unsorted_ticks[i]); - } - // Nav to Ent origin if everything falls flat - if (sorted_ticks.empty()) - { - if (nav::navTo(ent->m_vecOrigin(), 5, false, false)) - return true; - return false; - } - // Sort by 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; - }); + int best_spot = -1; + float maxscr = FLT_MAX; + int lowest_priority = 9999; + for (int i = 0; i < snip_spot.size(); i++) + { + if (disabled_spot[i]) + { + if (!disabled_cooldown[i].test_and_set(5000)) + continue; + else + disabled_spot[i] = false; + } + if ((priority_spots[i] < lowest_priority)) + lowest_priority = priority_spots[i]; + } + for (int i = 0; i < snip_spot.size(); i++) + { + if (disabled_spot[i]) + { + if (!disabled_cooldown[i].test_and_set(5000)) + continue; + else + disabled_spot[i] = false; + } + if ((priority_spots[i] > lowest_priority)) + continue; + float scr = snip_spot[i].DistTo(g_pLocalPlayer->v_Eye); + if (scr < maxscr) + { + maxscr = scr; + best_spot = i; + } + } - // Get the 5th tick and path to it, better than pathing to the last tick since the bot may just lag behind and never reach it - if (!sorted_ticks[5].tickcount || - !nav::navTo(sorted_ticks[5].entorigin, priority, false, - false)) - if (!nav::navTo(ent->m_vecOrigin(), priority, false)) + if (best_spot == -1) + { + snip_spot = sniper_spots; + int rng = rand() % snip_spot.size(); + random_spot = snip_spot.at(rng); + if (random_spot.z) + return nav::navTo(random_spot, false, true, priority); return false; - return true; + } + random_spot = snip_spot.at(best_spot); + if (random_spot.z) + toret = nav::navTo(random_spot, false, true, priority); + if (!toret) + { + disabled_spot[best_spot] = true; + disabled_cooldown[best_spot].update(); + } + priority_spots[best_spot]++; + } + else if (!snip_spot.empty()) + { + int rng = rand() % snip_spot.size(); + random_spot = snip_spot.at(rng); + if (random_spot.z) + toret = nav::navTo(random_spot, priority, true, false); + } + return toret; } +CatCommand debug_tele("navbot_debug", "debug", []() { + int idx = GetClosestBuilding(); + if (idx == -1) + return; + CachedEntity *ent = ENTITY(idx); + if (CE_BAD(ent)) + return; + logging::Info( + "%d %u %d %d %f %f %d %f %f %f", CE_INT(ent, netvar.m_iObjectType), + CE_BYTE(ent, netvar.m_bBuilding), CE_INT(ent, netvar.m_iTeleState), + CE_INT(ent, netvar.m_bMatchBuilding), + CE_FLOAT(ent, netvar.m_flTeleRechargeTime), + CE_FLOAT(ent, netvar.m_flTeleCurrentRechargeDuration), + CE_INT(ent, netvar.m_iTeleTimesUsed), + CE_FLOAT(ent, netvar.m_flTeleYawToExit), g_GlobalVars->curtime, + g_GlobalVars->curtime * g_GlobalVars->interval_per_tick); +}); -} // namespace hacks::shared::NavBot +static CatCommand debug_ammo("navbot_debug_ammo", "debug", []() { + if (CE_BAD(LOCAL_W) || CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) + return; + logging::Info("Clip size: %d %d", CE_INT(LOCAL_W, netvar.m_iClip1), + CE_INT(LOCAL_W, netvar.m_iClip2)); + for (int i = 0; i < 8; i++) + logging::Info("Ammo Table IDX %d: %d", i, + CE_INT(LOCAL_E, netvar.m_iAmmo + 4 * i)); +}); + +static HookedFunction + CreateMove(HookedFunctions_types::HF_CreateMove, "NavBot", 16, []() { + if (!enable || !nav::prepare()) + return; + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || CE_BAD(LOCAL_W)) + return; + if (primary_only) + UpdateSlot(); + UpdateBestSpot(); + if (*scout_mode && jump_cooldown.test_and_set(200)) + { + auto ent = NearestEnemy(); + if (CE_GOOD(ent)) + { + if (ent->m_flDistance() < *jump_distance) + current_user_cmd->buttons |= IN_JUMP; + } + } + if (HasLowHealth() && ammo_health_cooldown.test_and_set(5000)) + { + CachedEntity *med = nearestHealth(); + if (CE_GOOD(med)) + { + if (nav::curr_priority == 1337) + nav::clearInstructions(); + nav::navTo(med->m_vecOrigin(), 7, true, true); + } + } + if (HasLowAmmo() && ammo_health_cooldown.test_and_set(5000)) + { + CachedEntity *ammo = nearestAmmo(); + if (CE_GOOD(ammo)) + { + if (nav::curr_priority == 1337) + nav::clearInstructions(); + nav::navTo(ammo->m_vecOrigin(), 6, true, true); + } + } + if ((!HasLowHealth() && nav::curr_priority == 7) || + (!HasLowAmmo() && nav::curr_priority == 6)) + nav::clearInstructions(); + static int waittime = + /*(spy_mode || heavy_mode || engi_mode) ? 100 : 2000*/ 0; + if (*take_tele) + { + int idx = GetClosestTeleporter(); + if (idx != -1) + { + CachedEntity *ent = ENTITY(idx); + if (CE_GOOD(ent) && ent->m_flDistance() < 300.0f) + if (CE_FLOAT(ent, netvar.m_flTeleYawToExit) && + CE_INT(ent, netvar.m_iTeleState) == 2 && + CE_FLOAT(ent, netvar.m_flTeleRechargeTime) < + g_GlobalVars->curtime) + { + waittime = 1000; + nav_cooldown.update(); + if (nav::curr_priority == 1337) + nav::clearInstructions(); + nav::navTo(GetBuildingPosition(ent), 5, false, false); + } + } + } + if (*stay_near && nav_enemy_cd.test_and_set(1000) && !HasLowAmmo() && + !HasLowHealth()) + if (NavToEnemy()) + return; + if (enable) + { + if (!nav::ReadyForCommands && !spy_mode && !heavy_mode && + !scout_mode) + nav_cooldown.update(); + if (target_sentry && NavToSentry(3)) + return; + bool isready = (spy_mode || heavy_mode || scout_mode) + ? true + : nav::ReadyForCommands; + if (isready && nav_cooldown.test_and_set(waittime)) + { + waittime = + /*(spy_mode || heavy_mode || engi_mode) ? 100 : 2000*/ 0; + if (!spy_mode && !heavy_mode && !scout_mode) + { + nav_cooldown.update(); + if (init_timer.test_and_set(5000)) + Init(); + if (!NavToSniperSpot(5)) + waittime = 1; + } + else + { + CachedEntity *tar = NearestEnemy(); + if (CE_BAD(tar) && last_tar == -1 && nav::ReadyForCommands) + { + if (init_timer.test_and_set(5000)) + Init(); + if (!NavToSniperSpot(4)) + waittime = 1; + } + if (CE_GOOD(tar)) + { + if (!spy_mode || + !hacks::shared::backtrack::isBacktrackEnabled) + { + if (!nav::navTo(tar->m_vecOrigin(), 5, true, 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)) + sorted_ticks.push_back(unsorted_ticks[i]); + } + if (sorted_ticks.empty()) + { + if (!nav::navTo(tar->m_vecOrigin(), 5, true, + 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; + }); + + if (!sorted_ticks[5].tickcount || + nav::navTo(sorted_ticks[5].entorigin, false, + false)) + if (!nav::navTo(tar->m_vecOrigin(), 5, true, + false)) + last_tar = -1; + } + } + } + } + } + }); +} // namespace hacks::tf2::NavBot diff --git a/src/hacks/Spam.cpp b/src/hacks/Spam.cpp index 1c468623..7b46fe56 100644 --- a/src/hacks/Spam.cpp +++ b/src/hacks/Spam.cpp @@ -279,7 +279,7 @@ void createMove() static float last_voice_spam = 0.0f; if (g_GlobalVars->curtime - 4.0F > last_voice_spam) { - switch ((int) voicecommand_spam) + switch (*voicecommand_spam) { case 1: // RANDOM g_IEngine->ServerCmd( @@ -312,10 +312,10 @@ void createMove() static int safety_ticks = 0; static int last_source = 0; static float last_message = 0; - if ((int) spam_source != last_source) + if (*spam_source != last_source) { safety_ticks = 300; - last_source = (int) spam_source; + last_source = *spam_source; } if (safety_ticks > 0) { @@ -328,7 +328,7 @@ void createMove() } const std::vector *source = nullptr; - switch ((int) spam_source) + switch (*spam_source) { case 1: source = &file.lines; @@ -364,10 +364,11 @@ void createMove() { if (current_index >= source->size()) current_index = 0; - if (random_order) + if (random_order && source->size()) { current_index = rand() % source->size(); - while (current_index == last_index) + int tries = 0; + while (current_index == last_index && tries++ < 1000) { current_index = rand() % source->size(); } diff --git a/src/hacks/Trigger.cpp b/src/hacks/Trigger.cpp index 62b9d47b..78217da8 100644 --- a/src/hacks/Trigger.cpp +++ b/src/hacks/Trigger.cpp @@ -589,7 +589,7 @@ float EffectiveTargetingRange() // Pyros only have so much untill their flames hit else if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFFlameThrower)) - return 200.0f; + return 300.0f; // If user has set a max range, then use their setting, if (max_range) return *max_range; diff --git a/src/hacks/Walkbot.cpp b/src/hacks/Walkbot.cpp index 0ba05f22..191690ab 100644 --- a/src/hacks/Walkbot.cpp +++ b/src/hacks/Walkbot.cpp @@ -1218,7 +1218,7 @@ Timer map_check{}; int erasedelay = 0; static HookedFunction Move(HookedFunctions_types::HF_CreateMove, "Walkbot", 16, []() { - if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || CE_BAD(LOCAL_W)) return; if (state::state == WB_DISABLED) return; diff --git a/src/helpers.cpp b/src/helpers.cpp index b1f08d0e..992ef2ab 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -600,6 +600,19 @@ void VectorAngles(Vector &forward, Vector &angles) angles[2] = 0; } +// Get forward vector +void AngleVectors2(const QAngle &angles, Vector *forward) +{ + float sp, sy, cp, cy; + + SinCos(DEG2RAD(angles[YAW]), &sy, &cy); + SinCos(DEG2RAD(angles[PITCH]), &sp, &cp); + + forward->x = cp * cy; + forward->y = cp * sy; + forward->z = -sp; +} + char GetUpperChar(ButtonCode_t button) { switch (button) @@ -878,62 +891,7 @@ bool IsProjectileCrit(CachedEntity *ent) weaponmode GetWeaponMode() { - int weapon_handle, slot; - CachedEntity *weapon; - - if (CE_BAD(LOCAL_E)) - return weapon_invalid; - weapon_handle = CE_INT(LOCAL_E, netvar.hActiveWeapon); - if (IDX_BAD((weapon_handle & 0xFFF))) - { - // logging::Info("IDX_BAD: %i", weapon_handle & 0xFFF); - return weaponmode::weapon_invalid; - } - weapon = (ENTITY(weapon_handle & 0xFFF)); - if (CE_BAD(weapon)) - return weaponmode::weapon_invalid; - int classid = weapon->m_iClassID(); - slot = re::C_BaseCombatWeapon::GetSlot(RAW_ENT(weapon)); - if (slot == 2) - return weaponmode::weapon_melee; - if (slot > 2) - { - return weaponmode::weapon_pda; - } - else if (classid == CL_CLASS(CTFLunchBox) || - classid == CL_CLASS(CTFLunchBox_Drink) || - classid == CL_CLASS(CTFBuffItem)) - { - return weaponmode::weapon_consumable; - } - else if (classid == CL_CLASS(CTFRocketLauncher_DirectHit) || - classid == CL_CLASS(CTFRocketLauncher) || - classid == CL_CLASS(CTFGrenadeLauncher) || - classid == CL_CLASS(CTFPipebombLauncher) || - classid == CL_CLASS(CTFCompoundBow) || - classid == CL_CLASS(CTFBat_Wood) || - classid == CL_CLASS(CTFBat_Giftwrap) || - classid == CL_CLASS(CTFFlareGun) || - classid == CL_CLASS(CTFFlareGun_Revenge) || - classid == CL_CLASS(CTFSyringeGun) || - classid == CL_CLASS(CTFCrossbow) || - classid == CL_CLASS(CTFShotgunBuildingRescue) || - classid == CL_CLASS(CTFDRGPomson) || - classid == CL_CLASS(CTFWeaponFlameBall) || - classid == CL_CLASS(CTFRaygun) || - classid == CL_CLASS(CTFGrapplingHook)) - { - return weaponmode::weapon_projectile; - } - else if (classid == CL_CLASS(CTFJar) || classid == CL_CLASS(CTFJarMilk)) - { - return weaponmode::weapon_throwable; - } - else if (classid == CL_CLASS(CWeaponMedigun)) - { - return weaponmode::weapon_medigun; - } - return weaponmode::weapon_hitscan; + return g_pLocalPlayer->weapon_mode; } bool LineIntersectsBox(Vector &bmin, Vector &bmax, Vector &lmin, Vector &lmax) @@ -1282,11 +1240,7 @@ Vector QAngleToVector(QAngle in) void AimAt(Vector origin, Vector target, CUserCmd *cmd) { - Vector angles, tr; - tr = (target - origin); - VectorAngles(tr, angles); - fClampAngle(angles); - cmd->viewangles = angles; + cmd->viewangles = GetAimAtAngles(origin, target); } void AimAtHitbox(CachedEntity *ent, int hitbox, CUserCmd *cmd) diff --git a/src/hooks/CreateMove.cpp b/src/hooks/CreateMove.cpp index 9f60ff39..d14ac150 100644 --- a/src/hooks/CreateMove.cpp +++ b/src/hooks/CreateMove.cpp @@ -163,6 +163,14 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, return ret; } + // Disabled because this causes EXTREME aimbot inaccuracy + // Actually dont disable it. It causes even more inaccuracy + if (!cmd->command_number) + { + g_Settings.is_create_move = false; + return ret; + } + if (!isHackActive()) { g_Settings.is_create_move = false; @@ -245,8 +253,7 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, { entity_cache::Invalidate(); } - // Disabled because this causes EXTREME aimbot inaccuracy - // if (!cmd->command_number) return ret; + // PROF_BEGIN(); { PROF_SECTION(EntityCache); @@ -279,7 +286,7 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, // hacks::tf2::NavBot::initonce(); nav::status = nav::off; IRC::auth(); - hacks::shared::NavBot::Init(true); + hacks::tf2::NavBot::initonce(); firstcm = false; } g_Settings.bInvalid = false; @@ -447,7 +454,7 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, { speedapplied = false; if (roll_speedhack && cmd->buttons & IN_DUCK && - !(cmd->buttons & IN_ATTACK)) + !(cmd->buttons & IN_ATTACK) && !HasCondition(LOCAL_E)) { speed = Vector{ cmd->forwardmove, cmd->sidemove, 0.0f }.Length(); static float prevspeedang = 0.0f; diff --git a/src/hooks/others.cpp b/src/hooks/others.cpp index 7af8276b..769c5f0c 100755 --- a/src/hooks/others.cpp +++ b/src/hooks/others.cpp @@ -40,7 +40,17 @@ CatCommand spectate("spectate", "Spectate", [](const CCommand &args) { spectator_target = 0; return; } - int id = atoi(args.Arg(1)); + int id; + try + { + id = std::stoi(args.Arg(1)); + } + catch (const std::exception &e) + { + logging::Info("Error while setting spectate target. Error: %s", + e.what()); + id = 0; + } if (!id) spectator_target = 0; else diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 649c6e1d..873373ba 100755 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -12,6 +12,65 @@ CatCommand printfov("fov_print", "Dump achievements to file (development)", if (CE_GOOD(LOCAL_E)) logging::Info("%d", CE_INT(LOCAL_E, netvar.iFOV)); }); +weaponmode GetWeaponModeloc() +{ + int weapon_handle, slot; + CachedEntity *weapon; + + if (CE_BAD(LOCAL_E) | CE_BAD(LOCAL_W)) + return weapon_invalid; + weapon_handle = CE_INT(LOCAL_E, netvar.hActiveWeapon); + if (IDX_BAD((weapon_handle & 0xFFF))) + { + // logging::Info("IDX_BAD: %i", weapon_handle & 0xFFF); + return weaponmode::weapon_invalid; + } + weapon = (ENTITY(weapon_handle & 0xFFF)); + if (CE_BAD(weapon)) + return weaponmode::weapon_invalid; + int classid = weapon->m_iClassID(); + slot = re::C_BaseCombatWeapon::GetSlot(RAW_ENT(weapon)); + if (slot == 2) + return weaponmode::weapon_melee; + if (slot > 2) + { + return weaponmode::weapon_pda; + } + else if (classid == CL_CLASS(CTFLunchBox) || + classid == CL_CLASS(CTFLunchBox_Drink) || + classid == CL_CLASS(CTFBuffItem)) + { + return weaponmode::weapon_consumable; + } + else if (classid == CL_CLASS(CTFRocketLauncher_DirectHit) || + classid == CL_CLASS(CTFRocketLauncher) || + classid == CL_CLASS(CTFGrenadeLauncher) || + classid == CL_CLASS(CTFPipebombLauncher) || + classid == CL_CLASS(CTFCompoundBow) || + classid == CL_CLASS(CTFBat_Wood) || + classid == CL_CLASS(CTFBat_Giftwrap) || + classid == CL_CLASS(CTFFlareGun) || + classid == CL_CLASS(CTFFlareGun_Revenge) || + classid == CL_CLASS(CTFSyringeGun) || + classid == CL_CLASS(CTFCrossbow) || + classid == CL_CLASS(CTFShotgunBuildingRescue) || + classid == CL_CLASS(CTFDRGPomson) || + classid == CL_CLASS(CTFWeaponFlameBall) || + classid == CL_CLASS(CTFRaygun) || + classid == CL_CLASS(CTFGrapplingHook)) + { + return weaponmode::weapon_projectile; + } + else if (classid == CL_CLASS(CTFJar) || classid == CL_CLASS(CTFJarMilk)) + { + return weaponmode::weapon_throwable; + } + else if (classid == CL_CLASS(CWeaponMedigun)) + { + return weaponmode::weapon_medigun; + } + return weaponmode::weapon_hitscan; +} void LocalPlayer::Update() { CachedEntity *wep; @@ -28,7 +87,7 @@ void LocalPlayer::Update() wep = weapon(); if (CE_GOOD(wep)) { - weapon_mode = GetWeaponMode(); + weapon_mode = GetWeaponModeloc(); if (wep->m_iClassID() == CL_CLASS(CTFSniperRifle) || wep->m_iClassID() == CL_CLASS(CTFSniperRifleDecap)) holding_sniper_rifle = true; diff --git a/src/navparser.cpp b/src/navparser.cpp index 0576fe8a..dd3d6a41 100644 --- a/src/navparser.cpp +++ b/src/navparser.cpp @@ -279,7 +279,7 @@ public: { i.second.status = unknown; i.second.stucktime = 0; - reset_pather = true; + reset_pather = true; } break; case unknown: @@ -288,7 +288,7 @@ public: if (i.second.ignoreTimeout.check(20000)) { i.second.status = unknown; - reset_pather = true; + reset_pather = true; } break; case vischeck_failed: @@ -298,7 +298,7 @@ public: { i.second.status = unknown; i.second.stucktime = 0; - reset_pather = true; + reset_pather = true; } break; } @@ -542,6 +542,10 @@ bool navTo(Vector destination, int priority, bool should_repath, std::vector path = findPath(g_pLocalPlayer->v_Origin, destination); if (path.empty()) return false; + if (!crumbs.empty()) + { + ignoremanager::addTime(last_area, crumbs.at(0), inactivity); + } last_area = path.at(0); if (!nav_to_local) { @@ -554,10 +558,6 @@ bool navTo(Vector destination, int priority, bool should_repath, { findClosestNavSquare_localAreas.clear(); } - if (!crumbs.empty()) - { - ignoremanager::addTime(last_area, crumbs.at(0), inactivity); - } ensureArrival = should_repath; ReadyForCommands = false; curr_priority = priority; @@ -583,7 +583,7 @@ static HookedFunction CreateMove(HookedFunctions_types::HF_CreateMove, "NavParser", 17, []() { if (!enabled || status != on) return; - if (CE_BAD(LOCAL_E)) + if (CE_BAD(LOCAL_E) || CE_BAD(LOCAL_W)) return; if (!LOCAL_E->m_bAlivePlayer()) { @@ -636,7 +636,7 @@ static HookedFunction drawcrumbs(HF_Draw, "navparser", 10, []() { return; if (!enabled) return; - if (CE_BAD(LOCAL_E)) + if (CE_BAD(LOCAL_E) || CE_BAD(LOCAL_W)) return; if (!LOCAL_E->m_bAlivePlayer()) return; @@ -695,6 +695,9 @@ static CatCommand nav_init("nav_init", "Debug nav init", []() { static CatCommand nav_path("nav_path", "Debug nav path", []() { navTo(loc); }); +static CatCommand nav_path_no_local("nav_path_no_local", "Debug nav path", + []() { navTo(loc, 5, false, false); }); + static CatCommand nav_reset_ignores("nav_reset_ignores", "Reset all ignores.", []() { ignoremanager::reset(); }); diff --git a/src/trace.cpp b/src/trace.cpp old mode 100755 new mode 100644 index 94e8b432..dfd29740 --- a/src/trace.cpp +++ b/src/trace.cpp @@ -141,9 +141,9 @@ bool trace::FilterNoEntity::ShouldHitEntity(IHandleEntity *handle, int mask) // Hit doors, carts, etc switch (clazz->m_ClassID) { - case 6: - case 7: - return true; + case 6: + case 7: + return true; } return false; } diff --git a/src/visual/EffectChams.cpp b/src/visual/EffectChams.cpp index 9b7fe0be..62aac27f 100644 --- a/src/visual/EffectChams.cpp +++ b/src/visual/EffectChams.cpp @@ -32,7 +32,7 @@ static settings::Bool disco_chams{ "chams.disco", "false" }; namespace effect_chams { -CatCommand fix_black_chams("fix_black_chams", "Fix Black Chams", [](){ +CatCommand fix_black_chams("fix_black_chams", "Fix Black Chams", []() { effect_chams::g_EffectChams.Shutdown(); effect_chams::g_EffectChams.Init(); }); @@ -82,7 +82,7 @@ void EffectChams::EndRenderChams() CMatRenderContextPtr ptr(GET_RENDER_CONTEXT); g_IVModelRender->ForcedMaterialOverride(nullptr); } -static rgba_t data[32] = {colors::empty}; +static rgba_t data[32] = { colors::empty }; void EffectChams::SetEntityColor(CachedEntity *ent, rgba_t color) { if (ent->m_IDX > 31 || ent->m_IDX < 0) @@ -156,7 +156,7 @@ rgba_t EffectChams::ChamsColor(IClientEntity *entity) } if (data[entity->entindex()] != colors::empty) { - auto toret = data[entity->entindex()]; + auto toret = data[entity->entindex()]; data[entity->entindex()] = colors::empty; return toret; } diff --git a/src/visual/EffectGlow.cpp b/src/visual/EffectGlow.cpp index b157a750..ee1ffa1c 100644 --- a/src/visual/EffectGlow.cpp +++ b/src/visual/EffectGlow.cpp @@ -138,7 +138,7 @@ static ShaderStencilState_t SS_SolidInvisible{}; static ShaderStencilState_t SS_Null{}; static ShaderStencilState_t SS_Drawing{}; -CatCommand fix_black_glow("fix_black_glow", "Fix Black Glow", [](){ +CatCommand fix_black_glow("fix_black_glow", "Fix Black Glow", []() { effect_glow::g_EffectGlow.Shutdown(); effect_glow::g_EffectGlow.Init(); }); diff --git a/src/visual/fidgetspinner.cpp b/src/visual/fidgetspinner.cpp index 6ebeeca7..45f30ec0 100644 --- a/src/visual/fidgetspinner.cpp +++ b/src/visual/fidgetspinner.cpp @@ -15,23 +15,20 @@ #ifndef FEATURE_FIDGET_SPINNER_ENABLED -static settings::Bool enable_spinner{ "visuals.fidget-spinner.enable", - "false" }; -static settings::Bool v9mode{ "visuals.fidget-spinner.v952-mode", "false" }; -static settings::Float spinner_speed_cap{ "visuals.fidget-spinner.speed-cap", +static settings::Bool enable_spinner{ "visual.fidget-spinner.enable", "false" }; +static settings::Bool v9mode{ "visual.fidget-spinner.v952-mode", "false" }; +static settings::Float spinner_speed_cap{ "visual.fidget-spinner.speed-cap", "30" }; -static settings::Float spinner_speed_scale{ - "visuals.fidget-spinner.speed-scale", "0.03" -}; -static settings::Float spinner_decay_speed{ - "visuals.fidget-spinner.decay-speed", "0.1" -}; -static settings::Float spinner_scale{ "visuals.fidget-spinner.scale", "32" }; -static settings::Float spinner_min_speed{ "visuals.fidget-spinner.min-speed", +static settings::Float spinner_speed_scale{ "visual.fidget-spinner.speed-scale", + "0.03" }; +static settings::Float spinner_decay_speed{ "visual.fidget-spinner.decay-speed", + "0.1" }; +static settings::Float spinner_scale{ "visual.fidget-spinner.scale", "32" }; +static settings::Float spinner_min_speed{ "visual.fidget-spinner.min-speed", "2" }; -float spinning_speed = 0.0f; -float angle = 0; +static float spinning_speed = 0.0f; +static float angle = 0; // DEBUG /*CatCommand add_spinner_speed("fidgetspinner_debug_speedup", "Add speed", []() @@ -41,7 +38,7 @@ float angle = 0; class SpinnerListener : public IGameEventListener { public: - virtual void FireGameEvent(KeyValues *event) + void FireGameEvent(KeyValues *event) override { std::string name(event->GetName()); if (name == "player_death") @@ -64,7 +61,7 @@ void InitSpinner() g_IGameEventManager->AddListener(&listener, false); } -Timer retrytimer{}; +static Timer retrytimer{}; void DrawSpinner() { @@ -95,10 +92,10 @@ void DrawSpinner() angle += speed_scale * real_speed; int state = min(3, int(spinning_speed / 250)); - glez::draw::rect_textured(draw::width / 2, draw::height / 2, size, size, - colors::white, textures::atlas().texture, - 64 * state, (3 + (v9mode ? 0 : 1)) * 64, 64, 64, - angle); + glez::draw::rect_textured( + draw::width / 2 - size * 0.5f, draw::height / 2 - size * 0.5f, size, + size, colors::white, textures::atlas().texture, 64 * state, + (3 + (v9mode ? 0 : 1)) * 64, 64, 64, angle); if (angle > PI * 4) angle -= PI * 4; } diff --git a/tools/updater.sh b/tools/updater.sh deleted file mode 100755 index dd7a8abf..00000000 --- a/tools/updater.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -printf "\n\n";printf '\e[1;34m%-6s\e' "Your cathook version is out of date! Please reinstall by using \"wget https://raw.githubusercontent.com/nullworks/One-in-all-cathook-install/master/install-all && bash install-all\"";printf "\n\n" \ No newline at end of file