refactor: move Request Model logic to helper function (#2669)

This commit is contained in:
Anvar 2024-01-31 04:47:03 -05:00 committed by GitHub
parent 7efbee2e85
commit ad1dfc71d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 147 additions and 137 deletions

View File

@ -25,8 +25,8 @@ namespace big
virtual void execute(const command_arguments& args, const std::shared_ptr<command_context> ctx) override
{
const auto hash = args.get<rage::joaat_t>(0);
if (!STREAMING::IS_MODEL_IN_CDIMAGE(hash) || !STREAMING::IS_MODEL_A_VEHICLE(hash))
const auto hash = args.get<rage::joaat_t>(0);
if (!entity::request_model(hash))
{
ctx->report_error("BACKEND_SPAWN_VEHICLE_INVALID_MODEL"_T.data());
return;
@ -61,8 +61,6 @@ namespace big
};
spawn_vehicle g_spawn_vehicle("spawn", "GUI_TAB_SPAWN_VEHICLE", "BACKEND_SPAWN_VEHICLE_DESC", 1);
bool_command g_spawn_maxed("spawnmaxed", "SPAWN_MAXED", "SPAWN_MAXED_DESC",
g.spawn_vehicle.spawn_maxed);
bool_command g_spawn_inside("spawnin", "SPAWN_IN", "SPAWN_IN_DESC",
g.spawn_vehicle.spawn_inside);
bool_command g_spawn_maxed("spawnmaxed", "SPAWN_MAXED", "SPAWN_MAXED_DESC", g.spawn_vehicle.spawn_maxed);
bool_command g_spawn_inside("spawnin", "SPAWN_IN", "SPAWN_IN_DESC", g.spawn_vehicle.spawn_inside);
}

View File

@ -7,6 +7,7 @@
#include "util/explosion_anti_cheat_bypass.hpp"
#include "util/police.hpp"
#include "util/vehicle.hpp"
#include "util/world_model.hpp"
extern "C" void sound_overload_detour();
uint64_t g_sound_overload_ret_addr;
@ -21,6 +22,10 @@ namespace big
police::m_max_wanted_level_2 =
memory::byte_patch::make(g_pointers->m_gta.m_max_wanted_level.add(14).rip().as<uint32_t*>(), 0).get();
// Patch World Model Spawn Bypass
world_model_bypass::m_world_model_spawn_bypass =
memory::byte_patch::make(g_pointers->m_gta.m_world_model_spawn_bypass.as<PVOID*>(), 0).get();
// Patch blocked explosions
explosion_anti_cheat_bypass::m_can_blame_others =
memory::byte_patch::make(g_pointers->m_gta.m_blame_explode.as<uint16_t*>(), 0xE990).get();
@ -98,4 +103,4 @@ namespace big
g_byte_patch_manager = nullptr;
}
}
}

View File

@ -42,6 +42,8 @@ namespace big
{
memory::handle m_max_wanted_level;
memory::handle m_world_model_spawn_bypass;
memory::handle m_blame_explode;
memory::handle m_explosion_patch;
@ -100,7 +102,6 @@ namespace big
float* m_gravity_level;
functions::set_gravity_level m_set_gravity_level;
PVOID m_world_model_spawn_bypass;
PVOID m_native_return;
PVOID m_get_label_text;
functions::check_chat_profanity* m_check_chat_profanity;
@ -363,4 +364,4 @@ namespace big
};
#pragma pack(pop)
static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned");
}
}

View File

