Merge pull request #677 from nullworks/testing

Testing -> Master
This commit is contained in:
TotallyNotElite 2019-01-11 19:43:07 +01:00 committed by GitHub
commit 83287aac63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 301 additions and 196 deletions

2
.gitignore vendored
View File

@ -285,3 +285,5 @@ scripts/updater-preferences
/modules/*/ /modules/*/
!/modules/readme.md !/modules/readme.md
!/modules/CMakeLists.txt !/modules/CMakeLists.txt
scripts/partybypass-preferences

View File

@ -3,9 +3,12 @@
# SDL2 # SDL2
# GLEW # GLEW
set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/external/cotire/CMake") set(EnableCotire 1 CACHE BOOL "Enable CoTiRe (Compile Time Reducer)")
cmake_policy(SET CMP0011 NEW) if (EnableCotire)
include(cotire) set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/external/cotire/CMake")
cmake_policy(SET CMP0011 NEW)
include(cotire)
endif()
if(NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type") set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type")
@ -138,9 +141,11 @@ add_subdirectory(include)
add_subdirectory(external) add_subdirectory(external)
add_subdirectory(modules) add_subdirectory(modules)
set_target_properties(cathook PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${CMAKE_SOURCE_DIR}/include/common.hpp") if (EnableCotire)
set_target_properties(cathook PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE) set_target_properties(cathook PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${CMAKE_SOURCE_DIR}/include/common.hpp")
cotire(cathook) set_target_properties(cathook PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE)
cotire(cathook)
endif()
add_custom_command(TARGET cathook POST_BUILD add_custom_command(TARGET cathook POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:cathook> "${CMAKE_SOURCE_DIR}/bin/$<TARGET_FILE_NAME:cathook>") COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:cathook> "${CMAKE_SOURCE_DIR}/bin/$<TARGET_FILE_NAME:cathook>")

1
attach
View File

@ -1,6 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
sudo ./scripts/auto-updater sudo ./scripts/auto-updater
sudo ./scripts/attach-partybypass $1
line=$(pidof hl2_linux) line=$(pidof hl2_linux)
arr=($line) arr=($line)
inst=$1 inst=$1

View File

@ -1,6 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
sudo ./scripts/auto-updater sudo ./scripts/auto-updater
sudo ./scripts/attach-partybypass $1
line=$(pidof hl2_linux) line=$(pidof hl2_linux)
arr=($line) arr=($line)
inst=$1 inst=$1

View File

@ -4,6 +4,7 @@
# https://github.com/LWSS/Fuzion/commit/a53b6c634cde0ed47b08dd587ba40a3806adf3fe # https://github.com/LWSS/Fuzion/commit/a53b6c634cde0ed47b08dd587ba40a3806adf3fe
sudo ./scripts/auto-updater sudo ./scripts/auto-updater
sudo ./scripts/attach-partybypass $1
line=$(pidof hl2_linux) line=$(pidof hl2_linux)
arr=($line) arr=($line)
inst=$1 inst=$1

View File

@ -13,5 +13,5 @@ namespace hacks::shared::followbot
int ClassPriority(CachedEntity *ent); int ClassPriority(CachedEntity *ent);
bool isEnabled(); bool isEnabled();
int getTarget(); extern int follow_target;
} // namespace hacks::shared::followbot } // namespace hacks::shared::followbot

View File

@ -12,9 +12,11 @@ enum task : uint8_t
sniper_spot, sniper_spot,
stay_near, stay_near,
health, health,
ammo ammo,
followbot
}; };
} extern task current_task;
} // namespace task
struct bot_class_config struct bot_class_config
{ {
float min; float min;

BIN
lib/libpartybypass-linux.so Normal file

Binary file not shown.

52
scripts/attach-partybypass Executable file
View File

@ -0,0 +1,52 @@
#!/usr/bin/env bash
if [ ! -f ./scripts/partybypass-preferences ]; then
while true; do
echo 'https://github.com/nullworks/cathook/wiki/What-is-Partybypass-and-how-do-I-use-it%3F'
read -p "Do you want to enable the precompiled partybypass library? y/n " yn
case $yn in
[Yy]* ) echo true > ./scripts/partybypass-preferences; break;;
[Nn]* ) echo false > ./scripts/partybypass-preferences; exit;;
* ) echo "Please answer y or n.";;
esac
done
fi
if [ `cat ./scripts/partybypass-preferences` == "true" ]; then
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]}
# 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 "./lib/libpartybypass-linux.so" "$FILENAME"
gdb -n -q -batch \
-ex "attach $proc" \
-ex "set \$dlopen = (void*(*)(char*, int)) dlopen" \
-ex "call \$dlopen(\"$FILENAME\", 1)" \
-ex "detach" \
-ex "quit" > /dev/null 2>&1
rm $FILENAME
echo -e "\n\033[1;34mPartybypass injected.\033[0m" && exit 0
fi

