Merge pull request #17 from nullifiedcat/followbot-command
Followbot command
This commit is contained in:
commit
7957563e1c
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
*.d
|
*.d
|
||||||
*.o
|
*.o
|
||||||
bin/*
|
bin/*
|
||||||
|
/core
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit eccb7cc43302b1c391b431d4415a7cdaf043fe6b
|
Subproject commit e532876ffd707a48389d54ff904dcc40a84f2839
|
@ -17,6 +17,8 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <set>
|
||||||
|
#include <algorithm>
|
||||||
#include "aftercheaders.h"
|
#include "aftercheaders.h"
|
||||||
#include "drawing.h"
|
#include "drawing.h"
|
||||||
#include "entitycache.h"
|
#include "entitycache.h"
|
||||||
|
@ -17,24 +17,131 @@ float lost_time { 0 };
|
|||||||
float idle_time { 0 };
|
float idle_time { 0 };
|
||||||
int following_idx { 0 };
|
int following_idx { 0 };
|
||||||
|
|
||||||
|
std::set<int> selection {};
|
||||||
|
std::set<int> selection_secondary {};
|
||||||
|
|
||||||
|
float destination_point_time { 0.0f };
|
||||||
|
Vector destination_point {};
|
||||||
|
bool destination_reached { false };
|
||||||
|
bool allow_moving { true };
|
||||||
|
|
||||||
|
bool IsBot(CachedEntity* entity) {
|
||||||
|
if (!ipc::peer) return false;
|
||||||
|
if (entity->m_Type == ENTITY_PLAYER) {
|
||||||
|
if (entity->m_pPlayerInfo) {
|
||||||
|
if (ipc::peer) {
|
||||||
|
for (unsigned i = 1; i < cat_ipc::max_peers; i++) {
|
||||||
|
if (!ipc::peer->memory->peer_data[i].free && ipc::peer->memory->peer_user_data[i].friendid == entity->m_pPlayerInfo->friendsID) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectEntity(int idx) {
|
||||||
|
logging::Info("Selecting entity %i", idx);
|
||||||
|
CachedEntity* entity = ENTITY(idx);
|
||||||
|
if (CE_BAD(entity)) return;
|
||||||
|
std::set<int>& current_selection = IsBot(entity) ? selection : selection_secondary;
|
||||||
|
if (current_selection.find(idx) != current_selection.end()) {
|
||||||
|
current_selection.erase(current_selection.find(idx));
|
||||||
|
logging::Info("Deselected!");
|
||||||
|
} else {
|
||||||
|
current_selection.insert(idx);
|
||||||
|
logging::Info("Selected!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddMessageHandlers(ipc::peer_t* peer) {
|
||||||
|
peer->SetCommandHandler(ipc::commands::set_follow_steamid, [](cat_ipc::command_s& command, void* payload) {
|
||||||
|
logging::Info("IPC Message: now following %ld", *(unsigned*)&command.cmd_data);
|
||||||
|
hacks::shared::followbot::follow_steamid = *(unsigned*)&command.cmd_data;
|
||||||
|
});
|
||||||
|
peer->SetCommandHandler(ipc::commands::move_to_vector, [](cat_ipc::command_s& command, void* payload) {
|
||||||
|
float* data = (float*)&command.cmd_data;
|
||||||
|
logging::Info("IPC Message: moving to %.2f %.2f %.2f", data[0], data[1], data[2]);
|
||||||
|
destination_point = Vector(data[0], data[1], data[2]);
|
||||||
|
destination_point_time = g_GlobalVars->curtime;
|
||||||
|
destination_reached = false;
|
||||||
|
});
|
||||||
|
peer->SetCommandHandler(ipc::commands::start_moving, [](cat_ipc::command_s& command, void* payload) {
|
||||||
|
allow_moving = true;
|
||||||
|
});
|
||||||
|
peer->SetCommandHandler(ipc::commands::stop_moving, [](cat_ipc::command_s& command, void* payload) {
|
||||||
|
allow_moving = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
CatCommand follow_me("fb_follow_me", "Makes all bots follow you", []() {
|
CatCommand follow_me("fb_follow_me", "Makes all bots follow you", []() {
|
||||||
if (ipc::peer) {
|
if (ipc::peer) {
|
||||||
unsigned id = g_ISteamUser->GetSteamID().GetAccountID();
|
unsigned id = g_ISteamUser->GetSteamID().GetAccountID();
|
||||||
ipc::peer->SendMessage("owner", 0, &id, sizeof(id));
|
ipc::peer->SendMessage((const char*)&id, 0, ipc::commands::set_follow_steamid, 0, 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
CatCommand move_to_crosshair("fb_move_to_point", "Moves a bot (or all bots) to crosshair", [](const CCommand& args) {
|
unsigned MakeMask() {
|
||||||
logging::Info("not yet implemented.");
|
unsigned result = 0;
|
||||||
|
if (!ipc::peer) return 0;
|
||||||
|
// O(n^2) ik
|
||||||
|
for (const auto& idx : selection) {
|
||||||
|
CachedEntity* ent = ENTITY(idx);
|
||||||
|
if (CE_BAD(ent)) continue;
|
||||||
|
if (!ent->m_pPlayerInfo) continue;
|
||||||
|
for (unsigned i = 1; i < cat_ipc::max_peers; i++) {
|
||||||
|
if (!ipc::peer->memory->peer_data[i].free && ipc::peer->memory->peer_user_data[i].friendid == ent->m_pPlayerInfo->friendsID) {
|
||||||
|
result |= (1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
CatCommand tool("fb_tool", "Followbot multitool", [](const CCommand& args) {
|
||||||
|
if (!ipc::peer) return;
|
||||||
|
if (args.ArgC() == 1) {
|
||||||
|
// TODO open a gui or something...
|
||||||
|
} else {
|
||||||
|
if (!strcmp(args.Arg(1), "select")) {
|
||||||
|
logging::Info("FB TOOL -> SELECT");
|
||||||
|
if (g_IInputSystem->IsButtonDown(ButtonCode_t::KEY_LSHIFT)) {
|
||||||
|
// Shift cleans selection..
|
||||||
|
selection.clear();
|
||||||
|
selection_secondary.clear();
|
||||||
|
logging::Info("Selection cleared!");
|
||||||
|
} else {
|
||||||
|
logging::Info("Selecting entity...");
|
||||||
|
int eindex = 0;
|
||||||
|
WhatIAmLookingAt(&eindex, nullptr);
|
||||||
|
if (eindex) {
|
||||||
|
SelectEntity(eindex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!strcmp(args.Arg(1), "move")) {
|
||||||
|
logging::Info("FB TOOL -> MOVE");
|
||||||
|
Vector destination;
|
||||||
|
WhatIAmLookingAt(nullptr, &destination);
|
||||||
|
float array[3] = { destination.x, destination.y, destination.z };
|
||||||
|
ipc::peer->SendMessage((const char*)array, MakeMask(), ipc::commands::move_to_vector, nullptr, 0);
|
||||||
|
} else if (!strcmp(args.Arg(1), "stay")) {
|
||||||
|
logging::Info("FB TOOL -> STAY");
|
||||||
|
ipc::peer->SendMessage(nullptr, MakeMask(), ipc::commands::stop_moving, nullptr, 0);
|
||||||
|
} else if (!strcmp(args.Arg(1), "follow")) {
|
||||||
|
logging::Info("FB TOOL -> FOLLOW");
|
||||||
|
ipc::peer->SendMessage(nullptr, MakeMask(), ipc::commands::start_moving, nullptr, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
CatCommand follow("fb_follow", "Follows you (or player with SteamID specified)", [](const CCommand& args) {
|
CatCommand follow("fb_follow", "Follows you (or player with SteamID specified)", [](const CCommand& args) {
|
||||||
follow_steamid = strtol(args.Arg(1), nullptr, 10);
|
follow_steamid = strtol(args.Arg(1), nullptr, 10);
|
||||||
});
|
});
|
||||||
CatCommand follow_entity("fb_follow_entity", "Follows entity with specified entity ID", [](const CCommand& args) {
|
|
||||||
logging::Info("not yet implemented.");
|
|
||||||
});
|
|
||||||
CatVar bot(CV_SWITCH, "fb_bot", "0", "This player is a bot", "Set to 1 in followbots' configs");
|
CatVar bot(CV_SWITCH, "fb_bot", "0", "This player is a bot", "Set to 1 in followbots' configs");
|
||||||
CatVar mimic_slot(CV_SWITCH, "fb_mimic_slot", "1", "Mimic selected weapon", "If enabled, this bot will select same weapon slot as the owner");
|
CatVar mimic_slot(CV_SWITCH, "fb_mimic_slot", "1", "Mimic selected weapon", "If enabled, this bot will select same weapon slot as the owner");
|
||||||
|
CatVar always_medigun(CV_SWITCH, "fb_always_medigun", "1", "Always use Medigun", "Medics will always use Medigun");
|
||||||
|
//CatVar sync_taunt(CV_SWITCH, "fb_sync_taunt", "1", "Synchronize taunts", "Bots will taunt if owner is taunting");
|
||||||
|
|
||||||
// I've spent 2 days on writing this method.
|
// I've spent 2 days on writing this method.
|
||||||
// I couldn't succeed.
|
// I couldn't succeed.
|
||||||
@ -54,7 +161,7 @@ std::pair<float, float> ComputeMove(const Vector& a, const Vector& b) {
|
|||||||
|
|
||||||
// I've removed that too early.
|
// I've removed that too early.
|
||||||
void PrintDebug() {
|
void PrintDebug() {
|
||||||
|
/*
|
||||||
const Vector& a = LOCAL_E->m_vecOrigin;
|
const Vector& a = LOCAL_E->m_vecOrigin;
|
||||||
const Vector& b = last_direction;
|
const Vector& b = last_direction;
|
||||||
|
|
||||||
@ -74,7 +181,7 @@ void PrintDebug() {
|
|||||||
|
|
||||||
auto move = ComputeMove(a, b);
|
auto move = ComputeMove(a, b);
|
||||||
AddSideString(format("forward: ", move.first));
|
AddSideString(format("forward: ", move.first));
|
||||||
AddSideString(format("side: ", move.second));
|
AddSideString(format("side: ", move.second));*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void WalkTo(const Vector& vector) {
|
void WalkTo(const Vector& vector) {
|
||||||
@ -89,12 +196,44 @@ void WalkTo(const Vector& vector) {
|
|||||||
idle_time = 0;
|
idle_time = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto result = ComputeMove(LOCAL_E->m_vecOrigin, last_direction);
|
auto result = ComputeMove(LOCAL_E->m_vecOrigin, vector);
|
||||||
|
|
||||||
g_pUserCmd->forwardmove = result.first;
|
g_pUserCmd->forwardmove = result.first;
|
||||||
g_pUserCmd->sidemove = result.second;
|
g_pUserCmd->sidemove = result.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AfterCreateMove() {
|
||||||
|
auto it = selection.begin();
|
||||||
|
while (it != selection.end()) {
|
||||||
|
int idx = *it;
|
||||||
|
CachedEntity* entity = ENTITY(idx);
|
||||||
|
if (CE_BAD(entity)) {
|
||||||
|
selection.erase(it++);
|
||||||
|
} else {
|
||||||
|
hacks::shared::esp::AddEntityString(entity, "[SELECTED]", colors::orange);
|
||||||
|
if (fmod(g_GlobalVars->curtime, 2.0f) < 1.0f) {
|
||||||
|
hacks::shared::esp::SetEntityColor(entity, colors::yellow);
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it = selection_secondary.begin();
|
||||||
|
while (it != selection_secondary.end()) {
|
||||||
|
int idx = *it;
|
||||||
|
CachedEntity* entity = ENTITY(idx);
|
||||||
|
if (CE_BAD(entity)) {
|
||||||
|
selection_secondary.erase(it++);
|
||||||
|
} else {
|
||||||
|
hacks::shared::esp::AddEntityString(entity, "[SELECTED (SECONDARY)]", colors::orange);
|
||||||
|
if (fmod(g_GlobalVars->curtime, 2.0f) < 1.0f) {
|
||||||
|
hacks::shared::esp::SetEntityColor(entity, colors::yellow);
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DoWalking();
|
||||||
|
}
|
||||||
|
|
||||||
void DoWalking() {
|
void DoWalking() {
|
||||||
if (!bot) return;
|
if (!bot) return;
|
||||||
following_idx = 0;
|
following_idx = 0;
|
||||||
@ -112,7 +251,7 @@ void DoWalking() {
|
|||||||
static float last_slot_check = 0.0f;
|
static float last_slot_check = 0.0f;
|
||||||
if (g_GlobalVars->curtime < last_slot_check) last_slot_check = 0.0f;
|
if (g_GlobalVars->curtime < last_slot_check) last_slot_check = 0.0f;
|
||||||
|
|
||||||
if (mimic_slot && (g_GlobalVars->curtime - last_slot_check > 1.0f) && !g_pLocalPlayer->life_state && !CE_BYTE(found_entity, netvar.iLifeState)) {
|
if (following_idx && (always_medigun || mimic_slot) && (g_GlobalVars->curtime - last_slot_check > 1.0f) && !g_pLocalPlayer->life_state && !CE_BYTE(found_entity, netvar.iLifeState)) {
|
||||||
int owner_weapon_eid = (CE_INT(found_entity, netvar.hActiveWeapon) & 0xFFF);
|
int owner_weapon_eid = (CE_INT(found_entity, netvar.hActiveWeapon) & 0xFFF);
|
||||||
IClientEntity* owner_weapon = g_IEntityList->GetClientEntity(owner_weapon_eid);
|
IClientEntity* owner_weapon = g_IEntityList->GetClientEntity(owner_weapon_eid);
|
||||||
if (owner_weapon && CE_GOOD(g_pLocalPlayer->weapon())) {
|
if (owner_weapon && CE_GOOD(g_pLocalPlayer->weapon())) {
|
||||||
@ -121,8 +260,14 @@ void DoWalking() {
|
|||||||
vfunc<bool(*)(IClientEntity*)>(owner_weapon, 190, 0)(owner_weapon)) {
|
vfunc<bool(*)(IClientEntity*)>(owner_weapon, 190, 0)(owner_weapon)) {
|
||||||
int my_slot = vfunc<int(*)(IClientEntity*)>(g_pLocalPlayer->weapon()->m_pEntity, 395, 0)(g_pLocalPlayer->weapon()->m_pEntity);
|
int my_slot = vfunc<int(*)(IClientEntity*)>(g_pLocalPlayer->weapon()->m_pEntity, 395, 0)(g_pLocalPlayer->weapon()->m_pEntity);
|
||||||
int owner_slot = vfunc<int(*)(IClientEntity*)>(owner_weapon, 395, 0)(owner_weapon);
|
int owner_slot = vfunc<int(*)(IClientEntity*)>(owner_weapon, 395, 0)(owner_weapon);
|
||||||
if (my_slot != owner_slot) {
|
if (g_pLocalPlayer->clazz == tf_medic && always_medigun) {
|
||||||
g_IEngine->ExecuteClientCmd(format("slot", owner_slot + 1).c_str());
|
if (my_slot != 1) {
|
||||||
|
g_IEngine->ExecuteClientCmd("slot2");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (my_slot != owner_slot) {
|
||||||
|
g_IEngine->ExecuteClientCmd(format("slot", owner_slot + 1).c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FIXME proper classes
|
// FIXME proper classes
|
||||||
@ -131,22 +276,37 @@ void DoWalking() {
|
|||||||
last_slot_check = g_GlobalVars->curtime;
|
last_slot_check = g_GlobalVars->curtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found_entity->IsVisible()) {
|
if (destination_point_time > g_GlobalVars->curtime) destination_point_time = 0.0f;
|
||||||
if (!lost_time) {
|
|
||||||
lost_time = g_GlobalVars->curtime;
|
if (!destination_reached && (g_GlobalVars->curtime - destination_point_time < 5.0f)) {
|
||||||
|
WalkTo(destination_point);
|
||||||
|
last_direction = destination_point;
|
||||||
|
if (g_pLocalPlayer->v_Origin.DistTo(destination_point) < 50.0f) destination_reached = true;
|
||||||
|
} else if (following_idx) {
|
||||||
|
if (allow_moving) {
|
||||||
|
if (!found_entity->IsVisible()) {
|
||||||
|
if (!lost_time) {
|
||||||
|
lost_time = g_GlobalVars->curtime;
|
||||||
|
}
|
||||||
|
if (g_GlobalVars->curtime - lost_time < 2.0f) {
|
||||||
|
WalkTo(last_direction);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lost_time = 0;
|
||||||
|
if (found_entity->m_vecOrigin.DistTo(LOCAL_E->m_vecOrigin) > 150.0f) {
|
||||||
|
WalkTo(found_entity->m_vecOrigin);
|
||||||
|
}
|
||||||
|
last_direction = found_entity->m_vecOrigin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (g_GlobalVars->curtime - lost_time < 2.0f) {
|
}
|
||||||
WalkTo(last_direction);
|
|
||||||
}
|
if (following_idx) {
|
||||||
} else {
|
|
||||||
lost_time = 0;
|
|
||||||
if (found_entity->m_vecOrigin.DistTo(LOCAL_E->m_vecOrigin) > 150.0f) {
|
if (found_entity->m_vecOrigin.DistTo(LOCAL_E->m_vecOrigin) > 150.0f) {
|
||||||
if (LOCAL_E->m_vecOrigin.DistTo(found_entity->m_vecOrigin) > 350.0f) {
|
if (LOCAL_E->m_vecOrigin.DistTo(found_entity->m_vecOrigin) > 350.0f) {
|
||||||
if (g_pLocalPlayer->bZoomed) g_pUserCmd->buttons |= IN_ATTACK2;
|
if (g_pLocalPlayer->bZoomed) g_pUserCmd->buttons |= IN_ATTACK2;
|
||||||
}
|
}
|
||||||
WalkTo(found_entity->m_vecOrigin);
|
|
||||||
}
|
}
|
||||||
last_direction = found_entity->m_vecOrigin;
|
|
||||||
if (CE_INT(found_entity, netvar.iClass) == tf_heavy && g_pLocalPlayer->clazz == tf_heavy) {
|
if (CE_INT(found_entity, netvar.iClass) == tf_heavy && g_pLocalPlayer->clazz == tf_heavy) {
|
||||||
if (HasCondition(found_entity, TFCond_Slowed)) {
|
if (HasCondition(found_entity, TFCond_Slowed)) {
|
||||||
g_pUserCmd->buttons |= IN_ATTACK2;
|
g_pUserCmd->buttons |= IN_ATTACK2;
|
||||||
|
@ -10,6 +10,9 @@
|
|||||||
|
|
||||||
class CatCommand;
|
class CatCommand;
|
||||||
class CatVar;
|
class CatVar;
|
||||||
|
class CachedEntity;
|
||||||
|
|
||||||
|
#include "../ipc.h"
|
||||||
|
|
||||||
namespace hacks { namespace shared { namespace followbot {
|
namespace hacks { namespace shared { namespace followbot {
|
||||||
|
|
||||||
@ -21,8 +24,11 @@ extern CatVar bot;
|
|||||||
extern unsigned follow_steamid;
|
extern unsigned follow_steamid;
|
||||||
extern int following_idx;
|
extern int following_idx;
|
||||||
|
|
||||||
|
bool IsBot(CachedEntity* entity);
|
||||||
void DoWalking();
|
void DoWalking();
|
||||||
void PrintDebug();
|
void PrintDebug();
|
||||||
|
void AddMessageHandlers(ipc::peer_t* peer);
|
||||||
|
void AfterCreateMove();
|
||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ void CreateMove() {
|
|||||||
if (crit && !IsPlayerCritBoosted(LOCAL_E)) {
|
if (crit && !IsPlayerCritBoosted(LOCAL_E)) {
|
||||||
g_pUserCmd->buttons &= ~IN_ATTACK;
|
g_pUserCmd->buttons &= ~IN_ATTACK;
|
||||||
}
|
}
|
||||||
} else if (((GetWeaponMode(LOCAL_E) == weapon_melee && crit_melee) || crit_hack) && RandomCrits() && WeaponCanCrit()) {
|
} else if (((GetWeaponMode(LOCAL_E) == weapon_melee && crit_melee) || crit_hack) && RandomCrits() && WeaponCanCrit() && (g_pLocalPlayer->weapon()->m_iClassID != g_pClassID->CTFKnife)) {
|
||||||
if (!crit) g_pUserCmd->buttons &= ~IN_ATTACK;
|
if (!crit) g_pUserCmd->buttons &= ~IN_ATTACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,6 +636,34 @@ relation GetRelation(CachedEntity* ent) {
|
|||||||
return relation::NEUTRAL;
|
return relation::NEUTRAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WhatIAmLookingAt(int* result_eindex, Vector* result_pos) {
|
||||||
|
Ray_t ray;
|
||||||
|
trace::g_pFilterDefault->SetSelf(RAW_ENT(g_pLocalPlayer->entity));
|
||||||
|
Vector forward;
|
||||||
|
float sp, sy, cp, cy;
|
||||||
|
QAngle angle;
|
||||||
|
g_IEngine->GetViewAngles(angle);
|
||||||
|
sy = sinf(DEG2RAD(angle[1]));
|
||||||
|
cy = cosf(DEG2RAD(angle[1]));
|
||||||
|
sp = sinf(DEG2RAD(angle[0]));
|
||||||
|
cp = cosf(DEG2RAD(angle[0]));
|
||||||
|
forward.x = cp * cy;
|
||||||
|
forward.y = cp * sy;
|
||||||
|
forward.z = -sp;
|
||||||
|
forward = forward * 8192.0f + g_pLocalPlayer->v_Eye;
|
||||||
|
ray.Init(g_pLocalPlayer->v_Eye, forward);
|
||||||
|
trace_t trace;
|
||||||
|
g_ITrace->TraceRay(ray, 0x4200400B, trace::g_pFilterDefault, &trace);
|
||||||
|
if (result_pos)
|
||||||
|
*result_pos = trace.endpos;
|
||||||
|
if (result_eindex) {
|
||||||
|
*result_eindex = 0;
|
||||||
|
}
|
||||||
|
if (trace.m_pEnt && result_eindex) {
|
||||||
|
*result_eindex = ((IClientEntity*)(trace.m_pEnt))->entindex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool IsSentryBuster(CachedEntity* entity) {
|
bool IsSentryBuster(CachedEntity* entity) {
|
||||||
return (entity->m_Type == EntityType::ENTITY_PLAYER &&
|
return (entity->m_Type == EntityType::ENTITY_PLAYER &&
|
||||||
CE_INT(entity, netvar.iClass) == tf_class::tf_demoman &&
|
CE_INT(entity, netvar.iClass) == tf_class::tf_demoman &&
|
||||||
|
@ -83,6 +83,8 @@ void ReplaceString(char* target, char* what, char* with_what);
|
|||||||
// TODO move that to weaponid.h
|
// TODO move that to weaponid.h
|
||||||
bool IsAmbassador(CachedEntity* ent);
|
bool IsAmbassador(CachedEntity* ent);
|
||||||
|
|
||||||
|
void WhatIAmLookingAt(int* result_eindex, Vector* result_pos);
|
||||||
|
|
||||||
void Patch(void* address, void* patch, size_t length);
|
void Patch(void* address, void* patch, size_t length);
|
||||||
|
|
||||||
void AimAt(Vector origin, Vector target, CUserCmd* cmd);
|
void AimAt(Vector origin, Vector target, CUserCmd* cmd);
|
||||||
|
@ -128,7 +128,7 @@ bool CreateMove_hook(void* thisptr, float inputSample, CUserCmd* cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (found_entity && CE_GOOD(found_entity)) {
|
if (found_entity && CE_GOOD(found_entity)) {
|
||||||
if (jointeam && team_joining_state == 1 && (g_GlobalVars->curtime - last_jointeam_try) > 1.0f) {
|
if (jointeam && (g_GlobalVars->curtime - last_jointeam_try) > 1.0f) {
|
||||||
last_jointeam_try = g_GlobalVars->curtime;
|
last_jointeam_try = g_GlobalVars->curtime;
|
||||||
switch (CE_INT(found_entity, netvar.iTeamNum)) {
|
switch (CE_INT(found_entity, netvar.iTeamNum)) {
|
||||||
case TEAM_RED:
|
case TEAM_RED:
|
||||||
@ -220,7 +220,7 @@ bool CreateMove_hook(void* thisptr, float inputSample, CUserCmd* cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CE_GOOD(g_pLocalPlayer->entity) && !g_pLocalPlayer->life_state) {
|
if (CE_GOOD(g_pLocalPlayer->entity) && !g_pLocalPlayer->life_state) {
|
||||||
SAFE_CALL(hacks::shared::followbot::DoWalking());
|
SAFE_CALL(hacks::shared::followbot::AfterCreateMove());
|
||||||
}
|
}
|
||||||
if (cmd)
|
if (cmd)
|
||||||
g_Settings.last_angles = cmd->viewangles;
|
g_Settings.last_angles = cmd->viewangles;
|
||||||
|
35
src/ipc.cpp
35
src/ipc.cpp
@ -12,16 +12,6 @@
|
|||||||
|
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|
||||||
void CommandCallback(cat_ipc::command_s& command, void* payload) {
|
|
||||||
if (!strcmp("exec", (const char*)command.cmd_data) && payload) {
|
|
||||||
//std::lock_guard<std::mutex> lock(hack::command_stack_mutex);
|
|
||||||
hack::command_stack().push(std::string((const char*)payload));
|
|
||||||
} else if (!strcmp("owner", (const char*)command.cmd_data) && payload) {
|
|
||||||
logging::Info("Bot owner set to %ld", *(unsigned*)payload);
|
|
||||||
hacks::shared::followbot::follow_steamid = *(unsigned*)payload;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::atomic<bool> thread_running(false);
|
std::atomic<bool> thread_running(false);
|
||||||
pthread_t listener_thread { 0 };
|
pthread_t listener_thread { 0 };
|
||||||
|
|
||||||
@ -52,11 +42,17 @@ CatCommand connect("ipc_connect", "Connect to IPC server", []() {
|
|||||||
logging::Info("peer count: %i", peer->memory->peer_count);
|
logging::Info("peer count: %i", peer->memory->peer_count);
|
||||||
logging::Info("magic number: 0x%08x", peer->memory->global_data.magic_number);
|
logging::Info("magic number: 0x%08x", peer->memory->global_data.magic_number);
|
||||||
logging::Info("magic number offset: 0x%08x", (uintptr_t)&peer->memory->global_data.magic_number - (uintptr_t)peer->memory);
|
logging::Info("magic number offset: 0x%08x", (uintptr_t)&peer->memory->global_data.magic_number - (uintptr_t)peer->memory);
|
||||||
peer->SetCallback(CommandCallback);
|
peer->SetCommandHandler(commands::execute_client_cmd, [](cat_ipc::command_s& command, void* payload) {
|
||||||
|
hack::command_stack().push(std::string((const char*)&command.cmd_data));
|
||||||
|
});
|
||||||
|
peer->SetCommandHandler(commands::execute_client_cmd_long, [](cat_ipc::command_s& command, void* payload) {
|
||||||
|
hack::command_stack().push(std::string((const char*)payload));
|
||||||
|
});
|
||||||
|
hacks::shared::followbot::AddMessageHandlers(peer);
|
||||||
StoreClientData();
|
StoreClientData();
|
||||||
thread_running = true;
|
thread_running = true;
|
||||||
pthread_create(&listener_thread, nullptr, listen, nullptr);
|
pthread_create(&listener_thread, nullptr, listen, nullptr);
|
||||||
} catch (std::runtime_error& error) {
|
} catch (std::exception& error) {
|
||||||
logging::Info("Runtime error: %s", error.what());
|
logging::Info("Runtime error: %s", error.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,10 +83,21 @@ CatCommand exec("ipc_exec", "Execute command (first argument = bot ID)", [](cons
|
|||||||
}
|
}
|
||||||
std::string command = std::string(args.ArgS());
|
std::string command = std::string(args.ArgS());
|
||||||
command = command.substr(command.find(' ', 0) + 1);
|
command = command.substr(command.find(' ', 0) + 1);
|
||||||
peer->SendMessage("exec", (1 << target_id), command.c_str(), command.length() + 1);
|
ReplaceString(command, " && ", " ; ");
|
||||||
|
if (command.length() >= 63) {
|
||||||
|
peer->SendMessage(0, (1 << target_id), ipc::commands::execute_client_cmd_long, command.c_str(), command.length() + 1);
|
||||||
|
} else {
|
||||||
|
peer->SendMessage(command.c_str(), (1 << target_id), ipc::commands::execute_client_cmd, 0, 0);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
CatCommand exec_all("ipc_exec_all", "Execute command (on every peer)", [](const CCommand& args) {
|
CatCommand exec_all("ipc_exec_all", "Execute command (on every peer)", [](const CCommand& args) {
|
||||||
peer->SendMessage("exec", 0, args.ArgS(), strlen(args.ArgS()) + 1);
|
std::string command = args.ArgS();
|
||||||
|
ReplaceString(command, " && ", " ; ");
|
||||||
|
if (command.length() >= 63) {
|
||||||
|
peer->SendMessage(0, 0, ipc::commands::execute_client_cmd_long, command.c_str(), command.length() + 1);
|
||||||
|
} else {
|
||||||
|
peer->SendMessage(command.c_str(), 0, ipc::commands::execute_client_cmd, 0, 0);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
CatVar server_name(CV_STRING, "ipc_server", "cathook_followbot_server", "IPC server name");
|
CatVar server_name(CV_STRING, "ipc_server", "cathook_followbot_server", "IPC server name");
|
||||||
|
|
||||||
|
13
src/ipc.h
13
src/ipc.h
@ -8,14 +8,27 @@
|
|||||||
#ifndef IPC_H_
|
#ifndef IPC_H_
|
||||||
#define IPC_H_
|
#define IPC_H_
|
||||||
|
|
||||||
|
#include "beforecheaders.h"
|
||||||
#include "ipcb.hpp"
|
#include "ipcb.hpp"
|
||||||
#include "pthread.h"
|
#include "pthread.h"
|
||||||
|
#include "aftercheaders.h"
|
||||||
|
|
||||||
class CatCommand;
|
class CatCommand;
|
||||||
class CatVar;
|
class CatVar;
|
||||||
|
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|
||||||
|
namespace commands {
|
||||||
|
|
||||||
|
constexpr unsigned execute_client_cmd = 1;
|
||||||
|
constexpr unsigned set_follow_steamid = 2;
|
||||||
|
constexpr unsigned execute_client_cmd_long = 3;
|
||||||
|
constexpr unsigned move_to_vector = 4;
|
||||||
|
constexpr unsigned stop_moving = 5;
|
||||||
|
constexpr unsigned start_moving = 6;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
extern CatCommand connect;
|
extern CatCommand connect;
|
||||||
extern CatCommand disconnect;
|
extern CatCommand disconnect;
|
||||||
extern CatCommand exec;
|
extern CatCommand exec;
|
||||||
|
@ -12,6 +12,7 @@ void LocalPlayer::Update() {
|
|||||||
entity_idx = g_IEngine->GetLocalPlayer();
|
entity_idx = g_IEngine->GetLocalPlayer();
|
||||||
entity = ENTITY(entity_idx);
|
entity = ENTITY(entity_idx);
|
||||||
if (CE_BAD(entity)) {
|
if (CE_BAD(entity)) {
|
||||||
|
team = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
team = CE_INT(entity, netvar.iTeamNum);
|
team = CE_INT(entity, netvar.iTeamNum);
|
||||||
|
Reference in New Issue
Block a user