Redesign Script Patches for Lua (#3612)
* Refactor Script Patches for Lua * Use update_all_patches_for_script instead of update and store script's joaat instead of its string
This commit is contained in:
parent
88aa4d317e
commit
61ff817f11
41
docs/lua/classes/scr_patch.md
Normal file
41
docs/lua/classes/scr_patch.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Class: scr_patch
|
||||
|
||||
Class for patching GTA script functions.
|
||||
|
||||
## Constructors (1)
|
||||
|
||||
### `new(script_name, patch_name, pattern, offset, patch_)`
|
||||
|
||||
Adds a patch for the specified script.
|
||||
|
||||
- **Parameters:**
|
||||
- `script_name` (string): The name of the script.
|
||||
- `patch_name` (string): The name of the patch.
|
||||
- `pattern` (string): The pattern to scan for within the script.
|
||||
- `offset` (integer): The position within the pattern.
|
||||
- `patch_` (table): The bytes to be written into the script's bytecode.
|
||||
|
||||
**Example Usage:**
|
||||
```lua
|
||||
my_patch = scr_patch:new(script_name, patch_name, pattern, offset, patch_)
|
||||
```
|
||||
|
||||
## Functions (2)
|
||||
|
||||
### `enable()`
|
||||
|
||||
Enables the script patch for the current instance. When a new instance is created, it will be enabled by default.
|
||||
|
||||
**Example Usage:**
|
||||
```lua
|
||||
scr_patch:enable()
|
||||
```
|
||||
|
||||
### `disable()`
|
||||
|
||||
Disables the script patch for the current instance.
|
||||
|
||||
**Example Usage:**
|
||||
```lua
|
||||
scr_patch:disable()
|
||||
```
|
@ -102,26 +102,6 @@ script.is_active(script_name)
|
||||
script.execute_as_script(script_name, func)
|
||||
```
|
||||
|
||||
### `add_patch(script_name, name, pattern, offset, _patch)`
|
||||
|
||||
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})
|
||||
```
|
||||
|
||||
- **Parameters:**
|
||||
- `script_name` (string): The name of the script.
|
||||
- `name` (string): The name of the patch.
|
||||
- `pattern` (string): The pattern to scan for within the script.
|
||||
- `offset` (integer): The position within the pattern.
|
||||
- `_patch` (table): The bytes to be written into the script's bytecode.
|
||||
|
||||
**Example Usage:**
|
||||
```lua
|
||||
script.add_patch(script_name, name, pattern, offset, _patch)
|
||||
```
|
||||
|
||||
### `start_launcher_script(script_name)`
|
||||
|
||||
Tries to start a launcher script. Needs to be called in the fiber pool or a loop.
|
||||
|
53
src/lua/bindings/scr_patch.cpp
Normal file
53
src/lua/bindings/scr_patch.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include "scr_patch.hpp"
|
||||
|
||||
#include "gta_util.hpp"
|
||||
#include "lua/lua_module.hpp"
|
||||
#include "lua/bindings/network.hpp" // For convert_sequence
|
||||
#include "services/script_patcher/script_patcher_service.hpp"
|
||||
|
||||
namespace lua::scr_patch
|
||||
{
|
||||
scr_patch::scr_patch(const std::string& script_name, const std::string& patch_name, const std::string& pattern, const int offset, sol::table patch_, sol::this_state state) :
|
||||
m_script(rage::joaat(script_name)),
|
||||
m_patch_name(patch_name),
|
||||
m_pattern(pattern),
|
||||
m_offset(offset),
|
||||
m_patch(patch_),
|
||||
m_enable(true)
|
||||
{
|
||||
auto patch = convert_sequence<uint8_t>(m_patch);
|
||||
|
||||
big::g_script_patcher_service->add_patch({m_script, m_patch_name, ::memory::pattern(m_pattern), m_offset, patch, &m_enable});
|
||||
if (auto program = big::gta_util::find_script_program(m_script))
|
||||
big::g_script_patcher_service->on_script_load(program);
|
||||
|
||||
big::lua_module* module = sol::state_view(state)["!this"];
|
||||
module->m_registered_script_patches.push_back(std::make_unique<scr_patch>(*this));
|
||||
}
|
||||
|
||||
void scr_patch::enable()
|
||||
{
|
||||
if (!m_enable)
|
||||
{
|
||||
m_enable = true;
|
||||
big::g_script_patcher_service->update_all_patches_for_script(m_script);
|
||||
}
|
||||
}
|
||||
|
||||
void scr_patch::disable()
|
||||
{
|
||||
if (m_enable)
|
||||
{
|
||||
m_enable = false;
|
||||
big::g_script_patcher_service->update_all_patches_for_script(m_script);
|
||||
}
|
||||
}
|
||||
|
||||
void bind(sol::state& state)
|
||||
{
|
||||
auto scr_patch_ut = state.new_usertype<scr_patch>("scr_patch", sol::constructors<scr_patch(const std::string&, const std::string&, const std::string&, const int, sol::table, sol::this_state)>());
|
||||
|
||||
scr_patch_ut["enable_patch"] = &scr_patch::enable;
|
||||
scr_patch_ut["disable_patch"] = &scr_patch::disable;
|
||||
}
|
||||
}
|
39
src/lua/bindings/scr_patch.hpp
Normal file
39
src/lua/bindings/scr_patch.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
namespace lua::scr_patch
|
||||
{
|
||||
struct scr_patch
|
||||
{
|
||||
rage::joaat_t m_script;
|
||||
std::string m_patch_name;
|
||||
std::string m_pattern;
|
||||
int m_offset;
|
||||
sol::table m_patch;
|
||||
bool m_enable;
|
||||
|
||||
public:
|
||||
// Lua API: Constructor
|
||||
// Class: scr_patch
|
||||
// Param: script_name: string: The name of the script.
|
||||
// Param: patch_name: string: The name of the patch.
|
||||
// Param: pattern: string: The pattern to scan for within the script.
|
||||
// Param: offset: integer: The position within the pattern.
|
||||
// Param: patch_: table: The bytes to be written into the script's bytecode.
|
||||
// Adds a patch for the specified script.
|
||||
explicit scr_patch(const std::string& script_name, const std::string& patch_name, const std::string& pattern, const int offset, sol::table patch_, sol::this_state state);
|
||||
|
||||
// Lua API: Function
|
||||
// Class: scr_patch
|
||||
// Name: enable
|
||||
// Enables the script patch for the current instance. When a new instance is created, it will be enabled by default.
|
||||
void enable();
|
||||
|
||||
// Lua API: Function
|
||||
// Class: scr_patch
|
||||
// Name: disable
|
||||
// Disables the script patch for the current instance.
|
||||
void disable();
|
||||
};
|
||||
|
||||
void bind(sol::state& state);
|
||||
}
|
@ -3,9 +3,7 @@
|
||||
|
||||
#include "lua/lua_manager.hpp"
|
||||
#include "gta_util.hpp"
|
||||
#include "lua/bindings/network.hpp"
|
||||
#include "memory/pattern.hpp"
|
||||
#include "services/script_patcher/script_patcher_service.hpp"
|
||||
#include "util/scripts.hpp"
|
||||
|
||||
namespace lua::script
|
||||
@ -182,28 +180,6 @@ namespace lua::script
|
||||
big::gta_util::execute_as_script(rage::joaat(script_name), func);
|
||||
}
|
||||
|
||||
// Lua API: function
|
||||
// Table: script
|
||||
// Name: add_patch
|
||||
// Param: script_name: string: The name of the script.
|
||||
// Param: name: string: The name of the patch.
|
||||
// Param: pattern: string: The pattern to scan for within the script.
|
||||
// Param: offset: integer: The position within the pattern.
|
||||
// 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})
|
||||
// ```
|
||||
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<uint8_t>(_patch);
|
||||
|
||||
big::g_script_patcher_service->add_patch({rage::joaat(script_name), name, ::memory::pattern(pattern), offset, patch, nullptr}); // TO-DO: Add toggle feature?
|
||||
if (auto program = big::gta_util::find_script_program(rage::joaat(script_name)))
|
||||
big::g_script_patcher_service->on_script_load(program);
|
||||
}
|
||||
|
||||
// Lua API: function
|
||||
// Table: script
|
||||
// Name: start_launcher_script
|
||||
@ -227,7 +203,6 @@ namespace lua::script
|
||||
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["start_launcher_script"] = start_launcher_script;
|
||||
|
||||
auto usertype = state.new_usertype<script_util>("script_util");
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "bindings/network.hpp"
|
||||
#include "bindings/script.hpp"
|
||||
#include "bindings/scr_function.hpp"
|
||||
#include "bindings/scr_patch.hpp"
|
||||
#include "bindings/self.hpp"
|
||||
#include "bindings/stats.hpp"
|
||||
#include "bindings/tunables.hpp"
|
||||
@ -300,6 +301,7 @@ namespace big
|
||||
lua::globals::bind(m_state);
|
||||
lua::script::bind(m_state);
|
||||
lua::scr_function::bind(m_state);
|
||||
lua::scr_patch::bind(m_state);
|
||||
lua::native::bind(m_state);
|
||||
lua::memory::bind(m_state);
|
||||
lua::gui::bind(m_state);
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "core/data/menu_event.hpp"
|
||||
#include "lua/bindings/runtime_func_t.hpp"
|
||||
#include "lua/bindings/type_info_t.hpp"
|
||||
#include "lua/bindings/scr_patch.hpp"
|
||||
#include "lua_patch.hpp"
|
||||
#include "services/gui/gui_service.hpp"
|
||||
|
||||
@ -28,6 +29,7 @@ namespace big
|
||||
public:
|
||||
std::vector<std::unique_ptr<script>> m_registered_scripts;
|
||||
std::vector<std::unique_ptr<lua_patch>> m_registered_patches;
|
||||
std::vector<std::unique_ptr<lua::scr_patch::scr_patch>> m_registered_script_patches;
|
||||
|
||||
std::vector<big::tabs> m_owned_tabs;
|
||||
|
||||
|
@ -14,7 +14,6 @@ namespace big
|
||||
script_data* get_data_for_script(rage::joaat_t script);
|
||||
bool does_script_have_patches(rage::joaat_t script);
|
||||
void create_data_for_script(rage::scrProgram* program);
|
||||
void update_all_patches_for_script(rage::joaat_t script);
|
||||
|
||||
public:
|
||||
script_patcher_service();
|
||||
@ -23,6 +22,7 @@ namespace big
|
||||
void add_patch(script_patch&& patch);
|
||||
void on_script_load(rage::scrProgram* program);
|
||||
uint8_t** get_script_bytecode(rage::joaat_t script);
|
||||
void update_all_patches_for_script(rage::joaat_t script);
|
||||
void update();
|
||||
};
|
||||
|
||||
|
@ -75,6 +75,10 @@ namespace big
|
||||
"VIEW_LUA_SCRIPTS_MEMORY_PATCHES_REGISTERED"_T,
|
||||
selected_module.lock()->m_registered_patches.size())
|
||||
.c_str());
|
||||
ImGui::Text(std::format("{}: {}",
|
||||
"VIEW_LUA_SCRIPTS_SCRIPT_PATCHES_REGISTERED"_T,
|
||||
selected_module.lock()->m_registered_script_patches.size())
|
||||
.c_str());
|
||||
ImGui::Text(
|
||||
std::format("{}: {}", "VIEW_LUA_SCRIPTS_GUI_TABS_REGISTERED"_T, selected_module.lock()->m_gui.size()).c_str());
|
||||
|
||||
|
Reference in New Issue
Block a user