View File

@ -38,3 +38,5 @@ settings::Bool clean_screenshots{ "visual.clean-screenshots", "false" };
settings::Bool nolerp{ "misc.no-lerp", "false" }; settings::Bool nolerp{ "misc.no-lerp", "false" };
settings::Bool no_zoom{ "remove.scope", "false" }; settings::Bool no_zoom{ "remove.scope", "false" };
settings::Bool disable_visuals{ "visual.disable", "false" }; settings::Bool disable_visuals{ "visual.disable", "false" };
static CatCommand identify("print_steamid", "Prints your SteamID", []() { g_ICvar->ConsolePrintf("%u\n", g_ISteamUser->GetSteamID().GetAccountID()); });

View File

@ -430,8 +430,26 @@ bool IsTargetStateGood(CachedEntity *entity)
// Distance // Distance
if (EffectiveTargetingRange()) if (EffectiveTargetingRange())
{ {
if (entity->m_flDistance() > EffectiveTargetingRange()) if (g_pLocalPlayer->weapon_mode != weapon_melee)
return false; {
if (entity->m_flDistance() > EffectiveTargetingRange())
return false;
}
else
{
float swingrange = re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W));
int hb = BestHitbox(entity);
if (hb == -1)
return false;
Vector newangle = GetAimAtAngles(g_pLocalPlayer->v_Eye, entity->hitboxes.GetHitbox(hb)->center);
trace_t trace;
Ray_t ray;
trace::filter_default.SetSelf(RAW_ENT(g_pLocalPlayer->entity));
ray.Init(g_pLocalPlayer->v_Eye, GetForwardVector(g_pLocalPlayer->v_Eye, newangle, swingrange));
g_ITrace->TraceRay(ray, MASK_SHOT_HULL, &trace::filter_default, &trace);
if ((IClientEntity *) trace.m_pEnt != RAW_ENT(entity))
return false;
}
} }
// Rage only check // Rage only check
if (rageonly) if (rageonly)

View File

