This repository has been archived on 2024-10-22. You can view files and clone it, but cannot push or open issues or pull requests.
YimMenu/src/script_function.hpp

85 lines
3.2 KiB
C++

#pragma once
#include "gta_util.hpp"
#include "pointers.hpp"
#include "util/scripts.hpp"
#include <script/scrProgram.hpp>
namespace big
{
class script_function
{
rage::joaat_t m_script;
const memory::pattern m_pattern;
uint32_t m_ip;
std::string m_name;
public:
script_function(const std::string& name, const rage::joaat_t script, const std::string& pattern);
uint32_t get_ip(rage::scrProgram* program);
template<typename Arg>
void push_arg(uint64_t* stack, uint32_t& stack_pointer, Arg&& value)
{
*reinterpret_cast<std::remove_cv_t<std::remove_reference_t<Arg>>*>(reinterpret_cast<uint64_t*>(stack) + (stack_pointer++)) = std::forward<Arg>(value);
}
template<typename Ret, typename... Args>
Ret call(Args... args)
{
auto thread = gta_util::find_script_thread(m_script);
auto program = gta_util::find_script_program(m_script);
if (!thread || !program)
{
LOG(FATAL) << m_name << " failed to find its associated script running.";
return Ret();
}
auto ip = get_ip(program);
if (!ip)
{
return Ret();
}
auto tls_ctx = rage::tlsContext::get();
auto stack = (uint64_t*)thread->m_stack;
auto og_thread = tls_ctx->m_script_thread;
tls_ctx->m_script_thread = thread;
tls_ctx->m_is_script_thread_active = true;
rage::scrThreadContext ctx = thread->m_context;
auto top_stack = ctx.m_stack_pointer; // This will be the top item in the stack after the args and return address are cleaned off
(push_arg(stack, ctx.m_stack_pointer, std::forward<Args>(args)), ...);
stack[ctx.m_stack_pointer++] = 0;
ctx.m_instruction_pointer = ip;
ctx.m_state = rage::eThreadState::running;
g_pointers->m_gta.m_script_vm(stack, g_pointers->m_gta.m_script_globals, program, &ctx);
tls_ctx->m_script_thread = og_thread;
tls_ctx->m_is_script_thread_active = og_thread != nullptr;
if constexpr (!std::is_same_v<Ret, void>)
{
return *reinterpret_cast<Ret*>(stack + top_stack);
}
}
};
namespace scr_functions
{
inline script_function set_as_ceo("SAC", "freemode"_J, "2D 04 1D 00 00 5D");
inline script_function set_freemode_session_active("SFSA", "freemode"_J, "2D 00 02 00 00 75 5D ? ? ? 50");
inline script_function give_owned_freemode_weapons("GOFM", "freemode"_J, "2D 00 02 00 00 62 ? ? ? 72 57 ? ? 76");
inline script_function save_to_datafile("STD", "fm_race_creator"_J, "2D 01 03 00 00 71 2C");
inline script_function load_from_datafile("LFD", "fm_race_creator"_J, "2D 03 0C 00 00 71 2C");
inline script_function reset_session_data("RSD", "main_persistent"_J, "2D 02 7D 00 00");
inline script_function add_clan_logo_to_vehicle("ACLTV", "main_persistent"_J, "2D 02 04 00 00 5D ? ? ? 61");
inline script_function vehicle_cannot_accept_clan_logo("CVACL", "main_persistent"_J, "2D 01 03 00 00 2C 01 00 A1 06 ? 04");
inline script_function get_component_name_string("GCNS", "mp_weapons"_J, "2D 02 43 00 00 38 01");
inline script_function get_component_desc_string("GCDS", "mp_weapons"_J, "2D 02 43 00 00 38 00");
}
}