@ -1,8 +1,8 @@
#include "pointers.hpp"
#include "gta_pointers_layout_info.hpp"
#include "sc_pointers_layout_info.hpp"
#include "memory/all.hpp"
#include "sc_pointers_layout_info.hpp"
namespace big
{
@ -159,15 +159,6 @@ namespace big
g_pointers->m_gta.m_swapchain = ptr.add(3).rip().as<IDXGISwapChain**>();
}
},
// World Model Spawn Bypass
{
"WMSB",
"48 85 C0 0F 84 ? ? ? ? 8B 48 50",
[](memory::handle ptr)
{
g_pointers->m_gta.m_world_model_spawn_bypass = ptr.as<PVOID>();
}
},
// Native Return Spoofer
{
"NRF",
@ -1517,6 +1508,15 @@ namespace big
g_pointers->m_gta.m_max_wanted_level = ptr;
}
},
// World Model Spawn Bypass
{
"WMSB",
"48 85 C0 0F 84 ? ? ? ? 8B 48 50",
[](memory::handle ptr)
{
g_pointers->m_gta.m_world_model_spawn_bypass = ptr;
}
},
// Blame Explode
{
"BE",

View File

@ -56,7 +56,7 @@ namespace big::entity
ENTITY::DELETE_ENTITY(&vehicle);
}
}
ENTITY::DETACH_ENTITY(ent, 1, 1);
ENTITY::SET_ENTITY_COORDS_NO_OFFSET(ent, 7000.f, 7000.f, 15.f, 0, 0, 0);
if (!ENTITY::IS_ENTITY_A_MISSION_ENTITY(ent))
@ -193,33 +193,71 @@ namespace big::entity
bool load_ground_at_3dcoord(Vector3& location)
{
constexpr float max_ground_check = 1000.f;
constexpr int max_attempts = 300;
float ground_z = location.z;
int current_attempts = 0;
bool found_ground;
constexpr float max_ground_check = 1000.f;
constexpr int max_attempts = 300;
float ground_z = location.z;
int current_attempts = 0;
bool found_ground;
float height;
do {
found_ground = MISC::GET_GROUND_Z_FOR_3D_COORD(location.x, location.y, max_ground_check, &ground_z, FALSE, FALSE);
STREAMING::REQUEST_COLLISION_AT_COORD(location.x, location.y, location.z);
do
{
found_ground = MISC::GET_GROUND_Z_FOR_3D_COORD(location.x, location.y, max_ground_check, &ground_z, FALSE, FALSE);
STREAMING::REQUEST_COLLISION_AT_COORD(location.x, location.y, location.z);
if (current_attempts % 10 == 0)
{
location.z += 25.f;
}
if (current_attempts % 10 == 0)
{
location.z += 25.f;
}
++current_attempts;
++current_attempts;
script::get_current()->yield();
} while (!found_ground && current_attempts < max_attempts);
script::get_current()->yield();
} while (!found_ground && current_attempts < max_attempts);
if (!found_ground)
{
return false;
}
if (!found_ground)
{
return false;
}
location.z = ground_z + 1.f;
return true;
if (WATER::GET_WATER_HEIGHT(location.x, location.y, location.z, &height))
{
location.z = height;
}
else
{
location.z = ground_z + 1.f;
}
return true;
}
bool request_model(rage::joaat_t hash)
{
if (STREAMING::HAS_MODEL_LOADED(hash))
{
return true;
}
bool has_loaded;
if (STREAMING::IS_MODEL_VALID(hash) && STREAMING::IS_MODEL_IN_CDIMAGE(hash))
{
do
{
has_loaded = STREAMING::HAS_MODEL_LOADED(hash);
if (has_loaded)
break;
STREAMING::REQUEST_MODEL(hash);
script::get_current()->yield();
} while (!has_loaded);
return true;
}
return false;
}
double distance_to_middle_of_screen(const rage::fvector2& screen_pos)
@ -303,4 +341,4 @@ namespace big::entity
return closest_entity;
}
}
}

View File

@ -18,6 +18,7 @@ namespace big::entity
bool network_has_control_of_entity(rage::netObject* net_object);
std::vector<Entity> get_entities(bool vehicles, bool peds, bool props = false, bool include_self_veh = false);
bool load_ground_at_3dcoord(Vector3& location);
bool request_model(rage::joaat_t hash);
double distance_to_middle_of_screen(const rage::fvector2& screen_pos);
Entity get_entity_closest_to_middle_of_screen(rage::fwEntity** pointer = nullptr, std::vector<Entity> ignore_entities = {}, bool include_veh = true, bool include_ped = true, bool include_prop = true, bool include_players = true);
}

