Misc stuff (#3515)
Some checks are pending
Nightly Build / Check Recent Commit (push) Successful in 42s
Nightly Build / Build Nightly (push) Waiting to run
Nightly Build / Recreate Release (push) Blocked by required conditions

* feat(hotkeys): add support for mouse buttons
* feat: show message box with version note if pattern scan fails
* feat(exception handler): set destination register to 0 on move instructions
* feat: update r* admin list
* fix: fix spawned vehicle not being deleted when using bring player
* fix: fix exceptions when using bring player
* fix: fix gravity gun not working while requesting control
* fix: dont request control of entities that are not CPhysical
* fix: fix take_control_of not requesting control if timeout is 0
* fix: fix crash when executing commands on all players
* fix: fix cmd executor style being applied to all windows if command is invalid
* fix: fix rare exceptions in esp::draw_player
* fix: fix exceptions when using gravity gun on objects or dying with some models
* fix: fix incorrect reading of m_model_type
This commit is contained in:
Mr-X-GTA 2024-08-05 09:15:42 +02:00 committed by GitHub
parent eefd71196c
commit 013b463536
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 182 additions and 61 deletions

View File

@ -3,7 +3,7 @@ include(FetchContent)
FetchContent_Declare(
gtav_classes
GIT_REPOSITORY https://github.com/Yimura/GTAV-Classes.git
GIT_TAG a91475c198c59eff04de26929e83d86521299dda
GIT_TAG b9b832ab00c95a731f8472f696c5d026a29fd767
GIT_PROGRESS TRUE
CONFIGURE_COMMAND ""
BUILD_COMMAND ""

View File

@ -23,7 +23,7 @@ namespace big
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_WEAPON_WHEEL_PREV))
dist += 5;
if (!entity::take_control_of(e))
if (!entity::take_control_of(e, 0))
return; // TODO: remove from vector
ENTITY::SET_ENTITY_COLLISION(e, false, false);
@ -83,7 +83,7 @@ namespace big
}
else
{
if (entity::take_control_of(ent_to_add) && ENTITY::IS_ENTITY_A_PED(ent_to_add) && !PED::IS_PED_RAGDOLL(ent_to_add))
if (entity::take_control_of(ent_to_add, 0) && ENTITY::IS_ENTITY_A_PED(ent_to_add) && !PED::IS_PED_RAGDOLL(ent_to_add))
{
TASK::SET_HIGH_FALL_TASK(ent_to_add, 0, 0, 0);
@ -107,7 +107,7 @@ namespace big
{
for (const Entity& e : ents)
{
if (entity::take_control_of(e))
if (entity::take_control_of(e, 0))
{
if (g.weapons.gravity_gun.launch_on_release)
{

View File

@ -12,10 +12,14 @@ namespace big
void player_all_component::execute(const command_arguments& args, const std::shared_ptr<command_context> ctx)
{
g_fiber_pool->queue_job([this, args, &ctx] {
g_player_service->iterate([this, args, &ctx](const player_entry& player) {
m_parent->execute(player.second, args, ctx);
});
g_fiber_pool->queue_job([this, args, ctx] {
for (uint32_t i = 0; i < 32; ++i)
{
if (auto player = g_player_service->get_by_id(i); player && player->is_valid())
{
m_parent->execute(player, args, ctx);
}
}
});
}

File diff suppressed because one or more lines are too long

View File

@ -154,6 +154,7 @@ namespace big
functions::get_sync_type_info m_get_sync_type_info;
functions::get_net_object m_get_net_object;
functions::read_bitbuffer_into_sync_tree m_read_bitbuffer_into_sync_tree;
PVOID m_update_sync_tree;
//Sync Signatures END
PVOID m_receive_net_message;

View File

@ -61,6 +61,8 @@ namespace big
detour_hook_helper::add<hooks::received_clone_sync>("RCS", g_pointers->m_gta.m_received_clone_sync);
detour_hook_helper::add<hooks::can_apply_data>("CAD", g_pointers->m_gta.m_can_apply_data);
detour_hook_helper::add<hooks::update_sync_tree>("UST", g_pointers->m_gta.m_update_sync_tree);
detour_hook_helper::add<hooks::get_network_event_data>("GNED", g_pointers->m_gta.m_get_network_event_data);
detour_hook_helper::add<hooks::invalid_decal>("IDC", g_pointers->m_gta.m_invalid_decal_crash);

View File

@ -107,7 +107,8 @@ namespace big
static eAckCode received_clone_sync(CNetworkObjectMgr* mgr, CNetGamePlayer* src, CNetGamePlayer* dst, eNetObjType object_type, uint16_t object_id, rage::datBitBuffer* bufer, uint16_t unk, uint32_t timestamp);
static bool can_apply_data(rage::netSyncTree* tree, rage::netObject* object);
static void invalid_mods_crash_detour(int64_t a1, int64_t a2, int a3, char a4);
static void update_sync_tree(rage::netSyncTree* _this, rage::netObject* object, uint32_t flags, uint32_t timestamp, bool a5);
static void invalid_decal(uintptr_t a1, int a2);
static int task_parachute_object(uint64_t _this, int a2, int a3);
static int task_ambient_clips(uint64_t _this, int a2, int a3);

View File

@ -204,7 +204,7 @@ namespace big
const char* model_str = nullptr;
if (info->m_model_type == eModelType::Vehicle)
if (info->get_model_type() == eModelType::Vehicle)
{
for (auto& [name, data] : g_gta_data_service.vehicles())
{
@ -215,7 +215,7 @@ namespace big
}
}
}
else if (info->m_model_type == eModelType::Ped || info->m_model_type == eModelType::OnlineOnlyPed)
else if (info->get_model_type() == eModelType::Ped)
{
for (auto& [name, data] : g_gta_data_service.peds())
{

View File

@ -0,0 +1,13 @@
#include "hooking/hooking.hpp"
#include "pointers.hpp"
namespace big
{
void hooks::update_sync_tree(rage::netSyncTree* _this, rage::netObject* object, uint32_t flags, uint32_t timestamp, bool a5)
{
if (!object->GetSyncData()) [[unlikely]]
return;
g_hooking->get_original<hooks::update_sync_tree>()(_this, object, flags, timestamp, a5);
}
}

View File

@ -87,6 +87,30 @@ namespace big
else
{
exception_info->ContextRecord->Rip += opcode.len;
if (opcode.opcode == 0x8B && opcode.modrm_mod != 3) // MOV
{
uint8_t reg_id = opcode.rex_r << 3 | opcode.modrm_reg;
switch (reg_id)
{
case 0: exception_info->ContextRecord->Rax = 0; break;
case 1: exception_info->ContextRecord->Rcx = 0; break;
case 2: exception_info->ContextRecord->Rdx = 0; break;
case 3: exception_info->ContextRecord->Rbx = 0; break;
case 4: exception_info->ContextRecord->Rsp = 0; break;
case 5: exception_info->ContextRecord->Rbp = 0; break;
case 6: exception_info->ContextRecord->Rsi = 0; break;
case 7: exception_info->ContextRecord->Rdi = 0; break;
case 8: exception_info->ContextRecord->R8 = 0; break;
case 9: exception_info->ContextRecord->R9 = 0; break;
case 10: exception_info->ContextRecord->R10 = 0; break;
case 11: exception_info->ContextRecord->R11 = 0; break;
case 12: exception_info->ContextRecord->R12 = 0; break;
case 13: exception_info->ContextRecord->R13 = 0; break;
case 14: exception_info->ContextRecord->R14 = 0; break;
case 15: exception_info->ContextRecord->R15 = 0; break;
}
}
}
}

View File

@ -3,6 +3,8 @@
#include "gta_pointers_layout_info.hpp"
#include "sc_pointers_layout_info.hpp"
#define GTA_VERSION_TARGET "1.69-3274"
namespace big
{
constexpr auto pointers::get_gta_batch()
@ -449,6 +451,15 @@ namespace big
g_pointers->m_gta.m_read_bitbuffer_into_sync_tree = ptr.add(1).rip().as<functions::read_bitbuffer_into_sync_tree>();
}
},
// Update Sync Tree
{
"UST",
"E8 ? ? ? ? 45 84 ED 75 1B",
[](memory::handle ptr)
{
g_pointers->m_gta.m_update_sync_tree = ptr.add(1).rip().as<PVOID>();
}
},
// Model Hash Table
{
"MHT",
@ -2024,7 +2035,8 @@ namespace big
pointers::pointers() :
m_gta_pointers_cache(g_file_manager.get_project_file("./cache/gta_pointers.bin")),
m_sc_pointers_cache(g_file_manager.get_project_file("./cache/sc_pointers.bin"))
m_sc_pointers_cache(g_file_manager.get_project_file("./cache/sc_pointers.bin")),
m_gta_version_target(GTA_VERSION_TARGET)
{
g_pointers = this;

View File

@ -107,9 +107,26 @@ namespace big
{
if (!memory::batch_runner::run(batch, mem_region))
{
const std::string error_message =
std::string("Failed to find some patterns for ") + std::string(batch_name.str);
throw std::runtime_error(error_message);
auto message = std::format("Failed to find some patterns for {}", batch_name.str);
if (m_gta.m_online_version && m_gta.m_game_version)
{
auto gta_version = std::format("{}-{}", m_gta.m_online_version, m_gta.m_game_version);
if (gta_version != m_gta_version_target)
message = std::format("{} (Note: Found game version {} but this YimMenu version is for game version {})", message, gta_version, m_gta_version_target);
}
LOG(FATAL) << message;
if (!m_gta.m_is_session_started || !*m_gta.m_is_session_started) // AC not bypassed yet so exit directly when online
{
MessageBoxA(m_hwnd, message.c_str(), "YimMenu", MB_ICONWARNING | MB_TOPMOST);
}
Logger::FlushQueue();
std::exit(EXIT_FAILURE);
}
}
@ -121,6 +138,8 @@ namespace big
cache_file m_gta_pointers_cache;
cache_file m_sc_pointers_cache;
const char* m_gta_version_target;
public:
HWND m_hwnd{};

View File

@ -137,7 +137,7 @@ namespace big
{
if (m_pointer && m_pointer->m_model_info)
{
switch (m_pointer->m_model_info->m_model_type)
switch (m_pointer->m_model_info->get_model_type())
{
case eModelType::Object:
{
@ -147,7 +147,6 @@ namespace big
}
return &options.at(ContextEntityType::OBJECT);
}
case eModelType::OnlineOnlyPed:
case eModelType::Ped:
{
if (const auto ped = reinterpret_cast<CPed*>(m_pointer); ped)

View File

@ -102,6 +102,42 @@ namespace big
|| g.settings.hotkeys.is_mp_chat_active)
return;
switch (state)
{
case WM_LBUTTONUP:
state = eKeyState::RELEASE;
key = VK_LBUTTON;
break;
case WM_RBUTTONUP:
state = eKeyState::RELEASE;
key = VK_RBUTTON;
break;
case WM_MBUTTONUP:
state = eKeyState::RELEASE;
key = VK_MBUTTON;
break;
case WM_XBUTTONUP:
state = eKeyState::RELEASE;
key = GET_XBUTTON_WPARAM(key) == XBUTTON1 ? VK_XBUTTON1 : VK_XBUTTON2;
break;
case WM_LBUTTONDOWN:
state = eKeyState::DOWN;
key = VK_LBUTTON;
break;
case WM_RBUTTONDOWN:
state = eKeyState::DOWN;
key = VK_RBUTTON;
break;
case WM_MBUTTONDOWN:
state = eKeyState::DOWN;
key = VK_MBUTTON;
break;
case WM_XBUTTONDOWN:
state = eKeyState::DOWN;
key = GET_XBUTTON_WPARAM(key) == XBUTTON1 ? VK_XBUTTON1 : VK_XBUTTON2;
break;
}
if (state == eKeyState::RELEASE || state == eKeyState::DOWN)
{
auto& hotkey_map = m_hotkeys[state == eKeyState::RELEASE];

View File

@ -169,19 +169,19 @@ namespace big::entity
auto hnd = g_pointers->m_gta.m_handle_to_ptr(ent);
if (!hnd || !hnd->m_net_object || !*g_pointers->m_gta.m_is_session_started)
if (!hnd || !hnd->m_net_object)
return false;
if (network_has_control_of_entity(hnd->m_net_object))
return true;
if (hnd->m_entity_type != 3 && hnd->m_entity_type != 4 && hnd->m_entity_type != 5)
return false;
for (int i = 0; i < timeout; i++)
for (int i = 0; i <= timeout; ++i)
{
g_pointers->m_gta.m_request_control(hnd->m_net_object);
if (network_has_control_of_entity(hnd->m_net_object))
return true;
g_pointers->m_gta.m_request_control(hnd->m_net_object);
if (timeout != 0)
script::get_current()->yield();
}

View File

@ -21,7 +21,7 @@ namespace big::fuzzer
inline bool is_object_model(rage::joaat_t hash)
{
return model_info::is_model_of_type(hash, eModelType::Object, eModelType::Time, eModelType::Weapon, eModelType::Destructable, eModelType::WorldObject, eModelType::Sprinkler, eModelType::Unk65, eModelType::LOD, eModelType::Unk132, eModelType::Building);
return model_info::is_model_of_type(hash, eModelType::Object, eModelType::Time, eModelType::Weapon, eModelType::Destructable);
}
inline rage::joaat_t get_mismatched_model(rage::joaat_t original)
@ -44,7 +44,7 @@ namespace big::fuzzer
if (is_object_model(original))
std::erase(models, "apa_heist_apart2_door"_J);
else if (info && info->m_model_type == eModelType::Vehicle)
else if (info && info->get_model_type() == eModelType::Vehicle)
{
if (veh_model->m_vehicle_type == eVehicleType::VEHICLE_TYPE_BIKE)
std::erase(models, "faggio"_J);
@ -61,7 +61,7 @@ namespace big::fuzzer
else
std::erase(models, "zentorno"_J);
}
else if (info && (info->m_model_type == eModelType::Ped || info->m_model_type == eModelType::OnlineOnlyPed))
else if (info && (info->get_model_type() == eModelType::Ped))
std::erase(models, "player_zero"_J);
return models[math::rand(models.size())];
@ -73,9 +73,9 @@ namespace big::fuzzer
if (is_object_model(original))
return "urbanweeds01"_J;
else if (info && (info->m_model_type == eModelType::Ped || info->m_model_type == eModelType::OnlineOnlyPed))
else if (info && (info->get_model_type() == eModelType::Ped))
return "slod_human"_J;
else if (info && info->m_model_type == eModelType::Vehicle)
else if (info && info->get_model_type() == eModelType::Vehicle)
return "arbitergt"_J;
else
return math::rand(2) ? "urbanweeds01"_J : "slod_human"_J;
@ -126,9 +126,9 @@ namespace big::fuzzer
if (is_object_model(entity->m_model_info->m_hash))
return math::rand(2) ? get_first_ped_id() : get_first_veh_id();
else if (entity->m_model_info->m_model_type == eModelType::Ped || entity->m_model_info->m_model_type == eModelType::OnlineOnlyPed)
else if (entity->m_model_info->get_model_type() == eModelType::Ped)
return math::rand(2) ? get_first_obj_id() : get_first_veh_id();
else if (entity->m_model_info->m_model_type == eModelType::Vehicle)
else if (entity->m_model_info->get_model_type() == eModelType::Vehicle)
return math::rand(2) ? get_first_obj_id() : get_first_ped_id();
return math::rand(2) ? get_first_ped_id() : get_first_veh_id();

View File

@ -13,7 +13,7 @@ namespace big
{
if (const auto table_idx = node->m_idx; table_idx < m_model_table->m_size)
{
if (const auto model = m_model_table->m_data[table_idx]; model && model->m_model_type == eModelType::Vehicle)
if (const auto model = m_model_table->m_data[table_idx]; model && model->get_model_type() == eModelType::Vehicle)
{
}
@ -50,7 +50,7 @@ namespace big
static CVehicleModelInfo* get_vehicle_model(const rage::joaat_t hash)
{
if (const auto model = model_info::get_model<CVehicleModelInfo*>(hash); model && model->m_model_type == eModelType::Vehicle)
if (const auto model = model_info::get_model<CVehicleModelInfo*>(hash); model && model->get_model_type() == eModelType::Vehicle)
return model;
return nullptr;
}
@ -61,10 +61,10 @@ namespace big
bool of_type = false;
if (const auto model = model_info::get_model(hash))
{
of_type = model->m_model_type == arg;
of_type = model->get_model_type() == arg;
(
[&of_type, &model](eModelType type) {
of_type |= model->m_model_type == type;
of_type |= model->get_model_type() == type;
}(args),
...);
}

View File

@ -11,7 +11,7 @@ namespace big::protection
return true;
if (!model_info::get_model(model))
return false;
if (!model_info::is_model_of_type(model, eModelType::Object, eModelType::Time, eModelType::Weapon, eModelType::Destructable, eModelType::WorldObject, eModelType::Sprinkler, eModelType::Unk65, eModelType::Plant, eModelType::LOD, eModelType::Unk132, eModelType::Building))
if (!model_info::is_model_of_type(model, eModelType::Object, eModelType::Time, eModelType::Weapon, eModelType::Destructable))
return true;
return false;
}
@ -21,7 +21,7 @@ namespace big::protection
{
if (crash_peds.contains(model))
return true;
if (!model_info::is_model_of_type(model, eModelType::Ped, eModelType::OnlineOnlyPed))
if (!model_info::is_model_of_type(model, eModelType::Ped))
return true;
return false;
}
@ -31,7 +31,7 @@ namespace big::protection
{
if (crash_vehicles.contains(model))
return true;
if (!model_info::is_model_of_type(model, eModelType::Vehicle, eModelType::Unk133))
if (!model_info::is_model_of_type(model, eModelType::Vehicle))
return true;
return false;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "blip.hpp"
#include "entity.hpp"
#include "fiber_pool.hpp"
#include "gta/enums.hpp"
#include "services/players/player_service.hpp"
#include "vehicle.hpp"
@ -98,20 +99,28 @@ namespace big::teleport
{
script::get_current()->yield(25ms);
if (auto ptr = (rage::CDynamicEntity*)g_pointers->m_gta.m_handle_to_ptr(hnd))
{
if (auto netobj = ptr->m_net_object)
{
g_pointers->m_gta.m_migrate_object(player->get_net_game_player(), netobj, 3);
}
}
auto ptr = (rage::CDynamicEntity*)g_pointers->m_gta.m_handle_to_ptr(hnd);
if (!ptr || !ptr->m_net_object)
break;
auto plyr = player->get_net_game_player();
if (!plyr)
break;
g_pointers->m_gta.m_migrate_object(plyr, ptr->m_net_object, 3);
auto new_coords = ENTITY::GET_ENTITY_COORDS(hnd, true);
if (SYSTEM::VDIST2(coords.x, coords.y, coords.z, new_coords.x, new_coords.y, new_coords.z) < 20 * 20 && VEHICLE::GET_PED_IN_VEHICLE_SEAT(hnd, 0, true) == ent)
break;
}
entity::delete_entity(hnd);
g_fiber_pool->queue_job([hnd] {
auto ent = hnd;
entity::take_control_of(ent);
entity::delete_entity(ent);
});
std::erase_if(g.m_remote_player_teleports, [veh_id](auto& obj) {
return obj.first == veh_id;

View File

@ -601,7 +601,7 @@ namespace big
if (components::input_text_with_hint("", "CMD_EXECUTOR_TYPE_CMD"_T, command_buffer, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackAlways, nullptr, input_callback))
{
if (!s_buffer.get_command_of_index(cursor_pos))
return;
goto VIEW_END;
if (command::process(command_buffer, std::make_shared<default_command_context>(), false))
{

View File

@ -18,10 +18,12 @@ namespace big
void esp::draw_player(const player_ptr& plyr, ImDrawList* const draw_list)
{
if (!plyr->is_valid() || !plyr->get_ped() || !plyr->get_ped()->m_navigation)
auto ped = plyr->get_ped();
if (!ped || !ped->m_navigation)
return;
auto& player_pos = *plyr->get_ped()->m_navigation->get_position();
auto& player_pos = *ped->m_navigation->get_position();
float screen_x, screen_y;
@ -31,7 +33,7 @@ namespace big
if (multplr == -1.f || g.esp.global_render_distance[0] > distance)
return;
uint32_t ped_damage_bits = plyr->get_ped()->m_damage_bits;
uint32_t ped_damage_bits = ped->m_damage_bits;
if (g_pointers->m_gta.m_get_screen_coords_for_world_coords(player_pos.data, &screen_x, &screen_y))
{
@ -54,8 +56,8 @@ namespace big
esp_color = g.esp.enemy_near_color;
}
const auto armor_perc = plyr->get_ped()->m_armor / 50.f;
const auto health_perc = plyr->get_ped()->m_health / (plyr->get_ped()->m_maxhealth + 0.001f);
const auto armor_perc = ped->m_armor / 50.f;
const auto health_perc = ped->m_health / (ped->m_maxhealth + 0.001f);
if (distance < g.esp.tracer_render_distance[1] && distance > g.esp.tracer_render_distance[0] && g.esp.tracer)
draw_list->AddLine({(float)*g_pointers->m_gta.m_resolution_x * g.esp.tracer_draw_position[0],
@ -100,8 +102,8 @@ namespace big
}
}
if (auto player_vehicle = plyr->get_current_vehicle(); player_vehicle && (plyr->get_ped()->m_ped_task_flag & (uint32_t)ePedTask::TASK_DRIVING)
&& (player_vehicle->m_damage_bits & (uint32_t)eEntityProofs::GOD))
if (auto player_vehicle = plyr->get_current_vehicle();
player_vehicle && (ped->m_ped_task_flag & (uint32_t)ePedTask::TASK_DRIVING) && (player_vehicle->m_damage_bits & (uint32_t)eEntityProofs::GOD))
{
if (!mode_str.empty())
mode_str += ", ";
@ -153,7 +155,7 @@ namespace big
4);
}
}
if (g.esp.armor && plyr->get_ped()->m_armor > 0)
if (g.esp.armor && ped->m_armor > 0)
{
float offset = 5.f;
offset = g.esp.health ? 10.f : 5.f;
@ -177,11 +179,10 @@ namespace big
if (!g.esp.enabled)
return;
if (const auto draw_list = ImGui::GetBackgroundDrawList(); draw_list)
{
g_player_service->iterate([draw_list](const player_entry& entry) {
draw_player(entry.second, draw_list);
});
}
const auto draw_list = ImGui::GetBackgroundDrawList();
g_player_service->iterate([draw_list](const player_entry& entry) {
draw_player(entry.second, draw_list);
});
}
}