Better enemy detection for aimbot (#3527)

* Added better enemy detection to aimbot and triggerbot.

* Fixed aimbot and triggerbot using an unreliable method of determining the target's current vehicle.

* Fixed aimbot and triggerbot trying to go after targets that were untargetable.

* Refactored is_ped_a_friend function.

* Added threat check to aimbot.
This commit is contained in:
gir489 2024-08-10 19:11:56 -04:00 committed by GitHub
parent 12906d0365
commit 20da24e626
12 changed files with 728 additions and 668 deletions

View File

@ -6,6 +6,7 @@
#include "util/pools.hpp" #include "util/pools.hpp"
#include "services/friends/friends_service.hpp" #include "services/friends/friends_service.hpp"
#include "services/player_database/player_database_service.hpp" #include "services/player_database/player_database_service.hpp"
#include "util/ped.hpp"
namespace big namespace big
{ {
@ -15,6 +16,9 @@ namespace big
bool_command g_aimbot_only_on_enemy("aimonlyatenemy", "BACKEND_LOOPED_WEAPONS_AIM_ONLY_AT_ENEMY", "BACKEND_LOOPED_WEAPONS_AIM_ONLY_AT_ENEMY_DESC", bool_command g_aimbot_only_on_enemy("aimonlyatenemy", "BACKEND_LOOPED_WEAPONS_AIM_ONLY_AT_ENEMY", "BACKEND_LOOPED_WEAPONS_AIM_ONLY_AT_ENEMY_DESC",
g.weapons.aimbot.only_on_enemy); g.weapons.aimbot.only_on_enemy);
bool_command g_aimbot_only_on_threat("aimonlyatthreats", "BACKEND_LOOPED_WEAPONS_AIM_ONLY_AT_THREATS", "BACKEND_LOOPED_WEAPONS_AIM_ONLY_AT_THREATS_DESC",
g.weapons.aimbot.only_on_enemy);
class aimbot : looped_command class aimbot : looped_command
{ {
using looped_command::looped_command; using looped_command::looped_command;
@ -144,12 +148,17 @@ namespace big
continue; continue;
} }
const auto ped_handle = g_pointers->m_gta.m_ptr_to_handle(ped);
const bool is_not_a_player_and_we_target_only_players = g_aimbot_only_on_player.is_enabled() && !ped->m_player_info; const bool is_not_a_player_and_we_target_only_players = g_aimbot_only_on_player.is_enabled() && !ped->m_player_info;
const bool we_in_the_same_vehicle = self::veh != 0 && ped->m_vehicle == g_player_service->get_self()->get_current_vehicle(); const bool are_we_in_the_same_vehicle = self::veh != 0 && self::veh == PED::GET_VEHICLE_PED_IS_IN(ped_handle, TRUE);
if (is_not_a_player_and_we_target_only_players || we_in_the_same_vehicle) if (is_not_a_player_and_we_target_only_players || are_we_in_the_same_vehicle)
{ {
continue; continue;
} }
auto weapon_info = g_local_player->m_weapon_manager->m_weapon_info;
if (PED::GET_PED_CONFIG_FLAG(ped_handle, 9, TRUE) || !g_pointers->m_gta.m_can_do_damage_to_ped(g_local_player, weapon_info, ped)) //Can't do damage to them, skip.
continue;
if (g.weapons.aimbot.exclude_friends && ped->m_player_info) if (g.weapons.aimbot.exclude_friends && ped->m_player_info)
{ {
@ -162,29 +171,14 @@ namespace big
continue; continue;
} }
const auto ped_handle = g_pointers->m_gta.m_ptr_to_handle(ped); if (g_aimbot_only_on_enemy.is_enabled() && ped::is_ped_a_friend(ped_handle, ped))
if (g_aimbot_only_on_enemy.is_enabled())
{ {
bool is_hated_relationship = false; continue;
bool is_in_combat = PED::IS_PED_IN_COMBAT(ped_handle, self::ped); }
auto blip_color = HUD::GET_BLIP_HUD_COLOUR(HUD::GET_BLIP_FROM_ENTITY(ped_handle));
bool is_enemy = ((PED::GET_PED_CONFIG_FLAG(ped_handle, 38, TRUE) == TRUE) || (blip_color == HUD_COLOUR_RED));
switch (PED::GET_RELATIONSHIP_BETWEEN_PEDS(ped_handle, self::ped)) if (g.weapons.aimbot.only_on_threats && WEAPON::HAS_PED_GOT_WEAPON(ped_handle, 1, 1) == FALSE)
{ {
case Dislike: continue;
case Wanted:
case Hate: is_hated_relationship = blip_color != HUD_COLOUR_BLUE;
}
if (!is_hated_relationship && !is_in_combat && !is_enemy)
{
continue;
}
/*if (PED::GET_PED_TYPE(ped_handle) != PED_TYPE_ANIMAL)
LOG(INFO) << " PED_TYPE " << PED::GET_PED_TYPE(ped_handle) << " hated " << is_hated_relationship << " combat " << is_in_combat << " enemy " << is_enemy << " blip_color " << blip_color;*/
} }
if (is_a_ped_type_we_dont_care_about(ped_handle)) if (is_a_ped_type_we_dont_care_about(ped_handle))

View File

@ -4,6 +4,7 @@
#include "util/entity.hpp" #include "util/entity.hpp"
#include "services/friends/friends_service.hpp" #include "services/friends/friends_service.hpp"
#include "services/player_database/player_database_service.hpp" #include "services/player_database/player_database_service.hpp"
#include "util/ped.hpp"
namespace big namespace big
{ {
@ -31,12 +32,16 @@ namespace big
return; return;
const bool trace_hit_non_player = g.weapons.aimbot.only_on_player && !ped_ptr->m_player_info; const bool trace_hit_non_player = g.weapons.aimbot.only_on_player && !ped_ptr->m_player_info;
const bool we_in_the_same_vehicle = self::veh != 0 && ped_ptr->m_vehicle == g_player_service->get_self()->get_current_vehicle(); const bool are_we_in_the_same_vehicle = self::veh != 0 && self::veh == PED::GET_VEHICLE_PED_IS_IN(ped, TRUE);
if (trace_hit_non_player || we_in_the_same_vehicle) if (trace_hit_non_player || are_we_in_the_same_vehicle)
{ {
return; return;
} }
auto weapon_info = g_local_player->m_weapon_manager->m_weapon_info;
if (PED::GET_PED_CONFIG_FLAG(ped, 9, TRUE) || !g_pointers->m_gta.m_can_do_damage_to_ped(g_local_player, weapon_info, ped_ptr)) //Can't do damage to them, skip.
return;
if (g.weapons.aimbot.exclude_friends && ped_ptr->m_player_info) if (g.weapons.aimbot.exclude_friends && ped_ptr->m_player_info)
{ {
auto rockstar_id = ped_ptr->m_player_info->m_net_player_data.m_gamer_handle.m_rockstar_id; auto rockstar_id = ped_ptr->m_player_info->m_net_player_data.m_gamer_handle.m_rockstar_id;
@ -48,24 +53,14 @@ namespace big
return; return;
} }
if (g.weapons.aimbot.only_on_enemy) if (g.weapons.aimbot.only_on_enemy && ped::is_ped_a_friend(ped, ped_ptr))
{ {
bool is_hated_relationship = false; return;
bool is_in_combat = PED::IS_PED_IN_COMBAT(ped, self::ped); }
auto blip_color = HUD::GET_BLIP_HUD_COLOUR(HUD::GET_BLIP_FROM_ENTITY(ped));
bool is_enemy = ((PED::GET_PED_CONFIG_FLAG(ped, 38, TRUE) == TRUE) || (blip_color == HUD_COLOUR_RED));
switch (PED::GET_RELATIONSHIP_BETWEEN_PEDS(ped, self::ped)) if (g.weapons.aimbot.only_on_threats && WEAPON::HAS_PED_GOT_WEAPON(ped, 1, 1) == FALSE)
{ {
case Dislike: return;
case Wanted:
case Hate: is_hated_relationship = blip_color != HUD_COLOUR_BLUE;
}
if (!is_hated_relationship && !is_in_combat && !is_enemy)
{
return;
}
} }
bool is_a_ped_type_we_dont_care_about; bool is_a_ped_type_we_dont_care_about;

View File

@ -897,6 +897,7 @@ namespace big
bool only_on_player = false; bool only_on_player = false;
bool exclude_friends = false; bool exclude_friends = false;
bool only_on_enemy = false; bool only_on_enemy = false;
bool only_on_threats = false;
bool has_target = false; bool has_target = false;
bool use_weapon_range = false; bool use_weapon_range = false;
float fov = 60.f; float fov = 60.f;

View File

@ -225,4 +225,7 @@ namespace big::functions
using create_chat_guid = void (*)(GUID* guid); using create_chat_guid = void (*)(GUID* guid);
using begin_scaleform = bool (*)(uint32_t* scaleform, const char* method); using begin_scaleform = bool (*)(uint32_t* scaleform, const char* method);
using is_ped_enemies_with = bool (*)(CPedIntelligence* from, CPed* target, bool check_relationship, bool skip_friend_check, bool skip_combat_task_check);
using can_do_damage_to_ped = bool (*)(CPed* from, CWeaponInfo* current_weapon, CPed* target);
} }

View File

@ -1469,6 +1469,7 @@ enum class BlipColors
enum BlipDisplayBits : uint32_t enum BlipDisplayBits : uint32_t
{ {
BlipIsFriendly = (1 << 1),
BlipIsFlashing = (1 << 2), BlipIsFlashing = (1 << 2),
BlipIsGPSRoute = (1 << 4), BlipIsGPSRoute = (1 << 4),
BlipShowHeightMarker = (1 << 5), BlipShowHeightMarker = (1 << 5),

View File

@ -408,6 +408,9 @@ namespace big
uint32_t* m_game_lifetime; uint32_t* m_game_lifetime;
functions::begin_scaleform m_begin_scaleform; functions::begin_scaleform m_begin_scaleform;
functions::is_ped_enemies_with m_is_ped_enemies_with;
functions::can_do_damage_to_ped m_can_do_damage_to_ped;
}; };
#pragma pack(pop) #pragma pack(pop)
static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned"); static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned");

View File

@ -1940,6 +1940,24 @@ namespace big
{ {
g_pointers->m_gta.m_begin_scaleform = ptr.as<functions::begin_scaleform>(); g_pointers->m_gta.m_begin_scaleform = ptr.as<functions::begin_scaleform>();
} }
},
// Is Ped Enemies With
{
"IPEW",
"E8 ? ? ? ? 45 8A FE 84 C0",
[](memory::handle ptr)
{
g_pointers->m_gta.m_is_ped_enemies_with = ptr.add(1).rip().as<functions::is_ped_enemies_with>();
}
},
// Can Do Damage
{
"CDD",
"E8 ? ? ? ? 45 8A C4 84 C0",
[](memory::handle ptr)
{
g_pointers->m_gta.m_can_do_damage_to_ped = ptr.add(1).rip().as<functions::can_do_damage_to_ped>();
}
} }
>(); // don't leave a trailing comma at the end >(); // don't leave a trailing comma at the end

