Serverlag option + catbot fix
This commit is contained in:
parent
1851ec0362
commit
36654d7b6e
10
include/hacks/FollowBot.hpp
Executable file → Normal file
10
include/hacks/FollowBot.hpp
Executable file → Normal file
@ -7,9 +7,12 @@
|
||||
|
||||
#include "common.hpp";
|
||||
|
||||
namespace hacks {
|
||||
namespace shared {
|
||||
namespace followbot {
|
||||
namespace hacks
|
||||
{
|
||||
namespace shared
|
||||
{
|
||||
namespace followbot
|
||||
{
|
||||
|
||||
// Followed entity, externed for highlight color
|
||||
extern int follow_target;
|
||||
@ -17,7 +20,6 @@ extern CatVar followbot;
|
||||
extern CatVar follow_steam;
|
||||
void DrawTick();
|
||||
void WorldTick();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
471
src/hacks/FollowBot.cpp
Executable file → Normal file
471
src/hacks/FollowBot.cpp
Executable file → Normal file
@ -8,21 +8,35 @@
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace hacks {
|
||||
namespace shared {
|
||||
namespace followbot {
|
||||
namespace hacks
|
||||
{
|
||||
namespace shared
|
||||
{
|
||||
namespace followbot
|
||||
{
|
||||
|
||||
|
||||
CatVar followbot(CV_SWITCH, "fb", "0", "Followbot Switch", "Set to 1 in followbots' configs");
|
||||
static CatVar roambot(CV_SWITCH, "fb_roaming", "1", "Roambot", "Followbot will roam free, finding targets it can");
|
||||
static CatVar draw_crumb(CV_SWITCH, "fb_draw", "1", "Draw crumbs", "Self explanitory");
|
||||
static CatVar follow_distance(CV_INT, "fb_distance", "175", "Follow Distance", "How close the bots should stay to the target");
|
||||
static CatVar follow_activation(CV_INT, "fb_activation", "175", "Activation Distance", "How close a player should be until the followbot will pick them as a target");
|
||||
CatVar follow_steam(CV_INT, "fb_steam", "0", "Follow Steam Id", "Set a steam id to let followbot prioritize players");
|
||||
CatVar mimic_slot(CV_SWITCH, "fb_mimic_slot", "0", "Mimic weapon slot", "Mimic follow target's weapon slot");
|
||||
CatVar always_medigun(CV_SWITCH, "fb_always_medigun", "0", "Always Medigun", "Always use medigun");
|
||||
CatVar sync_taunt(CV_SWITCH, "fb_sync_taunt", "0", "Synced taunt", "Taunt when follow target does");
|
||||
CatVar change(CV_SWITCH, "fb_switch", "1", "Change followbot target", "Always change roaming target when possible");
|
||||
CatVar followbot(CV_SWITCH, "fb", "0", "Followbot Switch",
|
||||
"Set to 1 in followbots' configs");
|
||||
static CatVar roambot(CV_SWITCH, "fb_roaming", "1", "Roambot",
|
||||
"Followbot will roam free, finding targets it can");
|
||||
static CatVar draw_crumb(CV_SWITCH, "fb_draw", "1", "Draw crumbs",
|
||||
"Self explanitory");
|
||||
static CatVar follow_distance(CV_INT, "fb_distance", "175", "Follow Distance",
|
||||
"How close the bots should stay to the target");
|
||||
static CatVar follow_activation(CV_INT, "fb_activation", "175",
|
||||
"Activation Distance",
|
||||
"How close a player should be until the "
|
||||
"followbot will pick them as a target");
|
||||
CatVar follow_steam(CV_INT, "fb_steam", "0", "Follow Steam Id",
|
||||
"Set a steam id to let followbot prioritize players");
|
||||
CatVar mimic_slot(CV_SWITCH, "fb_mimic_slot", "0", "Mimic weapon slot",
|
||||
"Mimic follow target's weapon slot");
|
||||
CatVar always_medigun(CV_SWITCH, "fb_always_medigun", "0", "Always Medigun",
|
||||
"Always use medigun");
|
||||
CatVar sync_taunt(CV_SWITCH, "fb_sync_taunt", "0", "Synced taunt",
|
||||
"Taunt when follow target does");
|
||||
CatVar change(CV_SWITCH, "fb_switch", "1", "Change followbot target",
|
||||
"Always change roaming target when possible");
|
||||
// Something to store breadcrumbs created by followed players
|
||||
static std::vector<Vector> breadcrumbs;
|
||||
static const int crumb_limit = 64; // limit
|
||||
@ -30,224 +44,265 @@ static const int crumb_limit = 64; // limit
|
||||
// Followed entity, externed for highlight color
|
||||
int follow_target = 0;
|
||||
|
||||
void WorldTick() {
|
||||
if (!followbot) {
|
||||
follow_target = 0;
|
||||
return;
|
||||
}
|
||||
void WorldTick()
|
||||
{
|
||||
if (!followbot)
|
||||
{
|
||||
follow_target = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// We need a local player to control
|
||||
if (CE_BAD(LOCAL_E)) {
|
||||
follow_target = 0;
|
||||
return;
|
||||
}
|
||||
// We need a local player to control
|
||||
if (CE_BAD(LOCAL_E))
|
||||
{
|
||||
follow_target = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Still good check
|
||||
if (follow_target) {
|
||||
// Overflow protection
|
||||
if (breadcrumbs.size() > crumb_limit)
|
||||
follow_target =0;
|
||||
// Still good check
|
||||
else if (CE_BAD(ENTITY(follow_target)))
|
||||
follow_target = 0;
|
||||
}
|
||||
|
||||
// Target Selection
|
||||
if (!follow_target) {
|
||||
breadcrumbs.clear(); // no target == no path
|
||||
|
||||
if (follow_steam) {
|
||||
// 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++) {
|
||||
auto entity = ENTITY(i);
|
||||
if (CE_BAD(entity)) // Exist + dormant
|
||||
continue;
|
||||
if (entity->m_Type != ENTITY_PLAYER)
|
||||
continue;
|
||||
player_info_s info;
|
||||
g_IEngine->GetPlayerInfo(entity->m_IDX, &info);
|
||||
if ((int)follow_steam != info.friendsID) // steamid check
|
||||
continue;
|
||||
if (!entity->m_bAlivePlayer) // Dont follow dead players
|
||||
continue;
|
||||
if (!VisCheckEntFromEnt(LOCAL_E, entity))
|
||||
continue;
|
||||
follow_target = entity->m_IDX;
|
||||
break;
|
||||
}
|
||||
if (follow_target)
|
||||
{
|
||||
// Overflow protection
|
||||
if (breadcrumbs.size() > crumb_limit)
|
||||
follow_target = 0;
|
||||
// Still good check
|
||||
else if (CE_BAD(ENTITY(follow_target)))
|
||||
follow_target = 0;
|
||||
}
|
||||
// If we dont have a follow target from that, we look again for someone else who is suitable
|
||||
if ((!follow_target || change) && roambot) {
|
||||
// Try to get a new target
|
||||
auto ent_count = g_IEngine->GetMaxClients();
|
||||
for (int i = 0; i < ent_count; i++) {
|
||||
auto entity = ENTITY(i);
|
||||
if (CE_BAD(entity)) // Exist + dormant
|
||||
continue;
|
||||
if (entity->m_Type != ENTITY_PLAYER)
|
||||
continue;
|
||||
if (entity == LOCAL_E) // Follow self lol
|
||||
continue;
|
||||
if (!entity->m_bAlivePlayer || entity->m_iTeam == LOCAL_E->m_iTeam) // Dont follow dead players
|
||||
continue;
|
||||
if (follow_activation && entity->m_flDistance > (float)follow_activation)
|
||||
continue;
|
||||
if (!VisCheckEntFromEnt(LOCAL_E, entity))
|
||||
continue;
|
||||
if (follow_target && ENTITY(follow_target)->m_flDistance > entity->m_flDistance) // favor closer entitys
|
||||
continue;
|
||||
// ooooo, a target
|
||||
follow_target = entity->m_IDX;
|
||||
}
|
||||
}
|
||||
// last check for entity before we continue
|
||||
|
||||
// Target Selection
|
||||
if (!follow_target)
|
||||
return;
|
||||
}
|
||||
{
|
||||
breadcrumbs.clear(); // no target == no path
|
||||
|
||||
// If the player is close enough, we dont need to follow the path
|
||||
CachedEntity* followtar = ENTITY(follow_target);
|
||||
auto tar_orig = followtar->m_vecOrigin;
|
||||
auto loc_orig = LOCAL_E->m_vecOrigin;
|
||||
auto dist_to_target = loc_orig.DistTo(tar_orig);
|
||||
if (dist_to_target < 30)
|
||||
breadcrumbs.clear();
|
||||
|
||||
// Update timer on new target
|
||||
static Timer idle_time{};
|
||||
if (breadcrumbs.empty())
|
||||
idle_time.update();
|
||||
|
||||
// New crumbs, we add one if its empty so we have something to follow
|
||||
if ((breadcrumbs.empty() || tar_orig.DistTo(breadcrumbs.at(breadcrumbs.size() - 1)) > 40.0F) && DistanceToGround(ENTITY(follow_target)) < 30)
|
||||
breadcrumbs.push_back(tar_orig);
|
||||
|
||||
// Prune old and close crumbs that we wont need anymore, update idle timer too
|
||||
while (breadcrumbs.size() > 1 && loc_orig.DistTo(breadcrumbs.at(0)) < 60.f) {
|
||||
idle_time.update();
|
||||
breadcrumbs.erase(breadcrumbs.begin());
|
||||
}
|
||||
|
||||
// Follow the crumbs when too far away, or just starting to follow
|
||||
if (dist_to_target > (float)follow_distance) {
|
||||
|
||||
// Check for idle
|
||||
if (idle_time.test_and_set(3000)) {
|
||||
follow_target = 0;
|
||||
return;
|
||||
if (follow_steam)
|
||||
{
|
||||
// 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++)
|
||||
{
|
||||
auto entity = ENTITY(i);
|
||||
if (CE_BAD(entity)) // Exist + dormant
|
||||
continue;
|
||||
if (entity->m_Type != ENTITY_PLAYER)
|
||||
continue;
|
||||
player_info_s info;
|
||||
g_IEngine->GetPlayerInfo(entity->m_IDX, &info);
|
||||
if ((int) follow_steam != info.friendsID) // steamid check
|
||||
continue;
|
||||
if (!entity->m_bAlivePlayer) // Dont follow dead players
|
||||
continue;
|
||||
if (!VisCheckEntFromEnt(LOCAL_E, entity))
|
||||
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) && roambot)
|
||||
{
|
||||
// Try to get a new target
|
||||
auto ent_count = g_IEngine->GetMaxClients();
|
||||
for (int i = 0; i < ent_count; i++)
|
||||
{
|
||||
auto entity = ENTITY(i);
|
||||
if (CE_BAD(entity)) // Exist + dormant
|
||||
continue;
|
||||
if (entity->m_Type != ENTITY_PLAYER)
|
||||
continue;
|
||||
if (entity == LOCAL_E) // Follow self lol
|
||||
continue;
|
||||
if (!entity->m_bAlivePlayer ||
|
||||
entity->m_iTeam ==
|
||||
LOCAL_E->m_iTeam) // Dont follow dead players
|
||||
continue;
|
||||
if (follow_activation &&
|
||||
entity->m_flDistance > (float) follow_activation)
|
||||
continue;
|
||||
if (!VisCheckEntFromEnt(LOCAL_E, entity))
|
||||
continue;
|
||||
if (follow_target &&
|
||||
ENTITY(follow_target)->m_flDistance >
|
||||
entity->m_flDistance) // favor closer entitys
|
||||
continue;
|
||||
// ooooo, a target
|
||||
follow_target = entity->m_IDX;
|
||||
}
|
||||
}
|
||||
// last check for entity before we continue
|
||||
if (!follow_target)
|
||||
return;
|
||||
}
|
||||
if (sync_taunt && HasCondition<TFCond_Taunting>(ENTITY(follow_target)))
|
||||
g_IEngine->ClientCmd("taunt");
|
||||
static float last_slot_check = 0.0f;
|
||||
if (g_GlobalVars->curtime < last_slot_check)
|
||||
last_slot_check = 0.0f;
|
||||
if (follow_target && (always_medigun || mimic_slot) &&
|
||||
(g_GlobalVars->curtime - last_slot_check > 1.0f) &&
|
||||
!g_pLocalPlayer->life_state &&
|
||||
!CE_BYTE(ENTITY(follow_target), netvar.iLifeState))
|
||||
|
||||
// If the player is close enough, we dont need to follow the path
|
||||
CachedEntity *followtar = ENTITY(follow_target);
|
||||
auto tar_orig = followtar->m_vecOrigin;
|
||||
auto loc_orig = LOCAL_E->m_vecOrigin;
|
||||
auto dist_to_target = loc_orig.DistTo(tar_orig);
|
||||
if (dist_to_target < 30)
|
||||
breadcrumbs.clear();
|
||||
|
||||
// Update timer on new target
|
||||
static Timer idle_time{};
|
||||
if (breadcrumbs.empty())
|
||||
idle_time.update();
|
||||
|
||||
// New crumbs, we add one if its empty so we have something to follow
|
||||
if ((breadcrumbs.empty() ||
|
||||
tar_orig.DistTo(breadcrumbs.at(breadcrumbs.size() - 1)) > 40.0F) &&
|
||||
DistanceToGround(ENTITY(follow_target)) < 30)
|
||||
breadcrumbs.push_back(tar_orig);
|
||||
|
||||
// Prune old and close crumbs that we wont need anymore, update idle timer
|
||||
// too
|
||||
while (breadcrumbs.size() > 1 && loc_orig.DistTo(breadcrumbs.at(0)) < 60.f)
|
||||
{
|
||||
idle_time.update();
|
||||
breadcrumbs.erase(breadcrumbs.begin());
|
||||
}
|
||||
|
||||
// Follow the crumbs when too far away, or just starting to follow
|
||||
if (dist_to_target > (float) follow_distance)
|
||||
{
|
||||
|
||||
// We are checking our slot so reset the timer
|
||||
last_slot_check = g_GlobalVars->curtime;
|
||||
|
||||
// Get the follow targets active weapon
|
||||
int owner_weapon_eid =
|
||||
(CE_INT(ENTITY(follow_target), netvar.hActiveWeapon) & 0xFFF);
|
||||
IClientEntity *owner_weapon =
|
||||
g_IEntityList->GetClientEntity(owner_weapon_eid);
|
||||
|
||||
// If both the follow targets and the local players weapons arnt null or
|
||||
// dormant
|
||||
if (owner_weapon && CE_GOOD(g_pLocalPlayer->weapon()))
|
||||
// Check for idle
|
||||
if (idle_time.test_and_set(3000))
|
||||
{
|
||||
follow_target = 0;
|
||||
return;
|
||||
}
|
||||
if (sync_taunt && HasCondition<TFCond_Taunting>(ENTITY(follow_target)))
|
||||
g_IEngine->ClientCmd("taunt");
|
||||
static float last_slot_check = 0.0f;
|
||||
if (g_GlobalVars->curtime < last_slot_check)
|
||||
last_slot_check = 0.0f;
|
||||
if (follow_target && (always_medigun || mimic_slot) &&
|
||||
(g_GlobalVars->curtime - last_slot_check > 1.0f) &&
|
||||
!g_pLocalPlayer->life_state &&
|
||||
!CE_BYTE(ENTITY(follow_target), netvar.iLifeState))
|
||||
{
|
||||
|
||||
// IsBaseCombatWeapon()
|
||||
if (re::C_BaseCombatWeapon::IsBaseCombatWeapon(
|
||||
RAW_ENT(g_pLocalPlayer->weapon())) &&
|
||||
re::C_BaseCombatWeapon::IsBaseCombatWeapon(owner_weapon))
|
||||
// We are checking our slot so reset the timer
|
||||
last_slot_check = g_GlobalVars->curtime;
|
||||
|
||||
// Get the follow targets active weapon
|
||||
int owner_weapon_eid =
|
||||
(CE_INT(ENTITY(follow_target), netvar.hActiveWeapon) & 0xFFF);
|
||||
IClientEntity *owner_weapon =
|
||||
g_IEntityList->GetClientEntity(owner_weapon_eid);
|
||||
|
||||
// If both the follow targets and the local players weapons arnt
|
||||
// null or
|
||||
// dormant
|
||||
if (owner_weapon && CE_GOOD(g_pLocalPlayer->weapon()))
|
||||
{
|
||||
|
||||
// Get the players slot numbers and store in some vars
|
||||
int my_slot = re::C_BaseCombatWeapon::GetSlot(
|
||||
RAW_ENT(g_pLocalPlayer->weapon()));
|
||||
int owner_slot = re::C_BaseCombatWeapon::GetSlot(owner_weapon);
|
||||
|
||||
// If the local player is a medic and user settings allow, then
|
||||
// keep the medigun out
|
||||
if (g_pLocalPlayer->clazz == tf_medic && always_medigun)
|
||||
// IsBaseCombatWeapon()
|
||||
if (re::C_BaseCombatWeapon::IsBaseCombatWeapon(
|
||||
RAW_ENT(g_pLocalPlayer->weapon())) &&
|
||||
re::C_BaseCombatWeapon::IsBaseCombatWeapon(owner_weapon))
|
||||
{
|
||||
if (my_slot != 1)
|
||||
|
||||
// Get the players slot numbers and store in some vars
|
||||
int my_slot = re::C_BaseCombatWeapon::GetSlot(
|
||||
RAW_ENT(g_pLocalPlayer->weapon()));
|
||||
int owner_slot =
|
||||
re::C_BaseCombatWeapon::GetSlot(owner_weapon);
|
||||
|
||||
// If the local player is a medic and user settings allow,
|
||||
// then
|
||||
// keep the medigun out
|
||||
if (g_pLocalPlayer->clazz == tf_medic && always_medigun)
|
||||
{
|
||||
g_IEngine->ExecuteClientCmd("slot2");
|
||||
if (my_slot != 1)
|
||||
{
|
||||
g_IEngine->ExecuteClientCmd("slot2");
|
||||
}
|
||||
|
||||
// Else we attemt to keep our weapon mimiced with our
|
||||
// follow
|
||||
// target
|
||||
}
|
||||
|
||||
// Else we attemt to keep our weapon mimiced with our follow
|
||||
// target
|
||||
}
|
||||
else
|
||||
{
|
||||
if (my_slot != owner_slot)
|
||||
else
|
||||
{
|
||||
g_IEngine->ExecuteClientCmd(
|
||||
format("slot", owner_slot + 1).c_str());
|
||||
if (my_slot != owner_slot)
|
||||
{
|
||||
g_IEngine->ExecuteClientCmd(
|
||||
format("slot", owner_slot + 1).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
WalkTo(breadcrumbs.at(0));
|
||||
} else
|
||||
idle_time.update();
|
||||
}
|
||||
|
||||
void DrawTick(){
|
||||
if (!followbot || !draw_crumb) return;
|
||||
if (breadcrumbs.size() < 2) return;
|
||||
for (size_t i = 0; i < breadcrumbs.size() - 1; i++) {
|
||||
Vector wts1, wts2;
|
||||
if (draw::WorldToScreen(breadcrumbs.at(i), wts1) && draw::WorldToScreen(breadcrumbs.at(i + 1), wts2)) {
|
||||
draw_api::draw_line(wts1.x, wts1.y, wts2.x - wts1.x, wts2.y - wts1.y, colors::white, 0.1f);
|
||||
WalkTo(breadcrumbs.at(0));
|
||||
}
|
||||
}
|
||||
Vector wts;
|
||||
if (!draw::WorldToScreen(breadcrumbs.at(0), wts)) return;
|
||||
draw_api::draw_rect(wts.x - 4, wts.y - 4, 8, 8, colors::white);
|
||||
draw_api::draw_rect_outlined(wts.x - 4, wts.y - 4, 7, 7, colors::white, 1.0f);
|
||||
else
|
||||
idle_time.update();
|
||||
}
|
||||
|
||||
static CatCommand follow_me("fb_follow_me", "IPC connected bots will follow you", [](){
|
||||
if (!ipc::peer) {
|
||||
logging::Info("IPC isnt connected");
|
||||
return;
|
||||
}
|
||||
auto local_ent = LOCAL_E;
|
||||
if (!local_ent) {
|
||||
logging::Info("Cant get a local player");
|
||||
return;
|
||||
}
|
||||
player_info_s info;
|
||||
g_IEngine->GetPlayerInfo(local_ent->m_IDX, &info);
|
||||
auto steam_id = info.friendsID;
|
||||
if (!steam_id) {
|
||||
logging::Info("Cant get steam-id, the game module probably doesnt support it.");
|
||||
return;
|
||||
}
|
||||
// Construct the command
|
||||
std::string tmp = CON_PREFIX + follow_steam.name + " " + std::to_string(steam_id);
|
||||
if (tmp.length() >= 63)
|
||||
{
|
||||
ipc::peer->SendMessage(
|
||||
0, 0, ipc::commands::execute_client_cmd_long,
|
||||
tmp.c_str(), tmp.length() + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipc::peer->SendMessage(tmp.c_str(), 0,
|
||||
ipc::commands::execute_client_cmd,
|
||||
0, 0);
|
||||
}
|
||||
});
|
||||
void DrawTick()
|
||||
{
|
||||
#if TEXTMODE_VAC != 1
|
||||
if (!followbot || !draw_crumb)
|
||||
return;
|
||||
if (breadcrumbs.size() < 2)
|
||||
return;
|
||||
for (size_t i = 0; i < breadcrumbs.size() - 1; i++)
|
||||
{
|
||||
Vector wts1, wts2;
|
||||
if (draw::WorldToScreen(breadcrumbs.at(i), wts1) &&
|
||||
draw::WorldToScreen(breadcrumbs.at(i + 1), wts2))
|
||||
{
|
||||
draw_api::draw_line(wts1.x, wts1.y, wts2.x - wts1.x,
|
||||
wts2.y - wts1.y, colors::white, 0.1f);
|
||||
}
|
||||
}
|
||||
Vector wts;
|
||||
if (!draw::WorldToScreen(breadcrumbs.at(0), wts))
|
||||
return;
|
||||
draw_api::draw_rect(wts.x - 4, wts.y - 4, 8, 8, colors::white);
|
||||
draw_api::draw_rect_outlined(wts.x - 4, wts.y - 4, 7, 7, colors::white,
|
||||
1.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
static CatCommand
|
||||
follow_me("fb_follow_me", "IPC connected bots will follow you", []() {
|
||||
if (!ipc::peer)
|
||||
{
|
||||
logging::Info("IPC isnt connected");
|
||||
return;
|
||||
}
|
||||
auto local_ent = LOCAL_E;
|
||||
if (!local_ent)
|
||||
{
|
||||
logging::Info("Cant get a local player");
|
||||
return;
|
||||
}
|
||||
player_info_s info;
|
||||
g_IEngine->GetPlayerInfo(local_ent->m_IDX, &info);
|
||||
auto steam_id = info.friendsID;
|
||||
if (!steam_id)
|
||||
{
|
||||
logging::Info("Cant get steam-id, the game module probably doesnt "
|
||||
"support it.");
|
||||
return;
|
||||
}
|
||||
// Construct the command
|
||||
std::string tmp =
|
||||
CON_PREFIX + follow_steam.name + " " + std::to_string(steam_id);
|
||||
if (tmp.length() >= 63)
|
||||
{
|
||||
ipc::peer->SendMessage(0, 0, ipc::commands::execute_client_cmd_long,
|
||||
tmp.c_str(), tmp.length() + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipc::peer->SendMessage(tmp.c_str(), 0,
|
||||
ipc::commands::execute_client_cmd, 0, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,9 @@ CatVar master_switch(CV_SWITCH, "se_master", "1", "Enable sequence exploit",
|
||||
"disables everything else that uses it");
|
||||
CatVar value(CV_INT, "se_value", "900", "Sequence exploit value",
|
||||
"Value of user cmds to spam with");
|
||||
CatVar cap_range(CV_FLOAT, "se_cap_range", "200.0f", "Autocap range", "Autocap range, increase if you notice that you only lagy once you are already in the cap zone");
|
||||
CatVar cap_range(CV_FLOAT, "se_cap_range", "200.0f", "Autocap range",
|
||||
"Autocap range, increase if you notice that you only lagy "
|
||||
"once you are already in the cap zone");
|
||||
CatCommand do_lagexploit("se_do", "Sequence exploit (for use in scripts)",
|
||||
[]() { AddExploitTicks(6); });
|
||||
int exticks = 0;
|
||||
@ -263,9 +265,13 @@ void CreateMove()
|
||||
const Vector &min1 =
|
||||
p->OBBMins() + RAW_ENT(LOCAL_E)->GetAbsOrigin();
|
||||
const Vector &max2 =
|
||||
c->OBBMaxs() + pEnt->m_vecOrigin + Vector((float)cap_range, (float)cap_range, (float)cap_range);
|
||||
c->OBBMaxs() + pEnt->m_vecOrigin +
|
||||
Vector((float) cap_range, (float) cap_range,
|
||||
(float) cap_range);
|
||||
const Vector &min2 =
|
||||
c->OBBMins() + pEnt->m_vecOrigin - Vector((float)cap_range, (float)cap_range, (float)cap_range);
|
||||
c->OBBMins() + pEnt->m_vecOrigin -
|
||||
Vector((float) cap_range, (float) cap_range,
|
||||
(float) cap_range);
|
||||
if ((min1.x <= max2.x && max1.x >= min2.x) &&
|
||||
(min1.y <= max2.y && max1.y >= min2.y) &&
|
||||
(min1.z <= max2.z && max1.z >= min2.z))
|
||||
@ -379,14 +385,15 @@ void CreateMove()
|
||||
// SHOUTOUTS TO BLACKFIRE
|
||||
if (doom || razorback)
|
||||
{
|
||||
// Variablse to store Primary and secondary nextfire times
|
||||
// Variablse to store Primary and secondary nextfire times
|
||||
static float i = 0.0;
|
||||
static float i2 = 0.0;
|
||||
// Servertime to predict the next Primary and secondary times in seconds
|
||||
servertime =
|
||||
(float) (CE_INT(g_pLocalPlayer->entity, netvar.nTickBase)) *
|
||||
g_GlobalVars->interval_per_tick;
|
||||
// If not the holding the same weapon as last tick or i(2) is smaller than 0.1f
|
||||
// If not the holding the same weapon as last tick or i(2) is smaller
|
||||
// than 0.1f
|
||||
// Get a new nextattack(2)
|
||||
if (!nextattack || i < 0.1f ||
|
||||
g_pLocalPlayer->weapon()->m_iClassID != lastwep)
|
||||
@ -396,37 +403,43 @@ void CreateMove()
|
||||
g_pLocalPlayer->weapon()->m_iClassID != lastwep)
|
||||
nextattack2 = CE_FLOAT(g_pLocalPlayer->weapon(),
|
||||
netvar.flNextSecondaryAttack);
|
||||
// If the next attack (2) time would exceed 75 seconds, set it to 75 to prevent
|
||||
// If the next attack (2) time would exceed 75 seconds, set it to 75 to
|
||||
// prevent
|
||||
// The server disconnecting you for lagging too much
|
||||
if (servertime - nextattack > 75.0f)
|
||||
nextattack = servertime - 75.0f;
|
||||
if (servertime - nextattack2 > 75.0f)
|
||||
nextattack2 = servertime - 75.0f;
|
||||
// If doom is active and nextattack is positive (not reloading/holding m1 since a while)
|
||||
// If doom is active and nextattack is positive (not reloading/holding
|
||||
// m1 since a while)
|
||||
// and you are holding m1 run the Doom code
|
||||
if (doom && servertime - nextattack > 0.0f &&
|
||||
g_pUserCmd->buttons & IN_ATTACK)
|
||||
{
|
||||
// Incase i ever goes below 0.1 recalculate it (or if it's just inited)
|
||||
// Incase i ever goes below 0.1 recalculate it (or if it's just
|
||||
// inited)
|
||||
if (i < 0.1f)
|
||||
i = servertime - (int) nextattack;
|
||||
i = servertime - (int) nextattack;
|
||||
// Set amount to i * 66 (which lags for i seconds)
|
||||
amount = i * 66;
|
||||
// Don't attack if the clip is empty so you also instantly reload
|
||||
if (!CE_BYTE(g_pLocalPlayer->weapon(), netvar.m_iClip1))
|
||||
g_pUserCmd->buttons &= ~IN_ATTACK;
|
||||
amount = i * 66;
|
||||
// Don't attack if the clip is empty so you also instantly reload
|
||||
if (!CE_BYTE(g_pLocalPlayer->weapon(), netvar.m_iClip1))
|
||||
g_pUserCmd->buttons &= ~IN_ATTACK;
|
||||
}
|
||||
// If doom is active and nextattack2 is positive (not reloading/holding m2 since a while)
|
||||
// If doom is active and nextattack2 is positive (not reloading/holding
|
||||
// m2 since a while)
|
||||
// and you are holding m2 run the Doom code
|
||||
if (doom && servertime - nextattack2 > 0.0f &&
|
||||
g_pUserCmd->buttons & IN_ATTACK2)
|
||||
{
|
||||
// Incase i2 ever goes below 0.1 recalculate it (or if it's just inited)
|
||||
// Incase i2 ever goes below 0.1 recalculate it (or if it's just
|
||||
// inited)
|
||||
if (i2 < 0.1f)
|
||||
i2 = servertime - nextattack2;
|
||||
// Set lagexploit amount (i * 66 = i seconds of lag)
|
||||
amount = i2 * 66;
|
||||
// if primary ammo is empty don't hold m2, not a byte check since many weapons may not have a secondary clip
|
||||
// if primary ammo is empty don't hold m2, not a byte check since
|
||||
// many weapons may not have a secondary clip
|
||||
if (CE_INT(g_pLocalPlayer->weapon(), netvar.m_iClip2) == 0)
|
||||
g_pUserCmd->buttons &= ~IN_ATTACK2;
|
||||
}
|
||||
@ -434,33 +447,35 @@ void CreateMove()
|
||||
if (razorback && servertime - nextattack > 3.0f &&
|
||||
(g_pUserCmd->buttons & IN_ATTACK))
|
||||
{
|
||||
CachedEntity* snoiper = nullptr;
|
||||
for (int ii = 0; ii < g_IEngine->GetMaxClients(); ii++) {
|
||||
CachedEntity* snooiper = ENTITY(ii);
|
||||
// nullptr and dormant check
|
||||
if (CE_BAD(snooiper))
|
||||
continue;
|
||||
// Alive check
|
||||
if (!snooiper->m_bAlivePlayer)
|
||||
continue;
|
||||
// Vischeck
|
||||
if (!VisCheckEntFromEnt(LOCAL_E, snooiper))
|
||||
continue;
|
||||
// Range should be more than high enough
|
||||
if (!snooiper->m_flDistance < 200.0f)
|
||||
continue;
|
||||
int clazz = CE_INT(snooiper, netvar.iClass);
|
||||
if (clazz != tf_sniper)
|
||||
continue;
|
||||
// found entity
|
||||
snoiper = snooiper;
|
||||
// Break if you found an Entity, no need to go on further checking
|
||||
break;
|
||||
}
|
||||
// Return if no snipers were found
|
||||
if (CE_BAD(snoiper))
|
||||
return;
|
||||
// Only works with knife out obviously
|
||||
CachedEntity *snoiper = nullptr;
|
||||
for (int ii = 0; ii < g_IEngine->GetMaxClients(); ii++)
|
||||
{
|
||||
CachedEntity *snooiper = ENTITY(ii);
|
||||
// nullptr and dormant check
|
||||
if (CE_BAD(snooiper))
|
||||
continue;
|
||||
// Alive check
|
||||
if (!snooiper->m_bAlivePlayer)
|
||||
continue;
|
||||
// Vischeck
|
||||
if (!VisCheckEntFromEnt(LOCAL_E, snooiper))
|
||||
continue;
|
||||
// Range should be more than high enough
|
||||
if (!snooiper->m_flDistance < 200.0f)
|
||||
continue;
|
||||
int clazz = CE_INT(snooiper, netvar.iClass);
|
||||
if (clazz != tf_sniper)
|
||||
continue;
|
||||
// found entity
|
||||
snoiper = snooiper;
|
||||
// Break if you found an Entity, no need to go on further
|
||||
// checking
|
||||
break;
|
||||
}
|
||||
// Return if no snipers were found
|
||||
if (CE_BAD(snoiper))
|
||||
return;
|
||||
// Only works with knife out obviously
|
||||
if (g_pLocalPlayer->weapon()->m_iClassID == CL_CLASS(CTFKnife))
|
||||
{
|
||||
if (!i)
|
||||
@ -469,7 +484,8 @@ void CreateMove()
|
||||
g_pUserCmd->buttons |= IN_ATTACK;
|
||||
}
|
||||
}
|
||||
// If i is not below 0.1f then substract one from it to slowly decrease lag amount
|
||||
// If i is not below 0.1f then substract one from it to slowly decrease
|
||||
// lag amount
|
||||
if (i > 0.1f)
|
||||
i -= 1.0f;
|
||||
// Set last weapon classid
|
||||
@ -478,11 +494,13 @@ void CreateMove()
|
||||
// if Jarate spam active
|
||||
if (piss)
|
||||
{
|
||||
// Get Servertime
|
||||
// Get Servertime
|
||||
servertime =
|
||||
(float) (CE_INT(g_pLocalPlayer->entity, netvar.nTickBase)) *
|
||||
g_GlobalVars->interval_per_tick;
|
||||
// Get nextattack when it's invalid or the player selected another weapon (which is a tick, not a time like 1 second, but servertime + 1 second)
|
||||
// Get nextattack when it's invalid or the player selected another
|
||||
// weapon (which is a tick, not a time like 1 second, but servertime + 1
|
||||
// second)
|
||||
if (!nextattack || g_pLocalPlayer->weapon()->m_iClassID != lastwep)
|
||||
nextattack =
|
||||
CE_FLOAT(g_pLocalPlayer->weapon(), netvar.flNextPrimaryAttack);
|
||||
@ -491,7 +509,8 @@ void CreateMove()
|
||||
// Check if holding JARAAATE
|
||||
if (CE_INT(g_pLocalPlayer->weapon(), netvar.iItemDefinitionIndex) == 58)
|
||||
{
|
||||
// Setup Switch variable to not constantly spam jarate, since else the jarate may vanish
|
||||
// Setup Switch variable to not constantly spam jarate, since else
|
||||
// the jarate may vanish
|
||||
static int bSwitch = 0;
|
||||
// Only play Piss.wav once every second
|
||||
if ((g_pUserCmd->command_number % 66) == 0 &&
|
||||
@ -534,11 +553,12 @@ void Draw()
|
||||
auto amount = servertime - nextattack;
|
||||
auto amount2 = servertime - nextattack2;
|
||||
if (amount > 0.0f)
|
||||
AddCenterString(format("Fireable Primary amount: ", (int)amount),
|
||||
AddCenterString(format("Fireable Primary amount: ", (int) amount),
|
||||
colors::orange);
|
||||
if (amount2 > 0.0f)
|
||||
AddCenterString(format("Fireable Secondary amount: ", (int)amount2),
|
||||
colors::orange);
|
||||
AddCenterString(
|
||||
format("Fireable Secondary amount: ", (int) amount2),
|
||||
colors::orange);
|
||||
}
|
||||
if (razorback)
|
||||
{
|
||||
@ -558,12 +578,10 @@ void Draw()
|
||||
AddCenterString(format("Can Spam piss"), colors::green);
|
||||
}
|
||||
else if (servertime - nextattack < 21.0f)
|
||||
AddCenterString(
|
||||
format("Can't spam piss, ",
|
||||
(int) ((servertime - nextattack) * 100 /
|
||||
21),
|
||||
"% charge"),
|
||||
colors::red);
|
||||
AddCenterString(format("Can't spam piss, ",
|
||||
(int) ((servertime - nextattack) * 100 / 21),
|
||||
"% charge"),
|
||||
colors::red);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1198,8 +1198,9 @@ void Move()
|
||||
if (boost::contains(prvlvlname, "pl_"))
|
||||
{
|
||||
bool ret = false;
|
||||
if (lagexploit::pointarr[0] || lagexploit::pointarr[1] || lagexploit::pointarr[2] ||
|
||||
lagexploit::pointarr[3] || lagexploit::pointarr[4])
|
||||
if (lagexploit::pointarr[0] || lagexploit::pointarr[1] ||
|
||||
lagexploit::pointarr[2] || lagexploit::pointarr[3] ||
|
||||
lagexploit::pointarr[4])
|
||||
for (int i = 0; i < MAX_ENTITIES; i++)
|
||||
{
|
||||
if (!ret)
|
||||
|
@ -111,6 +111,7 @@ static CatVar debug_projectiles(CV_SWITCH, "debug_projectiles", "0",
|
||||
"Debug Projectiles");
|
||||
|
||||
static CatVar fakelag_amount(CV_INT, "fakelag", "0", "Bad Fakelag");
|
||||
static CatVar serverlag_amount(CV_INT, "serverlag", "0", "Lag the server by spamming this many voicecommands per tick");
|
||||
CatVar semiauto(CV_INT, "semiauto", "0", "Semiauto");
|
||||
|
||||
bool *bSendPackets;
|
||||
@ -126,7 +127,6 @@ bool CreateMove_hook(void *thisptr, float inputSample, CUserCmd *cmd)
|
||||
bool time_replaced, ret, speedapplied;
|
||||
float curtime_old, servertime, speed, yaw;
|
||||
Vector vsilent, ang;
|
||||
INetChannel *ch;
|
||||
|
||||
tickcount++;
|
||||
g_pUserCmd = cmd;
|
||||
@ -168,22 +168,6 @@ bool CreateMove_hook(void *thisptr, float inputSample, CUserCmd *cmd)
|
||||
if (g_pUserCmd && g_pUserCmd->command_number)
|
||||
last_cmd_number = g_pUserCmd->command_number;
|
||||
|
||||
ch = (INetChannel *) g_IEngine->GetNetChannelInfo();
|
||||
if (ch && !hooks::IsHooked((void *) ch))
|
||||
{
|
||||
hooks::netchannel.Set(ch);
|
||||
hooks::netchannel.HookMethod((void *) CanPacket_hook,
|
||||
offsets::CanPacket());
|
||||
hooks::netchannel.HookMethod((void *) SendNetMsg_hook,
|
||||
offsets::SendNetMsg());
|
||||
hooks::netchannel.HookMethod((void *) Shutdown_hook,
|
||||
offsets::Shutdown());
|
||||
hooks::netchannel.Apply();
|
||||
#if ENABLE_IPC
|
||||
ipc::UpdateServerAddress();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**bSendPackets = true;
|
||||
if (hacks::shared::lagexploit::ExploitActive()) {
|
||||
*bSendPackets = ((g_pUserCmd->command_number % 4) == 0);
|
||||
@ -254,7 +238,7 @@ bool CreateMove_hook(void *thisptr, float inputSample, CUserCmd *cmd)
|
||||
|
||||
if (hacks::shared::followbot::followbot)
|
||||
{
|
||||
hacks::shared::followbot::WorldTick();
|
||||
hacks::shared::followbot::WorldTick();
|
||||
if (g_GlobalVars->curtime < last_jointeam_try)
|
||||
{
|
||||
team_joining_state = 0;
|
||||
@ -287,7 +271,7 @@ bool CreateMove_hook(void *thisptr, float inputSample, CUserCmd *cmd)
|
||||
if (CE_BAD(ent))
|
||||
continue;
|
||||
if (ent->player_info.friendsID ==
|
||||
(int)hacks::shared::followbot::follow_steam)
|
||||
(int) hacks::shared::followbot::follow_steam)
|
||||
{
|
||||
found_entity = ent;
|
||||
break;
|
||||
@ -533,6 +517,9 @@ bool CreateMove_hook(void *thisptr, float inputSample, CUserCmd *cmd)
|
||||
if (cmd)
|
||||
g_Settings.last_angles = cmd->viewangles;
|
||||
}
|
||||
if (serverlag_amount)
|
||||
for (int i = 0; i < (int)serverlag_amount; i++)
|
||||
g_IEngine->ServerCmd("voicecommand 0 0", false);
|
||||
|
||||
// PROF_END("CreateMove");
|
||||
if (!(cmd->buttons & IN_ATTACK))
|
||||
|
@ -290,7 +290,8 @@ static CatVar chat_filter(CV_STRING, "chat_censor", "", "Censor words",
|
||||
"said, seperate with commas");
|
||||
static CatVar chat_filter_enabled(CV_SWITCH, "chat_censor_enabled", "0",
|
||||
"Enable censor", "Censor Words in chat");
|
||||
|
||||
static CatVar server_crash_key(CV_KEY, "crash_server", "0", "Server crash key",
|
||||
"hold key and wait...");
|
||||
bool SendNetMsg_hook(void *_this, INetMessage &msg, bool bForceReliable = false,
|
||||
bool bVoice = false)
|
||||
{
|
||||
@ -666,6 +667,24 @@ void FrameStageNotify_hook(void *_this, int stage)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cathook && stage == FRAME_RENDER_START) {
|
||||
INetChannel *ch;
|
||||
ch = (INetChannel *) g_IEngine->GetNetChannelInfo();
|
||||
if (ch && !hooks::IsHooked((void *) ch))
|
||||
{
|
||||
hooks::netchannel.Set(ch);
|
||||
hooks::netchannel.HookMethod((void *) CanPacket_hook,
|
||||
offsets::CanPacket());
|
||||
hooks::netchannel.HookMethod((void *) SendNetMsg_hook,
|
||||
offsets::SendNetMsg());
|
||||
hooks::netchannel.HookMethod((void *) Shutdown_hook,
|
||||
offsets::Shutdown());
|
||||
hooks::netchannel.Apply();
|
||||
#if ENABLE_IPC
|
||||
ipc::UpdateServerAddress();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (cathook && !g_Settings.bInvalid && stage == FRAME_RENDER_START)
|
||||
{
|
||||
IF_GAME(IsTF())
|
||||
|
@ -657,6 +657,7 @@ static const std::string list_tf2 = R"(
|
||||
]
|
||||
"Misc" [
|
||||
"Misc Menu"
|
||||
"serverlag_amount"
|
||||
"deadringer_auto"
|
||||
"halloween_mode"
|
||||
"name"
|
||||
|
Reference in New Issue
Block a user