diff --git a/src/backend/looped/world/ocean.cpp b/src/backend/looped/world/ocean.cpp new file mode 100644 index 00000000..48f593c9 --- /dev/null +++ b/src/backend/looped/world/ocean.cpp @@ -0,0 +1,73 @@ +#include "backend/looped_command.hpp" +#include "pointers.hpp" +#include "script.hpp" + +namespace big +{ + class modify_ocean : looped_command + { + using looped_command::looped_command; + + struct quad_info + { + uint64_t m_quad_pool; + short m_quad_count; + }; + + struct ocean_quad + { + private: + char pad_0[0x8]; + public: + int m_opacity; + private: + char pad_1[0x8]; + public: + float m_height; + }; + + virtual void on_tick() override + { + if (auto ocean_quads = reinterpret_cast(g_pointers->m_gta.m_ocean_quads)) + { + for (uint64_t i = 0; i < ocean_quads->m_quad_count; i++) + { + const auto index = ocean_quads->m_quad_pool + (i * 0x1C); + const auto quad = reinterpret_cast(index); + + // Disable ocean by lowering its height + if (g.world.ocean.disable_ocean) + quad->m_height = -10000.f; + else + quad->m_height = 0.f; + + // Change the ocean's opacity (alpha) + if (g.world.ocean.ocean_opacity == 100) + quad->m_opacity = 0x1A1A1A1A; + else if (!g.world.ocean.ocean_opacity) + quad->m_opacity = 0x01010101; + else + quad->m_opacity = (int)(255 * (float)(g.world.ocean.ocean_opacity / 100.f)); + } + } + } + + virtual void on_disable() override + { + if (auto ocean_quads = reinterpret_cast(g_pointers->m_gta.m_ocean_quads)) + { + for (uint64_t i = 0; i < ocean_quads->m_quad_count; i++) + { + const auto index = ocean_quads->m_quad_pool + (i * 0x1C); + const auto quad = reinterpret_cast(index); + + quad->m_height = 0.f; + quad->m_opacity = 0x1A1A1A1A; + } + } + } + }; + + modify_ocean g_modify_ocean("modifyocean", "BACKEND_LOOPED_WORLD_MODIFY_OCEAN", "BACKEND_LOOPED_WORLD_MODIFY_OCEAN_DESC", g.world.ocean.modify_ocean); + bool_command g_disable_ocean("disableocean", "BACKEND_LOOPED_WORLD_DISABLE_OCEAN", "BACKEND_LOOPED_WORLD_DISABLE_OCEAN_DESC", g.world.ocean.disable_ocean); +} \ No newline at end of file diff --git a/src/core/settings.hpp b/src/core/settings.hpp index 10aabf96..9e09da3a 100644 --- a/src/core/settings.hpp +++ b/src/core/settings.hpp @@ -542,6 +542,15 @@ namespace big NLOHMANN_DEFINE_TYPE_INTRUSIVE(water, part_water) } water{}; + struct ocean + { + bool modify_ocean = false; + bool disable_ocean = false; + int ocean_opacity = 100; + + NLOHMANN_DEFINE_TYPE_INTRUSIVE(ocean, modify_ocean, disable_ocean, ocean_opacity) + } ocean{}; + struct spawn_ped { bool preview_ped = false; diff --git a/src/function_types.hpp b/src/function_types.hpp index 126575c6..768c69c1 100644 --- a/src/function_types.hpp +++ b/src/function_types.hpp @@ -117,6 +117,8 @@ namespace big::functions using start_get_presence_attributes = bool (*)(int profile_index, rage::rlScHandle* handle, int num_handles, rage::rlQueryPresenceAttributesContext** contexts, int count, rage::rlScTaskStatus* state); using join_session_by_info = bool (*)(Network* network, rage::rlSessionInfo* info, int unk, int flags, rage::rlGamerHandle* handles, int handlecount); + using invite_player_by_gamer_handle = bool(*)(uint64_t config, rage::rlGamerHandle* handle, int unk1, int unk2, int unk3, int unk4); + using generate_uuid = bool (*)(uint64_t* uuid); using get_vehicle_gadget_array_size = int (*)(eVehicleGadgetType type); diff --git a/src/gta_pointers.hpp b/src/gta_pointers.hpp index c6738a61..6f6f5546 100644 --- a/src/gta_pointers.hpp +++ b/src/gta_pointers.hpp @@ -92,6 +92,8 @@ namespace big uint32_t* m_region_code; + uint64_t m_ocean_quads; + PVOID m_world_model_spawn_bypass; PVOID m_native_return; PVOID m_get_label_text; @@ -158,6 +160,9 @@ namespace big functions::start_matchmaking_find_sessions m_start_matchmaking_find_sessions; functions::join_session_by_info m_join_session_by_info; + functions::invite_player_by_gamer_handle m_invite_player_by_gamer_handle; + uint64_t m_network_config; + functions::reset_network_complaints m_reset_network_complaints; functions::fidevice_get_device m_fidevice_get_device; diff --git a/src/pointers.cpp b/src/pointers.cpp index 8ba01ef0..74dd026f 100644 --- a/src/pointers.cpp +++ b/src/pointers.cpp @@ -33,6 +33,15 @@ namespace big g_pointers->m_gta.m_region_code = ptr.add(16).rip().add(1).as(); } }, + // Ocean Quads + { + "OQ", + "74 41 4C 8B 05 ? ? ?", + [](memory::handle ptr) + { + g_pointers->m_gta.m_ocean_quads = ptr.add(5).rip().as(); + } + }, // Game State { "GS", @@ -610,6 +619,24 @@ namespace big g_pointers->m_gta.m_join_session_by_info = ptr.add(1).rip().as(); } }, + // Invite Player By Gamer Handle + { + "IPBGH", + "E8 ? ? ? ? 4C 8D 05 ? ? ? ? 48 8D 15 ? ? ? ? E9", + [](memory::handle ptr) + { + g_pointers->m_gta.m_invite_player_by_gamer_handle = ptr.add(1).rip().as(); + } + }, + // Network Config + { + "NC", + "48 8B 0D ? ? ? ? 45 33 C9 48 8B D7", + [](memory::handle ptr) + { + g_pointers->m_gta.m_network_config = ptr.add(3).rip().as(); + } + }, // Script VM { "VM", diff --git a/src/util/session.hpp b/src/util/session.hpp index 5fdf677a..1794b544 100644 --- a/src/util/session.hpp +++ b/src/util/session.hpp @@ -158,6 +158,18 @@ namespace big::session }); } + inline void invite_by_rockstar_id(uint64_t rid) + { + rage::rlGamerHandle player_handle(rid); + + bool success = g_pointers->m_gta.m_invite_player_by_gamer_handle(g_pointers->m_gta.m_network_config, &player_handle, 1, 0, 0, 0); + + if (!success) + return g_notification_service->push_error("Network", "Target player could not be invited, they might be offline?"); + + g_notification_service->push_success("Network", "Target player has been invited to your session!"); + } + inline void add_infraction(player_ptr player, Infraction infraction, const std::string& custom_reason = "") { if (g.debug.fuzzer.enabled) diff --git a/src/views/network/view_player_database.cpp b/src/views/network/view_player_database.cpp index 82a3e793..692b96ca 100644 --- a/src/views/network/view_player_database.cpp +++ b/src/views/network/view_player_database.cpp @@ -208,6 +208,10 @@ namespace big session::join_by_rockstar_id(current_player->rockstar_id); }); + components::button("INVITE_PLAYER"_T, [] { + session::invite_by_rockstar_id(current_player->rockstar_id); + }); + static char message[256]; components::input_text("INPUT_MSG"_T, message, sizeof(message)); if (components::button("SEND_MSG"_T)) diff --git a/src/views/view.hpp b/src/views/view.hpp index 3a706b7c..26156b89 100644 --- a/src/views/view.hpp +++ b/src/views/view.hpp @@ -56,6 +56,7 @@ namespace big static void spawn_ped(); static void squad_spawner(); static void time_and_weather(); + static void ocean(); static void spoofing(); static void teleport(); static void custom_teleport(); diff --git a/src/views/world/view_ocean.cpp b/src/views/world/view_ocean.cpp new file mode 100644 index 00000000..3a72ad93 --- /dev/null +++ b/src/views/world/view_ocean.cpp @@ -0,0 +1,16 @@ +#include "views/view.hpp" + +namespace big +{ + void view::ocean() + { + components::command_checkbox<"modifyocean">(); + + if (g.world.ocean.modify_ocean) + { + components::command_checkbox<"disableocean">(); + + ImGui::SliderInt("OCEAN_OPACITY"_T.data(), &g.world.ocean.ocean_opacity, 0, 100); + } + } +} \ No newline at end of file diff --git a/src/views/world/view_world.cpp b/src/views/world/view_world.cpp index 28b6cdd8..22d9fd6f 100644 --- a/src/views/world/view_world.cpp +++ b/src/views/world/view_world.cpp @@ -14,6 +14,11 @@ namespace big view::time_and_weather(); } + ImGui::SeparatorText("GUI_TAB_OCEAN"_T.data()); + { + view::ocean(); + } + ImGui::SeparatorText("PED"_T.data()); components::button("VIEW_DEBUG_THREADS_KILL"_T, [] {