View File

@ -446,24 +446,19 @@ namespace big::ped
inline bool change_player_model(const Hash hash)
{
for (uint8_t i = 0; !STREAMING::HAS_MODEL_LOADED(hash) && i < 100; i++)
if (entity::request_model(hash))
{
STREAMING::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;
}
if (!STREAMING::HAS_MODEL_LOADED(hash))
{
return false;
}
PLAYER::SET_PLAYER_MODEL(self::id, hash);
self::ped = PLAYER::PLAYER_PED_ID();
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;
}
inline bool steal_outfit(const Ped target)
@ -512,29 +507,22 @@ namespace big::ped
inline Ped spawn(ePedType pedType, Hash hash, Hash clone, Vector3 location, float heading, bool is_networked = true)
{
for (uint8_t i = 0; !STREAMING::HAS_MODEL_LOADED(hash) && i < 100; i++)
if (entity::request_model(hash))
{
STREAMING::REQUEST_MODEL(hash);
script::get_current()->yield();
Ped ped = PED::CREATE_PED(pedType, hash, location.x, location.y, location.z, heading, is_networked, false);
script::get_current()->yield();
if (clone)
{
PED::CLONE_PED_TO_TARGET(clone, ped);
}
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);
return ped;
}
if (!STREAMING::HAS_MODEL_LOADED(hash))
{
return 0;
}
auto ped = PED::CREATE_PED(pedType, hash, location.x, location.y, location.z, heading, is_networked, false);
script::get_current()->yield();
if (clone)
{
PED::CLONE_PED_TO_TARGET(clone, ped);
}
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);
return ped;
return 0;
}
inline void set_ped_random_component_variation(Ped ped)

View File

