diff --git a/src/core/frontend/widgets/imgui_bitfield.hpp b/src/core/frontend/widgets/imgui_bitfield.hpp new file mode 100644 index 0000000..ce5ef3b --- /dev/null +++ b/src/core/frontend/widgets/imgui_bitfield.hpp @@ -0,0 +1,72 @@ +#pragma once + +namespace ImGui +{ + template + bool Bitfield(const char* name, T* param) + { + bool ret = false; + ImGuiDataType type; + size_t size = sizeof(T); + std::string format; + if (size == 1) + { + type = ImGuiDataType_U8; + format = "%02X"; + } + if (size == 2) + { + type = ImGuiDataType_U16; + format = "%04X"; + } + if (size == 4) + { + type = ImGuiDataType_U32; + format = "%08X"; + } + if (size == 8) + { + type = ImGuiDataType_U64; + format = "%p"; + } + + if (ImGui::InputScalar(name, type, param, NULL, NULL, format.c_str(), ImGuiInputTextFlags_CharsHexadecimal)) + ret = true; + size_t bits = (size * 8) - 1ULL; + for (size_t i = bits; i < SIZE_MAX; i--) + { + if (i % 4 == 0) + ImGui::BeginGroup(); + if (*param & (1ULL << i)) + { + ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32_BLACK_TRANS); + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(41, 134, 204, 255)); + if (ImGui::Button(std::format("1##{}{}", name, i).c_str(), ImVec2(25, 0))) + { + ret = true; + *param ^= (1ULL << i); + } + ImGui::PopStyleColor(2); + } + else + { + ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32_BLACK_TRANS); + if (ImGui::Button(std::format("0##{}{}", name, i).c_str(), ImVec2(25, 0))) + { + ret = true; + *param ^= (1ULL << i); + } + ImGui::PopStyleColor(); + } + if (i % 4 == 0) + { + ImGui::Text("%i", i); + ImGui::EndGroup(); + } + if (i % 16 != 0) + ImGui::SameLine(); + } + + return ret; + } +} \ No newline at end of file diff --git a/src/game/backend/SavedVariables.hpp b/src/game/backend/SavedVariables.hpp index 528ea8d..9d20b91 100644 --- a/src/game/backend/SavedVariables.hpp +++ b/src/game/backend/SavedVariables.hpp @@ -10,9 +10,12 @@ namespace YimMenu enum class VariableType { INT, - FLOAT, + INT64, + BITSET, BOOL, - INT64 + FLOAT, + VECTOR, + STRING }; struct VariableAppendage diff --git a/src/game/backend/Tunables.cpp b/src/game/backend/Tunables.cpp index 880a288..0c6b01f 100644 --- a/src/game/backend/Tunables.cpp +++ b/src/game/backend/Tunables.cpp @@ -3,12 +3,20 @@ #include "core/memory/ModuleMgr.hpp" #include "core/backend/ScriptMgr.hpp" #include "game/backend/NativeHooks.hpp" +#include "game/gta/data/StackSizes.hpp" #include "game/gta/Natives.hpp" #include "game/gta/Scripts.hpp" #include "types/script/scrProgram.hpp" namespace YimMenu { + struct TUNABLES_LAUNCH_DATA + { + SCR_INT Context; + SCR_INT ContentModifier; + }; + static_assert(sizeof(TUNABLES_LAUNCH_DATA) == 2 * 8); + static void TunablesWaitHook(rage::scrNativeCallContext* src) { if (Tunables::CachingTunables()) @@ -73,9 +81,7 @@ namespace YimMenu if (m_CacheFile.UpToDate(ModuleMgr.Get("GTA5_Enhanced.exe"_J)->GetNtHeader()->FileHeader.TimeDateStamp)) { - LOG(INFO) << "Loading tunables from cache."; m_Loading = true; - Load(); } @@ -101,7 +107,7 @@ namespace YimMenu TUNABLES_LAUNCH_DATA args; args.Context = 6; // BASE_GLOBALS args.ContentModifier = 27; // MP_FM_RANDOM - if (!BUILTIN::START_NEW_SCRIPT_WITH_NAME_HASH_AND_ARGS("tuneables_processing"_J, &args, sizeof(args) / 8, 1424)) + if (!BUILTIN::START_NEW_SCRIPT_WITH_NAME_HASH_AND_ARGS("tuneables_processing"_J, &args, SCR_SIZEOF(args), eStackSizes::DEFAULT)) { LOG(FATAL) << "Failed to start tuneables_processing. Cannot cache tunables."; return; @@ -186,5 +192,7 @@ namespace YimMenu m_Initialized = true; m_Loading = false; + + LOG(INFO) << "Loaded " << m_Tunables.size() << " tunables from cache."; } } \ No newline at end of file diff --git a/src/game/backend/Tunables.hpp b/src/game/backend/Tunables.hpp index 0cd2c95..df1aac9 100644 --- a/src/game/backend/Tunables.hpp +++ b/src/game/backend/Tunables.hpp @@ -7,13 +7,6 @@ namespace YimMenu { constexpr int TUNABLE_BASE_ADDRESS = 0x40001; - struct TUNABLES_LAUNCH_DATA - { - alignas(8) int Context; - alignas(8) int ContentModifier; - }; - static_assert(sizeof(TUNABLES_LAUNCH_DATA) == 2 * 8); - #pragma pack(push, 1) struct TunableSaveStruct { diff --git a/src/game/features/recovery/GiveVehicleReward.cpp b/src/game/features/recovery/GiveVehicleReward.cpp index e4a7269..46b3264 100644 --- a/src/game/features/recovery/GiveVehicleReward.cpp +++ b/src/game/features/recovery/GiveVehicleReward.cpp @@ -1,6 +1,7 @@ #include "GiveVehicleReward.hpp" #include "core/backend/ScriptMgr.hpp" #include "game/backend/Self.hpp" +#include "game/gta/data/StackSizes.hpp" #include "game/gta/Natives.hpp" #include "game/gta/Scripts.hpp" #include "game/gta/ScriptFunction.hpp" @@ -40,7 +41,7 @@ namespace YimMenu SCRIPT::REQUEST_SCRIPT_WITH_NAME_HASH("AM_MP_VEHICLE_REWARD"_J); if (SCRIPT::HAS_SCRIPT_WITH_NAME_HASH_LOADED("AM_MP_VEHICLE_REWARD"_J)) { - int id = BUILTIN::START_NEW_SCRIPT_WITH_NAME_HASH("AM_MP_VEHICLE_REWARD"_J, 2050); + int id = BUILTIN::START_NEW_SCRIPT_WITH_NAME_HASH("AM_MP_VEHICLE_REWARD"_J, eStackSizes::FRIEND); m_Thread = Scripts::FindScriptThreadByID(id); if (m_Thread) m_Thread->m_Context.m_State = rage::scrThread::State::PAUSED; diff --git a/src/game/features/self/OpenWardrobe.cpp b/src/game/features/self/OpenWardrobe.cpp index 9f60f19..7cbb34c 100644 --- a/src/game/features/self/OpenWardrobe.cpp +++ b/src/game/features/self/OpenWardrobe.cpp @@ -4,11 +4,11 @@ #include "game/backend/Self.hpp" #include "game/backend/ScriptPatches.hpp" #include "game/backend/NativeHooks.hpp" +#include "game/gta/data/StackSizes.hpp" #include "game/gta/Natives.hpp" #include "game/gta/Scripts.hpp" #include "game/gta/ScriptLocal.hpp" #include "game/pointers/Pointers.hpp" -#include "types/script/types.hpp" namespace YimMenu::Features { @@ -50,7 +50,7 @@ namespace YimMenu::Features launchData.Type = 7; launchData.Position = Self::GetPed().GetPosition(); launchData.Heading = Self::GetPed().GetHeading(); - if (!BUILTIN::START_NEW_SCRIPT_WITH_NAME_HASH_AND_ARGS("wardrobe_mp"_J, &launchData, sizeof(launchData) / 8, 2324)) + if (!BUILTIN::START_NEW_SCRIPT_WITH_NAME_HASH_AND_ARGS("wardrobe_mp"_J, &launchData, SCR_SIZEOF(launchData), eStackSizes::SHOP)) { Notifications::Show("Wardrobe", "Failed to open the wardrobe.", NotificationType::Error); return; diff --git a/src/game/frontend/submenus/Debug.cpp b/src/game/frontend/submenus/Debug.cpp index 2f325d8..4cab3d8 100644 --- a/src/game/frontend/submenus/Debug.cpp +++ b/src/game/frontend/submenus/Debug.cpp @@ -1,21 +1,19 @@ #include "Debug.hpp" +#include "Debug/Misc.hpp" #include "Debug/Globals.hpp" #include "Debug/Locals.hpp" -//#include "Debug/Scripts.hpp" -#include "Debug/Misc.hpp" - +#include "Debug/Scripts.hpp" #include "game/frontend/items/Items.hpp" - - namespace YimMenu::Submenus { Debug::Debug() : Submenu::Submenu("Debug") { + AddCategory(BuildMiscMenu()); AddCategory(BuildGlobalsMenu()); AddCategory(BuildLocalsMenu()); - AddCategory(BuildMiscMenu()); + AddCategory(BuildScriptsMenu()); } } \ No newline at end of file diff --git a/src/game/frontend/submenus/Debug/DrawVariable.cpp b/src/game/frontend/submenus/Debug/DrawVariable.cpp new file mode 100644 index 0000000..227c870 --- /dev/null +++ b/src/game/frontend/submenus/Debug/DrawVariable.cpp @@ -0,0 +1,166 @@ +#include "DrawVariable.hpp" +#include "core/frontend/widgets/imgui_bitfield.hpp" +#include "types/script/scrVector.hpp" + +namespace YimMenu +{ + void DrawSavedVariableEdit(const SavedVariableBase& var, void* value) + { + if (!value) + return ImGui::TextDisabled("Invalid"); + + switch (var.type) + { + case VariableType::INT: + { + ImGui::SetNextItemWidth(200.f); + ImGui::InputScalar("Value", ImGuiDataType_S32, static_cast(value)); + break; + } + case VariableType::INT64: + { + ImGui::SetNextItemWidth(200.f); + ImGui::InputScalar("Value", ImGuiDataType_S64, static_cast(value)); + break; + } + case VariableType::BITSET: + { + ImGui::SetNextItemWidth(200.f); + ImGui::Bitfield("Value", static_cast(value)); + break; + } + case VariableType::BOOL: + { + ImGui::Checkbox("Value", static_cast(value)); + break; + } + case VariableType::FLOAT: + { + ImGui::SetNextItemWidth(200.f); + ImGui::InputScalar("Value", ImGuiDataType_Float, static_cast(value)); + break; + } + case VariableType::VECTOR: + { + auto vectorPtr = (rage::scrVector*)value; + ImGui::PushItemWidth(100.f); + ImGui::InputScalar("X", ImGuiDataType_Float, &vectorPtr->x); + ImGui::SameLine(); + ImGui::InputScalar("Y", ImGuiDataType_Float, &vectorPtr->y); + ImGui::SameLine(); + ImGui::InputScalar("Z", ImGuiDataType_Float, &vectorPtr->z); + ImGui::PopItemWidth(); + break; + } + case VariableType::STRING: + { + ImGui::SetNextItemWidth(200.f); + ImGui::InputText("Value", static_cast(value), 255); + break; + } + } + } + + void DrawSavedVariablePreview(const SavedVariableBase& var, void* value) + { + if (!value) + { + ImGui::Selectable("Invalid", false, ImGuiSelectableFlags_Disabled); + return; + } + + switch (var.type) + { + case VariableType::INT: + { + ImGui::Selectable(std::to_string(*static_cast(value)).c_str(), false, ImGuiSelectableFlags_Disabled); + break; + } + case VariableType::INT64: + { + ImGui::Selectable(std::to_string(*static_cast(value)).c_str(), false, ImGuiSelectableFlags_Disabled); + break; + } + case VariableType::BITSET: + { + std::ostringstream bitset; + bitset << HEX(*static_cast(value)); + ImGui::Selectable(bitset.str().c_str(), false, ImGuiSelectableFlags_Disabled); + break; + } + case VariableType::BOOL: + { + ImGui::Selectable(*static_cast(value) ? "True" : "False", false, ImGuiSelectableFlags_Disabled); + break; + } + case VariableType::FLOAT: + { + ImGui::Selectable(std::to_string(*static_cast(value)).c_str(), false, ImGuiSelectableFlags_Disabled); + break; + } + case VariableType::VECTOR: + { + auto vectorPtr = (rage::scrVector*)value; + std::ostringstream vector; + vector << "X: " << std::fixed << std::setprecision(2) << vectorPtr->x << " Y: " << vectorPtr->y << " Z: " << vectorPtr->z; + ImGui::Selectable(vector.str().c_str(), false, ImGuiSelectableFlags_Disabled); + break; + } + case VariableType::STRING: + { + ImGui::Selectable(static_cast(value), false, ImGuiSelectableFlags_Disabled); + break; + } + } + } + + void DrawSavedVariable(SavedVariableBase& var) + { + ImGui::SetNextItemWidth(175.0f); + ImGui::InputScalar("Index", ImGuiDataType_U32, &var.base); + ImGui::SameLine(); + ImGui::SetNextItemWidth(100.0f); + ImGui::Combo("##var_type", (int*)&var.type, "Int\0Int64\0Bitset\0Bool\0Float\0Vector\0String\0"); + + for (int i = 0; i < var.appendages.size(); i++) + { + auto& item = var.appendages[i]; + switch (item.type) + { + case VariableAppendage::Type::OFFSET: + ImGui::SetNextItemWidth(100.f); + ImGui::InputScalar(std::format("At##{}{}", i, (int)item.type).c_str(), ImGuiDataType_S32, &item.offset); + ImGui::SameLine(); + ImGui::SetNextItemWidth(100.f); + ImGui::InputScalar(std::format("Size##{}{}", i, (int)item.type).c_str(), ImGuiDataType_S32, &item.size); + break; + case VariableAppendage::Type::PLAYER_ID: + ImGui::SetNextItemWidth(100.f); + ImGui::InputScalar(std::format("Size##{}{}", i, (int)item.type).c_str(), ImGuiDataType_S32, &item.size); + break; + } + } + + if (ImGui::Button("Add Offset")) + var.appendages.push_back({VariableAppendage::Type::OFFSET, 0LL, 0ULL}); + ImGui::SameLine(); + if (ImGui::Button("Add Read Player Id")) + var.appendages.push_back({VariableAppendage::Type::PLAYER_ID, 0LL, 0ULL}); + + if (var.appendages.size() > 0) + { + ImGui::SameLine(); + if (ImGui::Button("Remove Offset")) + { + var.appendages.pop_back(); + } + } + + ImGui::SameLine(); + if (ImGui::Button("Clear")) + { + var.base = 0; + var.appendages.clear(); + } + } +} \ No newline at end of file diff --git a/src/game/frontend/submenus/Debug/DrawVariable.hpp b/src/game/frontend/submenus/Debug/DrawVariable.hpp index 5f0ca87..667187d 100644 --- a/src/game/frontend/submenus/Debug/DrawVariable.hpp +++ b/src/game/frontend/submenus/Debug/DrawVariable.hpp @@ -3,124 +3,7 @@ namespace YimMenu { - static void DrawSavedVariableEdit(const SavedVariableBase& var, void* value) - { - if (!value) - { - ImGui::BeginDisabled(); - ImGui::Text("Invalid"); - ImGui::EndDisabled(); - return; - } - - switch (var.type) - { - case VariableType::INT: - { - ImGui::SetNextItemWidth(200.f); - ImGui::InputInt("Value", static_cast(value)); - break; - } - case VariableType::BOOL: - { - ImGui::Checkbox("Value", static_cast(value)); - break; - } - case VariableType::FLOAT: - { - ImGui::SetNextItemWidth(200.f); - ImGui::InputFloat("Value", static_cast(value)); - break; - } - case VariableType::INT64: - { - ImGui::SetNextItemWidth(200.f); - ImGui::InputScalar("Value", ImGuiDataType_S64, static_cast(value)); - break; - } - } - } - - static void DrawSavedVariablePreview(const SavedVariableBase& var, void* value) - { - if (!value) - { - ImGui::Selectable("Invalid", false, ImGuiSelectableFlags_Disabled); - return; - } - - switch (var.type) - { - case VariableType::INT: - { - ImGui::Selectable(std::to_string(*static_cast(value)).c_str(), false, ImGuiSelectableFlags_Disabled); - break; - } - case VariableType::BOOL: - { - ImGui::Selectable(*static_cast(value) ? "True" : "False", false, ImGuiSelectableFlags_Disabled); - break; - } - case VariableType::FLOAT: - { - ImGui::Selectable(std::to_string(*static_cast(value)).c_str(), false, ImGuiSelectableFlags_Disabled); - break; - } - case VariableType::INT64: - { - ImGui::Selectable(std::to_string(*static_cast(value)).c_str(), false, ImGuiSelectableFlags_Disabled); - break; - } - } - } - - static void DrawSavedVariable(SavedVariableBase& var) - { - ImGui::SetNextItemWidth(175.0f); - ImGui::InputScalar("Index", ImGuiDataType_U32, &var.base); - ImGui::SameLine(); - ImGui::SetNextItemWidth(100.0f); - ImGui::Combo("##var_type", (int*)&var.type, "Int\0Float\0Bool\0Int64\0"); - - for (int i = 0; i < var.appendages.size(); i++) - { - auto& item = var.appendages[i]; - switch (item.type) - { - case VariableAppendage::Type::OFFSET: - ImGui::SetNextItemWidth(100.f); - ImGui::InputScalar(std::format("At##{}{}", i, (int)item.type).c_str(), ImGuiDataType_S32, &item.offset); - ImGui::SameLine(); - ImGui::SetNextItemWidth(100.f); - ImGui::InputScalar(std::format("Size##{}{}", i, (int)item.type).c_str(), ImGuiDataType_S32, &item.size); - break; - case VariableAppendage::Type::PLAYER_ID: - ImGui::SetNextItemWidth(100.f); - ImGui::InputScalar(std::format("Size##{}{}", i, (int)item.type).c_str(), ImGuiDataType_S32, &item.size); - break; - } - } - - if (ImGui::Button("Add Offset")) - var.appendages.push_back({VariableAppendage::Type::OFFSET, 0LL, 0ULL}); - ImGui::SameLine(); - if (ImGui::Button("Add Read Player Id")) - var.appendages.push_back({VariableAppendage::Type::PLAYER_ID, 0LL, 0ULL}); - - if (var.appendages.size() > 0) - { - ImGui::SameLine(); - if (ImGui::Button("Remove Offset")) - { - var.appendages.pop_back(); - } - } - - ImGui::SameLine(); - if (ImGui::Button("Clear")) - { - var.base = 0; - var.appendages.clear(); - } - } + extern void DrawSavedVariableEdit(const SavedVariableBase& var, void* value); + extern void DrawSavedVariablePreview(const SavedVariableBase& var, void* value); + extern void DrawSavedVariable(SavedVariableBase& var); } \ No newline at end of file diff --git a/src/game/frontend/submenus/Debug/Globals.cpp b/src/game/frontend/submenus/Debug/Globals.cpp index 1eb04e9..0b09457 100644 --- a/src/game/frontend/submenus/Debug/Globals.cpp +++ b/src/game/frontend/submenus/Debug/Globals.cpp @@ -1,32 +1,30 @@ #include "Globals.hpp" -#include "game/backend/SavedVariables.hpp" - #include "DrawVariable.hpp" // TODO: name compares are expensive, but this is way better than the old impl that reads the json file every frame namespace YimMenu::Submenus { - static void SaveGlobal(SavedGlobal& global_obj) + static void SaveGlobal(SavedGlobal& globalObj) { for (auto& global : SavedVariables::GetSavedGlobals()) { - if (global.name == global_obj.name) + if (global.name == globalObj.name) { - global = global_obj; + global = globalObj; SavedVariables::Save(); return; } } - SavedVariables::GetSavedGlobals().push_back(global_obj); + SavedVariables::GetSavedGlobals().push_back(globalObj); SavedVariables::Save(); } - static void DeleteGlobal(SavedGlobal& global_obj) + static void DeleteGlobal(SavedGlobal& globalObj) { std::erase_if(SavedVariables::GetSavedGlobals(), [&](SavedGlobal& g) { - return g.name == global_obj.name; + return g.name == globalObj.name; }); SavedVariables::Save(); } @@ -35,31 +33,31 @@ namespace YimMenu::Submenus { auto globals = std::make_unique("Globals"); - static bool ensure_vars_loaded = ([] { + auto editor = std::make_unique("Editor"); + auto saved = std::make_unique("Saved"); + + static bool ensureVarsLoaded = ([] { SavedVariables::Init(); return true; })(); - static char global_name[255]{}; + static char globalName[255]{}; + static SavedGlobal curGlobal{}; - static SavedGlobal cur_global{}; - - auto editor = std::make_unique("Editor"); editor->AddItem(std::make_unique([] { - DrawSavedVariable(cur_global); - DrawSavedVariableEdit(cur_global, cur_global.Read()); + DrawSavedVariable(curGlobal); + DrawSavedVariableEdit(curGlobal, curGlobal.Read()); })); - auto saved = std::make_unique("Saved"); saved->AddItem(std::make_unique([] { if (ImGui::BeginListBox("##savedglobals", ImVec2(200, 200))) { for (auto& var : SavedVariables::GetSavedGlobals()) { - if (ImGui::Selectable(var.name.c_str(), var.name == cur_global.name)) + if (ImGui::Selectable(var.name.c_str(), var.name == curGlobal.name)) { - cur_global = var; - strncpy(global_name, var.name.c_str(), sizeof(global_name)); + curGlobal = var; + strncpy(globalName, var.name.c_str(), sizeof(globalName)); } } ImGui::EndListBox(); @@ -77,19 +75,19 @@ namespace YimMenu::Submenus ImGui::BeginGroup(); ImGui::SetNextItemWidth(200.f); - ImGui::InputTextWithHint("##global_name", "Name", global_name, sizeof(global_name)); + ImGui::InputTextWithHint("##global_name", "Name", globalName, sizeof(globalName)); ImGui::SameLine(); if (ImGui::Button("Save")) { - cur_global.name = global_name; - SaveGlobal(cur_global); + curGlobal.name = globalName; + SaveGlobal(curGlobal); } ImGui::SameLine(); if (ImGui::Button("Delete")) { - cur_global.name = global_name; - DeleteGlobal(cur_global); - cur_global = SavedGlobal(); + curGlobal.name = globalName; + DeleteGlobal(curGlobal); + curGlobal = SavedGlobal(); } ImGui::EndGroup(); diff --git a/src/game/frontend/submenus/Debug/Locals.cpp b/src/game/frontend/submenus/Debug/Locals.cpp index c23c8a2..79dcf97 100644 --- a/src/game/frontend/submenus/Debug/Locals.cpp +++ b/src/game/frontend/submenus/Debug/Locals.cpp @@ -1,37 +1,30 @@ #include "Locals.hpp" - #include "DrawVariable.hpp" -#include "core/filemgr/FileMgr.hpp" -#include "game/backend/SavedVariables.hpp" -#include "game/backend/Self.hpp" -#include "game/pointers/Pointers.hpp" -#include "game/gta/ScriptGlobal.hpp" - -#include "types/rage/atArray.hpp" +#include "game/gta/Scripts.hpp" #include "types/script/scrThread.hpp" namespace YimMenu::Submenus { - static void SaveLocal(SavedLocal& local_obj) + static void SaveLocal(SavedLocal& localObj) { for (auto& local : SavedVariables::GetSavedLocals()) { - if (local.name == local_obj.name && local.script == local_obj.script) + if (local.name == localObj.name && local.script == localObj.script) { - local = local_obj; + local = localObj; SavedVariables::Save(); return; } } - SavedVariables::GetSavedLocals().push_back(local_obj); + SavedVariables::GetSavedLocals().push_back(localObj); SavedVariables::Save(); } - static void DeleteLocal(SavedLocal& local_obj) + static void DeleteLocal(SavedLocal& localObj) { std::erase_if(SavedVariables::GetSavedLocals(), [&](SavedLocal& g) { - return g.name == local_obj.name && g.script == local_obj.script; + return g.name == localObj.name && g.script == localObj.script; }); SavedVariables::Save(); } @@ -40,121 +33,66 @@ namespace YimMenu::Submenus { auto locals = std::make_unique("Locals"); - static bool ensure_vars_loaded = ([] { + auto editor = std::make_unique("Editor"); + auto saved = std::make_unique("Saved"); + + static bool ensureVarsLoaded = ([] { SavedVariables::Init(); return true; })(); - static char local_name[255]{}; + static char scriptName[255]{}; + static char localName[255]{}; + static SavedLocal curLocal{}; + static rage::scrThread* curThread = nullptr; - static SavedLocal cur_local{}; - - static rage::scrThread* cur_thread = nullptr; - static const char* cur_script_name = nullptr; - static std::uint32_t cur_script_hash = 0; - - auto script = std::make_unique("Script"); - - script->AddItem(std::make_unique([] { - // TODO: pointless code reduplication - if (!Pointers.ScriptThreads || Pointers.ScriptThreads->size() == 0) - { - cur_thread = nullptr; - ImGui::TextDisabled("None"); - return; - } - - ImGui::SetNextItemWidth(225.0f); - if (ImGui::BeginCombo("Thread", cur_thread ? cur_script_name : "(Select)")) - { - for (auto script : *Pointers.ScriptThreads) - { - if (script) - { - if (script->m_Context.m_State == rage::scrThread::State::KILLED || script->m_Context.m_StackSize == 0) - continue; - - ImGui::PushID(script->m_Context.m_ThreadId); - - auto script_name = script->m_ScriptName; - - if (ImGui::Selectable(script_name, cur_thread == script)) - { - cur_thread = script; - cur_script_name = script_name; - cur_script_hash = script->m_Context.m_ScriptHash; - } - - if (cur_thread == script) - ImGui::SetItemDefaultFocus(); - - ImGui::PopID(); - } - } - - ImGui::EndCombo(); - } - - if (cur_thread && (cur_thread->m_Context.m_ScriptHash != cur_script_hash || cur_thread->m_Context.m_StackSize == 0 || cur_thread->m_Context.m_State == rage::scrThread::State::KILLED)) - cur_thread = nullptr; - - if (!cur_thread) - return; - })); - - auto editor = std::make_unique("Editor"); editor->AddItem(std::make_unique([] { - if (!cur_thread) - { - ImGui::TextDisabled("Invalid"); - return; - } + ImGui::SetNextItemWidth(200.f); + ImGui::InputText("Script", scriptName, sizeof(scriptName)); - DrawSavedVariable(cur_local); - DrawSavedVariableEdit(cur_local, cur_local.Read(cur_thread)); + curThread = Scripts::FindScriptThread(Joaat(scriptName)); + if (!curThread) + return ImGui::TextDisabled("Invalid"); + + DrawSavedVariable(curLocal); + DrawSavedVariableEdit(curLocal, curLocal.Read(curThread)); })); - auto saved = std::make_unique("Saved"); saved->AddItem(std::make_unique([] { - if (!cur_thread) + if (!curThread) + return ImGui::TextDisabled("Invalid"); + + auto scriptIdf = curThread->m_ScriptHash; + if (scriptIdf != curLocal.script) { - ImGui::TextDisabled("Invalid"); - return; + curLocal = SavedLocal(); + curLocal.script = scriptIdf; } - auto script_idf = cur_thread->m_ScriptHash; - - // refresh local if script changes (TODO not always the best idea) - if (script_idf != cur_local.script) - { - cur_local = SavedLocal(); - cur_local.script = script_idf; - } - - if (ImGui::BeginListBox("##savedglobals", ImVec2(200, 200))) + if (ImGui::BeginListBox("##savedlocals", ImVec2(200, 200))) { for (auto& var : SavedVariables::GetSavedLocals()) { - if (var.script != script_idf) + if (var.script != scriptIdf) continue; - if (ImGui::Selectable(var.name.c_str(), var.name == cur_local.name)) + if (ImGui::Selectable(var.name.c_str(), var.name == curLocal.name)) { - cur_local = var; - strncpy(local_name, var.name.c_str(), sizeof(local_name)); + curLocal = var; + strncpy(localName, var.name.c_str(), sizeof(localName)); } } ImGui::EndListBox(); } ImGui::SameLine(); - if (ImGui::BeginListBox("##globalvalues", ImVec2(200, 200))) + if (ImGui::BeginListBox("##localvalues", ImVec2(200, 200))) { for (auto& var : SavedVariables::GetSavedLocals()) { - if (var.script != script_idf) + if (var.script != scriptIdf) continue; - DrawSavedVariablePreview(var, var.Read(cur_thread)); + DrawSavedVariablePreview(var, var.Read(curThread)); } ImGui::EndListBox(); } @@ -162,25 +100,24 @@ namespace YimMenu::Submenus ImGui::BeginGroup(); ImGui::SetNextItemWidth(200.f); - ImGui::InputText("##local_name", local_name, sizeof(local_name)); + ImGui::InputText("##localname", localName, sizeof(localName)); ImGui::SameLine(); if (ImGui::Button("Save")) { - cur_local.name = local_name; - SaveLocal(cur_local); + curLocal.name = localName; + SaveLocal(curLocal); } ImGui::SameLine(); if (ImGui::Button("Delete")) { - cur_local.name = local_name; - DeleteLocal(cur_local); - cur_local = SavedLocal(); + curLocal.name = localName; + DeleteLocal(curLocal); + curLocal = SavedLocal(); } ImGui::EndGroup(); })); - locals->AddItem(std::move(script)); locals->AddItem(std::move(editor)); locals->AddItem(std::move(saved)); return locals; diff --git a/src/game/frontend/submenus/Debug/Scripts.cpp b/src/game/frontend/submenus/Debug/Scripts.cpp new file mode 100644 index 0000000..933978a --- /dev/null +++ b/src/game/frontend/submenus/Debug/Scripts.cpp @@ -0,0 +1,174 @@ +#include "Scripts.hpp" +#include "core/backend/FiberPool.hpp" +#include "core/backend/ScriptMgr.hpp" +#include "core/frontend/Notifications.hpp" +#include "game/gta/data/ScriptNames.hpp" +#include "game/gta/data/StackSizes.hpp" +#include "game/gta/Scripts.hpp" +#include "game/gta/Natives.hpp" +#include "game/pointers/Pointers.hpp" +#include "types/rage/atArray.hpp" +#include "types/script/GtaThread.hpp" +#include "types/script/CGameScriptHandlerNetComponent.hpp" +#include "types/network/CNetGamePlayer.hpp" +#include "misc/cpp/imgui_stdlib.h" + +namespace YimMenu::Submenus +{ + std::shared_ptr BuildScriptsMenu() + { + auto scripts = std::make_unique("Scripts"); + + auto threads = std::make_unique("Threads"); + auto script = std::make_unique("Start Script"); + + static rage::scrThread* curThread = nullptr; + static std::string scriptSearch = ""; + static std::string scriptName = ""; + static std::string stackSizeName = stackSizes[0].first; + static int stackSize = 0; + + threads->AddItem(std::make_unique([] { + if (!Pointers.ScriptThreads || Pointers.ScriptThreads->size() == 0) + { + curThread = nullptr; + return ImGui::TextDisabled("None"); + } + + if (ImGui::BeginCombo("Thread", curThread ? curThread->m_ScriptName : "(Select)")) + { + for (auto thread : *Pointers.ScriptThreads) + { + if (thread) + { + if (thread->m_Context.m_State == rage::scrThread::State::KILLED || thread->m_Context.m_StackSize == 0) + continue; + + ImGui::PushID(thread->m_Context.m_ThreadId); + + if (ImGui::Selectable(thread->m_ScriptName, curThread == thread)) + { + curThread = thread; + } + + if (curThread == thread) + ImGui::SetItemDefaultFocus(); + + ImGui::PopID(); + } + } + + ImGui::EndCombo(); + } + + if (!curThread) + return; + + ImGui::Combo("State", (int*)&curThread->m_Context.m_State, "Idle\0Running\0Killed\0Paused\0Unk4\0"); + + if (auto netComponent = reinterpret_cast(curThread)->m_NetComponent) + { + if (auto host = netComponent->GetHost()) + { + ImGui::Text("Host: %s", host->GetName()); + } + ImGui::SameLine(); + ImGui::BeginDisabled(netComponent->IsLocalPlayerHost()); + if (ImGui::SmallButton("Take Control")) + { + FiberPool::Push([] { + Scripts::ForceScriptHost(curThread); + }); + } + ImGui::EndDisabled(); + } + + ImGui::Text("Thread ID: %d", curThread->m_Context.m_ThreadId); + ImGui::Text("Stack Size: %d", curThread->m_Context.m_StackSize); + ImGui::Text("Stack Pointer: 0x%X", &curThread->m_Context.m_StackPointer); + ImGui::Text("Program Counter: 0x%X", &curThread->m_Context.m_ProgramCounter); // This is not really accurate (always points to the WAIT) + if (curThread->m_Context.m_State == rage::scrThread::State::KILLED) + ImGui::Text("Exit Reason: %s", curThread->m_ErrorMessage); + })); + + script->AddItem(std::make_unique([] { + ImGui::InputTextWithHint("Script Name", "Search", &scriptSearch); + + if (ImGui::BeginCombo("Stack Size", stackSizeName.c_str())) + { + for (auto& p : stackSizes) + { + if (ImGui::Selectable(std::format("{} ({})", p.first, (int)p.second).data(), stackSize == p.second)) + { + stackSizeName = p.first; + stackSize = p.second; + } + + if (p.second == stackSize) + ImGui::SetItemDefaultFocus(); + } + + ImGui::EndCombo(); + } + + if (ImGui::BeginListBox("##scripts")) + { + std::string lowerSearch = scriptSearch; + std::transform(lowerSearch.begin(), lowerSearch.end(), lowerSearch.begin(), ::tolower); + for (auto& script : scriptNames) + { + std::string lowerScript = script; + std::transform(lowerScript.begin(), lowerScript.end(), lowerScript.begin(), ::tolower); + if (lowerScript.find(lowerSearch) != std::string::npos) + { + if (ImGui::Selectable(script, scriptName == script)) + { + scriptSearch = script; + scriptName = script; + } + } + } + + ImGui::EndListBox(); + } + + if (ImGui::Button("Start Script")) + { + FiberPool::Push([] { + auto hash = Joaat(scriptName); + + if (!SCRIPT::DOES_SCRIPT_WITH_NAME_HASH_EXIST(hash)) + { + Notifications::Show("Start Script", "Script does not exist.", NotificationType::Error); + return; + } + + if (SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(hash) > 0) + { + Notifications::Show("Start Script", "Script is already running.", NotificationType::Error); + return; + } + + if (MISC::GET_NUMBER_OF_FREE_STACKS_OF_THIS_SIZE(stackSize) == 0) + { + Notifications::Show("Start Script", "No free stack.", NotificationType::Error); + return; + } + + while (!SCRIPT::HAS_SCRIPT_WITH_NAME_HASH_LOADED(hash)) + { + SCRIPT::REQUEST_SCRIPT_WITH_NAME_HASH(hash); + ScriptMgr::Yield(); + } + + BUILTIN::START_NEW_SCRIPT_WITH_NAME_HASH(hash, stackSize); + SCRIPT::SET_SCRIPT_WITH_NAME_HASH_AS_NO_LONGER_NEEDED(hash); + }); + } + })); + + scripts->AddItem(std::move(threads)); + scripts->AddItem(std::move(script)); + return scripts; + } +} \ No newline at end of file diff --git a/src/game/frontend/submenus/Debug/Scripts.hpp b/src/game/frontend/submenus/Debug/Scripts.hpp new file mode 100644 index 0000000..c146591 --- /dev/null +++ b/src/game/frontend/submenus/Debug/Scripts.hpp @@ -0,0 +1,8 @@ +#pragma once +#include "core/frontend/manager/Category.hpp" +#include "game/frontend/items/Items.hpp" + +namespace YimMenu::Submenus +{ + std::shared_ptr BuildScriptsMenu(); +} \ No newline at end of file diff --git a/src/game/frontend/submenus/network/RandomEvents.cpp b/src/game/frontend/submenus/network/RandomEvents.cpp index e6ad5d7..49b23d3 100644 --- a/src/game/frontend/submenus/network/RandomEvents.cpp +++ b/src/game/frontend/submenus/network/RandomEvents.cpp @@ -117,7 +117,6 @@ namespace YimMenu::Submenus { if (auto eventProgram = Scripts::FindScriptProgram(randomEventScripts[(int)selectedEvent])) { - // TO-DO: Cache these too? if (NetComponent->IsLocalPlayerHost()) { std::string ptrName = "SetFMContentScriptServerState" + std::to_string(selectedEvent); diff --git a/src/game/gta/data/ScriptNames.hpp b/src/game/gta/data/ScriptNames.hpp new file mode 100644 index 0000000..b663985 --- /dev/null +++ b/src/game/gta/data/ScriptNames.hpp @@ -0,0 +1,1107 @@ +#pragma once + +namespace YimMenu +{ + static constexpr std::array scriptNames = { + "abigail1", + "abigail2", + "achievement_controller", + "activity_creator_prototype_launcher", + "act_cinema", + "af_intro_t_sandy", + "agency_heist1", + "agency_heist2", + "agency_heist3a", + "agency_heist3b", + "agency_prep1", + "agency_prep2amb", + "aicover_test", + "ainewengland_test", + "altruist_cult", + "ambientblimp", + "ambient_diving", + "ambient_mrsphilips", + "ambient_solomon", + "ambient_sonar", + "ambient_tonya", + "ambient_tonyacall", + "ambient_tonyacall2", + "ambient_ufos", + "ambient_tonyacall5", + "am_agency_suv", + "am_airstrike", + "am_ammo_drop", + "am_arena_shp", + "am_armwrestling", + "am_armwrestling_apartment", + "am_armybase", + "am_beach_washup_cinematic", + "am_backup_heli", + "am_boat_taxi", + "am_bru_box", + "am_car_mod_tut", + "am_casino_limo", + "am_casino_luxury_car", + "am_casino_peds", + "am_challenges", + "am_contact_requests", + "am_cp_collection", + "am_criminal_damage", + "am_crate_drop", + "am_darts", + "am_darts_apartment", + "am_dead_drop", + "am_destroy_veh", + "am_distract_cops", + "am_doors", + "am_ferriswheel", + "am_gang_call", + "am_ga_pickups", + "am_heist_int", + "am_heli_taxi", + "am_hi_plane_land_cinematic", + "am_hi_plane_take_off_cinematic", + "am_hold_up", + "am_hot_property", + "am_hot_target", + "am_hs4_isd_take_vel", + "am_hs4_lsa_land_nimb_arrive", + "am_hs4_lsa_land_vel", + "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_hunt_the_beast", + "am_imp_exp", + "am_island_backup_heli", + "am_kill_list", + "am_joyrider", + "am_king_of_the_castle", + "am_launcher", + "am_lester_cut", + "am_lowrider_int", + "am_lsia_take_off_cinematic", + "am_luxury_showroom", + "am_mission_launch", + "am_mp_acid_lab", + "am_mp_arcade", + "am_mp_arcade_claw_crane", + "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_arena_box", + "am_mp_arena_garage", + "am_mp_armory_truck", + "am_mp_armory_aircraft", + "am_mp_auto_shop", + "am_mp_bail_office", + "am_mp_boardroom_seating", + "am_mp_biker_warehouse", + "am_mp_bunker", + "am_mp_business_hub", + "am_mp_carwash_launch", + "am_mp_car_meet_sandbox", + "am_mp_car_meet_property", + "am_mp_casino", + "am_mp_casino_apartment", + "am_mp_casino_nightclub", + "am_mp_casino_valet_garage", + "am_mp_creator_aircraft", + "am_mp_creator_trailer", + "am_mp_defunct_base", + "am_mp_drone", + "am_mp_field_hangar", + "am_mp_fixer_hq", + "am_mp_garage_control", + "am_mp_hacker_den", + "am_mp_hacker_truck", + "am_mp_hangar", + "am_mp_hotwire", + "am_mp_ie_warehouse", + "am_mp_island", + "am_mp_juggalo_hideout", + "am_mp_multistorey_garage", + "am_mp_music_studio", + "am_mp_orbital_cannon", + "am_mp_nightclub", + "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_shooting_range", + "am_mp_simeon_showroom", + "am_mp_smoking_activity", + "am_mp_smpl_interior_ext", + "am_mp_smpl_interior_int", + "am_mp_social_club_garage", + "am_mp_solomon_office", + "am_mp_submarine", + "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_warehouse", + "am_npc_invites", + "am_pass_the_parcel", + "am_penned_in", + "am_penthouse_peds", + "am_pi_menu", + "am_plane_takedown", + "am_prison", + "am_prostitute", + "am_rollercoaster", + "am_rontrevor_cut", + "am_simosa", + "am_vehicle_spawn", + "am_taxi", + "animal_controller", + "apartment_minigame_launcher", + "apparcadebusiness", + "apparcadebusinesshub", + "appavengeroperations", + "appbailoffice", + "appbikerbusiness", + "appbroadcast", + "appbunkerbusiness", + "appbusinesshub", + "appcamera", + "appchecklist", + "appcontacts", + "appcovertops", + "appextraction", + "appemail", + "appfixersecurity", + "apphackerden", + "apphackertruck", + "apphs_sleep", + "appimportexport", + "appinternet", + "appjipmp", + "appmpemail", + "appmpbossagency", + "appmedia", + "appmpjoblistnew", + "apporganiser", + "appprogresshub", + "apprepeatplay", + "appsecurohack", + "appsecuroserv", + "appsettings", + "appsidetask", + "appsmuggler", + "apptextmessage", + "apptrackify", + "appvinewoodmenu", + "appvlsi", + "appzit", + "arcade_seating", + "arena_box_bench_seats", + "arena_carmod", + "arena_workshop_seats", + "armenian1", + "armenian2", + "armenian3", + "armory_aircraft_carmod", + "assassin_bus", + "assassin_construction", + "assassin_hooker", + "assassin_multi", + "assassin_rankup", + "assassin_valet", + "atm_trigger", + "audiotest", + "autosave_controller", + "auto_shop_seating", + "bailbond1", + "bailbond4", + "bailbond3", + "bailbond2", + "bailbond_launcher", + "bail_office_seating", + "barry1", + "barry2", + "barry3a", + "barry3", + "barry3c", + "barry4", + "base_carmod", + "base_corridor_seats", + "base_entrance_seats", + "base_heist_seats", + "base_lounge_seats", + "base_quaters_seats", + "base_reception_seats", + "basic_creator", + "beach_exterior_seating", + "benchmark", + "bigwheel", + "bj", + "blackjack", + "blimptest", + "blip_controller", + "bootycallhandler", + "bootycall_debug_controller", + "buddydeathresponse", + "bugstar_mission_export", + "buildingsiteambience", + "building_controller", + "business_battles_defend", + "business_battles", + "business_battles_sell", + "business_hub_carmod", + "business_hub_garage_seats", + "cablecar", + "camera_test", + "camhedz_arcade", + "cam_coord_sender", + "candidate_controller", + "carmod_shop", + "carsteal1", + "carsteal3", + "carsteal2", + "carsteal4", + "carwash1", + "carwash2", + "car_meet_carmod", + "car_meet_exterior_seating", + "car_meet_interior_seating", + "car_roof_test", + "casinoroulette", + "casino_bar_seating", + "casino_exterior_seating", + "casino_interior_seating", + "casino_lucky_wheel", + "casino_main_lounge_seating", + "casino_nightclub_seating", + "casino_penthouse_seating", + "casino_slots", + "celebrations", + "celebration_editor", + "cellphone_controller", + "cellphone_flashhand", + "charactergoals", + "cheat_controller", + "charanimtest", + "chinese1", + "chinese2", + "circuitblockhack", + "chop", + "clothes_shop_mp", + "clothes_shop_sp", + "code_controller", + "combat_test", + "comms_controller", + "completionpercentage_controller", + "component_checker", + "context_controller", + "controller_ambientarea", + "controller_races", + "controller_taxi", + "controller_towing", + "controller_trafficking", + "coordinate_recorder", + "country_race", + "creation_startup", + "country_race_controller", + "creator", + "custom_config", + "cutscenemetrics", + "cutscenesamples", + "cutscene_test", + "darts", + "debug", + "debug_app_select_screen", + "debug_clone_outfit_testing", + "debug_launcher", + "debug_ped_data", + "degenatron_games", + "density_test", + "director_mode", + "dialogue_handler", + "docks2asubhandler", + "docks_heista", + "docks_prep1", + "docks_heistb", + "docks_prep2b", + "docks_setup", + "dont_cross_the_line", + "dreyfuss1", + "drf2", + "drf1", + "drf3", + "drf5", + "drf4", + "drunk", + "drunk_controller", + "dynamixtest", + "emergencycall", + "email_controller", + "emergencycalllauncher", + "epscars", + "epsdesert", + "epsilon1", + "epsilon3", + "epsilon2", + "epsilon4", + "epsilon5", + "epsilon6", + "epsilon7", + "epsilon8", + "epsilontract", + "epsrobes", + "error_listener", + "error_thrower", + "event_controller", + "exile1", + "exile_city_denial", + "exile2", + "exile3", + "extreme2", + "extreme1", + "extreme3", + "extreme4", + "fairgroundhub", + "fake_interiors", + "fameorshame_eps", + "fameorshame_eps_1", + "fame_or_shame_set", + "family1taxi", + "family2", + "family1", + "family3", + "family6", + "family4", + "family5", + "family_scene_f0", + "family_scene_f1", + "family_scene_m", + "family_scene_t0", + "family_scene_t1", + "fanatic1", + "fanatic2", + "fanatic3", + "fbi1", + "fbi2", + "fbi3", + "fbi4", + "fbi4_intro", + "fbi4_prep1", + "fbi4_prep2", + "fbi4_prep3", + "fbi4_prep3amb", + "fbi4_prep4", + "fbi4_prep5", + "field_hangar_seating", + "fbi5a", + "finaleb", + "finalea", + "finalec1", + "finalec2", + "finale_choice", + "finale_credits", + "finale_endgame", + "finale_heist1", + "finale_heist2a", + "finale_heist2b", + "finale_heist2_intro", + "finale_heist_prepb", + "finale_heist_prepa", + "finale_heist_prepc", + "finale_heist_prepd", + "finale_heist_prepeamb", + "finale_intro", + "fixer_hq_carmod", + "fixer_hq_seating", + "fixer_hq_seating_op_floor", + "fixer_hq_seating_pq", + "floating_help_controller", + "flowintrotitle", + "flowstartaccept", + "flow_autoplay", + "flow_controller", + "flow_help", + "flyunderbridges", + "fmmc_contentquicklauncher", + "fmmc_launcher", + "fmmc_playlist_controller", + "fm_bj_race_controler", + "fm_capture_creator", + "fm_content_acid_lab_sell", + "fm_content_acid_lab_source", + "fm_content_acid_lab_setup", + "fm_content_ammunation", + "fm_content_armoured_truck", + "fm_content_arms_trafficking", + "fm_content_auto_shop_delivery", + "fm_content_bank_shootout", + "fm_content_bar_resupply", + "fm_content_bicycle_time_trial", + "fm_content_bike_shop_delivery", + "fm_content_bounty_targets", + "fm_content_business_battles", + "fm_content_cargo", + "fm_content_cerberus", + "fm_content_chop_shop_delivery", + "fm_content_clubhouse_contracts", + "fm_content_club_management", + "fm_content_club_odd_jobs", + "fm_content_club_source", + "fm_content_community_outreach", + "fm_content_convoy", + "fm_content_crime_scene", + "fm_content_daily_bounty", + "fm_content_dispatch_work", + "fm_content_drone", + "fm_content_drug_lab_work", + "fm_content_drug_vehicle", + "fm_content_export_cargo", + "fm_content_ghosthunt", + "fm_content_golden_gun", + "fm_content_gunrunning", + "fm_content_hacker_cargo_finale", + "fm_content_hacker_cargo_prep", + "fm_content_hacker_house_finale", + "fm_content_hacker_house_prep", + "fm_content_hacker_whistle_fin", + "fm_content_hacker_whistle_prep", + "fm_content_hacker_zancudo_fin", + "fm_content_hacker_zancudo_prep", + "fm_content_hsw_setup", + "fm_content_hsw_time_trial", + "fm_content_island_dj", + "fm_content_island_heist", + "fm_content_metal_detector", + "fm_content_movie_props", + "fm_content_mp_intro", + "fm_content_payphone_hit", + "fm_content_parachuter", + "fm_content_phantom_car", + "fm_content_pizza_delivery", + "fm_content_security_contract", + "fm_content_robbery", + "fm_content_possessed_animals", + "fm_content_sightseeing", + "fm_content_slasher", + "fm_content_skydive", + "fm_content_smuggler_ops", + "fm_content_smuggler_plane", + "fm_content_smuggler_resupply", + "fm_content_smuggler_trail", + "fm_content_smuggler_sell", + "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_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_prep", + "fm_content_vehrob_scoping", + "fm_content_vehrob_submarine", + "fm_content_vip_contract_1", + "fm_content_vehrob_task", + "fm_content_xmas_mugger", + "fm_content_xmas_truck", + "fm_deathmatch_controler", + "fm_hideout_controler", + "fm_deathmatch_creator", + "fm_hold_up_tut", + "fm_horde_controler", + "fm_impromptu_dm_controler", + "fm_intro", + "fm_intro_cut_dev", + "fm_lts_creator", + "fm_maintain_cloud_header_data", + "fm_maintain_transition_players", + "fm_main_menu", + "fm_mission_controller", + "fm_mission_controller_2020", + "fm_mission_creator", + "fm_race_controler", + "fm_race_creator", + "fm_street_dealer", + "fm_survival_controller", + "fm_survival_creator", + "forsalesigns", + "fps_test", + "fps_test_mag", + "franklin0", + "franklin2", + "franklin1", + "freemode", + "freemode_clearglobals", + "freemode_creator", + "freemode_init", + "friends_controller", + "friendactivity", + "friends_debug_controller", + "fullmap_test", + "fullmap_test_flow", + "game_server_test", + "gb_airfreight", + "gb_amphibious_assault", + "gb_bank_job", + "gb_assault", + "gb_bellybeast", + "gb_biker_bad_deal", + "gb_biker_burn_assets", + "gb_biker_contraband_defend", + "gb_biker_contraband_sell", + "gb_biker_contract_killing", + "gb_biker_criminal_mischief", + "gb_biker_destroy_vans", + "gb_biker_driveby_assassin", + "gb_biker_free_prisoner", + "gb_biker_joust", + "gb_biker_last_respects", + "gb_biker_race_p2p", + "gb_biker_rescue_contact", + "gb_biker_rippin_it_up", + "gb_biker_safecracker", + "gb_biker_search_and_destroy", + "gb_biker_shuttle", + "gb_biker_stand_your_ground", + "gb_biker_steal_bikes", + "gb_biker_unload_weapons", + "gb_biker_target_rival", + "gb_biker_wheelie_rider", + "gb_cashing_out", + "gb_carjacking", + "gb_casino", + "gb_casino_heist", + "gb_casino_heist_planning", + "gb_collect_money", + "gb_contraband_buy", + "gb_contraband_defend", + "gb_contraband_sell", + "gb_data_hack", + "gb_deathmatch", + "gb_delivery", + "gb_finderskeepers", + "gb_fivestar", + "gb_fortified", + "gb_fragile_goods", + "gb_fully_loaded", + "gb_gangops", + "gb_gang_ops_planning", + "gb_gunrunning", + "gb_gunrunning_defend", + "gb_gunrunning_delivery", + "gb_headhunter", + "gb_hunt_the_boss", + "gb_ie_delivery_cutscene", + "gb_infiltration", + "gb_illicit_goods_resupply", + "gb_jewel_store_grab", + "gb_ploughed", + "gb_point_to_point", + "gb_ramped_up", + "gb_rob_shop", + "gb_salvage", + "gb_security_van", + "gb_sightseer", + "gb_smuggler", + "gb_stockpiling", + "gb_target_pursuit", + "gb_transporter", + "gb_terminate", + "gb_vehicle_export", + "gb_velocity", + "general_test", + "gb_yacht_rob", + "ggsm_arcade", + "globals_fmmc_struct_registration", + "globals_fmmcstruct2_registration", + "golf", + "golf_ai_foursome", + "golf_ai_foursome_putting", + "golf_mp", + "gpb_andymoon", + "gpb_baygor", + "gpb_billbinder", + "gpb_clinton", + "gpb_griff", + "gpb_jane", + "gpb_jerome", + "gpb_jesse", + "gpb_mani", + "gpb_mime", + "gpb_pameladrake", + "gpb_superhero", + "gpb_tonya", + "gpb_zombie", + "grid_arcade_cabinet", + "gtest_airplane", + "gtest_avoidance", + "gtest_boat", + "gtest_divingfromcar", + "gtest_divingfromcarwhilefleeing", + "gtest_helicopter", + "gunclub_shop", + "gtest_nearlymissedbycar", + "gunfighttest", + "gunslinger_arcade", + "hacker_den_carmod", + "hacker_den_ext_seating", + "hacker_den_seating", + "hairdo_shop_mp", + "hacker_truck_carmod", + "hairdo_shop_sp", + "hangar_carmod", + "headertest", + "heatmap_test", + "hao1", + "heatmap_test_flow", + "heist_ctrl_agency", + "heist_ctrl_docks", + "heist_ctrl_finale", + "heist_ctrl_jewel", + "heist_ctrl_rural", + "heist_island_planning", + "heli_streaming", + "heli_gun", + "hud_creator", + "hunting_ambient", + "idlewarper", + "hunting2", + "hunting1", + "ingamehud", + "item_ownership_output", + "initial", + "jewelry_heist", + "jewelry_prep1a", + "jewelry_prep1b", + "jewelry_prep2a", + "jewelry_setup1", + "josh1", + "josh2", + "josh3", + "josh4", + "juggalo_hideout_carmod", + "juggalo_hideout_seating", + "lamar1", + "landing_pre_startup", + "laptop_trigger", + "launcher_abigail", + "launcher_barry", + "launcher_basejumpheli", + "launcher_basejumppack", + "launcher_carwash", + "launcher_darts", + "launcher_epsilon", + "launcher_dreyfuss", + "launcher_extreme", + "launcher_fanatic", + "launcher_hunting", + "launcher_golf", + "launcher_hao", + "launcher_hunting_ambient", + "launcher_josh", + "launcher_maude", + "launcher_minute", + "launcher_mrsphilips", + "launcher_nigel", + "launcher_offroadracing", + "launcher_omega", + "launcher_paparazzo", + "launcher_pilotschool", + "launcher_racing", + "launcher_rampage", + "launcher_range", + "launcher_stunts", + "launcher_tennis", + "launcher_tonya", + "launcher_thelastone", + "launcher_triathlon", + "launcher_yoga", + "lesterhandler", + "lester1", + "letterscraps", + "line_activation_test", + "liverecorder", + "localpopulator", + "luxe_veh_activity", + "locates_tester", + "magdemo", + "main", + "main_install", + "magdemo2", + "maintransition", + "main_persistent", + "martin1", + "maude1", + "maude_postbailbond", + "me_amanda1", + "me_jimmy1", + "mg_race_to_point", + "me_tracey1", + "michael1", + "michael3", + "michael2", + "michael4", + "michael4leadout", + "minigame_ending_stinger", + "minigame_stats_tracker", + "minute1", + "minute2", + "minute3", + "missioniaaturret", + "mission_race", + "mission_repeat_controller", + "mission_stat_alerter", + "mission_stat_watcher", + "mission_triggerer_a", + "mission_triggerer_b", + "mission_triggerer_c", + "mission_triggerer_d", + "mmmm", + "mpstatsinit", + "mptestbed", + "mp_awards", + "mp_bed_high", + "mp_fm_registration", + "mp_gameplay_menu", + "mp_menuped", + "mp_player_damage_numbers", + "mp_prop_global_block", + "mp_registration", + "mp_prop_special_global_block", + "mp_skycam_stuck_wiggler", + "mp_save_game_global_block", + "mp_unlocks", + "mp_weapons", + "mrsphilips2", + "mrsphilips1", + "multistorey_garage_ext_seating", + "multistorey_garage_seating", + "murdermystery", + "music_studio_seating", + "music_studio_seating_external", + "navmeshtest", + "music_studio_smoking", + "net_activity_creator_ui", + "net_apartment_activity", + "net_apartment_activity_light", + "net_bot_brain", + "net_bot_simplebrain", + "net_cloud_mission_loader", + "net_combat_soaktest", + "net_freemode_debug_2023", + "net_freemode_debug_stat_2023", + "net_jacking_soaktest", + "net_session_soaktest", + "net_test_drive", + "net_tunable_check", + "nigel1", + "nigel1a", + "nigel1b", + "nigel1c", + "nigel1d", + "nigel2", + "nigel3", + "nightclubpeds", + "nightclub_ground_floor_seats", + "nightclub_office_seats", + "nightclub_vip_seats", + "nodemenututorial", + "nodeviewer", + "ob_abatdoor", + "ob_abattoircut", + "ob_airdancer", + "ob_bong", + "ob_drinking_shots", + "ob_cashregister", + "ob_foundry_cauldron", + "ob_franklin_beer", + "ob_franklin_tv", + "ob_franklin_wine", + "ob_huffing_gas", + "ob_jukebox", + "ob_mp_bed_high", + "ob_mp_bed_low", + "ob_mp_bed_med", + "ob_mp_shower_med", + "ob_mp_stripper", + "ob_mr_raspberry_jam", + "ob_poledancer", + "ob_sofa_franklin", + "ob_sofa_michael", + "ob_telescope", + "ob_tv", + "ob_vend1", + "ob_vend2", + "ob_wheatgrass", + "offroad_races", + "omega1", + "omega2", + "paparazzo1", + "paparazzo2", + "paparazzo3", + "paparazzo3a", + "paparazzo3b", + "paparazzo4", + "paradise2", + "paradise", + "pausemenu", + "pausemenucareerhublaunch", + "pausemenu_example", + "pausemenu_map", + "pausemenu_multiplayer", + "pausemenu_sp_repeat", + "pb_homeless", + "pb_busker", + "pb_preacher", + "pb_prostitute", + "personal_carmod_shop", + "photographymonkey", + "physics_perf_test", + "photographywildlife", + "physics_perf_test_launcher", + "pickuptest", + "pickup_controller", + "pickupvehicles", + "pilot_school", + "placeholdermission", + "pilot_school_mp", + "pi_menu", + "placementtest", + "player_controller_b", + "planewarptest", + "player_controller", + "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_shopping", + "player_scene_t_bbfight", + "player_scene_t_chasecar", + "player_scene_t_insult", + "player_scene_t_park", + "player_scene_t_tie", + "player_timetable_scene", + "playthrough_builder", + "pm_defend", + "pm_delivery", + "pm_plane_promotion", + "pm_gang_attack", + "postkilled_bailbond2", + "pm_recover_stolen", + "postrc_barry4", + "postrc_barry1and2", + "postrc_epsilon4", + "postrc_nigel3", + "profiler_registration", + "prologue1", + "prop_drop", + "puzzle", + "racetest", + "rampage1", + "rampage2", + "rampage3", + "rampage4", + "rampage5", + "rampage_controller", + "randomchar_controller", + "range_modern_mp", + "range_modern", + "replay_controller", + "rcpdata", + "rerecord_recording", + "respawn_controller", + "restrictedareas", + "re_abandonedcar", + "re_accident", + "re_armybase", + "re_arrests", + "re_atmrobbery", + "re_bikethief", + "re_border", + "re_burials", + "re_bus_tours", + "re_cartheft", + "re_chasethieves", + "re_crashrescue", + "re_dealgonewrong", + "re_cultshootout", + "re_domestic", + "re_drunkdriver", + "re_gangfight", + "re_duel", + "re_gang_intimidation", + "re_getaway_driver", + "re_hitch_lift", + "re_homeland_security", + "re_lossantosintl", + "re_lured", + "re_monkey", + "re_mountdance", + "re_muggings", + "re_prison", + "re_paparazzi", + "re_prisonerlift", + "re_prisonvanbreak", + "re_rescuehostage", + "re_seaplane", + "re_securityvan", + "re_shoprobbery", + "re_snatched", + "re_stag_do", + "re_yetarian", + "rng_output", + "road_arcade", + "rollercoaster", + "rural_bank_heist", + "rural_bank_prep1", + "salvage_yard_seating", + "rural_bank_setup", + "savegame_bed", + "save_anywhere", + "scaleformminigametest", + "scaleformgraphictest", + "scaleformprofiling", + "scaleformtest", + "scene_builder", + "sclub_front_bouncer", + "scripted_cam_editor", + "scriptplayground", + "scripttest1", + "scripttest2", + "scripttest3", + "scripttest4", + "script_metrics", + "scroll_arcade_cabinet", + "sc_lb_global_block", + "sctv", + "selector", + "selector_example", + "selling_short_1", + "selling_short_2", + "shooting_camera", + "shoprobberies", + "shop_controller", + "shot_bikejump", + "shrinkletter", + "sh_intro_f_hills", + "sh_intro_m_home", + "smoketest", + "simeon_showroom_seating", + "social_controller", + "solomon1", + "solomon2", + "solomon3", + "spaceshipparts", + "spawn_activities", + "spmc_instancer", + "speech_reverb_tracker", + "spmc_preloader", + "sp_dlc_registration", + "sp_editor_mission_instance", + "sp_pilotschool_reg", + "sp_menuped", + "standard_global_init", + "standard_global_reg", + "startup", + "startup_install", + "startup_positioning", + "startup_locationtest", + "startup_smoketest", + "stats_controller", + "stock_controller", + "streaming", + "stripclub", + "stripclub_drinking", + "stripclub_mp", + "stripperhome", + "stunt_plane_races", + "tasklist_1", + "tattoo_shop", + "taxilauncher", + "taxiservice", + "taxitutorial", + "taxi_clowncar", + "taxi_cutyouin", + "taxi_deadline", + "taxi_followcar", + "taxi_gotyounow", + "taxi_gotyourback", + "taxi_needexcitement", + "taxi_procedural", + "taxi_takeiteasy", + "taxi_taketobest", + "tempalpha", + "tennis", + "temptest", + "tennis_ambient", + "tennis_family", + "tennis_network_mp", + "test_startup", + "thelastone", + "three_card_poker", + "timershud", + "title_update_registration_2", + "title_update_registration", + "tonya1", + "tonya2", + "tonya5", + "tonya3", + "tonya4", + "towing", + "traffickingsettings", + "traffickingteleport", + "traffick_air", + "traffick_ground", + "train_create_widget", + "train_tester", + "trevor1", + "trevor3", + "trevor2", + "trevor4", + "triathlonsp", + "tunables_registration", + "tuner_planning", + "tuneables_processing", + "tuner_property_carmod", + "tuner_sandbox_activity", + "ufo", + "turret_cam_script", + "ugc_global_registration", + "ugc_global_registration_2", + "underwaterpickups", + "vehiclespawning", + "utvc", + "vehicle_ai_test", + "vehicle_force_widget", + "vehicle_plate", + "vehicle_gen_controller", + "vehicle_stealth_mode", + "vehrob_planning", + "veh_play_widget", + "vinewood_premium_garage_carmod", + "walking_ped", + "wardrobe_mp", + "wardrobe_sp", + "weapon_audio_widget", + "wizard_arcade", + "word_hack", + "wp_partyboombox", + "xml_menus", + "yoga" + }; +} \ No newline at end of file diff --git a/src/game/gta/data/StackSizes.hpp b/src/game/gta/data/StackSizes.hpp new file mode 100644 index 0000000..3272b25 --- /dev/null +++ b/src/game/gta/data/StackSizes.hpp @@ -0,0 +1,67 @@ +#pragma once + +namespace YimMenu +{ + enum eStackSizes + { + MICRO = 128, + MINI = 512, + DEFAULT = 1424, + SPECIAL_ABILITY = 1828, + FRIEND = 2050, + SHOP = 2324, + CELLPHONE = 2552, + VEHICLE_SPAWN = 3568, + CAR_MOD_SHOP = 3750, + PAUSE_MENU_SCRIPT = 3076, + APP_INTERNET = 4592, + MULTIPLAYER_MISSION = 5050, + CONTACTS_APP = 4000, + INTERACTION_MENU = 9800, + SCRIPT_XML = 8344, + PROPERTY_INT = 19400, + ACTIVITY_CREATOR_INT = 15900, + SMPL_INTERIOR = 2512, + WAREHOUSE = 14100, + IE_DELIVERY = 2324, + SHOP_CONTROLLER = 3800, + AM_MP_YACHT = 5000, + INGAMEHUD = 4600, + TRANSITION = 8032, + FMMC_LAUNCHER = 27000, + MULTIPLAYER_FREEMODE = 87500, + MISSION = 63500, + MP_LAUNCH_SCRIPT = 34750 + }; + + static constexpr std::pair stackSizes[] = { + {"MICRO", MICRO}, + {"MINI", MINI}, + {"DEFAULT", DEFAULT}, + {"SPECIAL_ABILITY", SPECIAL_ABILITY}, + {"FRIEND", FRIEND}, + {"SHOP", SHOP}, + {"CELLPHONE", CELLPHONE}, + {"VEHICLE_SPAWN", VEHICLE_SPAWN}, + {"CAR_MOD_SHOP", CAR_MOD_SHOP}, + {"PAUSE_MENU_SCRIPT", PAUSE_MENU_SCRIPT}, + {"APP_INTERNET", APP_INTERNET}, + {"MULTIPLAYER_MISSION", MULTIPLAYER_MISSION}, + {"CONTACTS_APP", CONTACTS_APP}, + {"INTERACTION_MENU", INTERACTION_MENU}, + {"SCRIPT_XML", SCRIPT_XML}, + {"PROPERTY_INT", PROPERTY_INT}, + {"ACTIVITY_CREATOR_INT", ACTIVITY_CREATOR_INT}, + {"SMPL_INTERIOR", SMPL_INTERIOR}, + {"WAREHOUSE", WAREHOUSE}, + {"IE_DELIVERY", IE_DELIVERY}, + {"SHOP_CONTROLLER", SHOP_CONTROLLER}, + {"AM_MP_YACHT", AM_MP_YACHT}, + {"INGAMEHUD", INGAMEHUD}, + {"TRANSITION", TRANSITION}, + {"FMMC_LAUNCHER", FMMC_LAUNCHER}, + {"MULTIPLAYER_FREEMODE", MULTIPLAYER_FREEMODE}, + {"MISSION", MISSION}, + {"MP_LAUNCH_SCRIPT", MP_LAUNCH_SCRIPT} + }; +} \ No newline at end of file diff --git a/src/types/script/types.hpp b/src/types/script/types.hpp index 6b4943b..7aecc38 100644 --- a/src/types/script/types.hpp +++ b/src/types/script/types.hpp @@ -31,6 +31,7 @@ using Vector3 = rage::scrVector; #define INTERIOR_INDEX alignas(8) Interior #define NETWORK_INDEX alignas(8) int +#define SCR_SIZEOF(x) (sizeof(x) / 8) #define SCR_HASH alignas(8) Hash #define SCR_INT alignas(8) int #define SCR_BOOL alignas(8) BOOL