From 6149b8ec9b801e8f4bfb0de41da6ecd0a2b58390 Mon Sep 17 00:00:00 2001 From: Andreas Maerten <24669514+Yimura@users.noreply.github.com> Date: Wed, 21 Feb 2024 23:34:11 +0100 Subject: [PATCH] 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 --- src/backend/looped/weapons/rapid_fire.cpp | 21 ++++++++++- src/backend/reactions/reaction.cpp | 2 +- src/byte_patch_manager.cpp | 4 +- src/core/settings.hpp | 2 +- src/gta_pointers.hpp | 2 +- src/pointers.cpp | 4 +- src/views/network/view_network.cpp | 46 ++++++++--------------- src/views/self/view_weapons.cpp | 28 +++++++------- 8 files changed, 57 insertions(+), 52 deletions(-) diff --git a/src/backend/looped/weapons/rapid_fire.cpp b/src/backend/looped/weapons/rapid_fire.cpp index 6e8d0f8b..4d7f1335 100644 --- a/src/backend/looped/weapons/rapid_fire.cpp +++ b/src/backend/looped/weapons/rapid_fire.cpp @@ -10,11 +10,27 @@ namespace big { 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 { 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); 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); } diff --git a/src/backend/reactions/reaction.cpp b/src/backend/reactions/reaction.cpp index c6e62afb..4354297a 100644 --- a/src/backend/reactions/reaction.cpp +++ b/src/backend/reactions/reaction.cpp @@ -63,7 +63,7 @@ namespace big if (announce_in_chat) { 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()(*g_pointers->m_gta.m_send_chat_ptr, g_player_service->get_self()->get_net_data(), diff --git a/src/byte_patch_manager.cpp b/src/byte_patch_manager.cpp index 30f8aeab..6e48fab3 100644 --- a/src/byte_patch_manager.cpp +++ b/src/byte_patch_manager.cpp @@ -23,8 +23,10 @@ namespace big memory::byte_patch::make(g_pointers->m_gta.m_max_wanted_level.add(14).rip().as(), 0).get(); // Patch World Model Spawn Bypass + std::array world_spawn_patch; + std::fill(world_spawn_patch.begin(), world_spawn_patch.end(), 0x90); 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(), 0).get(); + memory::byte_patch::make(g_pointers->m_gta.m_world_model_spawn_bypass, world_spawn_patch).get(); // Patch blocked explosions explosion_anti_cheat_bypass::m_can_blame_others = diff --git a/src/core/settings.hpp b/src/core/settings.hpp index d77ca096..a68aa87a 100644 --- a/src/core/settings.hpp +++ b/src/core/settings.hpp @@ -625,7 +625,7 @@ namespace big NLOHMANN_DEFINE_TYPE_INTRUSIVE(auto_disarm, enable, neutralize) } 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{}; struct model_swapper diff --git a/src/gta_pointers.hpp b/src/gta_pointers.hpp index 9f3f7e97..147f40a7 100644 --- a/src/gta_pointers.hpp +++ b/src/gta_pointers.hpp @@ -43,7 +43,7 @@ namespace big { memory::handle m_max_wanted_level; - memory::handle m_world_model_spawn_bypass; + PVOID m_world_model_spawn_bypass; memory::handle m_blame_explode; diff --git a/src/pointers.cpp b/src/pointers.cpp index 6e09bb24..69e185be 100644 --- a/src/pointers.cpp +++ b/src/pointers.cpp @@ -1510,10 +1510,10 @@ namespace big // World Model Spawn Bypass { "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) { - g_pointers->m_gta.m_world_model_spawn_bypass = ptr; + g_pointers->m_gta.m_world_model_spawn_bypass = ptr.as(); } }, // Blame Explode diff --git a/src/views/network/view_network.cpp b/src/views/network/view_network.cpp index 8c99a7df..5ddb0489 100644 --- a/src/views/network/view_network.cpp +++ b/src/views/network/view_network.cpp @@ -19,26 +19,12 @@ namespace big { - /*struct SessionType + struct SessionType { 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() { ImGui::BeginGroup(); @@ -105,23 +91,23 @@ namespace big ImGui::Spacing(); - static const std::vector> sessions = { //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), - make_tuple(eSessionType::NEW_PUBLIC, "BACKEND_SESSION_TYPE_NEW_PUBLIC"_T), - make_tuple(eSessionType::CLOSED_CREW, "BACKEND_SESSION_TYPE_CLOSED_CREW"_T), - make_tuple(eSessionType::CREW, "BACKEND_SESSION_TYPE_CREW"_T), - make_tuple(eSessionType::CLOSED_FRIENDS, "BACKEND_SESSION_TYPE_CLOSED_FRIENDS"_T), - make_tuple(eSessionType::FIND_FRIEND, "BACKEND_SESSION_TYPE_FIND_FRIEND"_T), - make_tuple(eSessionType::SOLO, "BACKEND_SESSION_TYPE_SOLO"_T), - make_tuple(eSessionType::INVITE_ONLY, "BACKEND_SESSION_TYPE_INVITE_ONLY"_T), - make_tuple(eSessionType::JOIN_CREW, "BACKEND_SESSION_TYPE_JOIN_CREW"_T), - make_tuple(eSessionType::SC_TV, "BACKEND_SESSION_TYPE_SC_TV"_T), - make_tuple(eSessionType::LEAVE_ONLINE, "BACKEND_SESSION_TYPE_LEAVE_ONLINE"_T) - }; + static const auto sessions = std::to_array({ //This has to be here because if it's generated at compile time, the translations break for some reason. + {eSessionType::JOIN_PUBLIC, "BACKEND_SESSION_TYPE_JOIN_PUBLIC"}, + {eSessionType::NEW_PUBLIC, "BACKEND_SESSION_TYPE_NEW_PUBLIC"}, + {eSessionType::CLOSED_CREW, "BACKEND_SESSION_TYPE_CLOSED_CREW"}, + {eSessionType::CREW, "BACKEND_SESSION_TYPE_CREW"}, + {eSessionType::CLOSED_FRIENDS, "BACKEND_SESSION_TYPE_CLOSED_FRIENDS"}, + {eSessionType::FIND_FRIEND, "BACKEND_SESSION_TYPE_FIND_FRIEND"}, + {eSessionType::SOLO, "BACKEND_SESSION_TYPE_SOLO"}, + {eSessionType::INVITE_ONLY, "BACKEND_SESSION_TYPE_INVITE_ONLY"}, + {eSessionType::JOIN_CREW, "BACKEND_SESSION_TYPE_JOIN_CREW"}, + {eSessionType::SC_TV, "BACKEND_SESSION_TYPE_SC_TV"}, + {eSessionType::LEAVE_ONLINE, "BACKEND_SESSION_TYPE_LEAVE_ONLINE"} + }); 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); }); } diff --git a/src/views/self/view_weapons.cpp b/src/views/self/view_weapons.cpp index 801d33d2..1fa028c1 100644 --- a/src/views/self/view_weapons.cpp +++ b/src/views/self/view_weapons.cpp @@ -14,20 +14,20 @@ namespace big struct custom_weapon { big::CustomWeapon id; - const std::string_view name; + const char* name; }; - const custom_weapon custom_weapons[] = { - {big::CustomWeapon::NONE, "VIEW_SELF_WEAPONS_NONE"_T}, - {big::CustomWeapon::CAGE_GUN, "VIEW_SELF_WEAPONS_CAGE_GUN"_T}, - {big::CustomWeapon::DELETE_GUN, "VIEW_SELF_WEAPONS_DELETE_GUN"_T}, - {big::CustomWeapon::GRAVITY_GUN, "VIEW_SELF_WEAPONS_GRAVITY_GUN"_T}, - {big::CustomWeapon::STEAL_VEHICLE_GUN, "BACKEND_LOOPED_WEAPONS_STEAL_VEHICLE_GUN"_T}, - {big::CustomWeapon::REPAIR_GUN, "BACKEND_LOOPED_WEAPONS_REPAIR_GUN"_T}, - {big::CustomWeapon::VEHICLE_GUN, "BACKEND_LOOPED_WEAPONS_VEHICLE_GUN"_T}, - {big::CustomWeapon::TP_GUN, "VIEW_SELF_WEAPONS_TP_GUN"_T}, - {big::CustomWeapon::PAINT_GUN, "VIEW_SELF_WEAPONS_PAINT_GUN"_T}, - }; + constexpr auto custom_weapons = std::to_array({ + {big::CustomWeapon::NONE, "VIEW_SELF_WEAPONS_NONE"}, + {big::CustomWeapon::CAGE_GUN, "VIEW_SELF_WEAPONS_CAGE_GUN"}, + {big::CustomWeapon::DELETE_GUN, "VIEW_SELF_WEAPONS_DELETE_GUN"}, + {big::CustomWeapon::GRAVITY_GUN, "VIEW_SELF_WEAPONS_GRAVITY_GUN"}, + {big::CustomWeapon::STEAL_VEHICLE_GUN, "BACKEND_LOOPED_WEAPONS_STEAL_VEHICLE_GUN"}, + {big::CustomWeapon::REPAIR_GUN, "BACKEND_LOOPED_WEAPONS_REPAIR_GUN"}, + {big::CustomWeapon::VEHICLE_GUN, "BACKEND_LOOPED_WEAPONS_VEHICLE_GUN"}, + {big::CustomWeapon::TP_GUN, "VIEW_SELF_WEAPONS_TP_GUN"}, + {big::CustomWeapon::PAINT_GUN, "VIEW_SELF_WEAPONS_PAINT_GUN"}, + }); 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); 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) { - 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; }