Add huge copypasted working aimbot mess (#11)

* Add huge copypasted working aimbot mess

* remove unnecessary dependency on execution

* remove bad code
This commit is contained in:
F1ssi0N 2018-03-14 21:03:43 +00:00 committed by GitHub
parent 3c3040c69c
commit b3f7031cf1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 424 additions and 3 deletions

View File

@ -6,6 +6,8 @@
#include "sdk/log.hh"
#include "sdk/player.hh"
#include "modules/aimbot.hh"
using namespace sdk;
namespace create_move {
@ -51,19 +53,20 @@ bool hooked_create_move(void *instance, float sample_framerate, UserCmd *user_cm
auto local_player = Player::local();
if (local_player == nullptr) return true;
// TODO: remove
Log::msg("tick: %d", user_cmd->tick_count);
// TODO: call original
// Currently possible but the method is slow
// Fixme in HookFunction!
// Do create_move_pre_predict()
aimbot::create_move_pre_predict(user_cmd);
local_player_prediction(local_player, user_cmd);
// Do create_move()
aimbot::create_move(user_cmd);
return false;
}

375
src/modules/aimbot.cc Normal file
View File

@ -0,0 +1,375 @@
#include <precompiled.hh>
#include "aimbot.hh"
// TODO:
//#include "backtrack.hh"
#include "sdk/class_id.hh"
#include "sdk/entity.hh"
#include "sdk/interface.hh"
#include "sdk/player.hh"
#include "sdk/sdk.hh"
#include "sdk/weapon.hh"
#include "sdk/convar.hh"
#include "sdk/log.hh"
#include "utils/math.hh"
#include <algorithm>
using namespace sdk;
namespace aimbot {
using Target = std::pair<Entity *, math::Vector>;
std::vector<Target> targets;
u32 next_index;
Player *local_player;
Weapon *local_weapon;
bool can_find_targets = false;
int local_team;
math::Vector local_view;
// TODO: HORRIBLE HACK
// this needs to be done on a per target basis and not like this !!!
u32 cmd_delta = 0;
// Check it a point is visible to the player
static auto visible_no_entity(const math::Vector &position) {
trace::TraceResult result;
trace::Ray ray;
trace::Filter f(local_player);
ray.init(local_view, position);
IFace<Trace>()->trace_ray(ray, 0x46004003, &f, &result);
return result.fraction == 1.0f;
}
static auto doghook_aimbot_pedantic_mode = Convar<bool>{"doghook_aimbot_pedantic_mode", true, nullptr};
static auto visible(Entity *e, const math::Vector &position, const int hitbox) {
trace::TraceResult result;
trace::Ray ray;
trace::Filter f(local_player);
ray.init(local_view, position);
IFace<Trace>()->trace_ray(ray, 0x46004003, &f, &result);
if (doghook_aimbot_pedantic_mode == true) {
if (result.entity == e && result.hitbox == hitbox) return true;
} else if (result.entity == e) {
return true;
}
return false;
}
static auto multipoint_internal(Entity *e, float granularity, const int hitbox, const math::Vector &centre, const math::Vector &min, const math::Vector &max, math::Vector &out) {
// go from centre to centre min first
for (float i = 0.0f; i <= 1.0f; i += granularity) {
math::Vector point = centre.lerp(min, i);
if (visible(e, point, hitbox)) {
out = point;
return true;
}
}
// now from centre to max
for (float i = 0.0f; i <= 1.0f; i += granularity) {
math::Vector point = centre.lerp(max, i);
if (visible(e, point, hitbox)) {
out = point;
return true;
}
}
return false;
}
// TODO: remove
static auto doghook_aimbot_multipoint_granularity = Convar<float>{"doghook_aimbot_multipoint_granularity", 0, 0, 10, nullptr};
// TODO: there must be some kind of better conversion we can use here to get a straight line across the hitbox
static auto multipoint(Player *player, const int hitbox, const math::Vector &centre, const math::Vector &min, const math::Vector &max, math::Vector &position_out) -> bool {
// create a divisor out of the granularity
float divisor = doghook_aimbot_multipoint_granularity;
if (divisor == 0) return false;
float granularity = 1.0f / divisor;
auto new_x = math::lerp(0.5, min.x, max.x);
// Create a horizontal cross shape out of this box instead of top left bottom right or visa versa
math::Vector centre_min_x = math::Vector(new_x, min.y, centre.z);
math::Vector centre_max_x = math::Vector(new_x, max.y, centre.z);
if (multipoint_internal(player, granularity, hitbox, centre, centre_min_x, centre_max_x, position_out) == true)
return true;
math::Vector centre_min_y = math::Vector(min.x, math::lerp(0.5, min.y, max.y), centre.z);
math::Vector centre_max_y = math::Vector(max.x, math::lerp(0.5, min.y, max.y), centre.z);
if (multipoint_internal(player, granularity, hitbox, centre, centre_min_y, centre_max_y, position_out) == true)
return true;
return false;
}
static auto find_best_box() {
auto tf_class = local_player->tf_class();
auto weapon_class_id = local_weapon->client_class()->class_id;
switch (tf_class) {
case 2: // sniper
if (weapon_class_id == 305) return std::make_pair(0, true); // aim head with the rifle
default:
return std::make_pair(3, false); // chest
}
}
static auto doghook_aimbot_enable_backtrack = Convar<bool>{"doghook_aimbot_enable_backtrack", true, nullptr};
auto visible_target(Entity *e, math::Vector &pos, bool &visible) {
// TODO: should entity have a to_player_nocheck() method
// as we already know at this point that this is a player...
auto player = e->to_player();
PlayerHitboxes hitboxes;
auto hitboxes_count = player->hitboxes(&hitboxes, false);
// Tell backtrack about these hitboxes
//Backtrack::update_player_hitboxes(player, &hitboxes, hitboxes_count);
auto current_tick = IFace<Globals>()->tickcount;
// TODO: This can probably be expressed much better
auto delta = 0;
//while (delta < Backtrack::max_ticks) {
cmd_delta = delta;
// TODO: there must be a better way to do this...
//if (delta > 0) Backtrack::get_hitboxes_for_player_at_tick(player, current_tick - delta, &hitboxes);
auto best_box = find_best_box();
// check best hitbox first
if (aimbot::visible(e, hitboxes.centre[best_box.first], best_box.first)) {
pos = hitboxes.centre[best_box.first];
visible = true;
return;
} else if (multipoint(player, best_box.first, hitboxes.centre[best_box.first], hitboxes.min[best_box.first], hitboxes.max[best_box.first], pos)) {
visible = true;
return;
}
// .second is whether we should only check the best box
if (best_box.second != true) {
for (u32 i = 0; i < hitboxes_count; i++) {
if (aimbot::visible(e, hitboxes.centre[i], i)) {
pos = hitboxes.centre[i];
visible = true;
return;
}
}
// Perform multiboxing after confirming that we do not have any other options
for (u32 i = 0; i < hitboxes_count; i++) {
if (multipoint(player, i, hitboxes.centre[i], hitboxes.min[i], hitboxes.max[i], std::ref(pos))) {
visible = true;
return;
}
}
}
// If we dont want to do backtracking, escape
//if (doghook_aimbot_enable_backtrack == false) break;
// Backtrack to the previous tick
// backtrack_player_to_tick will return false if the player is dead at this tick
// so we need to keep trying until we hit the max or we find an alive state
// auto success = false;
// do {
// delta += 1;
// success = Backtrack::backtrack_player_to_tick(player, current_tick - delta);
// } while (success == false && delta < Backtrack::max_ticks);
//}
visible = false;
return;
}
auto valid_target(Entity *e, bool &valid) {
if (can_find_targets == false) {
valid = false;
return;
}
if (auto player = e->to_player()) {
if (player->alive() == false) return;
if (local_team == player->team()) return;
valid = true;
}
return;
}
auto flush_targets() {
next_index = 0;
// deal with some local data that we want to keep around
local_player = Player::local();
assert(local_player);
local_weapon = local_player->active_weapon()->to_weapon();
local_team = local_player->team();
local_view = local_player->view_position();
// If we dont have the necessary information (we havent spawned yet or are dead)
// then do not attempt to find targets.
can_find_targets = local_weapon != nullptr;
targets.clear();
targets.resize(IFace<EntList>()->max_entity_index());
}
auto finished_target(Target t) -> void {
assert(t.first != nullptr);
IFace<DebugOverlay>()->add_entity_text_overlay(t.first->index(), 2, 0, 255, 255, 255, 255, "finished");
targets[next_index] = t;
next_index += 1;
}
void sort_targets() {
std::sort(targets.begin(), targets.end(),
[](const Target &a, const Target &b) {
// Ignore null targets (artifact of having a resized vector mess
if (a.first == nullptr) return false;
if (b.first == nullptr) return false;
return a.second.distance(local_view) < b.second.distance(local_view);
});
}
// TODO: move this outside of aimbot
// Other modules may mess the angles up aswell
// So our best bet is to run this at the end of createmove...
inline static auto clamp_angle(const math::Vector &angles) {
math::Vector out;
out.x = angles.x;
out.y = angles.y;
out.z = 0;
while (out.x > 89.0f) out.x -= 180.0f;
while (out.x < -89.0f) out.x += 180.0f;
while (out.y > 180.0f) out.y -= 360.0f;
while (out.y < -180.0f) out.y += 360.0f;
out.y = std::clamp(out.y, -180.0f, 180.0f);
out.x = std::clamp(out.x, -90.0f, 90.0f);
return out;
}
inline static auto fix_movement_for_new_angles(const math::Vector &movement, const math::Vector &old_angles, const math::Vector &new_angles) {
math::Matrix3x4 rotate_matrix;
auto delta_angles = new_angles - old_angles;
delta_angles = clamp_angle(delta_angles);
rotate_matrix.from_angle(delta_angles);
return rotate_matrix.rotate_vector(movement);
}
// TODO: something something zoomed only convar
static auto try_autoshoot(sdk::UserCmd *cmd) {
auto autoshoot_allowed = false;
// Only allow autoshoot when we are zoomed and can get headshots
if (local_weapon->client_class()->class_id == sdk::class_id::CTFSniperRifle && (local_player->cond() & 2)) {
if ((local_player->tick_base() * IFace<Globals>()->interval_per_tick - local_player->fov_time()) >= 0.2)
autoshoot_allowed = true;
}
if (autoshoot_allowed) cmd->buttons |= 1;
}
static auto doghook_aimbot_silent = Convar<bool>{"doghook_aimbot_silent", true, nullptr};
static auto doghook_aimbot_autoshoot = Convar<bool>{"doghook_aimbot_autoshoot", true, nullptr};
static auto doghook_aimbot_aim_if_not_attack = Convar<bool>{"doghook_aimbot_aim_if_not_attack", true, nullptr};
static auto doghook_aimbot_disallow_attack_if_no_target = Convar<bool>{"doghook_aimbot_disallow_attack_if_no_target", false, nullptr};
void create_move(sdk::UserCmd *cmd) {
flush_targets();
if (local_weapon == nullptr) return;
// find targets
// TODO: clean up this mess
for (auto e : IFace<EntList>()->get_range()) {
if (e->is_valid() == false) continue;
if (e->dormant() == true) continue;
auto is_valid = false;
aimbot::valid_target(e, is_valid);
if (is_valid) {
auto is_visible = false;
auto pos = math::Vector::invalid();
aimbot::visible_target(e, pos, is_visible);
if (is_visible) aimbot::finished_target(Target{e, pos});
}
}
aimbot::sort_targets();
if (doghook_aimbot_aim_if_not_attack != true) {
// check if we are IN_ATTACK
if ((cmd->buttons & 1) != 1) return;
}
if (targets.size() > 0 && targets[0].first != nullptr) {
IFace<DebugOverlay>()->add_box_overlay(targets[0].second, {-2, -2, -2}, {2, 2, 2}, {0, 0, 0}, 255, 255, 0, 100, 0);
math::Vector delta = targets[0].second - local_view;
math::Vector new_angles = delta.to_angle();
new_angles = clamp_angle(new_angles);
math::Vector new_movement = fix_movement_for_new_angles({cmd->forwardmove, cmd->sidemove, 0}, cmd->viewangles, new_angles);
if (local_weapon->can_shoot(local_player->tick_base())) {
cmd->viewangles = new_angles;
if (doghook_aimbot_autoshoot == true) try_autoshoot(cmd);
cmd->forwardmove = new_movement.x;
cmd->sidemove = new_movement.y;
cmd->tick_count -= cmd_delta;
}
if (doghook_aimbot_silent == false) IFace<Engine>()->set_view_angles(new_angles);
} else {
if (doghook_aimbot_disallow_attack_if_no_target == true) cmd->buttons &= ~1;
}
}
void create_move_pre_predict(sdk::UserCmd *cmd) {
}
} // namespace aimbot

12
src/modules/aimbot.hh Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include "sdk/sdk.hh"
namespace aimbot {
void init_all();
void update(float frametime);
void create_move(sdk::UserCmd *cmd);
void create_move_pre_predict(sdk::UserCmd *cmd);
}; // namespace aimbot

27
src/sdk/trace.cc Normal file
View File

@ -0,0 +1,27 @@
#include <precompiled.hh>
#include "trace.hh"
#include "sdk.hh"
auto trace::Filter::should_hit_entity(sdk::Entity *handle_entity, int contents_mask) -> bool {
auto handle = handle_entity->to_handle();
auto real_entity = IFace<sdk::EntList>()->from_handle(handle);
if (real_entity == nullptr) return false;
auto client_class = real_entity->client_class();
// ignore "bad" entities
switch (client_class->class_id) {
case 64: // CFuncRespawnRoomVisualizer
case 230: // CTFMedigunShield
case 55: // CFuncAreaPortalWindow
return false;
}
if (real_entity == ignore_self ||
real_entity == ignore_entity) return false;
return true;
}

View File

@ -2,6 +2,10 @@
#include "platform.hh"
namespace sdk {
class Entity;
}
namespace trace {
class VectorAligned : public math::Vector {
float pad;