@ -100,7 +100,7 @@ void ResetPlayer(int idx)
g_Settings.brute.choke[idx] = {}; g_Settings.brute.choke[idx] = {};
g_Settings.brute.brutenum[idx] = 0; g_Settings.brute.brutenum[idx] = 0;
g_Settings.brute.last_angles[idx] = {}; g_Settings.brute.last_angles[idx] = {};
g_Settings.brute.lastsimtime = 0.0f; g_Settings.brute.lastsimtime = 0.0f;
} }
class ResolverListener : public IGameEventListener class ResolverListener : public IGameEventListener
{ {

View File

@ -472,7 +472,7 @@ int HealingPriority(int idx)
#if ENABLE_IPC #if ENABLE_IPC
if (ipc::peer) if (ipc::peer)
{ {
if (hacks::shared::followbot::isEnabled() && hacks::shared::followbot::getTarget() == idx) if (hacks::shared::followbot::isEnabled() && hacks::shared::followbot::follow_target == idx)
{ {
priority *= 6.0f; priority *= 6.0f;
} }

View File

@ -12,6 +12,7 @@
#endif #endif
#include <settings/Bool.hpp> #include <settings/Bool.hpp>
#include "navparser.hpp" #include "navparser.hpp"
#include "NavBot.hpp"
static settings::Bool enable{ "follow-bot.enable", "false" }; static settings::Bool enable{ "follow-bot.enable", "false" };
static settings::Bool roambot{ "follow-bot.roaming", "true" }; static settings::Bool roambot{ "follow-bot.roaming", "true" };
@ -30,10 +31,12 @@ static settings::Bool corneractivate{ "follow-bot.corners", "true" };
static settings::Int steam_var{ "follow-bot.steamid", "0" }; static settings::Int steam_var{ "follow-bot.steamid", "0" };
namespace hacks::shared::followbot namespace hacks::shared::followbot
{ {
static Timer navBotInterval{}; namespace nb = hacks::tf2::NavBot;
unsigned steamid = 0x0;
CatCommand follow_steam("fb_steam", "Follow Steam Id", [](const CCommand &args) { static Timer navBotInterval{};
static unsigned steamid = 0x0;
static CatCommand follow_steam("fb_steam", "Follow Steam Id", [](const CCommand &args) {
if (args.ArgC() < 1) if (args.ArgC() < 1)
{ {
steam_var = 0; steam_var = 0;
@ -52,7 +55,7 @@ CatCommand follow_steam("fb_steam", "Follow Steam Id", [](const CCommand &args)
} }
}); });
CatCommand steam_debug("debug_steamid", "Print steamids", []() { static CatCommand steam_debug("debug_steamid", "Print steamids", []() {
for (int i = 0; i < g_IEngine->GetMaxClients(); i++) for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
{ {
auto ent = ENTITY(i); auto ent = ENTITY(i);
@ -62,19 +65,19 @@ CatCommand steam_debug("debug_steamid", "Print steamids", []() {
// Something to store breadcrumbs created by followed players // Something to store breadcrumbs created by followed players
static std::vector<Vector> breadcrumbs; static std::vector<Vector> breadcrumbs;
static const int crumb_limit = 64; // limit static constexpr int crumb_limit = 64; // limit
static bool followcart{ false }; static bool followcart{ false };
// Followed entity, externed for highlight color // Followed entity, externed for highlight color
int follow_target = 0; int follow_target = 0;
static bool inited; static bool inited = false;
Timer lastTaunt{}; // time since taunt was last executed, used to avoid kicks static Timer lastTaunt{}; // time since taunt was last executed, used to avoid kicks
Timer lastJump{}; static Timer lastJump{};
std::array<Timer, 32> afkTicks; // for how many ms the player hasn't been moving static std::array<Timer, 32> afkTicks; // for how many ms the player hasn't been moving
void checkAFK() static void checkAFK()
{ {
for (int i = 0; i < g_GlobalVars->maxClients; i++) for (int i = 0; i < g_GlobalVars->maxClients; i++)
{ {
@ -88,7 +91,7 @@ void checkAFK()
} }
} }
void init() static void init()
{ {
for (int i = 0; i < afkTicks.size(); i++) for (int i = 0; i < afkTicks.size(); i++)
{ {
@ -99,7 +102,7 @@ void init()
} }
// auto add checked crumbs for the walkbot to follow // auto add checked crumbs for the walkbot to follow
void addCrumbs(CachedEntity *target, Vector corner = g_pLocalPlayer->v_Origin) static void addCrumbs(CachedEntity *target, Vector corner = g_pLocalPlayer->v_Origin)
{ {
breadcrumbs.clear(); breadcrumbs.clear();
if (g_pLocalPlayer->v_Origin != corner) if (g_pLocalPlayer->v_Origin != corner)
@ -120,7 +123,7 @@ void addCrumbs(CachedEntity *target, Vector corner = g_pLocalPlayer->v_Origin)
} }
} }
void addCrumbPair(CachedEntity *player1, CachedEntity *player2, std::pair<Vector, Vector> corners) static void addCrumbPair(CachedEntity *player1, CachedEntity *player2, std::pair<Vector, Vector> corners)
{ {
Vector corner1 = corners.first; Vector corner1 = corners.first;
Vector corner2 = corners.second; Vector corner2 = corners.second;
@ -163,7 +166,7 @@ void addCrumbPair(CachedEntity *player1, CachedEntity *player2, std::pair<Vector
* tf_engineer = 9 * tf_engineer = 9
*/ */
constexpr int priority_list[10][10] = { static constexpr int priority_list[10][10] = {
/*0 1 2 3 4 5 6 7 8 9 */ /*0 1 2 3 4 5 6 7 8 9 */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // No class { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // No class
{ 0, 8, 2, 7, 6, 2, 5, 1, 0, 0 }, // Scout { 0, 8, 2, 7, 6, 2, 5, 1, 0, 0 }, // Scout
@ -184,8 +187,56 @@ int ClassPriority(CachedEntity *ent)
return priority_list[local_class][ents_class]; return priority_list[local_class][ents_class];
} }
Timer waittime{}; static int lastent = 0;
int lastent = 0; static Timer waittime{};
static Timer navinactivity{};
static int navtarget = 0;
static bool startFollow(CachedEntity *entity, bool useNavbot)
{
if (!follow_activation || entity->m_flDistance() <= (float) follow_activation)
{
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<Vector, Vector> 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)
return false;
// addCrumbs(LOCAL_E, corners.first);
// addCrumbs(entity, corners.second);
addCrumbPair(LOCAL_E, entity, corners);
return true;
}
if (indirectOrigin.z)
{
addCrumbs(entity, indirectOrigin);
return true;
}
}
else
{
if (VisCheckEntFromEnt(LOCAL_E, entity))
{
return true;
}
}
}
if (useNavbot)
{
if (nav::navTo(entity->m_vecOrigin(), 8, true, false))
{
navtarget = entity->m_IDX;
return true;
}
}
return false;
}
#if ENABLE_IPC #if ENABLE_IPC
static void cm() static void cm()
@ -193,6 +244,8 @@ static void cm()
if (!enable) if (!enable)
{ {
follow_target = 0; follow_target = 0;
if (nb::task::current_task == nb::task::followbot)
nb::task::current_task = nb::task::none;
return; return;
} }
if (!inited) if (!inited)
@ -200,6 +253,13 @@ static void cm()
// We need a local player to control // We need a local player to control
if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || CE_BAD(LOCAL_W)) if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || CE_BAD(LOCAL_W))
{
follow_target = 0;
if (nb::task::current_task == nb::task::followbot)
nb::task::current_task = nb::task::none;
return;
}
if (nb::task::current_task == nb::task::health || nb::task::current_task == nb::task::ammo)
{ {
follow_target = 0; follow_target = 0;
return; return;
@ -208,33 +268,6 @@ static void cm()
if (afk) if (afk)
checkAFK(); checkAFK();
// Naving
static bool isnaving = false;
static Timer navtime{};
static Timer navtimeout{};
if (isnaving)
{
if (!follow_target)
{
isnaving = false;
return;
}
if (CE_GOOD(ENTITY(follow_target)) && navtime.test_and_set(500))
{
if (nav::navTo(ENTITY(follow_target)->m_vecOrigin(), 8, true, false))
{
navtimeout.update();
}
}
if (navtimeout.check(15000) || nav::curr_priority == 0)
{
isnaving = false;
nav::clearInstructions();
}
return;
}
// Still good check // Still good check
if (follow_target) if (follow_target)
{ {
@ -254,11 +287,11 @@ static void cm()
// Target Selection // Target Selection
{ {
if (steamid && ((follow_target && ENTITY(follow_target)->player_info.friendsID != steamid) || !follow_target)) if (steamid && !(ENTITY(follow_target)->player_info.friendsID == steamid || ENTITY(navtarget)->player_info.friendsID == steamid))
{ {
// Find a target with the steam id, as it is prioritized // Find a target with the steam id, as it is prioritized
auto ent_count = g_IEngine->GetMaxClients(); auto ent_count = g_IEngine->GetMaxClients();
for (int i = 0; i < ent_count; i++) for (int i = 1; i < ent_count; i++)
{ {
auto entity = ENTITY(i); auto entity = ENTITY(i);
if (CE_BAD(entity)) // Exist + dormant if (CE_BAD(entity)) // Exist + dormant
@ -272,57 +305,24 @@ static void cm()
if (!entity->m_bAlivePlayer()) // Dont follow dead players if (!entity->m_bAlivePlayer()) // Dont follow dead players
continue; continue;
bool found = false; if (startFollow(entity, isNavBotCM))
if (corneractivate)
{ {
Vector indirectOrigin = VischeckCorner(LOCAL_E, entity, *follow_activation / 2, navinactivity.update();
true); // get the corner location that the follow_target = entity->m_IDX;
// future target is visible from afkTicks[i].update();
std::pair<Vector, Vector> corners; break;
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 we dont have a follow target from that, we look again for someone // If we dont have a follow target from that, we look again for someone
// else who is suitable // else who is suitable
{ {
if ((!follow_target || change || (ClassPriority(ENTITY(follow_target)) < 6 && ENTITY(follow_target)->player_info.friendsID != steamid)) && roambot) if (roambot && !navtarget && (!follow_target || change || (ClassPriority(ENTITY(follow_target)) < 6 && ENTITY(follow_target)->player_info.friendsID != steamid)))
{ {
// Try to get a new target // Try to get a new target
auto ent_count = followcart ? HIGHEST_ENTITY : g_IEngine->GetMaxClients(); auto ent_count = followcart ? HIGHEST_ENTITY : g_IEngine->GetMaxClients();
for (int i = 0; i < ent_count; i++) for (int i = 1; i < ent_count; i++)
{ {
auto entity = ENTITY(i); auto entity = ENTITY(i);
if (CE_BAD(entity)) // Exist + dormant if (CE_BAD(entity)) // Exist + dormant
@ -341,9 +341,7 @@ static void cm()
continue; continue;
if (!entity->m_bAlivePlayer()) // Dont follow dead players if (!entity->m_bAlivePlayer()) // Dont follow dead players
continue; continue;
if (follow_activation && entity->m_flDistance() > (float) follow_activation) // const model_t *model = ENTITY(follow_target)->InternalEntity()->GetModel();
continue;
const model_t *model = ENTITY(follow_target)->InternalEntity()->GetModel();
// FIXME follow cart/point // FIXME follow cart/point
/*if (followcart && model && /*if (followcart && model &&
(lagexploit::pointarr[0] || lagexploit::pointarr[1] || (lagexploit::pointarr[0] || lagexploit::pointarr[1] ||
@ -364,56 +362,64 @@ static void cm()
// target // target
if (ClassPriority(ENTITY(follow_target)) >= ClassPriority(ENTITY(i))) if (ClassPriority(ENTITY(follow_target)) >= ClassPriority(ENTITY(i)))
continue; continue;
bool found = false; if (startFollow(entity, isNavBotCM))
if (corneractivate)
{ {
Vector indirectOrigin = VischeckCorner(LOCAL_E, entity, *follow_activation / 2, // ooooo, a target
true); // get the corner location that the navinactivity.update();
// future target is visible from follow_target = i;
std::pair<Vector, Vector> corners; afkTicks[i].update(); // set afk time to 03
if (!indirectOrigin.z && entity->m_IDX == lastent) // if we couldn't find it, run break;
// 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
} }
} }
} }
lastent++; lastent++;
if (lastent > g_IEngine->GetMaxClients()) if (lastent > g_IEngine->GetMaxClients())
lastent = 0; lastent = 1;
if (navtarget)
{
auto ent = ENTITY(navtarget);
if (CE_GOOD(ent) && startFollow(ent, false))
{
follow_target = navtarget;
navtarget = 0;
}
else
{
breadcrumbs.clear();
follow_target = 0;
static Timer navtimer{};
if (CE_GOOD(ent))
{
if (!ent->m_bAlivePlayer())
{
navtarget = 0;
}
if (navtimer.test_and_set(800))
{
if (nav::navTo(ent->m_vecOrigin(), 8, true, false))
navinactivity.update();
}
}
if (navinactivity.check(15000))
{
navtarget = 0;
}
nb::task::current_task = nb::task::followbot;
return;
}
}
// last check for entity before we continue // last check for entity before we continue
if (!follow_target) if (!follow_target)
{
if (nb::task::current_task == nb::task::followbot)
nb::task::current_task = nb::task::none;
return; return;
}
nb::task::current_task = nb::task::followbot;
nav::clearInstructions();
CachedEntity *followtar = ENTITY(follow_target); CachedEntity *followtar = ENTITY(follow_target);
// wtf is this needed // wtf is this needed
@ -582,20 +588,6 @@ static void draw()
} }
#endif #endif
static InitRoutine runinit([]() {
#if ENABLE_IPC
EC::Register(EC::CreateMove, cm, "cm_followbot", EC::average);
#endif
#if ENABLE_VISUALS
EC::Register(EC::Draw, draw, "draw_followbot", EC::average);
#endif
});
int getTarget()
{
return follow_target;
}
bool isEnabled() bool isEnabled()
{ {
return *enable; return *enable;
@ -641,5 +633,14 @@ void rvarCallback(settings::VariableBase<int> &var, int after)
return; return;
steamid = after; steamid = after;
} }
static InitRoutine Init([]() { steam_var.installChangeCallback(rvarCallback); });
static InitRoutine runinit([]() {
#if ENABLE_IPC
EC::Register(EC::CreateMove, cm, "cm_followbot", EC::average);
#endif
#if ENABLE_VISUALS
EC::Register(EC::Draw, draw, "draw_followbot", EC::average);
#endif
steam_var.installChangeCallback(rvarCallback);
});
} // namespace hacks::shared::followbot } // namespace hacks::shared::followbot

View File

@ -3,6 +3,7 @@
#include "NavBot.hpp" #include "NavBot.hpp"
#include "PlayerTools.hpp" #include "PlayerTools.hpp"
#include "Aimbot.hpp" #include "Aimbot.hpp"
#include "FollowBot.hpp"
namespace hacks::tf2::NavBot namespace hacks::tf2::NavBot
{ {
@ -22,13 +23,17 @@ static bool stayNear();
static bool getHealthAndAmmo(); static bool getHealthAndAmmo();
static void autoJump(); static void autoJump();
static void updateSlot(); static void updateSlot();
using task::current_task;
// -Variables- // -Variables-
static std::vector<std::pair<CNavArea *, Vector>> sniper_spots; static std::vector<std::pair<CNavArea *, Vector>> sniper_spots;
// How long should the bot wait until pathing again? // How long should the bot wait until pathing again?
static Timer wait_until_path{}; static Timer wait_until_path{};
// What is the bot currently doing // What is the bot currently doing
static task::task current_task; namespace task
{
task current_task;
}
constexpr bot_class_config DIST_OTHER{ 100.0f, 200.0f, 300.0f }; constexpr bot_class_config DIST_OTHER{ 100.0f, 200.0f, 300.0f };
constexpr bot_class_config DIST_SNIPER{ 1000.0f, 1500.0f, 3000.0f }; constexpr bot_class_config DIST_SNIPER{ 1000.0f, 1500.0f, 3000.0f };
@ -38,7 +43,7 @@ static void CreateMove()
return; return;
if (!init(false)) if (!init(false))
return; return;
if (!nav::ReadyForCommands) if (!nav::ReadyForCommands || current_task == task::followbot)
wait_until_path.update(); wait_until_path.update();
else else
current_task = task::none; current_task = task::none;
@ -52,7 +57,7 @@ static void CreateMove()
if (getHealthAndAmmo()) if (getHealthAndAmmo())
return; return;
// Try to stay near enemies to increase efficiency // Try to stay near enemies to increase efficiency
if (stay_near || heavy_mode) if ((stay_near || heavy_mode) && current_task != task::followbot)
if (stayNear()) if (stayNear())
return; return;
// We don't have anything else to do. Just nav to sniper spots. // We don't have anything else to do. Just nav to sniper spots.
@ -88,7 +93,7 @@ bool init(bool first_cm)
static bool navToSniperSpot() static bool navToSniperSpot()
{ {
// Don't path if you already have commands. But also don't error out. // Don't path if you already have commands. But also don't error out.
if (!nav::ReadyForCommands) if (!nav::ReadyForCommands || current_task != task::none)
return true; return true;
// Wait arround a bit before pathing again // Wait arround a bit before pathing again
if (!wait_until_path.check(2000)) if (!wait_until_path.check(2000))
@ -327,6 +332,8 @@ static bool getHealthAndAmmo()
static Timer health_ammo_timer{}; static Timer health_ammo_timer{};
if (!health_ammo_timer.check(3000)) if (!health_ammo_timer.check(3000))
return false; return false;
if (current_task == task::health && static_cast<float>(LOCAL_E->m_iHealth()) / LOCAL_E->m_iMaxHealth() >= 0.64f)
current_task = task::none;
if (current_task == task::health) if (current_task == task::health)
return true; return true;
@ -353,6 +360,8 @@ static bool getHealthAndAmmo()
} }
} }
if (current_task == task::ammo && !hasLowAmmo())
current_task = task::none;
if (current_task == task::ammo) if (current_task == task::ammo)
return true; return true;
if (hasLowAmmo()) if (hasLowAmmo())
@ -405,6 +414,8 @@ static int GetBestSlot()
return primary; return primary;
case tf_heavy: case tf_heavy:
return primary; return primary;
case tf_medic:
return secondary;
default: default:
{ {
float nearest_dist = getNearestPlayerDistance().second; float nearest_dist = getNearestPlayerDistance().second;

View File

@ -481,16 +481,19 @@ void ReplaceString(std::string &input, const std::string &what, const std::strin
} }
} }
void ReplaceSpecials(std::string &str) { void ReplaceSpecials(std::string &str)
{
int val, i; int val, i;
size_t c = 0, len = str.size(); size_t c = 0, len = str.size();
for (int i = 0; i + c < len; ++i) { for (int i = 0; i + c < len; ++i)
{
str[i] = str[i + c]; str[i] = str[i + c];
if (str[i] != '\\') if (str[i] != '\\')
continue; continue;
if (i + c + 1 == len) if (i + c + 1 == len)
break; break;
switch (str[i + c + 1]) { switch (str[i + c + 1])
{
// Several control characters // Several control characters
case 'b': case 'b':
++c; ++c;
@ -544,15 +547,20 @@ void ReplaceSpecials(std::string &str) {
std::sscanf(&str[i + c + 2], "%04X", &val); std::sscanf(&str[i + c + 2], "%04X", &val);
c += 5; c += 5;
// 2. Convert value to UTF-8 // 2. Convert value to UTF-8
if (val <= 0x7F) { if (val <= 0x7F)
{
str[i] = val; str[i] = val;
} else if (val <= 0x7FF) { }
str[i] = 0xC0 | ((val >> 6) & 0x1F); else if (val <= 0x7FF)
{
str[i] = 0xC0 | ((val >> 6) & 0x1F);
str[i + 1] = 0x80 | (val & 0x3F); str[i + 1] = 0x80 | (val & 0x3F);
++i; ++i;
--c; --c;
} else { }
str[i] = 0xE0 | ((val >> 12) & 0xF); else
{
str[i] = 0xE0 | ((val >> 12) & 0xF);
str[i + 1] = 0x80 | ((val >> 6) & 0x3F); str[i + 1] = 0x80 | ((val >> 6) & 0x3F);
str[i + 2] = 0x80 | (val & 0x3F); str[i + 2] = 0x80 | (val & 0x3F);
i += 2; i += 2;
@ -885,6 +893,8 @@ bool VisCheckEntFromEntVector(Vector startVector, CachedEntity *startEnt, Cached
Vector GetBuildingPosition(CachedEntity *ent) Vector GetBuildingPosition(CachedEntity *ent)
{ {
if (ent->hitboxes.GetHitbox(0))
return ent->hitboxes.GetHitbox(0)->center;
Vector res; Vector res;
res = ent->m_vecOrigin(); res = ent->m_vecOrigin();
int classid = ent->m_iClassID(); int classid = ent->m_iClassID();

View File

@ -183,27 +183,14 @@ void ItemModelMapper::RegisterItem(std::string modelpath, k_EItemType type)
k_EItemType ItemModelMapper::GetItemType(CachedEntity *entity) k_EItemType ItemModelMapper::GetItemType(CachedEntity *entity)
{ {
const uintptr_t model = (uint64_t) RAW_ENT(entity)->GetModel(); const uintptr_t model = (uint64_t) RAW_ENT(entity)->GetModel();
try auto find = map.find(model);
{ if (find != map.end())
return map.at(model); return find->second;
}
// Do Nothing
catch (std::out_of_range)
{
}
std::string path(g_IModelInfo->GetModelName((const model_t *) model)); std::string path(g_IModelInfo->GetModelName((const model_t *) model));
bool set = false; bool set = false;
// Do Nothing auto find2 = models.find(path);
try if (find2 != models.end())
{
models.at(path);
set = true; set = true;
}
catch (std::out_of_range)
{
}
if (!set) if (!set)
map[model] = k_EItemType::ITEM_NONE; map[model] = k_EItemType::ITEM_NONE;
return k_EItemType::ITEM_NONE; return k_EItemType::ITEM_NONE;

View File

@ -6,6 +6,8 @@
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include "core/logging.hpp" #include "core/logging.hpp"
#include "interfaces.hpp"
#include "icvar.h"
settings::SettingsWriter::SettingsWriter(settings::Manager &manager) : manager(manager) settings::SettingsWriter::SettingsWriter(settings::Manager &manager) : manager(manager)
{ {
@ -21,6 +23,7 @@ bool settings::SettingsWriter::saveTo(std::string path, bool only_changed)
if (!stream || stream.bad() || !stream.is_open() || stream.fail()) if (!stream || stream.bad() || !stream.is_open() || stream.fail())
{ {
logging::Info("cat_save: FATAL! FAILED to create stream!"); logging::Info("cat_save: FATAL! FAILED to create stream!");
g_ICvar->ConsolePrintf("CAT: cat_save: Can't create config file!\n");
return false; return false;
} }
@ -42,8 +45,12 @@ bool settings::SettingsWriter::saveTo(std::string path, bool only_changed)
stream.flush(); stream.flush();
} }
if (!stream || stream.bad() || stream.fail()) if (!stream || stream.bad() || stream.fail())
{
g_ICvar->ConsolePrintf("CAT: cat_save: Failed to save config!\n");
logging::Info("cat_save: FATAL! Stream bad!"); logging::Info("cat_save: FATAL! Stream bad!");
logging::Info("cat_save: Finished"); }
else
g_ICvar->ConsolePrintf("CAT: cat_save: Successfully saved config!\n");
stream.close(); stream.close();
if (stream.fail()) if (stream.fail())
logging::Info("cat_save: FATAL! Stream bad (2)!"); logging::Info("cat_save: FATAL! Stream bad (2)!");
@ -92,6 +99,7 @@ bool settings::SettingsReader::loadFrom(std::string path)
if (stream.fail()) if (stream.fail())
{ {
logging::Info("cat_load: Can't access file!"); logging::Info("cat_load: Can't access file!");
g_ICvar->ConsolePrintf("CAT: cat_load: File doesn't exist / can't open file!\n");
return false; return false;
} }
@ -106,10 +114,12 @@ bool settings::SettingsReader::loadFrom(std::string path)
if (stream.fail() && !stream.eof()) if (stream.fail() && !stream.eof())
{ {
logging::Info("cat_load: FATAL: Read failed!"); logging::Info("cat_load: FATAL: Read failed!");
g_ICvar->ConsolePrintf("CAT: cat_load: Failed to read config!\n");
return false; return false;
} }
logging::Info("cat_load: Read Success!"); logging::Info("cat_load: Read Success!");
g_ICvar->ConsolePrintf("CAT: cat_load: Successfully loaded config!\n");
finishString(true); finishString(true);
return true; return true;

View File

@ -30,6 +30,8 @@ CatCommand get_state("mm_state", "Get party state", []() {
logging::Info("State: %d", re::CTFParty::state_(party)); logging::Info("State: %d", re::CTFParty::state_(party));
}); });
static CatCommand mm_stop_queue("mm_stop_queue", "Stop current TF2 MM queue", []() { tfmm::leaveQueue(); });
namespace tfmm namespace tfmm
{ {
int queuecount = 0; int queuecount = 0;

View File

@ -50,32 +50,32 @@ public:
} }
else if (name == "player_disconnect") else if (name == "player_disconnect")
{ {
//logging::Info("removePlayer %d", userid); // logging::Info("removePlayer %d", userid);
controller->removePlayer(userid); controller->removePlayer(userid);
} }
else if (name == "player_team") else if (name == "player_team")
{ {
//logging::Info("updatePlayerTeam %d", userid); // logging::Info("updatePlayerTeam %d", userid);
controller->updatePlayerTeam(userid, event->GetInt("team") - 1); controller->updatePlayerTeam(userid, event->GetInt("team") - 1);
} }
else if (name == "player_changeclass") else if (name == "player_changeclass")
{ {
//logging::Info("updatePlayerClass %d", userid); // logging::Info("updatePlayerClass %d", userid);
controller->updatePlayerClass(userid, event->GetInt("class")); controller->updatePlayerClass(userid, event->GetInt("class"));
} }
else if (name == "player_changename") else if (name == "player_changename")
{ {
//logging::Info("updatePlayerName %d", userid); // logging::Info("updatePlayerName %d", userid);
controller->updatePlayerName(userid, event->GetString("newname")); controller->updatePlayerName(userid, event->GetString("newname"));
} }
else if (name == "player_death") else if (name == "player_death")
{ {
//logging::Info("updatePlayerLifeState %d", userid); // logging::Info("updatePlayerLifeState %d", userid);
controller->updatePlayerLifeState(userid, true); controller->updatePlayerLifeState(userid, true);
} }
else if (name == "player_spawn") else if (name == "player_spawn")
{ {
//logging::Info("updatePlayerLifeState %d", userid); // logging::Info("updatePlayerLifeState %d", userid);
controller->updatePlayerLifeState(userid, false); controller->updatePlayerLifeState(userid, false);
} }
} }
@ -148,7 +148,7 @@ bool gui::handleSdlEvent(SDL_Event *event)
{ {
if (event->key.keysym.scancode == (*open_gui_button).scan) if (event->key.keysym.scancode == (*open_gui_button).scan)
{ {
//logging::Info("GUI open button pressed"); // logging::Info("GUI open button pressed");
zerokernel::Menu::instance->setInGame(!zerokernel::Menu::instance->isInGame()); zerokernel::Menu::instance->setInGame(!zerokernel::Menu::instance->isInGame());
if (!zerokernel::Menu::instance->isInGame()) if (!zerokernel::Menu::instance->isInGame())
{ {