Many different fixes (#2749)

* fix(BytePatch): regression in world spawn bypass introduced in #2669
* fix(View/Network): session join options not updating after language change
* fix(RapidFire): prevent game from crashing by filling up the bullet pool
* refactor(Settings): don't save certain settings that users usually don't want to have enabled
* fix(CustomWeapons): render weapon names properly
* fix(reaction): names don't appear in chat
This commit is contained in:
Andreas Maerten 2024-02-21 23:34:11 +01:00 committed by GitHub
parent 1064077b9c
commit 6149b8ec9b
8 changed files with 57 additions and 52 deletions

View File

@ -10,11 +10,27 @@ namespace big
{ {
using looped_command::looped_command; using looped_command::looped_command;
const std::size_t m_tick_rate = 5u;
std::size_t m_current_tick = 0;
/**
* @brief We have to limit the fire rate for some shotguns as they can fill the bullet pool and crash the game.
*
* @return true
* @return false
*/
inline bool can_shoot()
{
bool result = (m_current_tick == 0);
m_current_tick = (m_current_tick + 1) % m_tick_rate;
return result;
}
virtual void on_tick() override virtual void on_tick() override
{ {
if (!HUD::IS_PAUSE_MENU_ACTIVE() && !g_gui->is_open() && !PED::IS_PED_DEAD_OR_DYING(self::ped, true)) if (!HUD::IS_PAUSE_MENU_ACTIVE() && !g_gui->is_open() && !PED::IS_PED_DEAD_OR_DYING(self::ped, true))
{ {
if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_ATTACK)) if (PAD::IS_DISABLED_CONTROL_PRESSED(0, (int)ControllerInputs::INPUT_ATTACK) && can_shoot())
{ {
const auto weapon_entity = WEAPON::GET_CURRENT_PED_WEAPON_ENTITY_INDEX(self::ped, 0); const auto weapon_entity = WEAPON::GET_CURRENT_PED_WEAPON_ENTITY_INDEX(self::ped, 0);
if (!weapon_entity) if (!weapon_entity)
@ -62,5 +78,6 @@ namespace big
} }
}; };
rapid_fire g_rapid_fire("rapidfire", "BACKEND_LOOPED_WEAPONS_RAPID_FIRE", "BACKEND_LOOPED_WEAPONS_RAPID_FIRE_DESC", g.weapons.rapid_fire); rapid_fire g_rapid_fire("rapidfire", "BACKEND_LOOPED_WEAPONS_RAPID_FIRE", "BACKEND_LOOPED_WEAPONS_RAPID_FIRE_DESC",
g.weapons.rapid_fire);
} }

View File

@ -63,7 +63,7 @@ namespace big
if (announce_in_chat) if (announce_in_chat)
{ {
g_fiber_pool->queue_job([player, this] { g_fiber_pool->queue_job([player, this] {
auto chat = std::format("{} {}", g.session.chat_output_prefix, g_translation_service.get_translation(m_announce_message)); auto chat = std::format("{} {}", g.session.chat_output_prefix, std::vformat(g_translation_service.get_translation(m_announce_message), std::make_format_args(player->get_name())));
if (g_hooking->get_original<hooks::send_chat_message>()(*g_pointers->m_gta.m_send_chat_ptr, if (g_hooking->get_original<hooks::send_chat_message>()(*g_pointers->m_gta.m_send_chat_ptr,
g_player_service->get_self()->get_net_data(), g_player_service->get_self()->get_net_data(),

View File

@ -23,8 +23,10 @@ namespace big
memory::byte_patch::make(g_pointers->m_gta.m_max_wanted_level.add(14).rip().as<uint32_t*>(), 0).get(); 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 // Patch World Model Spawn Bypass
std::array<uint8_t, 24> world_spawn_patch;
std::fill(world_spawn_patch.begin(), world_spawn_patch.end(), 0x90);
world_model_bypass::m_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.add(3).rip().as<PVOID*>(), 0).get(); memory::byte_patch::make(g_pointers->m_gta.m_world_model_spawn_bypass, world_spawn_patch).get();
// Patch blocked explosions // Patch blocked explosions
explosion_anti_cheat_bypass::m_can_blame_others = explosion_anti_cheat_bypass::m_can_blame_others =

View File

@ -625,7 +625,7 @@ namespace big
NLOHMANN_DEFINE_TYPE_INTRUSIVE(auto_disarm, enable, neutralize) NLOHMANN_DEFINE_TYPE_INTRUSIVE(auto_disarm, enable, neutralize)
} auto_disarm{}; } auto_disarm{};
NLOHMANN_DEFINE_TYPE_INTRUSIVE(nearby, ignore, ped_rain, veh_rain, high_alert, ped_rush, combative, auto_disarm) NLOHMANN_DEFINE_TYPE_INTRUSIVE(nearby, ignore, high_alert, ped_rush, auto_disarm)
} nearby{}; } nearby{};
struct model_swapper struct model_swapper

View File

@ -43,7 +43,7 @@ namespace big
{ {
memory::handle m_max_wanted_level; memory::handle m_max_wanted_level;
memory::handle m_world_model_spawn_bypass; PVOID m_world_model_spawn_bypass;
memory::handle m_blame_explode; memory::handle m_blame_explode;

View File

@ -1510,10 +1510,10 @@ namespace big
// World Model Spawn Bypass // World Model Spawn Bypass
{ {
"WMSB", "WMSB",
"48 85 C0 0F 84 ? ? ? ? 8B 48 ? C1 E9 ? F6 C1 ? 0F 84 ? ? ? ? 45 84 E4", "48 85 C0 0F 84 ? ? ? ? 8B 48 50",
[](memory::handle ptr) [](memory::handle ptr)
{ {
g_pointers->m_gta.m_world_model_spawn_bypass = ptr; g_pointers->m_gta.m_world_model_spawn_bypass = ptr.as<PVOID>();
} }
}, },
// Blame Explode // Blame Explode

View File

@ -19,26 +19,12 @@
namespace big namespace big
{ {
/*struct SessionType struct SessionType
{ {
eSessionType id; eSessionType id;
const std::string_view name; const char* name;
}; };
const SessionType sessions[] = {
{eSessionType::JOIN_PUBLIC, "BACKEND_SESSION_TYPE_JOIN_PUBLIC"_T},
{eSessionType::NEW_PUBLIC, "BACKEND_SESSION_TYPE_NEW_PUBLIC"_T},
{eSessionType::CLOSED_CREW, "BACKEND_SESSION_TYPE_CLOSED_CREW"_T},
{eSessionType::CREW, "BACKEND_SESSION_TYPE_CREW"_T},
{eSessionType::CLOSED_FRIENDS, "BACKEND_SESSION_TYPE_CLOSED_FRIENDS"_T},
{eSessionType::FIND_FRIEND, "BACKEND_SESSION_TYPE_FIND_FRIEND"_T},
{eSessionType::SOLO, "BACKEND_SESSION_TYPE_SOLO"_T},
{eSessionType::INVITE_ONLY, "BACKEND_SESSION_TYPE_INVITE_ONLY"_T},
{eSessionType::JOIN_CREW, "BACKEND_SESSION_TYPE_JOIN_CREW"_T},
{eSessionType::SC_TV, "BACKEND_SESSION_TYPE_SC_TV"_T},
{eSessionType::LEAVE_ONLINE, "BACKEND_SESSION_TYPE_LEAVE_ONLINE"_T},
};*/
void render_rid_joiner() void render_rid_joiner()
{ {
ImGui::BeginGroup(); ImGui::BeginGroup();
@ -105,23 +91,23 @@ namespace big
ImGui::Spacing(); ImGui::Spacing();
static const std::vector<std::tuple<eSessionType, std::string_view>> sessions = { //This has to be here because if it's generated at compile time, the translations break for some reason. static const auto sessions = std::to_array<SessionType>({ //This has to be here because if it's generated at compile time, the translations break for some reason.
make_tuple(eSessionType::JOIN_PUBLIC, "BACKEND_SESSION_TYPE_JOIN_PUBLIC"_T), {eSessionType::JOIN_PUBLIC, "BACKEND_SESSION_TYPE_JOIN_PUBLIC"},
make_tuple(eSessionType::NEW_PUBLIC, "BACKEND_SESSION_TYPE_NEW_PUBLIC"_T), {eSessionType::NEW_PUBLIC, "BACKEND_SESSION_TYPE_NEW_PUBLIC"},
make_tuple(eSessionType::CLOSED_CREW, "BACKEND_SESSION_TYPE_CLOSED_CREW"_T), {eSessionType::CLOSED_CREW, "BACKEND_SESSION_TYPE_CLOSED_CREW"},
make_tuple(eSessionType::CREW, "BACKEND_SESSION_TYPE_CREW"_T), {eSessionType::CREW, "BACKEND_SESSION_TYPE_CREW"},
make_tuple(eSessionType::CLOSED_FRIENDS, "BACKEND_SESSION_TYPE_CLOSED_FRIENDS"_T), {eSessionType::CLOSED_FRIENDS, "BACKEND_SESSION_TYPE_CLOSED_FRIENDS"},
make_tuple(eSessionType::FIND_FRIEND, "BACKEND_SESSION_TYPE_FIND_FRIEND"_T), {eSessionType::FIND_FRIEND, "BACKEND_SESSION_TYPE_FIND_FRIEND"},
make_tuple(eSessionType::SOLO, "BACKEND_SESSION_TYPE_SOLO"_T), {eSessionType::SOLO, "BACKEND_SESSION_TYPE_SOLO"},
make_tuple(eSessionType::INVITE_ONLY, "BACKEND_SESSION_TYPE_INVITE_ONLY"_T), {eSessionType::INVITE_ONLY, "BACKEND_SESSION_TYPE_INVITE_ONLY"},
make_tuple(eSessionType::JOIN_CREW, "BACKEND_SESSION_TYPE_JOIN_CREW"_T), {eSessionType::JOIN_CREW, "BACKEND_SESSION_TYPE_JOIN_CREW"},
make_tuple(eSessionType::SC_TV, "BACKEND_SESSION_TYPE_SC_TV"_T), {eSessionType::SC_TV, "BACKEND_SESSION_TYPE_SC_TV"},
make_tuple(eSessionType::LEAVE_ONLINE, "BACKEND_SESSION_TYPE_LEAVE_ONLINE"_T) {eSessionType::LEAVE_ONLINE, "BACKEND_SESSION_TYPE_LEAVE_ONLINE"}
}; });
for (const auto& [id, name] : sessions) for (const auto& [id, name] : sessions)
{ {
components::selectable(name, false, [&id] { components::selectable(g_translation_service.get_translation(name), false, [&id] {
session::join_type(id); session::join_type(id);
}); });
} }

View File

@ -14,20 +14,20 @@ namespace big
struct custom_weapon struct custom_weapon
{ {
big::CustomWeapon id; big::CustomWeapon id;
const std::string_view name; const char* name;
}; };
const custom_weapon custom_weapons[] = { constexpr auto custom_weapons = std::to_array<custom_weapon>({
{big::CustomWeapon::NONE, "VIEW_SELF_WEAPONS_NONE"_T}, {big::CustomWeapon::NONE, "VIEW_SELF_WEAPONS_NONE"},
{big::CustomWeapon::CAGE_GUN, "VIEW_SELF_WEAPONS_CAGE_GUN"_T}, {big::CustomWeapon::CAGE_GUN, "VIEW_SELF_WEAPONS_CAGE_GUN"},
{big::CustomWeapon::DELETE_GUN, "VIEW_SELF_WEAPONS_DELETE_GUN"_T}, {big::CustomWeapon::DELETE_GUN, "VIEW_SELF_WEAPONS_DELETE_GUN"},
{big::CustomWeapon::GRAVITY_GUN, "VIEW_SELF_WEAPONS_GRAVITY_GUN"_T}, {big::CustomWeapon::GRAVITY_GUN, "VIEW_SELF_WEAPONS_GRAVITY_GUN"},
{big::CustomWeapon::STEAL_VEHICLE_GUN, "BACKEND_LOOPED_WEAPONS_STEAL_VEHICLE_GUN"_T}, {big::CustomWeapon::STEAL_VEHICLE_GUN, "BACKEND_LOOPED_WEAPONS_STEAL_VEHICLE_GUN"},
{big::CustomWeapon::REPAIR_GUN, "BACKEND_LOOPED_WEAPONS_REPAIR_GUN"_T}, {big::CustomWeapon::REPAIR_GUN, "BACKEND_LOOPED_WEAPONS_REPAIR_GUN"},
{big::CustomWeapon::VEHICLE_GUN, "BACKEND_LOOPED_WEAPONS_VEHICLE_GUN"_T}, {big::CustomWeapon::VEHICLE_GUN, "BACKEND_LOOPED_WEAPONS_VEHICLE_GUN"},
{big::CustomWeapon::TP_GUN, "VIEW_SELF_WEAPONS_TP_GUN"_T}, {big::CustomWeapon::TP_GUN, "VIEW_SELF_WEAPONS_TP_GUN"},
{big::CustomWeapon::PAINT_GUN, "VIEW_SELF_WEAPONS_PAINT_GUN"_T}, {big::CustomWeapon::PAINT_GUN, "VIEW_SELF_WEAPONS_PAINT_GUN"},
}; });
void view::weapons() void view::weapons()
{ {
@ -133,11 +133,11 @@ namespace big
ImGui::Checkbox("VIEW_WEAPON_CUSTOM_GUN_ONLY_FIRES_WHEN_THE_WEAPON_IS_OUT"_T.data(), &g.self.custom_weapon_stop); ImGui::Checkbox("VIEW_WEAPON_CUSTOM_GUN_ONLY_FIRES_WHEN_THE_WEAPON_IS_OUT"_T.data(), &g.self.custom_weapon_stop);
CustomWeapon selected = g.weapons.custom_weapon; CustomWeapon selected = g.weapons.custom_weapon;
if (ImGui::BeginCombo("WEAPON"_T.data(), custom_weapons[(int)selected].name.data())) if (ImGui::BeginCombo("WEAPON"_T.data(), g_translation_service.get_translation(custom_weapons[(int)selected].name).data()))
{ {
for (const custom_weapon& weapon : custom_weapons) for (const custom_weapon& weapon : custom_weapons)
{ {
if (ImGui::Selectable(weapon.name.data(), weapon.id == selected)) if (ImGui::Selectable(g_translation_service.get_translation(weapon.name).data(), weapon.id == selected))
{ {
g.weapons.custom_weapon = weapon.id; g.weapons.custom_weapon = weapon.id;
} }