From f6a6f5dd861d63edacb4180ff0725a0db9ae21d3 Mon Sep 17 00:00:00 2001 From: Arthur <121949966+ShinyWasabi@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:34:30 +0300 Subject: [PATCH] Refactor Debug Threads & Expose More Functions (#3408) - Added a search box for the script names in Debug -> Threads. - Added `is_session_started` and `force_script_on_player` functions to the Lua network class. - Added `is_active` and `start_launcher_script` functions to the Lua script class. - Moved `view_stat_editor.cpp` to `src/views/network` from `src/views/settings`. - Added a help text for directly editing the sliders in outfit editor. --- docs/lua/tables/network.md | 27 +- docs/lua/tables/script.md | 28 +- src/lua/bindings/network.cpp | 28 +- src/lua/bindings/script.cpp | 60 +- src/views/debug/view_debug_threads.cpp | 86 +- .../view_stat_editor.cpp | 1288 ++++++++--------- src/views/self/view_outfit_editor.cpp | 2 + 7 files changed, 820 insertions(+), 699 deletions(-) rename src/views/{settings => network}/view_stat_editor.cpp (97%) diff --git a/docs/lua/tables/network.md b/docs/lua/tables/network.md index beaccdf2..7510e04b 100644 --- a/docs/lua/tables/network.md +++ b/docs/lua/tables/network.md @@ -2,7 +2,7 @@ Table containing helper functions for network related features. -## Functions (15) +## Functions (17) ### `trigger_script_event(bitset, _args)` @@ -17,6 +17,15 @@ Call trigger_script_event (TSE) network.trigger_script_event(bitset, _args) ``` +### `is_session_started()` + +Returns true if the local player is in a multiplayer session. + +**Example Usage:** +```lua +network.is_session_started() +``` + ### `give_pickup_rewards(player, reward)` Give the given pickup reward to the given player. @@ -134,7 +143,7 @@ string = network.get_flagged_modder_reason(player_idx) ### `force_script_host(script_name)` -Try to force ourself to be host for the given GTA Script. +Try to force ourself to be host for the given GTA Script. Needs to be called in the fiber pool or a loop. - **Parameters:** - `script_name` (string): Name of the script @@ -144,6 +153,20 @@ Try to force ourself to be host for the given GTA Script. network.force_script_host(script_name) ``` +### `force_script_on_player(player_idx, script_name, instance_id)` + +Forces the given GTA script to be started on a player. Needs to be called in the fiber pool or a loop. + +- **Parameters:** + - `player_idx` (integer): Index of the player. + - `script_name` (string): Name of the script. + - `instance_id` (integer): Instance ID of the script. + +**Example Usage:** +```lua +network.force_script_on_player(script_name) +``` + ### `send_chat_message(msg, team_only)` Sends a message to the in game chat. diff --git a/docs/lua/tables/script.md b/docs/lua/tables/script.md index 6a076e78..3ed540a3 100644 --- a/docs/lua/tables/script.md +++ b/docs/lua/tables/script.md @@ -2,7 +2,7 @@ Table containing helper functions related to gta scripts. -## Functions (5) +## Functions (7) ### `register_looped(name, func)` @@ -67,6 +67,18 @@ script.run_in_fiber(function (script) end) ``` +### `is_active(script_name)` + +Returns true if the specified script is currently active/running. + +- **Parameters:** + - `script_name` (string): The name of the script. + +**Example Usage:** +```lua +local is_freemode_active = script.is_active("freemode") +``` + ### `execute_as_script(script_name, func)` - **Parameters:** @@ -108,4 +120,18 @@ Calls a function from the specified script. **Example Usage:** ```lua script.call_function("Collect Collectible", "freemode", "2D 05 33 00 00", 0, {17, 0, 1, 1, 0}) +``` + +### `start_launcher_script(script_name)` + +Tries to start a launcher script. Needs to be called in the fiber pool or a loop. + +- **Parameters:** + - `name` (string): The name of the script. + +**Example Usage:** +```lua +script.run_in_fiber(function() + script.start_launcher_script("am_hunt_the_beast") +end) ``` \ No newline at end of file diff --git a/src/lua/bindings/network.cpp b/src/lua/bindings/network.cpp index 00e20541..ee69ed45 100644 --- a/src/lua/bindings/network.cpp +++ b/src/lua/bindings/network.cpp @@ -40,6 +40,15 @@ namespace lua::network big::g_pointers->m_gta.m_trigger_script_event(1, actual_args.data(), actual_args.size(), bitset, args[0]); } + // Lua API: Function + // Table: network + // Name: is_session_started + // Returns true if the local player is in a multiplayer session. + static bool is_session_started() + { + return *big::g_pointers->m_gta.m_is_session_started; + } + // Lua API: Function // Table: network // Name: give_pickup_rewards @@ -171,13 +180,26 @@ namespace lua::network // Lua API: Function // Table: network // Name: force_script_host - // Param: script_name: string: Name of the script - // Try to force ourself to be host for the given GTA Script. + // Param: script_name: string: Name of the script. + // Try to force ourself to be host for the given GTA Script. Needs to be called in the fiber pool or a loop. static void force_script_host(const std::string& script_name) { big::scripts::force_host(rage::joaat(script_name)); } + // Lua API: function + // Table: script + // Name: force_script_on_player + // Param: player_idx: integer: Index of the player. + // Param: script_name: string: Name of the script. + // Param: script_name: integer: Instance ID of the script. + // Forces the given GTA script to be started on a player. Needs to be called in the fiber pool or a loop. + static void force_script_on_player(int player_idx, const std::string& script_name, int instance_id) + { + if (auto player = big::g_player_service->get_by_id(player_idx)) + big::scripts::force_script_on_player(player, rage::joaat(script_name), instance_id); + } + // Lua API: Function // Table: network // Name: send_chat_message @@ -335,6 +357,7 @@ namespace lua::network auto ns = state["network"].get_or_create(); ns["trigger_script_event"] = trigger_script_event; + ns["is_session_started"] = is_session_started; ns["give_pickup_rewards"] = give_pickup_rewards; ns["set_player_coords"] = set_player_coords; ns["set_all_player_coords"] = set_all_player_coords; @@ -345,6 +368,7 @@ namespace lua::network ns["is_player_friend"] = is_player_friend; ns["get_flagged_modder_reason"] = get_flagged_modder_reason; ns["force_script_host"] = force_script_host; + ns["force_script_on_player"] = force_script_on_player; ns["send_chat_message"] = send_chat_message; ns["send_chat_message_to_player"] = send_chat_message_to_player; ns["get_player_rank"] = get_player_rank; diff --git a/src/lua/bindings/script.cpp b/src/lua/bindings/script.cpp index a102b936..8875930e 100644 --- a/src/lua/bindings/script.cpp +++ b/src/lua/bindings/script.cpp @@ -7,6 +7,7 @@ #include "lua/bindings/network.hpp" #include "memory/pattern.hpp" #include "services/script_patcher/script_patcher_service.hpp" +#include "util/scripts.hpp" namespace lua::script { @@ -155,6 +156,23 @@ namespace lua::script module->m_registered_scripts.push_back(std::move(lua_script)); } + // Lua API: function + // Table: script + // Name: is_active + // Param: script_name: string: The name of the script. + // Returns true if the specified script is currently active/running. + // **Example Usage:** + // ```lua + // local is_freemode_active = script.is_active("freemode") + // ``` + static bool is_active(const std::string& script_name) + { + if (auto script = big::gta_util::find_script_thread(rage::joaat(script_name))) + return true; + + return false; + } + // Lua API: function // Table: script // Name: execute_as_script @@ -175,9 +193,9 @@ namespace lua::script // Param _patch: table: The bytes to be written into the script's bytecode. // Adds a patch for the specified script. // **Example Usage:** - //```lua - //script.add_patch("fm_content_xmas_truck", "Flickering Fix", "56 ? ? 4F ? ? 40 ? 5D ? ? ? 74", 0, {0x2B, 0x00, 0x00}) - //``` + // ```lua + // script.add_patch("fm_content_xmas_truck", "Flickering Fix", "56 ? ? 4F ? ? 40 ? 5D ? ? ? 74", 0, {0x2B, 0x00, 0x00}) + // ``` static void add_patch(const std::string& script_name, const std::string& name, const std::string& pattern, int offset, sol::table _patch) { auto patch = convert_sequence(_patch); @@ -197,9 +215,9 @@ namespace lua::script // Param _args: table: The arguments to pass to the script function. // Calls a function from the specified script. // **Example Usage:** - //```lua - //script.call_function("Collect Collectible", "freemode", "2D 05 33 00 00", 0, {17, 0, 1, 1, 0}) - //``` + // ```lua + // script.call_function("Collect Collectible", "freemode", "2D 05 33 00 00", 0, {17, 0, 1, 1, 0}) + // ``` static void call_function(const std::string& name, const std::string& script_name, const std::string& pattern, int offset, sol::table _args) { auto args = convert_sequence(_args); @@ -208,14 +226,32 @@ namespace lua::script script_function(args); } + // Lua API: function + // Table: script + // Name: start_launcher_script + // Param: script_name: string: The name of the script. + // Tries to start a launcher script. Needs to be called in the fiber pool or a loop. + // **Example Usage:** + // ```lua + // script.run_in_fiber(function() + // script.start_launcher_script("am_hunt_the_beast") + // end) + // ``` + static void start_launcher_script(const std::string& script_name) + { + big::scripts::start_launcher_script(rage::joaat(script_name)); + } + void bind(sol::state& state) { - auto ns = state["script"].get_or_create(); - ns["register_looped"] = register_looped; - ns["run_in_fiber"] = run_in_fiber; - ns["execute_as_script"] = execute_as_script; - ns["add_patch"] = add_patch; - ns["call_function"] = call_function; + auto ns = state["script"].get_or_create(); + ns["register_looped"] = register_looped; + ns["run_in_fiber"] = run_in_fiber; + ns["is_active"] = is_active; + ns["execute_as_script"] = execute_as_script; + ns["add_patch"] = add_patch; + ns["call_function"] = call_function; + ns["start_launcher_script"] = start_launcher_script; auto usertype = state.new_usertype("script_util"); diff --git a/src/views/debug/view_debug_threads.cpp b/src/views/debug/view_debug_threads.cpp index 88153908..6b9788f8 100644 --- a/src/views/debug/view_debug_threads.cpp +++ b/src/views/debug/view_debug_threads.cpp @@ -12,7 +12,7 @@ static rage::scrThread* selected_thread; static int selected_stack_size = 128; static int free_stacks = -1; static const char* selected_stack_size_str = "MULTIPLAYER_MISSION"; -static const char* selected_script = "