feat(lua): initial lua scripting prototype

This commit is contained in:
maybegreat48
2025-06-25 17:01:10 -04:00
parent 7c48d52b71
commit b769d36a1c
24 changed files with 1179 additions and 124 deletions
+4 -1
View File
@@ -9,6 +9,7 @@ include(cmake/async-logger.cmake)
include(cmake/imgui.cmake)
include(cmake/json.cmake)
include(cmake/minhook.cmake)
include(cmake/luajit.cmake)
# source
set(SRC_DIR "${PROJECT_SOURCE_DIR}/src")
@@ -35,7 +36,9 @@ target_include_directories(${PROJECT_NAME} PRIVATE
"${imgui_SOURCE_DIR}"
"${minhook_SOURCE_DIR}/include"
"${minhook_SOURCE_DIR}/src/hde"
"${luajit_SOURCE_DIR}/src"
"${luajit_BINARY_DIR}/src"
)
message(STATUS "Setting up linked libraries")
target_link_libraries(${PROJECT_NAME} PRIVATE AsyncLogger imgui minhook nlohmann_json::nlohmann_json dbghelp d3dcompiler dwmapi)
target_link_libraries(${PROJECT_NAME} PRIVATE AsyncLogger imgui minhook nlohmann_json::nlohmann_json dbghelp d3dcompiler dwmapi libluajit)
+23
View File
@@ -0,0 +1,23 @@
include(FetchContent)
message("LuaJIT")
# For some reason putting this into crosscompile.cmake doesn't work.
if(CROSSCOMPILE)
set(CMAKE_SYSTEM_VERSION 10.0.26100)
endif()
set(LUAJIT_BUILD_TOOL OFF)
set(LUAJIT_FORCE_UTF8_FOPEN ON)
FetchContent_Declare(
luajit
GIT_REPOSITORY https://github.com/WohlSoft/LuaJIT.git
GIT_TAG 27878965958986687f8caaf8a2b6b73bc5df85e0
GIT_PROGRESS TRUE
)
FetchContent_MakeAvailable(luajit)
target_compile_definitions(libluajit PRIVATE
"_CRT_SECURE_NO_WARNINGS"
"LUAJIT_ENABLE_LUA52COMPAT"
)
+10
View File
@@ -0,0 +1,10 @@
#include "LuaLibrary.hpp"
#include "LuaManager.hpp"
namespace YimMenu
{
LuaLibrary::LuaLibrary()
{
LuaManager::RegisterLibrary(this);
}
}
+13
View File
@@ -0,0 +1,13 @@
#pragma once
#include "lua.hpp"
namespace YimMenu
{
class LuaLibrary
{
public:
LuaLibrary();
virtual void Register(lua_State* state) = 0;
};
}
+75
View File
@@ -0,0 +1,75 @@
#include "LuaManager.hpp"
#include "core/filemgr/FileMgr.hpp"
#include "core/backend/ScriptMgr.hpp"
#include "core/frontend/Notifications.hpp"
namespace YimMenu
{
void LuaManager::RegisterLibraryImpl(LuaLibrary* library)
{
m_Libraries.push_back(library);
}
void LuaManager::LoadLibrariesImpl(lua_State* state)
{
for (auto library : m_Libraries)
library->Register(state);
}
void LuaManager::LoadScriptImpl(std::string path)
{
std::lock_guard lock(m_LoadMutex);
m_ScriptsToLoad.push(path);
}
void LuaManager::RunScriptImpl()
{
m_MainThreadId = GetCurrentThreadId();
auto scripts_dir = FileMgr::GetProjectFolder("./scripts");
for (const auto& entry : std::filesystem::directory_iterator(scripts_dir.Path()))
{
if (entry.path().extension() != ".lua")
continue;
m_ScriptsToLoad.push(entry.path().string());
}
while (g_Running)
{
{
// 1) process new load requests
std::lock_guard lock(m_LoadMutex);
while (!m_ScriptsToLoad.empty())
{
m_LoadedScripts.push_back(std::make_shared<LuaScript>(m_ScriptsToLoad.front()));
m_ScriptsToLoad.pop();
}
// 2) remove malfunctioning scripts
std::erase_if(m_LoadedScripts, [](auto& script) {
auto is_malfunctioning = script->IsMalfunctioning();
if (is_malfunctioning)
{
script->Invalidate();
Notifications::Show("Lua Scripting", std::format("Script {} has been unloaded due to a malfunction", script->GetName()), NotificationType::Warning);
return true;
}
return false;
});
}
// 3) run tick coroutines
{
// TODO!
}
ScriptMgr::Yield();
}
}
bool LuaManager::IsRunningInMainThreadImpl()
{
return GetCurrentThreadId() == m_MainThreadId;
}
}
+60
View File
@@ -0,0 +1,60 @@
#pragma once
#include "LuaScript.hpp"
#include "LuaLibrary.hpp"
namespace YimMenu
{
// note to future self: Lua is a horrible language and should never be used
class LuaManager
{
public:
enum class ScriptPermission
{
};
private:
std::vector<std::shared_ptr<LuaScript>> m_LoadedScripts;
std::vector<LuaLibrary*> m_Libraries;
std::queue<std::string> m_ScriptsToLoad;
std::mutex m_LoadMutex;
std::uint32_t m_MainThreadId;
void RegisterLibraryImpl(LuaLibrary* library);
void LoadLibrariesImpl(lua_State* state);
void LoadScriptImpl(std::string path);
void RunScriptImpl();
bool IsRunningInMainThreadImpl();
static LuaManager& GetInstance()
{
static LuaManager instance;
return instance;
}
public:
static void RegisterLibrary(LuaLibrary* library)
{
GetInstance().RegisterLibraryImpl(library);
}
static void LoadLibraries(lua_State* state)
{
GetInstance().LoadLibrariesImpl(state);
}
static void LoadScript(std::string file_name)
{
GetInstance().LoadScriptImpl(file_name);
}
static void RunScript()
{
GetInstance().RunScriptImpl();
}
static bool IsRunningInMainThread()
{
return GetInstance().IsRunningInMainThreadImpl();
}
};
}
+99
View File
@@ -0,0 +1,99 @@
#include "LuaScript.hpp"
#include "LuaManager.hpp"
namespace YimMenu
{
// https://github.com/brimworks/lua-ev/blob/2d11066b6f96a7501805e8c28d92f70dd2c0ab13/lua_ev.c#L144
// TODO: may need to check if debug is a real table if ChatGPT is to be trusted
static int ErrorHandler(lua_State* state)
{
auto error_msg = lua_tostring(state, 1);
if (!error_msg)
return 1; // return error_msg
// ok this is the fun part
// our stack right now: retaddr error_message <
lua_getglobal(state, "debug");
lua_getfield(state, -1, "traceback");
lua_pushstring(state, error_msg);
lua_pushinteger(state, 2);
lua_call(state, 2, 1); // now the top of stack should have the stacktrace
return 1;
}
bool LuaScript::CallFunction(int n_args, int n_results)
{
if (!LuaManager::IsRunningInMainThread())
{
LOGF(FATAL, "LuaScript::CallFunction: {} attempted to call a Lua function outside the main thread. This is not allowed", m_ModuleName);
lua_pop(m_State, 1); // pop the function from the stack since we aren't going to call it
SetMalfunctioning();
return false;
}
lua_pushcfunction(m_State, &ErrorHandler);
int handler_index = lua_gettop(m_State) - n_args - 1;
lua_insert(m_State, handler_index); // move it before all the args
auto result = lua_pcall(m_State, n_args, n_results, handler_index);
if (result == LUA_OK)
{
// the lua runtime doesn't pop the handler if there's no error
lua_remove(m_State, handler_index); // TODO: does this actually work? What happens if your function returns stuff?
return true;
}
else
{
auto trace = lua_tostring(m_State, -1);
LOGF(FATAL, "{}: {}", m_ModuleName, trace);
lua_pop(m_State, 1); // pop the stack trace
SetMalfunctioning();
return false;
}
}
LuaScript::LuaScript(std::string_view file_name) :
m_FileName(file_name),
m_ModuleName(std::filesystem::path(file_name).filename().string())
{
m_State = luaL_newstate();
lua_pushlightuserdata(m_State, (void*)this);
lua_setfield(m_State, LUA_REGISTRYINDEX, "context");
LuaManager::LoadLibraries(m_State);
if (luaL_loadfilex(m_State, file_name.data(), "t") != LUA_OK) // don't load binary chunks
{
auto error = lua_tostring(m_State, -1);
LOGF(FATAL, "{}: {}", m_ModuleName, error);
SetMalfunctioning();
return;
}
// we should have a function in the top of stack
CallFunction(0, 0);
m_IsValid = true;
}
LuaScript::~LuaScript()
{
if (m_State)
{
lua_close(m_State);
m_State = nullptr;
}
}
LuaScript& LuaScript::GetScript(lua_State* state)
{
lua_getfield(state, LUA_REGISTRYINDEX, "context");
auto script = static_cast<LuaScript*>(lua_touserdata(state, -1));
lua_pop(state, 1);
return *script;
}
}
+49
View File
@@ -0,0 +1,49 @@
#pragma once
#include "lua.hpp"
namespace YimMenu
{
class LuaScript
{
lua_State* m_State;
std::string m_FileName;
std::string m_ModuleName;
bool m_IsMalfunctioning; // when this is set to true, the script will be unloaded next tick
bool m_IsValid;
// Calls the function at the top of stack. If this returns false the stack would have nothing on it
bool CallFunction(int n_args, int n_results);
public:
LuaScript(std::string_view file_name);
~LuaScript();
bool IsMalfunctioning() const
{
return m_IsMalfunctioning;
}
bool IsValid() const
{
return m_IsValid;
}
void Invalidate()
{
m_IsValid = false;
}
void SetMalfunctioning()
{
m_IsMalfunctioning = true;
}
std::string_view GetName()
{
return m_ModuleName;
}
// we're guaranteed to have a LuaScript for each lua_State, so we can return it as a reference
static LuaScript& GetScript(lua_State* state);
};
}
+49
View File
@@ -0,0 +1,49 @@
#include "core/scripting/LuaLibrary.hpp"
#include "core/scripting/LuaScript.hpp"
namespace YimMenu::Lua
{
class Default : LuaLibrary
{
using LuaLibrary::LuaLibrary;
virtual void Register(lua_State* state) override
{
// ensure that only safe libraries are loaded
static const luaL_Reg lj_lib_load[] = {
{"", luaopen_base},
// {LUA_LOADLIBNAME, luaopen_package},
{LUA_TABLIBNAME, luaopen_table},
// {LUA_IOLIBNAME, luaopen_io},
// {LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
{LUA_BITLIBNAME, luaopen_bit},
{LUA_JITLIBNAME, luaopen_jit},
{NULL, NULL}};
static const luaL_Reg lj_lib_preload[] = {
// {LUA_FFILIBNAME, luaopen_ffi},
{NULL, NULL}};
const luaL_Reg* lib;
for (lib = lj_lib_load; lib->func; lib++)
{
lua_pushcfunction(state, lib->func);
lua_pushstring(state, lib->name);
lua_call(state, 1, 0);
}
luaL_findtable(state, LUA_REGISTRYINDEX, "_PRELOAD", sizeof(lj_lib_preload) / sizeof(lj_lib_preload[0]) - 1);
for (lib = lj_lib_preload; lib->func; lib++)
{
lua_pushcfunction(state, lib->func);
lua_setfield(state, -2, lib->name);
}
lua_pop(state, 1);
}
};
Default _Default;
}
+71
View File
@@ -0,0 +1,71 @@
#include "core/scripting/LuaLibrary.hpp"
#include "core/scripting/LuaScript.hpp"
namespace YimMenu::Lua
{
class Logging : LuaLibrary
{
using LuaLibrary::LuaLibrary;
static int Verbose(lua_State* state)
{
const char* message = luaL_checkstring(state, 1);
LOGF(VERBOSE, "{}: {}", LuaScript::GetScript(state).GetName(), message);
return 0;
}
static int Info(lua_State* state)
{
const char* message = luaL_checkstring(state, 1);
LOGF(INFO, "{}: {}", LuaScript::GetScript(state).GetName(), message);
return 0;
}
static int Warn(lua_State* state)
{
const char* message = luaL_checkstring(state, 1);
LOGF(WARNING, "{}: {}", LuaScript::GetScript(state).GetName(), message);
return 0;
}
static int Error(lua_State* state)
{
const char* message = luaL_checkstring(state, 1);
LOGF(FATAL, "{}: {}", LuaScript::GetScript(state).GetName(), message);
return 0;
}
static int Trace(lua_State* state)
{
const char* message = luaL_checkstring(state, 1);
luaL_traceback(state, state, message, 1);
LOGF(VERBOSE, "{}: {}", LuaScript::GetScript(state).GetName(), lua_tostring(state, -1));
lua_pop(state, 1); // pop the traceback
return 0;
}
virtual void Register(lua_State* state) override
{
lua_newtable(state);
lua_pushcfunction(state, Verbose);
lua_setfield(state, -2, "verbose");
lua_pushcfunction(state, Info);
lua_setfield(state, -2, "info");
lua_pushcfunction(state, Warn);
lua_setfield(state, -2, "warn");
lua_pushcfunction(state, Error);
lua_setfield(state, -2, "error");
lua_pushcfunction(state, Trace);
lua_setfield(state, -2, "trace");
lua_setglobal(state, "log");
}
};
Logging _Logging;
}
+32 -6
View File
@@ -242,21 +242,24 @@ namespace YimMenu::Submenus
ImGui::EndGroup();
ImGui::TreePop();
}
RenderBytecode(curProgram);
if (ImGui::TreeNode("Bytecode"))
{
RenderBytecode(curProgram);
}
}
}));
script->AddItem(std::make_unique<ImGuiItem>([] {
static std::string scriptSearch = "";
static std::string scriptName = "";
static std::string stackSizeName = stackSizes[0].first;
static std::optional<int> launcherIndex = std::nullopt;
static int stackSize = 0;
static std::int64_t* args = nullptr;
static int argCount = 0;
static int previousArgCount = 0;
static bool pauseAfterStarting = false;
ImGui::InputTextWithHint("Script Name", "Search", &scriptSearch);
bool modified = ImGui::InputTextWithHint("Script Name", "Search", &scriptSearch);
if (ImGui::BeginCombo("Stack Size", stackSizeName.c_str()))
{
@@ -312,10 +315,10 @@ namespace YimMenu::Submenus
std::transform(lowerScript.begin(), lowerScript.end(), lowerScript.begin(), ::tolower);
if (lowerScript.find(lowerSearch) != std::string::npos)
{
if (ImGui::Selectable(script, scriptName == script))
if (ImGui::Selectable(script, scriptSearch == script))
{
scriptSearch = script;
scriptName = script;
modified = true;
}
}
}
@@ -323,12 +326,17 @@ namespace YimMenu::Submenus
ImGui::EndListBox();
}
if (modified)
{
launcherIndex = Scripts::GetLauncherIndexFromScript(Joaat(scriptSearch));
}
ImGui::Checkbox("Pause After Starting", &pauseAfterStarting);
if (ImGui::Button("Start Script"))
{
FiberPool::Push([] {
auto hash = Joaat(scriptName);
auto hash = Joaat(scriptSearch);
if (!SCRIPT::DOES_SCRIPT_WITH_NAME_HASH_EXIST(hash))
{
@@ -374,6 +382,24 @@ namespace YimMenu::Submenus
Notifications::Show("Start Script", std::format("Started script with ID {}.", id), NotificationType::Success);
});
}
if (launcherIndex && *Pointers.IsSessionStarted)
{
ImGui::SameLine();
if (ImGui::Button("Start Session Script"))
{
FiberPool::Push([] {
Scripts::StartLauncherScript(Joaat(scriptSearch));
});
}
ImGui::SameLine();
if (ImGui::Button("Start Script With Event"))
{
FiberPool::Push([] {
Scripts::ForceScriptOnPlayer(Joaat(scriptSearch), -1);
});
}
}
}));
menu->AddItem(std::make_shared<ImGuiItem>([] {
+158
View File
@@ -9,11 +9,17 @@
#include "types/script/CGameScriptHandlerNetComponent.hpp"
#include "types/script/CGameScriptId.hpp"
#include "types/script/globals/GlobalPlayerBD.hpp"
#include "types/script/globals/GPBD_FM_3.hpp"
#include "types/script/globals/LauncherServerData.hpp"
#include "types/script/locals/LauncherClientData.hpp"
#include "game/gta/Natives.hpp"
#include "game/gta/Packet.hpp"
#include "game/backend/Players.hpp"
#include "game/backend/Self.hpp"
#include "core/memory/Pattern.hpp"
#include "game/gta/data/LauncherScripts.hpp"
#include "types/script/ScriptEvent.hpp"
#include "game/gta/ScriptGlobal.hpp"
namespace YimMenu::Scripts
{
@@ -187,4 +193,156 @@ namespace YimMenu::Scripts
pkt.Send(player.second.GetMessageId());
}
}
std::optional<int> GetLauncherIndexFromScript(joaat_t hash)
{
for (int i = 0; i < g_LauncherScripts.size(); i++)
if (g_LauncherScripts[i] == hash)
return i;
return std::nullopt;
}
void StartLauncherScript(joaat_t hash)
{
auto index = GetLauncherIndexFromScript(hash);
if (!index)
return;
static auto atLeastOnePlayerInState = [](GtaThread* launcher, eLauncherState state) -> bool {
bool set = false;
if (!launcher->m_NetComponent)
return false;
for (auto& [_, plyr] : Players::GetPlayers())
{
if (launcher->m_NetComponent->IsParticipant(plyr.GetId()))
{
if (LauncherClientData::Get(launcher)->Entries[plyr.GetId()].LauncherState == state)
{
set = true;
break;
}
}
}
return set;
};
// 1) Get launcher
if (auto launcher = reinterpret_cast<GtaThread*>(FindScriptThread("am_launcher"_J)); launcher && launcher->m_NetComponent)
{
// 2) Force host of launcher
if (!launcher->m_NetComponent->IsLocalPlayerHost())
{
ForceScriptHost(launcher);
ScriptMgr::Yield(400ms);
}
launcher->m_Context.m_State = rage::scrThread::State::PAUSED;
auto serverData = LauncherServerData::Get();
// 3) Remove players from that annoying waiting stage
if (atLeastOnePlayerInState(launcher, eLauncherState::WAIT_FOR_ACK))
{
for (int i = 0; atLeastOnePlayerInState(launcher, eLauncherState::WAIT_FOR_ACK); i++)
{
if (i > 200)
break; // 3F) Timeout
serverData->CurrentScript.LauncherIndex = 0;
serverData->LauncherState = eLauncherState::START_SCRIPT;
ScriptMgr::Yield(10ms);
}
} // State should now be 6 or 0
// 4) Check if a script is already being executed, and unstuck from that state if so
if (atLeastOnePlayerInState(launcher, eLauncherState::START_SCRIPT))
{
for (int i = 0; atLeastOnePlayerInState(launcher, eLauncherState::START_SCRIPT); i++)
{
if (i > 200)
break; // 4F) Timeout
serverData->CurrentScript.LauncherIndex = 0;
serverData->LauncherState = eLauncherState::WAIT_FOR_TERMINATION;
ScriptMgr::Yield(10ms);
}
} // State should now be 7 or 0
// 5) Get everyone out of state 7
if (atLeastOnePlayerInState(launcher, eLauncherState::WAIT_FOR_TERMINATION))
{
for (int i = 0; atLeastOnePlayerInState(launcher, eLauncherState::WAIT_FOR_TERMINATION); i++)
{
if (i > 200)
break; // 5F) Timeout
serverData->LauncherState = eLauncherState::EMPTY;
ScriptMgr::Yield(10ms);
}
} // State should now be 0
// 6) Actually get the script to start
serverData->Flags.Set(eLauncherFlags::RUN_IMMEDIATELY);
serverData->CurrentScript.EventIndex = 0;
serverData->CurrentScript.LauncherIndex = *index;
serverData->CurrentScript.Terminated = false;
serverData->LauncherState = eLauncherState::START_SCRIPT;
LauncherClientData::Get(launcher)->Entries[Self::GetPlayer().GetId()].LauncherState = eLauncherState::START_SCRIPT;
launcher->m_Context.m_State = rage::scrThread::State::RUNNING;
}
}
void ForceScriptOnPlayer(joaat_t hash, int bits)
{
auto index = GetLauncherIndexFromScript(hash);
if (!index)
return;
int random_int = time(0) ^ -*index;
MP_SCRIPT_DATA data{};
data.MissionIndex = *index;
strcpy(data.CloudFileName.Data, "0");
data.InstanceId = -1;
data.UniqueId = random_int;
data.GenericInt = 0;
SCRIPT_EVENT_FORCE_PLAYER_ON_MISSION event;
event.ScriptData = data;
event.Flags = 0;
event.ReplayProtectionValue = GPBD_FM_3::Get()->Entries[Self::GetPlayer().GetId()].ScriptEventReplayProtectionCounter;
event.PAD_0026 = random_int ^ 917391583 ^ rand();
// we need to REALLY make sure we're getting an unique random number since the script checks it against the last five events sent
auto& rand_int_2 = event.GetEventIndex();
rand_int_2 ^= (random_int ^ -2024791401); // TODO: this is a pretty ghetto way to create random numbers
rand_int_2 ^= (random_int ^ 917391583);
auto bypass_global = ScriptGlobal(1986361); // this global will bypass the new checks added this update
auto old_val = *bypass_global.As<int*>();
*bypass_global.As<int*>() = rand_int_2 ^ rand() ^ time(0);
event.SetPlayerBits(bits);
event.Send();
for (int i = 0; i < 2; i++)
{
SCRIPT_EVENT_FORCE_PLAYER_ON_MISSION_SERVER_ACK ack; // not strictly necessary but still useful
ack.ScriptData = data;
ack.SetPlayerBits(bits);
ack.Send();
ScriptMgr::Yield(20ms);
}
// restore global just in case
*bypass_global.As<int*>() = old_val;
}
}
+3
View File
@@ -22,4 +22,7 @@ namespace YimMenu::Scripts
extern bool SafeToModifyFreemodeBroadcastGlobals(); // TODO: find a better method for this that works for all scripts
extern std::optional<std::uint32_t> GetCodeLocationByPattern(rage::scrProgram* program, SimplePattern pattern);
extern void ForceScriptHost(rage::scrThread* thread); // likely unstable, beware!
extern std::optional<int> GetLauncherIndexFromScript(joaat_t hash);
extern void StartLauncherScript(joaat_t hash);
extern void ForceScriptOnPlayer(joaat_t hash, int bits);
}
+274
View File
@@ -0,0 +1,274 @@
#pragma once
#include "core/util/Joaat.hpp"
namespace YimMenu
{
constexpr auto g_LauncherScripts = std::to_array({
""_J,
"AM_HOLD_UP"_J,
""_J,
"AM_CR_SELL_DRUGS"_J,
"AM_STRIPPER"_J,
"stripclub_mp"_J,
"AM_ArmWrestling"_J,
"AM_ImportExport"_J,
"AM_Tennis"_J,
"AM_Darts"_J,
"AM_FistFight"_J,
"AM_DropOffHooker"_J,
"AM_Safehouse"_J,
"AM_Hitchhiker"_J,
""_J,
"AM_DOORS"_J,
"MG_RACE_TO_POINT"_J,
"AM_PI_MENU"_J,
"AM_CRATE_DROP"_J,
"AM_IMP_EXP"_J,
"FM_INTRO"_J,
"AM_PROSTITUTE"_J,
"AM_TAXI"_J,
"AM_TAXI_LAUNCHER"_J,
"AM_GANG_CALL"_J,
"heli_gun"_J,
"AM_backup_heli"_J,
"AM_airstrike"_J,
"AM_AMMO_DROP"_J,
"AM_VEHICLE_DROP"_J,
"AM_BRU_BOX"_J,
"AM_GA_PICKUPS"_J,
"AM_JOYRIDER"_J,
"AM_PLANE_TAKEDOWN"_J,
"AM_DISTRACT_COPS"_J,
"AM_DESTROY_VEH"_J,
"AM_HOT_TARGET"_J,
"AM_KILL_LIST"_J,
"AM_TIME_TRIAL"_J,
"AM_CP_COLLECTION"_J,
"AM_CHALLENGES"_J,
"AM_PENNED_IN"_J,
"AM_PASS_THE_PARCEL"_J,
"AM_HOT_PROPERTY"_J,
"AM_DEAD_DROP"_J,
"AM_KING_OF_THE_CASTLE"_J,
"AM_CRIMINAL_DAMAGE"_J,
"AM_HUNT_THE_BEAST"_J,
"GB_LIMO_ATTACK"_J,
"GB_DEATHMATCH"_J,
"GB_STEAL_VEH"_J,
"GB_POINT_TO_POINT"_J,
"GB_TERMINATE"_J,
"GB_YACHT_ROB"_J,
"GB_BELLYBEAST"_J,
"GB_FIVESTAR"_J,
"GB_ROB_SHOP"_J,
"GB_COLLECT_MONEY"_J,
"GB_ASSAULT"_J,
"GB_VEH_SURV"_J,
"GB_SIGHTSEER"_J,
"GB_FLYING_IN_STYLE"_J,
"GB_FINDERSKEEPERS"_J,
"GB_HUNT_THE_BOSS"_J,
"GB_CARJACKING"_J,
"GB_HEADHUNTER"_J,
"GB_CONTRABAND_BUY"_J,
"GB_CONTRABAND_SELL"_J,
"GB_CONTRABAND_DEFEND"_J,
"GB_AIRFREIGHT"_J,
"GB_CASHING_OUT"_J,
"GB_SALVAGE"_J,
"GB_FRAGILE_GOODS"_J,
"GB_VEHICLE_EXPORT"_J,
"GB_VEHICLE_EXPORT"_J,
"GB_PLOUGHED"_J,
"GB_FULLY_LOADED"_J,
"GB_AMPHIBIOUS_ASSAULT"_J,
"GB_TRANSPORTER"_J,
"GB_FORTIFIED"_J,
"GB_VELOCITY"_J,
"GB_RAMPED_UP"_J,
"GB_STOCKPILING"_J,
"GB_BIKER_RACE_P2P"_J,
"GB_BIKER_JOUST"_J,
"GB_BIKER_UNLOAD_WEAPONS"_J,
""_J,
"GB_BIKER_BAD_DEAL"_J,
"GB_BIKER_RESCUE_CONTACT"_J,
"GB_BIKER_LAST_RESPECTS"_J,
"GB_BIKER_CONTRACT_KILLING"_J,
"GB_BIKER_CONTRABAND_SELL"_J,
"GB_BIKER_CONTRABAND_DEFEND"_J,
"GB_ILLICIT_GOODS_RESUPPLY"_J,
"GB_BIKER_DRIVEBY_ASSASSIN"_J,
"GB_BIKER_RIPPIN_IT_UP"_J,
"GB_BIKER_FREE_PRISONER"_J,
"GB_BIKER_SAFECRACKER"_J,
"GB_BIKER_STEAL_BIKES"_J,
"GB_BIKER_SEARCH_AND_DESTROY"_J,
"AM_PENNED_IN"_J,
"GB_BIKER_STAND_YOUR_GROUND"_J,
"GB_BIKER_CRIMINAL_MISCHIEF"_J,
"GB_BIKER_DESTROY_VANS"_J,
"GB_BIKER_BURN_ASSETS"_J,
"GB_BIKER_SHUTTLE"_J,
"GB_BIKER_WHEELIE_RIDER"_J,
"GB_GUNRUNNING"_J,
"GB_GUNRUNNING"_J,
"GB_GUNRUNNING_DEFEND"_J,
"GB_SMUGGLER"_J,
"GB_SMUGGLER"_J,
"GB_SMUGGLER"_J,
"GB_GANGOPS"_J,
"BUSINESS_BATTLES"_J,
"BUSINESS_BATTLES_SELL"_J,
"BUSINESS_BATTLES_DEFEND"_J,
"GB_SECURITY_VAN"_J,
"GB_TARGET_PURSUIT"_J,
"GB_JEWEL_STORE_GRAB"_J,
"GB_BANK_JOB"_J,
"GB_DATA_HACK"_J,
"GB_INFILTRATION"_J,
"BUSINESS_BATTLES_DEFEND"_J,
"BUSINESS_BATTLES_SELL"_J,
"GB_CASINO"_J,
"GB_CASINO_HEIST"_J,
"fm_content_business_battles"_J,
"fm_content_drug_vehicle"_J,
"fm_content_movie_props"_J,
"fm_content_island_heist"_J,
"fm_content_island_dj"_J,
"AM_ISLAND_BACKUP_HELI"_J,
"fm_content_golden_gun"_J,
"fm_content_tuner_robbery"_J,
"fm_content_vehicle_list"_J,
"tuner_sandbox_activity"_J,
"fm_content_auto_shop_delivery"_J,
"fm_content_payphone_hit"_J,
"fm_content_security_contract"_J,
"fm_content_vip_contract_1"_J,
"fm_content_metal_detector"_J,
"am_agency_suv"_J,
"fm_content_phantom_car"_J,
"fm_content_slasher"_J,
"fm_content_sightseeing"_J,
"fm_content_hsw_time_trial"_J,
"fm_content_mp_intro"_J,
"fm_content_hsw_setup"_J,
"fm_content_smuggler_trail"_J,
"fm_content_smuggler_plane"_J,
"fm_content_skydive"_J,
"fm_content_cerberus"_J,
"fm_content_parachuter"_J,
"fm_content_crime_scene"_J,
"fm_content_bar_resupply"_J,
"fm_content_bike_shop_delivery"_J,
"fm_content_clubhouse_contracts"_J,
"fm_content_cargo"_J,
"fm_content_export_cargo"_J,
"fm_content_ammunation"_J,
"fm_content_gunrunning"_J,
"fm_content_source_research"_J,
"fm_content_club_management"_J,
"fm_content_club_odd_jobs"_J,
"fm_content_club_source"_J,
"fm_content_convoy"_J,
"fm_content_robbery"_J,
"fm_content_acid_lab_setup"_J,
"fm_content_acid_lab_source"_J,
"fm_content_acid_lab_sell"_J,
"fm_content_drug_lab_work"_J,
"fm_content_stash_house"_J,
"fm_content_taxi_driver"_J,
"fm_content_xmas_mugger"_J,
"fm_content_bank_shootout"_J,
"fm_content_armoured_truck"_J,
"fm_content_ghosthunt"_J,
"fm_content_ufo_abduction"_J,
"fm_content_smuggler_sell"_J,
"fm_content_smuggler_resupply"_J,
"fm_content_smuggler_ops"_J,
"fm_content_bicycle_time_trial"_J,
"fm_content_possessed_animals"_J,
"fm_content_chop_shop_delivery"_J,
"fm_content_xmas_truck"_J,
"fm_content_tow_truck_work"_J,
"fm_content_vehrob_scoping"_J,
"fm_content_vehrob_task"_J,
"fm_content_vehrob_prep"_J,
"fm_content_vehrob_disrupt"_J,
"fm_content_vehrob_cargo_ship"_J,
"fm_content_vehrob_police"_J,
"fm_content_vehrob_arena"_J,
"fm_content_vehrob_casino_prize"_J,
"fm_content_vehrob_submarine"_J,
"fm_content_bounty_targets"_J,
"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,
"fm_content_car_wash_work"_J,
"fm_content_car_wash_detailing"_J,
"fm_content_helitours_work"_J,
"fm_content_helitours_tour"_J,
"fm_content_weed_shop_work"_J,
"fm_content_weed_shop_delivery"_J,
"fm_content_tycoon_odd_jobs"_J,
"fm_content_cutscene"_J,
"AM_BOAT_TAXI"_J,
"AM_HELI_TAXI"_J,
"fm_hold_up_tut"_J,
"AM_CAR_MOD_TUT"_J,
"AM_CONTACT_REQUESTS"_J,
"am_mission_launch"_J,
"am_npc_invites"_J,
"am_lester_cut"_J,
"am_heist_int"_J,
"am_lowrider_int"_J,
"AM_VEHICLE_SPAWN"_J,
"am_ronTrevor_Cut"_J,
"AM_ARMYBASE"_J,
"AM_PRISON"_J,
"am_rollercoaster"_J,
"am_ferriswheel"_J,
"AM_LAUNCHER"_J,
"AM_DAILY_OBJECTIVES"_J,
"AM_ArmWrestling"_J,
"AM_Darts"_J,
"golf_mp"_J,
"Range_Modern_MP"_J,
"tennis_network_mp"_J,
"Pilot_School_MP"_J,
"FM_Impromptu_DM_Controler"_J,
"fm_Bj_race_controler"_J,
"fm_deathmatch_controler"_J,
"fm_hideout_controler"_J,
"fm_mission_controller"_J,
"FM_Race_Controler"_J,
"FM_Horde_Controler"_J,
"dont_cross_the_line"_J,
"am_darts_apartment"_J,
"AM_Armwrestling_Apartment"_J,
"grid_arcade_cabinet"_J,
"scroll_arcade_cabinet"_J,
"example_arcade"_J,
"road_arcade"_J,
"gunslinger_arcade"_J,
"wizard_arcade"_J,
"AM_CASINO_LIMO"_J,
"AM_CASINO_LUXURY_CAR"_J,
"Degenatron Games"_J,
"ggsm_arcade"_J,
"puzzle"_J,
"camhedz_arcade"_J,
"SCTV"_J,
});
}
+126 -108
View File
@@ -2,7 +2,8 @@
namespace YimMenu
{
static constexpr auto scriptNames = std::to_array({"abigail1",
static constexpr auto scriptNames = std::to_array({
"abigail1",
"abigail2",
"achievement_controller",
"activity_creator_prototype_launcher",
@@ -25,8 +26,8 @@ namespace YimMenu
"ambient_tonya",
"ambient_tonyacall",
"ambient_tonyacall2",
"ambient_ufos",
"ambient_tonyacall5",
"ambient_ufos",
"am_agency_suv",
"am_airstrike",
"am_ammo_drop",
@@ -34,8 +35,8 @@ namespace YimMenu
"am_armwrestling",
"am_armwrestling_apartment",
"am_armybase",
"am_beach_washup_cinematic",
"am_backup_heli",
"am_beach_washup_cinematic",
"am_boat_taxi",
"am_bru_box",
"am_car_mod_tut",
@@ -45,8 +46,8 @@ namespace YimMenu
"am_challenges",
"am_contact_requests",
"am_cp_collection",
"am_criminal_damage",
"am_crate_drop",
"am_criminal_damage",
"am_darts",
"am_darts_apartment",
"am_dead_drop",
@@ -69,13 +70,13 @@ namespace YimMenu
"am_hs4_lsa_take_vel",
"am_hs4_nimb_isd_lsa_leave",
"am_hs4_nimb_lsa_isd_arrive",
"am_hs4_vel_lsa_isd",
"am_hs4_nimb_lsa_isd_leave",
"am_hs4_vel_lsa_isd",
"am_hunt_the_beast",
"am_imp_exp",
"am_island_backup_heli",
"am_kill_list",
"am_joyrider",
"am_kill_list",
"am_king_of_the_castle",
"am_launcher",
"am_lester_cut",
@@ -89,21 +90,21 @@ namespace YimMenu
"am_mp_arcade_fortune_teller",
"am_mp_arcade_love_meter",
"am_mp_arcade_peds",
"am_mp_arc_cab_manager",
"am_mp_arcade_strength_test",
"am_mp_arc_cab_manager",
"am_mp_arena_box",
"am_mp_arena_garage",
"am_mp_armory_truck",
"am_mp_armory_aircraft",
"am_mp_armory_truck",
"am_mp_auto_shop",
"am_mp_bail_office",
"am_mp_boardroom_seating",
"am_mp_biker_warehouse",
"am_mp_boardroom_seating",
"am_mp_bunker",
"am_mp_business_hub",
"am_mp_carwash_launch",
"am_mp_car_meet_sandbox",
"am_mp_car_meet_property",
"am_mp_car_meet_sandbox",
"am_mp_casino",
"am_mp_casino_apartment",
"am_mp_casino_nightclub",
@@ -124,14 +125,17 @@ namespace YimMenu
"am_mp_juggalo_hideout",
"am_mp_multistorey_garage",
"am_mp_music_studio",
"am_mp_orbital_cannon",
"am_mp_nightclub",
"am_mp_orbital_cannon",
"am_mp_peds",
"am_mp_property_ext",
"am_mp_property_int",
"am_mp_rc_vehicle",
"am_mp_rpa_menu",
"am_mp_salvage_yard",
"am_mp_sb_car_wash",
"am_mp_sb_heli_tours",
"am_mp_sb_weed_shop",
"am_mp_shooting_range",
"am_mp_simeon_showroom",
"am_mp_smoking_activity",
@@ -143,10 +147,10 @@ namespace YimMenu
"am_mp_vehicle_organization_menu",
"am_mp_vehicle_reward",
"am_mp_vehicle_weapon",
"am_mp_vinewood_premium_modshop",
"am_mp_vinewood_premium_garage",
"am_mp_yacht",
"am_mp_vinewood_premium_modshop",
"am_mp_warehouse",
"am_mp_yacht",
"am_npc_invites",
"am_pass_the_parcel",
"am_penned_in",
@@ -158,8 +162,8 @@ namespace YimMenu
"am_rollercoaster",
"am_rontrevor_cut",
"am_simosa",
"am_vehicle_spawn",
"am_taxi",
"am_vehicle_spawn",
"animal_controller",
"apartment_minigame_launcher",
"apparcadebusiness",
@@ -174,8 +178,8 @@ namespace YimMenu
"appchecklist",
"appcontacts",
"appcovertops",
"appextraction",
"appemail",
"appextraction",
"appfixersecurity",
"apphackerden",
"apphackertruck",
@@ -183,9 +187,9 @@ namespace YimMenu
"appimportexport",
"appinternet",
"appjipmp",
"appmpemail",
"appmpbossagency",
"appmedia",
"appmpbossagency",
"appmpemail",
"appmpjoblistnew",
"apporganiser",
"appprogresshub",
@@ -219,15 +223,15 @@ namespace YimMenu
"autosave_controller",
"auto_shop_seating",
"bailbond1",
"bailbond4",
"bailbond3",
"bailbond2",
"bailbond3",
"bailbond4",
"bailbond_launcher",
"bail_office_seating",
"barry1",
"barry2",
"barry3a",
"barry3",
"barry3a",
"barry3c",
"barry4",
"base_carmod",
@@ -251,8 +255,8 @@ namespace YimMenu
"bugstar_mission_export",
"buildingsiteambience",
"building_controller",
"business_battles_defend",
"business_battles",
"business_battles_defend",
"business_battles_sell",
"business_hub_carmod",
"business_hub_garage_seats",
@@ -263,8 +267,8 @@ namespace YimMenu
"candidate_controller",
"carmod_shop",
"carsteal1",
"carsteal3",
"carsteal2",
"carsteal3",
"carsteal4",
"carwash1",
"carwash2",
@@ -286,12 +290,12 @@ namespace YimMenu
"cellphone_controller",
"cellphone_flashhand",
"charactergoals",
"cheat_controller",
"charanimtest",
"cheat_controller",
"chinese1",
"chinese2",
"circuitblockhack",
"chop",
"circuitblockhack",
"clothes_shop_mp",
"clothes_shop_sp",
"code_controller",
@@ -307,8 +311,8 @@ namespace YimMenu
"controller_trafficking",
"coordinate_recorder",
"country_race",
"creation_startup",
"country_race_controller",
"creation_startup",
"creator",
"custom_config",
"cutscenemetrics",
@@ -322,32 +326,32 @@ namespace YimMenu
"debug_ped_data",
"degenatron_games",
"density_test",
"director_mode",
"dialogue_handler",
"director_mode",
"docks2asubhandler",
"docks_heista",
"docks_prep1",
"docks_heistb",
"docks_prep1",
"docks_prep2b",
"docks_setup",
"dont_cross_the_line",
"dreyfuss1",
"drf2",
"drf1",
"drf2",
"drf3",
"drf5",
"drf4",
"drf5",
"drunk",
"drunk_controller",
"dynamixtest",
"emergencycall",
"email_controller",
"emergencycall",
"emergencycalllauncher",
"epscars",
"epsdesert",
"epsilon1",
"epsilon3",
"epsilon2",
"epsilon3",
"epsilon4",
"epsilon5",
"epsilon6",
@@ -359,11 +363,11 @@ namespace YimMenu
"error_thrower",
"event_controller",
"exile1",
"exile_city_denial",
"exile2",
"exile3",
"extreme2",
"exile_city_denial",
"extreme1",
"extreme2",
"extreme3",
"extreme4",
"fairgroundhub",
@@ -371,13 +375,13 @@ namespace YimMenu
"fameorshame_eps",
"fameorshame_eps_1",
"fame_or_shame_set",
"family1",
"family1taxi",
"family2",
"family1",
"family3",
"family6",
"family4",
"family5",
"family6",
"family_scene_f0",
"family_scene_f1",
"family_scene_m",
@@ -397,10 +401,10 @@ namespace YimMenu
"fbi4_prep3amb",
"fbi4_prep4",
"fbi4_prep5",
"field_hangar_seating",
"fbi5a",
"finaleb",
"field_hangar_seating",
"finalea",
"finaleb",
"finalec1",
"finalec2",
"finale_choice",
@@ -410,8 +414,8 @@ namespace YimMenu
"finale_heist2a",
"finale_heist2b",
"finale_heist2_intro",
"finale_heist_prepb",
"finale_heist_prepa",
"finale_heist_prepb",
"finale_heist_prepc",
"finale_heist_prepd",
"finale_heist_prepeamb",
@@ -433,8 +437,8 @@ namespace YimMenu
"fm_bj_race_controler",
"fm_capture_creator",
"fm_content_acid_lab_sell",
"fm_content_acid_lab_source",
"fm_content_acid_lab_setup",
"fm_content_acid_lab_source",
"fm_content_ammunation",
"fm_content_armoured_truck",
"fm_content_arms_trafficking",
@@ -446,6 +450,8 @@ namespace YimMenu
"fm_content_bounty_targets",
"fm_content_business_battles",
"fm_content_cargo",
"fm_content_car_wash_detailing",
"fm_content_car_wash_work",
"fm_content_cerberus",
"fm_content_chop_shop_delivery",
"fm_content_clubhouse_contracts",
@@ -455,6 +461,7 @@ namespace YimMenu
"fm_content_community_outreach",
"fm_content_convoy",
"fm_content_crime_scene",
"fm_content_cutscene",
"fm_content_daily_bounty",
"fm_content_dispatch_work",
"fm_content_drone",
@@ -472,6 +479,8 @@ namespace YimMenu
"fm_content_hacker_whistle_prep",
"fm_content_hacker_zancudo_fin",
"fm_content_hacker_zancudo_prep",
"fm_content_helitours_tour",
"fm_content_helitours_work",
"fm_content_hsw_setup",
"fm_content_hsw_time_trial",
"fm_content_island_dj",
@@ -479,44 +488,47 @@ namespace YimMenu
"fm_content_metal_detector",
"fm_content_movie_props",
"fm_content_mp_intro",
"fm_content_payphone_hit",
"fm_content_parachuter",
"fm_content_payphone_hit",
"fm_content_phantom_car",
"fm_content_pizza_delivery",
"fm_content_security_contract",
"fm_content_robbery",
"fm_content_possessed_animals",
"fm_content_robbery",
"fm_content_security_contract",
"fm_content_sightseeing",
"fm_content_slasher",
"fm_content_skydive",
"fm_content_slasher",
"fm_content_smuggler_ops",
"fm_content_smuggler_plane",
"fm_content_smuggler_resupply",
"fm_content_smuggler_trail",
"fm_content_smuggler_sell",
"fm_content_smuggler_trail",
"fm_content_source_research",
"fm_content_stash_house",
"fm_content_taxi_driver",
"fm_content_test",
"fm_content_tow_truck_work",
"fm_content_tuner_robbery",
"fm_content_tycoon_odd_jobs",
"fm_content_ufo_abduction",
"fm_content_vehicle_list",
"fm_content_vehrob_arena",
"fm_content_vehrob_cargo_ship",
"fm_content_vehrob_casino_prize",
"fm_content_vehrob_police",
"fm_content_vehrob_disrupt",
"fm_content_vehrob_police",
"fm_content_vehrob_prep",
"fm_content_vehrob_scoping",
"fm_content_vehrob_submarine",
"fm_content_vip_contract_1",
"fm_content_vehrob_task",
"fm_content_vip_contract_1",
"fm_content_weed_shop_delivery",
"fm_content_weed_shop_work",
"fm_content_xmas_mugger",
"fm_content_xmas_truck",
"fm_deathmatch_controler",
"fm_hideout_controler",
"fm_deathmatch_creator",
"fm_hideout_controler",
"fm_hold_up_tut",
"fm_horde_controler",
"fm_impromptu_dm_controler",
@@ -538,22 +550,22 @@ namespace YimMenu
"fps_test",
"fps_test_mag",
"franklin0",
"franklin2",
"franklin1",
"franklin2",
"freemode",
"freemode_clearglobals",
"freemode_creator",
"freemode_init",
"friends_controller",
"friendactivity",
"friends_controller",
"friends_debug_controller",
"fullmap_test",
"fullmap_test_flow",
"game_server_test",
"gb_airfreight",
"gb_amphibious_assault",
"gb_bank_job",
"gb_assault",
"gb_bank_job",
"gb_bellybeast",
"gb_biker_bad_deal",
"gb_biker_burn_assets",
@@ -574,11 +586,11 @@ namespace YimMenu
"gb_biker_shuttle",
"gb_biker_stand_your_ground",
"gb_biker_steal_bikes",
"gb_biker_unload_weapons",
"gb_biker_target_rival",
"gb_biker_unload_weapons",
"gb_biker_wheelie_rider",
"gb_cashing_out",
"gb_carjacking",
"gb_cashing_out",
"gb_casino",
"gb_casino_heist",
"gb_casino_heist_planning",
@@ -602,8 +614,8 @@ namespace YimMenu
"gb_headhunter",
"gb_hunt_the_boss",
"gb_ie_delivery_cutscene",
"gb_infiltration",
"gb_illicit_goods_resupply",
"gb_infiltration",
"gb_jewel_store_grab",
"gb_ploughed",
"gb_point_to_point",
@@ -615,15 +627,16 @@ namespace YimMenu
"gb_smuggler",
"gb_stockpiling",
"gb_target_pursuit",
"gb_transporter",
"gb_terminate",
"gb_transporter",
"gb_vehicle_export",
"gb_velocity",
"general_test",
"gb_yacht_rob",
"general_test",
"ggsm_arcade",
"globals_fmmc_struct_registration",
"globals_fmmcstruct2_registration",
"globals_fmmcstruct3_registration",
"globals_fmmc_struct_registration",
"golf",
"golf_ai_foursome",
"golf_ai_foursome_putting",
@@ -649,20 +662,20 @@ namespace YimMenu
"gtest_divingfromcar",
"gtest_divingfromcarwhilefleeing",
"gtest_helicopter",
"gunclub_shop",
"gtest_nearlymissedbycar",
"gunclub_shop",
"gunfighttest",
"gunslinger_arcade",
"hacker_den_carmod",
"hacker_den_ext_seating",
"hacker_den_seating",
"hairdo_shop_mp",
"hacker_truck_carmod",
"hairdo_shop_mp",
"hairdo_shop_sp",
"hangar_carmod",
"hao1",
"headertest",
"heatmap_test",
"hao1",
"heatmap_test_flow",
"heist_ctrl_agency",
"heist_ctrl_docks",
@@ -670,16 +683,16 @@ namespace YimMenu
"heist_ctrl_jewel",
"heist_ctrl_rural",
"heist_island_planning",
"heli_streaming",
"heli_gun",
"heli_streaming",
"hud_creator",
"hunting1",
"hunting2",
"hunting_ambient",
"idlewarper",
"hunting2",
"hunting1",
"ingamehud",
"item_ownership_output",
"initial",
"item_ownership_output",
"jewelry_heist",
"jewelry_prep1a",
"jewelry_prep1b",
@@ -700,13 +713,13 @@ namespace YimMenu
"launcher_basejumppack",
"launcher_carwash",
"launcher_darts",
"launcher_epsilon",
"launcher_dreyfuss",
"launcher_epsilon",
"launcher_extreme",
"launcher_fanatic",
"launcher_hunting",
"launcher_golf",
"launcher_hao",
"launcher_hunting",
"launcher_hunting_ambient",
"launcher_josh",
"launcher_maude",
@@ -722,34 +735,34 @@ namespace YimMenu
"launcher_range",
"launcher_stunts",
"launcher_tennis",
"launcher_tonya",
"launcher_thelastone",
"launcher_tonya",
"launcher_triathlon",
"launcher_yoga",
"lesterhandler",
"lester1",
"lesterhandler",
"letterscraps",
"line_activation_test",
"liverecorder",
"localpopulator",
"luxe_veh_activity",
"locates_tester",
"luxe_veh_activity",
"magdemo",
"main",
"main_install",
"magdemo2",
"main",
"maintransition",
"main_install",
"main_persistent",
"martin1",
"maude1",
"maude_postbailbond",
"me_amanda1",
"me_jimmy1",
"mg_race_to_point",
"me_tracey1",
"mg_race_to_point",
"michael1",
"michael3",
"michael2",
"michael3",
"michael4",
"michael4leadout",
"minigame_ending_stinger",
@@ -776,21 +789,21 @@ namespace YimMenu
"mp_menuped",
"mp_player_damage_numbers",
"mp_prop_global_block",
"mp_registration",
"mp_prop_special_global_block",
"mp_skycam_stuck_wiggler",
"mp_registration",
"mp_save_game_global_block",
"mp_skycam_stuck_wiggler",
"mp_unlocks",
"mp_weapons",
"mrsphilips2",
"mrsphilips1",
"mrsphilips2",
"multistorey_garage_ext_seating",
"multistorey_garage_seating",
"murdermystery",
"music_studio_seating",
"music_studio_seating_external",
"navmeshtest",
"music_studio_smoking",
"navmeshtest",
"net_activity_creator_ui",
"net_apartment_activity",
"net_apartment_activity_light",
@@ -801,6 +814,7 @@ namespace YimMenu
"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",
@@ -821,8 +835,8 @@ namespace YimMenu
"ob_abattoircut",
"ob_airdancer",
"ob_bong",
"ob_drinking_shots",
"ob_cashregister",
"ob_drinking_shots",
"ob_foundry_cauldron",
"ob_franklin_beer",
"ob_franklin_tv",
@@ -852,42 +866,42 @@ namespace YimMenu
"paparazzo3a",
"paparazzo3b",
"paparazzo4",
"paradise2",
"paradise",
"paradise2",
"pausemenu",
"pausemenucareerhublaunch",
"pausemenu_example",
"pausemenu_map",
"pausemenu_multiplayer",
"pausemenu_sp_repeat",
"pb_homeless",
"pb_busker",
"pb_homeless",
"pb_preacher",
"pb_prostitute",
"personal_carmod_shop",
"photographymonkey",
"physics_perf_test",
"photographywildlife",
"physics_perf_test",
"physics_perf_test_launcher",
"pickuptest",
"pickup_controller",
"pickupvehicles",
"pickup_controller",
"pilot_school",
"placeholdermission",
"pilot_school_mp",
"pi_menu",
"placeholdermission",
"placementtest",
"player_controller_b",
"planewarptest",
"player_controller",
"player_controller_b",
"player_scene_ft_franklin1",
"player_scene_f_lamgraff",
"player_scene_f_lamtaunt",
"player_scene_f_taxi",
"player_scene_mf_traffic",
"player_scene_m_cinema",
"player_scene_m_kids",
"player_scene_m_fbi2",
"player_scene_m_kids",
"player_scene_m_shopping",
"player_scene_t_bbfight",
"player_scene_t_chasecar",
@@ -898,17 +912,18 @@ namespace YimMenu
"playthrough_builder",
"pm_defend",
"pm_delivery",
"pm_plane_promotion",
"pm_gang_attack",
"postkilled_bailbond2",
"pm_plane_promotion",
"pm_recover_stolen",
"postrc_barry4",
"postkilled_bailbond2",
"postrc_barry1and2",
"postrc_barry4",
"postrc_epsilon4",
"postrc_nigel3",
"profiler_registration",
"prologue1",
"prop_drop",
"public_mission_creator",
"puzzle",
"racetest",
"rampage1",
@@ -918,10 +933,10 @@ namespace YimMenu
"rampage5",
"rampage_controller",
"randomchar_controller",
"range_modern_mp",
"range_modern",
"replay_controller",
"range_modern_mp",
"rcpdata",
"replay_controller",
"rerecord_recording",
"respawn_controller",
"restrictedareas",
@@ -937,12 +952,12 @@ namespace YimMenu
"re_cartheft",
"re_chasethieves",
"re_crashrescue",
"re_dealgonewrong",
"re_cultshootout",
"re_dealgonewrong",
"re_domestic",
"re_drunkdriver",
"re_gangfight",
"re_duel",
"re_gangfight",
"re_gang_intimidation",
"re_getaway_driver",
"re_hitch_lift",
@@ -952,8 +967,8 @@ namespace YimMenu
"re_monkey",
"re_mountdance",
"re_muggings",
"re_prison",
"re_paparazzi",
"re_prison",
"re_prisonerlift",
"re_prisonvanbreak",
"re_rescuehostage",
@@ -968,12 +983,14 @@ namespace YimMenu
"rollercoaster",
"rural_bank_heist",
"rural_bank_prep1",
"salvage_yard_seating",
"rural_bank_setup",
"salvage_yard_seating",
"savegame_bed",
"save_anywhere",
"scaleformminigametest",
"sb_heli_tours_seating",
"sb_weed_shop_seating",
"scaleformgraphictest",
"scaleformminigametest",
"scaleformprofiling",
"scaleformtest",
"scene_builder",
@@ -986,8 +1003,8 @@ namespace YimMenu
"scripttest4",
"script_metrics",
"scroll_arcade_cabinet",
"sc_lb_global_block",
"sctv",
"sc_lb_global_block",
"selector",
"selector_example",
"selling_short_1",
@@ -999,27 +1016,27 @@ namespace YimMenu
"shrinkletter",
"sh_intro_f_hills",
"sh_intro_m_home",
"smoketest",
"simeon_showroom_seating",
"smoketest",
"social_controller",
"solomon1",
"solomon2",
"solomon3",
"spaceshipparts",
"spawn_activities",
"spmc_instancer",
"speech_reverb_tracker",
"spmc_instancer",
"spmc_preloader",
"sp_dlc_registration",
"sp_editor_mission_instance",
"sp_pilotschool_reg",
"sp_menuped",
"sp_pilotschool_reg",
"standard_global_init",
"standard_global_reg",
"startup",
"startup_install",
"startup_positioning",
"startup_locationtest",
"startup_positioning",
"startup_smoketest",
"stats_controller",
"stock_controller",
@@ -1045,8 +1062,8 @@ namespace YimMenu
"taxi_takeiteasy",
"taxi_taketobest",
"tempalpha",
"tennis",
"temptest",
"tennis",
"tennis_ambient",
"tennis_family",
"tennis_network_mp",
@@ -1054,13 +1071,13 @@ namespace YimMenu
"thelastone",
"three_card_poker",
"timershud",
"title_update_registration_2",
"title_update_registration",
"title_update_registration_2",
"tonya1",
"tonya2",
"tonya5",
"tonya3",
"tonya4",
"tonya5",
"towing",
"traffickingsettings",
"traffickingteleport",
@@ -1069,26 +1086,26 @@ namespace YimMenu
"train_create_widget",
"train_tester",
"trevor1",
"trevor3",
"trevor2",
"trevor3",
"trevor4",
"triathlonsp",
"tunables_registration",
"tuner_planning",
"tuneables_processing",
"tuner_planning",
"tuner_property_carmod",
"tuner_sandbox_activity",
"ufo",
"turret_cam_script",
"ufo",
"ugc_global_registration",
"ugc_global_registration_2",
"underwaterpickups",
"vehiclespawning",
"utvc",
"vehiclespawning",
"vehicle_ai_test",
"vehicle_force_widget",
"vehicle_plate",
"vehicle_gen_controller",
"vehicle_plate",
"vehicle_stealth_mode",
"vehrob_planning",
"veh_play_widget",
@@ -1101,5 +1118,6 @@ namespace YimMenu
"word_hack",
"wp_partyboombox",
"xml_menus",
"yoga"});
"yoga",
});
}
+2
View File
@@ -10,6 +10,7 @@
#include "core/hooking/CallHook.hpp"
#include "core/memory/ModuleMgr.hpp"
#include "core/renderer/Renderer.hpp"
#include "core/scripting/LuaManager.hpp"
#include "game/backend/AnticheatBypass.hpp"
#include "game/backend/Players.hpp"
#include "game/backend/SavedLocations.hpp"
@@ -70,6 +71,7 @@ namespace YimMenu
ScriptMgr::AddScript(std::make_unique<Script>(&Self::RunScript));
ScriptMgr::AddScript(std::make_unique<Script>(&GUI::RunScript));
FiberPool::Init(16);
ScriptMgr::AddScript(std::make_unique<Script>(&LuaManager::RunScript));
ScriptMgr::AddScript(std::make_unique<Script>(&HotkeySystem::RunScript));
ScriptMgr::AddScript(std::make_unique<Script>(&Commands::RunScript));
ScriptMgr::AddScript(std::make_unique<Script>(&Features::SavePersonalVehicle::RunScript));
@@ -101,5 +101,10 @@ public:
return m_Host->m_Player;
}
inline bool IsParticipant(int player_index) const
{
return (m_ParticipantBitset & (1 << player_index)) != 0;
}
};
static_assert(sizeof(CGameScriptHandlerNetComponent) == 0x1B0);
+12 -4
View File
@@ -1,11 +1,19 @@
#pragma once
#include "types.hpp"
// names taken from GTA5_Enhanced.exe+0x2252260 (0F 84 7F 01 00 00 4C 8B 47 20 48 8D 15 -0x21) (SCRIPT_EVENT_FPOM)
struct MP_SCRIPT_DATA
{
SCR_INT Index; // this is an enum
uint64_t Args[15];
SCR_INT InstanceId;
uint64_t MoreArgs[4];
SCR_INT MissionIndex; // this is an enum
SCR_INT Variation;
SCR_INT Creator;
TEXT_LABEL_23 CloudFileName;
SCR_INT SharedRegId;
uint64_t PAD_0005[6]; // not serialized in the metric
SCR_INT InstanceId;
SCR_INT UniqueId;
SCR_INT BitSet;
SCR_INT GenericInt;
SCR_INT TruckBitSet;
};
static_assert(sizeof(MP_SCRIPT_DATA) == 21 * 8);
+26 -2
View File
@@ -1,5 +1,6 @@
#pragma once
#include "types.hpp"
#include "MPScriptData.hpp"
#define REGISTER_SCRIPT_EVENT(classType, indexType) \
constexpr static auto EVENT_INDEX = ScriptEventIndex::indexType; \
@@ -77,7 +78,7 @@ enum class ScriptEventIndex
TriggerCEORaid = -1906536929,
StartScriptBegin = -366707054,
StartScriptProceed = 1757622014,
StartScriptProceed = 1757622014,
RequestRandomEvent = -126218586,
CollectCollectable = 968269233,
@@ -97,7 +98,7 @@ public:
return SenderIndex;
}
Hash GetEventIndex() const
Hash& GetEventIndex()
{
return EventIndex;
}
@@ -121,6 +122,11 @@ public:
{
PlayerBits |= (1 << player);
}
void SetPlayerBits(int bits)
{
PlayerBits = bits;
}
protected:
void SendImpl(int size);
@@ -255,4 +261,22 @@ struct SET_SKYDIVE_COMPLETED : public SCRIPT_EVENT
SCR_BOOL AccurateLanding;
};
// FPOM
struct SCRIPT_EVENT_FORCE_PLAYER_ON_MISSION : public SCRIPT_EVENT
{
REGISTER_SCRIPT_EVENT(SCRIPT_EVENT_FORCE_PLAYER_ON_MISSION, StartScriptBegin);
MP_SCRIPT_DATA ScriptData;
SCR_INT Flags;
SCR_INT ReplayProtectionValue;
SCR_INT PAD_0026;
};
static_assert(sizeof(SCRIPT_EVENT_FORCE_PLAYER_ON_MISSION) == 27 * 8);
struct SCRIPT_EVENT_FORCE_PLAYER_ON_MISSION_SERVER_ACK : public SCRIPT_EVENT
{
REGISTER_SCRIPT_EVENT(SCRIPT_EVENT_FORCE_PLAYER_ON_MISSION_SERVER_ACK, StartScriptProceed);
MP_SCRIPT_DATA ScriptData;
};
static_assert(sizeof(SCRIPT_EVENT_FORCE_PLAYER_ON_MISSION_SERVER_ACK) == 24 * 8);
#undef REGISTER_SCRIPT_EVENT
+1 -1
View File
@@ -315,7 +315,7 @@ struct GBPD_FM_3_Entry
SCR_BOOL TimeTrialActive; // verify
BOSS_GOON BossGoon;
uint64_t PAD_507[3]; // unused
SCR_INT ScriptEventReplayProtectionCounter;
SCR_INT ScriptEventReplayProtectionCounter; // "uniqueId"
TIMER CoronaForcedLaunchTimer;
LEAVE_IN_HELI LeaveInHeli;
SCR_INT OfficeDesktopFlags; // bit 0 -> login, bit 1 -> map
+3 -1
View File
@@ -19,6 +19,7 @@
#include "DailyObjectivesState.hpp"
#include "WeeklyChallenge.hpp"
#include "FreemodeDelivery.hpp"
#include "LauncherServerData.hpp"
#include "game/gta/ScriptGlobal.hpp"
#define DEFINE_GLOBAL_ACCESSOR(str, global) \
@@ -50,4 +51,5 @@ DEFINE_GLOBAL_ACCESSOR(g_SavedMPGlobals, 2359296);
DEFINE_GLOBAL_ACCESSOR(FreemodeGeneral, 2740191);
DEFINE_GLOBAL_ACCESSOR(DailyObjectivesState, 1574745);
DEFINE_GLOBAL_ACCESSOR(WeeklyChallenge, 2739243);
DEFINE_GLOBAL_ACCESSOR(FreemodeDelivery, 1953035);
DEFINE_GLOBAL_ACCESSOR(FreemodeDelivery, 1953035);
DEFINE_GLOBAL_ACCESSOR(LauncherServerData, 2699563);
@@ -0,0 +1,60 @@
#pragma once
#include "types/script/types.hpp"
#include "types/script/Timer.hpp"
enum class eHostScriptState
{
INITIALIZING,
RUNNING,
PREPARING_TO_SHUT_DOWN,
SHUTTING_DOWN
};
enum class eLauncherFlags
{
RUN_IMMEDIATELY = 1
};
enum class eLauncherState
{
EMPTY,
FIND_SCRIPT,
UNK_2, // unused
PICK_MISSION_VARIATION,
UNK_4,
WAIT_FOR_ACK,
START_SCRIPT,
WAIT_FOR_TERMINATION,
RESET
};
struct LAUNCHER_SCRIPT
{
SCR_INT EventIndex;
SCR_INT LauncherIndex; // this is the script index we want to set
SCR_FLOAT Probability;
SCR_INT PAD_0003; // unused
SCR_BOOL Terminated;
};
static_assert(sizeof(LAUNCHER_SCRIPT) == 5 * 8);
struct LauncherServerData
{
alignas(8) eHostScriptState HostState;
SCR_BITSET<eLauncherFlags> Flags;
alignas(8) eLauncherState LauncherState;
LAUNCHER_SCRIPT CurrentScript;
SCR_ARRAY<LAUNCHER_SCRIPT, 21> QueuedScripts;
SCR_ARRAY<uint64_t, 21> QueuedEvents;
uint64_t PAD_0136[41]; // unused
TIMER CrateDropTimer;
TIMER ScriptLaunchTimer;
SCR_INT TimeToWaitForLaunch;
SCR_INT CurrentEvent;
SCR_INT ScriptParam1;
SCR_INT ScriptParam2;
SCR_INT ScriptParam3;
static LauncherServerData* Get();
};
static_assert(sizeof(LauncherServerData) == 186 * 8);
@@ -0,0 +1,19 @@
#pragma once
#include "../types.hpp"
#include "../globals/LauncherServerData.hpp"
struct LauncherClientDataEntry
{
SCR_INT ClientState;
SCR_INT Flags;
alignas(8) eLauncherState LauncherState;
};
static_assert(sizeof(LauncherClientDataEntry) == 3 * 8);
struct LauncherClientData
{
SCR_ARRAY<LauncherClientDataEntry, 32> Entries;
static LauncherClientData* Get(rage::scrThread* thread);
};
static_assert(sizeof(LauncherClientData) == 97 * 8);
+5 -1
View File
@@ -4,6 +4,7 @@
#include "RCBanditoTimeTrialData.hpp"
#include "HSWTimeTrialData.hpp"
#include "BikeTimeTrialData.hpp"
#include "LauncherClientData.hpp"
#include "game/gta/ScriptLocal.hpp"
#define DEFINE_LOCAL_ACCESSOR(str, local) \
@@ -20,4 +21,7 @@ DEFINE_LOCAL_ACCESSOR(RANDOM_EVENTS_FREEMODE_DATA, 16019);
DEFINE_LOCAL_ACCESSOR(StandardTimeTrialData, 14640);
DEFINE_LOCAL_ACCESSOR(RCBanditoTimeTrialData, 14690);
DEFINE_LOCAL_ACCESSOR(HSWTimeTrialData, 14734);
DEFINE_LOCAL_ACCESSOR(BikeTimeTrialData, 15529);
DEFINE_LOCAL_ACCESSOR(BikeTimeTrialData, 15529);
// am_launcher
DEFINE_LOCAL_ACCESSOR(LauncherClientData, 245);