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