View File

@ -79,4 +79,17 @@ namespace big::blip
} }
return nullptr; return nullptr;
} }
rage::CBlip* get_blip_from_blip_id(Blip blip_id)
{
for (int i = 0; i < 1500; i++)
{
auto blip = g_pointers->m_gta.m_blip_list->m_Blips[i].m_pBlip;
if (blip && (blip->m_blip_array_index == blip_id))
{
return blip;
}
}
return nullptr;
}
} }

View File

@ -16,4 +16,6 @@ namespace big::blip
bool get_objective_location(Vector3& location); bool get_objective_location(Vector3& location);
rage::CBlip* get_selected_blip(); rage::CBlip* get_selected_blip();
rage::CBlip* get_blip_from_blip_id(Blip);
} }

195
src/util/ped.cpp Normal file
View File

@ -0,0 +1,195 @@
#include "ped.hpp"
namespace big::ped
{
bool change_player_model(const Hash hash)
{
if (entity::request_model(hash))
{
self::ped = PLAYER::PLAYER_PED_ID();
PLAYER::SET_PLAYER_MODEL(self::id, hash);
script::get_current()->yield();
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);
for (int i = 0; i < 12; i++)
{
PED::SET_PED_COMPONENT_VARIATION(self::ped, i, PED::GET_PED_DRAWABLE_VARIATION(self::ped, i), PED::GET_PED_TEXTURE_VARIATION(self::ped, i), PED::GET_PED_PALETTE_VARIATION(self::ped, i));
}
return true;
}
return false;
}
bool steal_outfit(const Ped target)
{
Ped ped = self::ped;
if (ENTITY::GET_ENTITY_MODEL(ped) != ENTITY::GET_ENTITY_MODEL(target))
{
return false;
}
for (int i = 0; i < 12; i++)
{
PED::SET_PED_COMPONENT_VARIATION(ped, i, PED::GET_PED_DRAWABLE_VARIATION(target, i), PED::GET_PED_TEXTURE_VARIATION(target, i), PED::GET_PED_PALETTE_VARIATION(target, i));
}
return true;
}
void clone_ped(const Ped src, const Ped target)
{
PED::CLONE_PED_TO_TARGET(src, target);
auto src_ptr = g_pointers->m_gta.m_handle_to_ptr(src);
auto dst_ptr = g_pointers->m_gta.m_handle_to_ptr(target);
if (src_ptr && dst_ptr)
{
for (auto container = src_ptr->m_extension_container; container; container = container->m_next)
{
if (container->m_entry && container->m_entry->get_id() == 0xB)
{
g_pointers->m_gta.m_set_head_blend_data(reinterpret_cast<CPed*>(dst_ptr),
reinterpret_cast<CHeadBlendData*>(container->m_entry));
break;
}
}
}
}
void steal_identity(const Ped target)
{
const int max_health = ENTITY::GET_ENTITY_MAX_HEALTH(self::ped);
const int current_health = ENTITY::GET_ENTITY_HEALTH(self::ped);
const int current_armor = PED::GET_PED_ARMOUR(self::ped);
if (ENTITY::GET_ENTITY_MODEL(target) != ENTITY::GET_ENTITY_MODEL(self::id))
{
PLAYER::SET_PLAYER_MODEL(self::id, ENTITY::GET_ENTITY_MODEL(target));
script::get_current()->yield();
}
clone_ped(target, self::ped);
ENTITY::SET_ENTITY_MAX_HEALTH(self::ped, max_health);
ENTITY::SET_ENTITY_HEALTH(self::ped, current_health, 0, 0);
PED::SET_PED_ARMOUR(self::ped, current_armor);
}
void kill_ped(const Ped ped)
{
if (entity::take_control_of(ped, 0))
ENTITY::SET_ENTITY_HEALTH(ped, 0, self::ped, 0);
else
{
auto ptr = g_pointers->m_gta.m_handle_to_ptr(ped);
if (!ptr)
return;
g_pointers->m_gta.m_send_network_damage(g_player_service->get_self()->get_ped(), ptr, ptr->get_position(), 0, true, "weapon_explosion"_J, 10000.0f, 2, 0, (1 << 4), 0, 0, 0, false, false, true, true, nullptr);
}
}
Ped spawn(ePedType pedType, Hash hash, Ped clone, Vector3 location, float heading, bool is_networked)
{
if (entity::request_model(hash))
{
Ped ped = PED::CREATE_PED(pedType, hash, location.x, location.y, location.z, heading, is_networked, false);
script::get_current()->yield();
if (clone)
{
clone_ped(clone, ped);
}
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);
return ped;
}
return 0;
}
void set_ped_random_component_variation(Ped ped)
{
constexpr auto range = [](int lower_bound, int upper_bound) -> int {
return std::rand() % (upper_bound - lower_bound + 1) + lower_bound;
};
outfit::components_t components;
for (auto& item : components.items)
{
int drawable_id_max = PED::GET_NUMBER_OF_PED_DRAWABLE_VARIATIONS(ped, item.id) - 1;
if (drawable_id_max == -1)
continue;
int drawable_id = range(0, drawable_id_max);
int texture_id_max = PED::GET_NUMBER_OF_PED_TEXTURE_VARIATIONS(ped, item.id, drawable_id) - 1;
if (texture_id_max == -1)
continue;
int texture_id = range(0, texture_id_max);
PED::SET_PED_COMPONENT_VARIATION(ped, item.id, drawable_id, texture_id, PED::GET_PED_PALETTE_VARIATION(ped, item.id));
}
}
player_ptr get_player_from_ped(Ped ped)
{
for (auto& p : g_player_service->players())
{
if (p.second->get_ped())
{
if (p.second->get_ped() == g_pointers->m_gta.m_handle_to_ptr(ped))
return p.second;
}
}
return nullptr;
}
bool load_animation_dict(const char* dict)
{
if (STREAMING::HAS_ANIM_DICT_LOADED(dict))
return true;
for (uint8_t i = 0; !STREAMING::HAS_ANIM_DICT_LOADED(dict) && i < 35; i++)
{
STREAMING::REQUEST_ANIM_DICT(dict);
script::get_current()->yield();
}
return STREAMING::HAS_ANIM_DICT_LOADED(dict);
}
void ped_play_animation(Ped ped, const std::string_view& animDict, const std::string_view& animName, float speed, float speedMultiplier, int duration, int flag, float playbackRate, bool lockPos, Vector3 pos, Vector3 rot, int ik_flags)
{
if (load_animation_dict(animDict.data()))
if (pos.x == 0 && pos.y == 0 && pos.z == 0)
TASK::TASK_PLAY_ANIM(ped, animDict.data(), animName.data(), speed, speedMultiplier, duration, flag, playbackRate, lockPos, lockPos, lockPos);
else
TASK::TASK_PLAY_ANIM_ADVANCED(ped, animDict.data(), animName.data(), pos.x, pos.y, pos.z, rot.x, rot.y, rot.z, speed, speedMultiplier, duration, flag, playbackRate, lockPos, ik_flags);
}
/*
* Will make the ped enter the vehicle with animation if vehicle is in vicinity
* Param movespeed: 1 = walk, 2 = run, 3 = sprint
*/
void ped_enter_vehicle_animated(Ped ped, Vehicle veh, eVehicleSeats seat, int movespeed)
{
if (entity::take_control_of(ped))
{
if (ENTITY::DOES_ENTITY_EXIST(veh))
{
if (math::distance_between_vectors(ENTITY::GET_ENTITY_COORDS(ped, 0), ENTITY::GET_ENTITY_COORDS(veh, 0)) < 15.f)
TASK::TASK_ENTER_VEHICLE(ped, veh, 10000, (int)seat, movespeed, 8, NULL, 0);
else
PED::SET_PED_INTO_VEHICLE(ped, veh, (int)seat);
}
}
}
bool is_ped_a_friend(Ped ped, CPed* ped_ptr)
{
if (PED::GET_PED_CONFIG_FLAG(ped, 38, TRUE) == TRUE)
return false;
if (PED::IS_PED_IN_COMBAT(ped, self::ped))
return false;
return !g_pointers->m_gta.m_is_ped_enemies_with(ped_ptr->m_ped_intelligence, g_local_player, true, false, false);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -194,6 +194,8 @@ namespace big
ImGui::Checkbox("TRUST_FRIENDS"_T.data(), &g.weapons.aimbot.exclude_friends); ImGui::Checkbox("TRUST_FRIENDS"_T.data(), &g.weapons.aimbot.exclude_friends);
ImGui::SameLine(); ImGui::SameLine();
components::command_checkbox<"aimonlyatenemy">(); components::command_checkbox<"aimonlyatenemy">();
ImGui::SameLine();
components::command_checkbox<"aimonlyatthreats">();
ImGui::CheckboxFlags("PLAYERS"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_NETWORK_PLAYER); ImGui::CheckboxFlags("PLAYERS"_T.data(), &g.weapons.aimbot.only_on_ped_type, (int64_t)ePedTypeFlag::PED_TYPE_NETWORK_PLAYER);
ImGui::SameLine(); ImGui::SameLine();