diff --git a/src/backend/backend.cpp b/src/backend/backend.cpp index 004a6542..fd8d2f2d 100644 --- a/src/backend/backend.cpp +++ b/src/backend/backend.cpp @@ -21,6 +21,9 @@ namespace big { void bypass_battleye() { + if (g.spoofing.spoof_game_data_hash) + return; + constexpr std::array valid_hashes = {4022154788, 988, 3512952254, 472, 0, 0, 3308328917, 0, 0, 1731098795, 2256610353, 18616, 1540917665, 307143837, 1629784955, 2012170620}; if (auto hashes = *g_pointers->m_gta.m_game_data_hash) diff --git a/src/backend/commands/player/kick/battleye.cpp b/src/backend/commands/player/kick/battleye.cpp index bae9eba2..eeca1812 100644 --- a/src/backend/commands/player/kick/battleye.cpp +++ b/src/backend/commands/player/kick/battleye.cpp @@ -27,11 +27,55 @@ namespace big msg.write(KickReason::BATTLEYE_KICK, 5); msg.write(0, 32); msg.write(false, 1); - auto msg_id = player->get_session_player()->m_msg_id; msg.send(msg_id); } }; + class battleye_ban : player_command + { + using player_command::player_command; + + virtual CommandAccessLevel get_access_level() override + { + return CommandAccessLevel::TOXIC; + } + + virtual void execute(player_ptr player, const command_arguments& _args, const std::shared_ptr ctx) override + { + packet msg{}; + + msg.write_message(rage::eNetMessage::MsgKickPlayer); + msg.write(KickReason::BATTLEYE_BAN, 5); + msg.write(0, 32); + msg.write(false, 1); + auto msg_id = player->get_session_player()->m_msg_id; + msg.send(msg_id); + } + }; + + class battleye_update_kick : player_command + { + using player_command::player_command; + + virtual CommandAccessLevel get_access_level() override + { + return CommandAccessLevel::TOXIC; + } + + virtual void execute(player_ptr player, const command_arguments& _args, const std::shared_ptr ctx) override + { + unsigned char data[] = {0x00, 0x50, 0x31, 0x4A, 0xC0, 0x1A, 0x13, 0xFF, 0xFF, 0xFF}; + player->tampered_with_be = true; + for (int i = 0; i < 20; i++) + { + data[0] = i; + g_battleye_service.send_message_to_client(player->get_net_game_player()->get_host_token(), &data, sizeof(data)); + } + } + }; + battleye_kick g_battleye_kick("battlekick", "BATTLEYE_KICK", "BATTLEYE_KICK_DESC", 0); + battleye_ban g_battleye_ban("battleban", "BATTLEYE_FAKE_BAN", "BATTLEYE_FAKE_BAN_DESC", 0); + battleye_update_kick g_battleye_update_kick("battleupdate", "BATTLEYE_UPDATE_KICK", "BATTLEYE_UPDATE_KICK_DESC", 0); } \ No newline at end of file diff --git a/src/core/data/all_script_names.hpp b/src/core/data/all_script_names.hpp index d851e719..5affbff6 100644 --- a/src/core/data/all_script_names.hpp +++ b/src/core/data/all_script_names.hpp @@ -200,6 +200,17 @@ namespace big "fm_content_daily_bounty"_J, "fm_content_dispatch_work"_J, "fm_content_pizza_delivery"_J, + "fm_content_hacker_cargo_finale"_J, + "fm_content_hacker_zancudo_fin"_J, + "fm_content_hacker_house_finale"_J, + "fm_content_hacker_whistle_fin"_J, + "fm_content_hacker_cargo_prep"_J, + "fm_content_hacker_zancudo_prep"_J, + "fm_content_hacker_house_prep"_J, + "fm_content_hacker_whistle_prep"_J, + "fm_content_arms_trafficking"_J, + "AM_MP_HOTWIRE"_J, + "fm_content_community_outreach"_J, "AM_BOAT_TAXI"_J, "AM_HELI_TAXI"_J, "fm_hold_up_tut"_J, @@ -228,7 +239,7 @@ namespace big "fm_Bj_race_controler"_J, "fm_deathmatch_controler"_J, "fm_hideout_controler"_J, - "fm_mission_controller_2020"_J, + "FM_Mission_controller"_J, "FM_Race_Controler"_J, "FM_Horde_Controler"_J, "dont_cross_the_line"_J, @@ -360,10 +371,13 @@ namespace big "am_mp_creator_trailer", "am_mp_defunct_base", "am_mp_drone", + "am_mp_field_hangar", "am_mp_fixer_hq", "am_mp_garage_control", + "am_mp_hacker_den", "am_mp_hacker_truck", "am_mp_hangar", + "am_mp_hotwire", "am_mp_ie_warehouse", "am_mp_island", "am_mp_juggalo_hideout", @@ -375,6 +389,7 @@ namespace big "am_mp_property_ext", "am_mp_property_int", "am_mp_rc_vehicle", + "am_mp_rpa_menu", "am_mp_salvage_yard", "am_mp_shooting_range", "am_mp_simeon_showroom", @@ -401,6 +416,7 @@ namespace big "am_prostitute", "am_rollercoaster", "am_rontrevor_cut", + "am_simosa", "am_taxi", "am_vehicle_spawn", "animal_controller", @@ -420,6 +436,7 @@ namespace big "appemail", "appextraction", "appfixersecurity", + "apphackerden", "apphackertruck", "apphs_sleep", "appimportexport", @@ -533,6 +550,7 @@ namespace big "chinese1", "chinese2", "chop", + "circuitblockhack", "clothes_shop_mp", "clothes_shop_sp", "code_controller", @@ -639,6 +657,7 @@ namespace big "fbi4_prep4", "fbi4_prep5", "fbi5a", + "field_hangar_seating", "finalea", "finaleb", "finalec1", @@ -677,6 +696,7 @@ namespace big "fm_content_acid_lab_source", "fm_content_ammunation", "fm_content_armoured_truck", + "fm_content_arms_trafficking", "fm_content_auto_shop_delivery", "fm_content_bank_shootout", "fm_content_bar_resupply", @@ -691,16 +711,26 @@ namespace big "fm_content_club_management", "fm_content_club_odd_jobs", "fm_content_club_source", + "fm_content_community_outreach", "fm_content_convoy", "fm_content_crime_scene", "fm_content_daily_bounty", "fm_content_dispatch_work", + "fm_content_drone", "fm_content_drug_lab_work", "fm_content_drug_vehicle", "fm_content_export_cargo", "fm_content_ghosthunt", "fm_content_golden_gun", "fm_content_gunrunning", + "fm_content_hacker_cargo_finale", + "fm_content_hacker_cargo_prep", + "fm_content_hacker_house_finale", + "fm_content_hacker_house_prep", + "fm_content_hacker_whistle_fin", + "fm_content_hacker_whistle_prep", + "fm_content_hacker_zancudo_fin", + "fm_content_hacker_zancudo_prep", "fm_content_hsw_setup", "fm_content_hsw_time_trial", "fm_content_island_dj", @@ -882,6 +912,9 @@ namespace big "gunclub_shop", "gunfighttest", "gunslinger_arcade", + "hacker_den_carmod", + "hacker_den_ext_seating", + "hacker_den_seating", "hacker_truck_carmod", "hairdo_shop_mp", "hairdo_shop_sp", @@ -1027,7 +1060,6 @@ namespace big "net_freemode_debug_2023", "net_freemode_debug_stat_2023", "net_jacking_soaktest", - "net_rank_tunable_loader", "net_session_soaktest", "net_test_drive", "net_tunable_check", @@ -1136,7 +1168,6 @@ namespace big "profiler_registration", "prologue1", "prop_drop", - "public_mission_creator", "puzzle", "racetest", "rampage1", @@ -1326,6 +1357,7 @@ namespace big "wardrobe_sp", "weapon_audio_widget", "wizard_arcade", + "word_hack", "wp_partyboombox", "xml_menus", "yoga", diff --git a/src/gta_pointers.hpp b/src/gta_pointers.hpp index 1a5c871e..dd1ce290 100644 --- a/src/gta_pointers.hpp +++ b/src/gta_pointers.hpp @@ -408,6 +408,9 @@ namespace big PVOID m_network_can_access_multiplayer; PVOID m_be_network_bail_patch; + + PVOID m_add_skeleton_extension; + int* m_skeleton_extension_count; }; #pragma pack(pop) static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned"); diff --git a/src/hooking/hooking.cpp b/src/hooking/hooking.cpp index 64489c53..86168de2 100644 --- a/src/hooking/hooking.cpp +++ b/src/hooking/hooking.cpp @@ -157,6 +157,8 @@ namespace big detour_hook_helper::add("NCAM", g_pointers->m_gta.m_network_can_access_multiplayer); + detour_hook_helper::add("ASE", g_pointers->m_gta.m_add_skeleton_extension); + g_hooking = this; } diff --git a/src/hooking/hooking.hpp b/src/hooking/hooking.hpp index c1e91972..f6381edd 100644 --- a/src/hooking/hooking.hpp +++ b/src/hooking/hooking.hpp @@ -212,6 +212,8 @@ namespace big static void* create_pool_item(GenericPool* pool); static uint32_t network_can_access_multiplayer(uint32_t a1, uint64_t* a2); + + static void* add_skeleton_extension(rage::fwEntity* entity); }; class minhook_keepalive diff --git a/src/hooks/protections/add_skeleton_extension.cpp b/src/hooks/protections/add_skeleton_extension.cpp new file mode 100644 index 00000000..4d8ddd57 --- /dev/null +++ b/src/hooks/protections/add_skeleton_extension.cpp @@ -0,0 +1,15 @@ +#include "hooking/hooking.hpp" +#include "pointers.hpp" + +namespace big +{ + void* hooks::add_skeleton_extension(rage::fwEntity* entity) + { + if (*g_pointers->m_gta.m_skeleton_extension_count >= 32) [[unlikely]] + { + return nullptr; + } + + return g_hooking->get_original()(entity); + } +} \ No newline at end of file diff --git a/src/hooks/protections/received_event.cpp b/src/hooks/protections/received_event.cpp index b7c9552d..b5c9b617 100644 --- a/src/hooks/protections/received_event.cpp +++ b/src/hooks/protections/received_event.cpp @@ -267,7 +267,7 @@ namespace big return false; } - void scan_explosion_event(CNetGamePlayer* player, rage::datBitBuffer* buffer) + bool scan_explosion_event(CNetGamePlayer* player, rage::datBitBuffer* buffer) { uint16_t f186; uint16_t targetEntity; @@ -302,6 +302,8 @@ namespace big uint32_t f164; + uint32_t interiorIndex; + float posX224; float posY224; float posZ224; @@ -345,6 +347,8 @@ namespace big f191 = buffer->Read(1); f164 = buffer->Read(32); + interiorIndex = buffer->Read(32); + if (f242) { posX224 = buffer->ReadSignedFloat(31, 27648.0f); @@ -358,10 +362,14 @@ namespace big posZ224 = 0; } - auto f168 = buffer->Read(32);// >= 1868: f_168 - - f240 = buffer->Read(1); + + if (addOwnedExplosion) + { + buffer->Read(32); + buffer->Read(32); + } + if (f240) { f218 = buffer->Read(16); @@ -374,6 +382,12 @@ namespace big buffer->Seek(0); + if (*(int16_t*)&interiorIndex < -1) + { + notify::crash_blocked(player, "invalid interior"); + return true; + } + auto object = g_pointers->m_gta.m_get_net_object(*g_pointers->m_gta.m_network_object_mgr, ownerNetId, true); auto entity = object ? object->GetGameObject() : nullptr; @@ -391,7 +405,7 @@ namespace big reinterpret_cast(entity)->m_player_info->m_net_player_data.m_name))); session::add_infraction(g_player_service->get_by_id(player->m_player_id), Infraction::BLAME_EXPLOSION_DETECTED); LOGF(stream::net_events, WARNING, "{} sent an EXPLOSION_EVENT with addOwnedExplosion enabled and with the wrong owner", player->get_name()); - return; + return true; } if (g.session.explosion_karma && g_local_player @@ -403,6 +417,7 @@ namespace big }); } + return false; // clang-format on } diff --git a/src/hooks/protections/script_event_handler.cpp b/src/hooks/protections/script_event_handler.cpp index 56b90923..e3f59025 100644 --- a/src/hooks/protections/script_event_handler.cpp +++ b/src/hooks/protections/script_event_handler.cpp @@ -440,7 +440,7 @@ namespace big } case eRemoteEvent::StartScriptBegin: { - auto script_id = args[3]; + int script_id = args[3]; if (!protection::should_allow_script_launch(script_id)) { diff --git a/src/pointers.cpp b/src/pointers.cpp index b47fa6f9..193dee26 100644 --- a/src/pointers.cpp +++ b/src/pointers.cpp @@ -1914,6 +1914,17 @@ namespace big { g_pointers->m_gta.m_be_network_bail_patch = ptr.add(17).rip().add(1).rip().as(); } + }, + // Add Skeleton Extension + { + "ASE", + "E8 ? ? ? ? 48 89 44 24 ? 48 85 C0 0F 84 ? ? ? ? 0F 28 05", + [](memory::handle ptr) + { + ptr = ptr.rip(); + g_pointers->m_gta.m_add_skeleton_extension = ptr.as(); + g_pointers->m_gta.m_skeleton_extension_count = ptr.add(0x2C).rip().as(); + } } >(); // don't leave a trailing comma at the end diff --git a/src/services/gta_data/gta_data_service.cpp b/src/services/gta_data/gta_data_service.cpp index ed99eeea..24ec1776 100644 --- a/src/services/gta_data/gta_data_service.cpp +++ b/src/services/gta_data/gta_data_service.cpp @@ -429,6 +429,9 @@ namespace big const auto name = item.child("Name").text().as_string(); const auto hash = rage::joaat(name); + if (hash == "WEAPON_STRICKLER"_J) // Gen9 exclusive + continue; + if (hash == "WEAPON_BIRD_CRAP"_J) continue; diff --git a/src/util/scripts.hpp b/src/util/scripts.hpp index b02158c0..9e645098 100644 --- a/src/util/scripts.hpp +++ b/src/util/scripts.hpp @@ -119,7 +119,7 @@ namespace big::scripts { if (((CGameScriptHandlerNetComponent*)launcher->m_net_component)->is_player_a_participant(plyr->get_net_game_player())) { - if (*script_local(launcher->m_stack, 238).at(plyr->id(), 3).at(2).as() == state) + if (*script_local(launcher->m_stack, 240).at(plyr->id(), 3).at(2).as() == state) { set = true; break; @@ -187,7 +187,7 @@ namespace big::scripts // 6) Actually get the script to start misc::set_bit(scr_globals::launcher_global.at(1).as(), 1); // run immediately *scr_globals::launcher_global.at(2).as() = 6; // will change to 7 shortly but that's fine as players are guaranteed not to be in the waiting stage - *script_local(launcher->m_stack, 238).at(self::id, 3).at(2).as() = 6; + *script_local(launcher->m_stack, 240).at(self::id, 3).at(2).as() = 6; *scr_globals::launcher_global.at(3).at(1).as() = script_id; launcher->m_context.m_state = rage::eThreadState::running; diff --git a/src/views/players/player/player_kick.cpp b/src/views/players/player/player_kick.cpp index 51c0ebbe..6f19bdd1 100644 --- a/src/views/players/player/player_kick.cpp +++ b/src/views/players/player/player_kick.cpp @@ -15,6 +15,10 @@ namespace big components::player_command_button<"breakup">(g_player_service->get_selected()); ImGui::SameLine(); components::player_command_button<"battlekick">(g_player_service->get_selected()); + ImGui::SameLine(); + components::player_command_button<"battleban">(g_player_service->get_selected()); + ImGui::SameLine(); + components::player_command_button<"battleupdate">(g_player_service->get_selected()); ImGui::EndDisabled(); components::player_command_button<"smartkick">(g_player_service->get_selected());