@ -6,8 +6,8 @@ namespace big::vehicle
{
switch (speed_unit)
{
case SpeedUnit::KMPH: return mps * 3.6f; break;
case SpeedUnit::MIPH: return mps * 2.2369f; break;
case SpeedUnit::KMPH: return mps * 3.6f;
case SpeedUnit::MIPH: return mps * 2.2369f;
}
return mps;
@ -17,8 +17,8 @@ namespace big::vehicle
{
switch (speed_unit)
{
case SpeedUnit::KMPH: return speed / 3.6f; break;
case SpeedUnit::MIPH: return speed / 2.2369f; break;
case SpeedUnit::KMPH: return speed / 3.6f;
case SpeedUnit::MIPH: return speed / 2.2369f;
}
return speed;
@ -77,7 +77,7 @@ namespace big::vehicle
if (driver_ped != 0)
{
if (PED::GET_PED_TYPE(driver_ped) == ePedType::PED_TYPE_NETWORK_PLAYER)
if (PED::GET_PED_TYPE(driver_ped) == PED_TYPE_NETWORK_PLAYER)
{
TASK::CLEAR_PED_TASKS_IMMEDIATELY(driver_ped);
}
@ -152,27 +152,20 @@ namespace big::vehicle
Vehicle spawn(Hash hash, Vector3 location, float heading, bool is_networked, bool script_veh)
{
for (int i = 0; !STREAMING::HAS_MODEL_LOADED(hash) && i < 100; i++)
if (entity::request_model(hash))
{
STREAMING::REQUEST_MODEL(hash);
script::get_current()->yield();
auto veh = VEHICLE::CREATE_VEHICLE(hash, location.x, location.y, location.z, heading, is_networked, script_veh, false);
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);
if (*g_pointers->m_gta.m_is_session_started)
{
set_mp_bitset(veh);
}
return veh;
}
if (!STREAMING::HAS_MODEL_LOADED(hash))
{
return 0;
}
auto veh = VEHICLE::CREATE_VEHICLE(hash, location.x, location.y, location.z, heading, is_networked, script_veh, false);
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);
if (*g_pointers->m_gta.m_is_session_started)
{
set_mp_bitset(veh);
}
return veh;
return 0;
}
Vehicle clone_from_vehicle_data(std::map<int, int32_t>& data, Vector3 location, float heading)
@ -226,7 +219,7 @@ namespace big::vehicle
return 0;
}
auto veh = vehicle::get_closest_to_location(tmpLocation, 200);
auto veh = get_closest_to_location(tmpLocation, 200);
if (veh == 0)
{
return 0;
@ -551,8 +544,6 @@ namespace big::vehicle
void max_vehicle(Vehicle veh)
{
Hash model = ENTITY::GET_ENTITY_MODEL(veh);
VEHICLE::SET_VEHICLE_MOD_KIT(veh, 0);
VEHICLE::TOGGLE_VEHICLE_MOD(veh, MOD_TURBO, TRUE);
@ -688,13 +679,10 @@ namespace big::vehicle
VEHICLE::SET_VEHICLE_INDIVIDUAL_DOORS_LOCKED(veh, i, (int)state);
return VEHICLE::GET_VEHICLE_DOOR_LOCK_STATUS(veh) == (int)state;
}
else
{
if (VEHICLE::GET_IS_DOOR_VALID(veh, (int)doorId))
VEHICLE::SET_VEHICLE_INDIVIDUAL_DOORS_LOCKED(veh, (int)doorId, (int)state);
if (VEHICLE::GET_IS_DOOR_VALID(veh, (int)doorId))
VEHICLE::SET_VEHICLE_INDIVIDUAL_DOORS_LOCKED(veh, (int)doorId, (int)state);
return VEHICLE::GET_VEHICLE_INDIVIDUAL_DOOR_LOCK_STATUS(veh, (int)doorId) == (int)state;
}
return VEHICLE::GET_VEHICLE_INDIVIDUAL_DOOR_LOCK_STATUS(veh, (int)doorId) == (int)state;
}
return false;

View File

@ -3,38 +3,29 @@
#include "pointers.hpp"
#include "script.hpp"
struct world_model_bypass
{
inline static memory::byte_patch* m_world_model_spawn_bypass;
};
namespace big::world_model
{
constexpr size_t patch_size = 24;
static inline std::once_flag once_flag;
static inline std::array<byte, patch_size> backup;
static inline void setup_backup()
{
memcpy(backup.data(), g_pointers->m_gta.m_world_model_spawn_bypass, patch_size);
}
inline Object spawn(Hash hash, Vector3 location = Vector3(), bool is_networked = true)
{
STREAMING::REQUEST_MODEL(hash);
for (int i = 0; i < 100 && !STREAMING::HAS_MODEL_LOADED(hash); i++)
if (entity::request_model(hash))
{
script::get_current()->yield();
}
if (!STREAMING::HAS_MODEL_LOADED(hash))
{
LOG(WARNING) << "Failed to load model " << HEX_TO_UPPER(hash);
return 0;
world_model_bypass::m_world_model_spawn_bypass->apply();
const auto object = OBJECT::CREATE_OBJECT(hash, location.x, location.y, location.z, is_networked, false, false);
world_model_bypass::m_world_model_spawn_bypass->restore();
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);
return object;
}
std::call_once(once_flag, setup_backup);
memset(g_pointers->m_gta.m_world_model_spawn_bypass, 0x90, patch_size);
const auto object = OBJECT::CREATE_OBJECT(hash, location.x, location.y, location.z, is_networked, false, false);
memcpy(g_pointers->m_gta.m_world_model_spawn_bypass, backup.data(), patch_size);
STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash);
return object;
LOG(WARNING) << "Failed to load model " << HEX_TO_UPPER(hash);
return 0;
}
}