feat: Add menu onboarding to YimMenu (#2492)

This commit is contained in:
Andreas Maerten 2024-02-23 22:54:25 +01:00 committed by GitHub
parent 5b73acecc2
commit 681d6590a8
11 changed files with 205 additions and 104 deletions

View File

@ -0,0 +1,17 @@
#include "backend/bool_command.hpp"
namespace big
{
class external_console : bool_command
{
using bool_command::bool_command;
virtual void refresh() override
{
g_log.toggle_external_console(m_toggle);
}
};
external_console
g_external_console("external_console", "BACKEND_EXTERNAL_CONSOLE", "BACKEND_EXTERNAL_CONSOLE_DESC", g.debug.external_console);
}

View File

@ -8,17 +8,6 @@ namespace big
{ {
m_save_file = save_file; m_save_file = save_file;
load(); load();
g_thread_pool->push([this] {
while (!g_running)
std::this_thread::yield();
while (g_running)
{
std::this_thread::sleep_for(100ms);
attempt_save();
}
});
} }
void menu_settings::attempt_save() void menu_settings::attempt_save()

View File

@ -122,9 +122,11 @@ namespace big
int thread_id = 0; int thread_id = 0;
std::int16_t syncing_object_id = -1; std::int16_t syncing_object_id = -1;
} fuzzer{}; } fuzzer{};
bool external_console = true;
bool window_hook = false; bool window_hook = false;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(debug, logs, window_hook) NLOHMANN_DEFINE_TYPE_INTRUSIVE(debug, logs, external_console, window_hook)
} debug{}; } debug{};
struct tunables struct tunables
@ -453,6 +455,7 @@ namespace big
struct settings struct settings
{ {
bool onboarding_complete = false;
bool dev_dlc = false; bool dev_dlc = false;
struct hotkeys struct hotkeys
@ -489,7 +492,7 @@ namespace big
NLOHMANN_DEFINE_TYPE_INTRUSIVE(hotkeys, editing_menu_toggle, menu_toggle, teleport_waypoint, teleport_objective, teleport_selected, teleport_pv, noclip, vehicle_flymode, bringvehicle, invis, heal, fill_inventory, skip_cutscene, freecam, superrun, passive, superjump, beastjump, invisveh, localinvisveh, fill_ammo, fast_quit, cmd_excecutor, repairpv, open_vehicle_controller, clear_wanted, random_ped_components) NLOHMANN_DEFINE_TYPE_INTRUSIVE(hotkeys, editing_menu_toggle, menu_toggle, teleport_waypoint, teleport_objective, teleport_selected, teleport_pv, noclip, vehicle_flymode, bringvehicle, invis, heal, fill_inventory, skip_cutscene, freecam, superrun, passive, superjump, beastjump, invisveh, localinvisveh, fill_ammo, fast_quit, cmd_excecutor, repairpv, open_vehicle_controller, clear_wanted, random_ped_components)
} hotkeys{}; } hotkeys{};
NLOHMANN_DEFINE_TYPE_INTRUSIVE(settings, hotkeys, dev_dlc) NLOHMANN_DEFINE_TYPE_INTRUSIVE(settings, hotkeys, dev_dlc, onboarding_complete)
} settings{}; } settings{};
struct spawn_vehicle struct spawn_vehicle

View File

@ -363,8 +363,8 @@ namespace big
functions::get_ped_seat m_get_ped_seat; functions::get_ped_seat m_get_ped_seat;
functions::received_clone_remove m_received_clone_remove; functions::received_clone_remove m_received_clone_remove;
CWeaponInfoManager* m_weapon_info_manager; CWeaponInfoManager* m_weapon_info_manager;
}; };
#pragma pack(pop) #pragma pack(pop)
static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned"); static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned");

View File

@ -10,19 +10,49 @@
namespace big namespace big
{ {
/**
* @brief The later an entry comes in this enum to higher up it comes in the z-index.
*/
enum eRenderPriority
{
// low priority
ESP,
CONTEXT_MENU,
// medium priority
MENU = 0x1000,
VEHICLE_CONTROL,
// high priority
INFO_OVERLAY = 0x2000,
CMD_EXECUTOR,
GTA_DATA_CACHE = 0x3000,
ONBOARDING,
// should remain in a league of its own
NOTIFICATIONS = 0x4000,
};
gui::gui() : gui::gui() :
m_is_open(false), m_is_open(false),
m_override_mouse(false) m_override_mouse(false)
{ {
g_renderer.add_dx_callback(view::gta_data, -1); g_renderer.add_dx_callback(view::notifications, eRenderPriority::NOTIFICATIONS);
g_renderer.add_dx_callback(view::notifications, -2); g_renderer.add_dx_callback(view::onboarding, eRenderPriority::ONBOARDING);
g_renderer.add_dx_callback(view::overlay, -3); g_renderer.add_dx_callback(view::gta_data, eRenderPriority::GTA_DATA_CACHE);
g_renderer.add_dx_callback(view::cmd_executor, -4); g_renderer.add_dx_callback(view::cmd_executor, eRenderPriority::CMD_EXECUTOR);
g_renderer.add_dx_callback(view::overlay, eRenderPriority::INFO_OVERLAY);
g_renderer.add_dx_callback(view::vehicle_control, eRenderPriority::VEHICLE_CONTROL);
g_renderer.add_dx_callback(esp::draw, eRenderPriority::ESP); // TODO: move to ESP service
g_renderer.add_dx_callback(view::context_menu, eRenderPriority::CONTEXT_MENU);
g_renderer.add_dx_callback( g_renderer.add_dx_callback(
[this] { [this] {
dx_on_tick(); dx_on_tick();
}, },
-5); eRenderPriority::MENU);
g_renderer.add_wndproc_callback([this](HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { g_renderer.add_wndproc_callback([this](HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
wndproc(hwnd, msg, wparam, lparam); wndproc(hwnd, msg, wparam, lparam);
@ -34,10 +64,6 @@ namespace big
} }
}); });
g_renderer.add_dx_callback(view::vehicle_control, 3);
g_renderer.add_dx_callback(esp::draw, 2); // TODO: move to ESP service
g_renderer.add_dx_callback(view::context_menu, 1);
dx_init(); dx_init();

View File

@ -1,5 +1,5 @@
#pragma once
#include "logger.hpp" #include "logger.hpp"
#include "util/is_proton.hpp" #include "util/is_proton.hpp"
namespace big namespace big
@ -12,34 +12,39 @@ namespace big
return system_clock::to_time_t(sctp); return system_clock::to_time_t(sctp);
} }
logger::logger(std::string_view console_title, file file, bool attach_console) : void logger::initialize(const std::string_view console_title, file file, bool attach_console)
m_attach_console(attach_console),
m_did_console_exist(false),
m_console_logger(&logger::format_console),
m_console_title(console_title),
m_original_console_mode(0),
m_console_handle(nullptr),
m_file(file)
{ {
m_console_title = console_title;
m_file = file;
if (is_proton()) if (is_proton())
{ {
LOG(VERBOSE) << "Using simple logger."; LOG(VERBOSE) << "Using simple logger.";
m_console_logger = &logger::format_console_simple; m_console_logger = &logger::format_console_simple;
} }
initialize(); toggle_external_console(attach_console);
create_backup();
m_file_out.open(m_file.get_path(), std::ios_base::out | std::ios_base::trunc);
g_log = this; Logger::Init();
Logger::AddSink([this](LogMessagePtr msg) {
(this->*m_console_logger)(std::move(msg));
});
Logger::AddSink([this](LogMessagePtr msg) {
format_file(std::move(msg));
});
} }
logger::~logger() void logger::destroy()
{ {
g_log = nullptr; Logger::Destroy();
m_file_out.close();
toggle_external_console(false);
} }
void logger::initialize() void logger::toggle_external_console(bool toggle)
{ {
if (m_attach_console) if (toggle)
{ {
if (m_did_console_exist = ::AttachConsole(GetCurrentProcessId()); !m_did_console_exist) if (m_did_console_exist = ::AttachConsole(GetCurrentProcessId()); !m_did_console_exist)
AllocConsole(); AllocConsole();
@ -60,28 +65,17 @@ namespace big
SetConsoleMode(m_console_handle, console_mode); SetConsoleMode(m_console_handle, console_mode);
} }
m_console_out.open("CONOUT$", std::ios_base::out | std::ios_base::app);
return;
} }
create_backup();
open_outstreams();
Logger::Init();
Logger::AddSink([this](LogMessagePtr msg) {
(this->*m_console_logger)(std::move(msg));
});
Logger::AddSink([this](LogMessagePtr msg) {
format_file(std::move(msg));
});
}
void logger::destroy()
{
Logger::Destroy();
close_outstreams();
m_console_out.close();
if (m_did_console_exist) if (m_did_console_exist)
SetConsoleMode(m_console_handle, m_original_console_mode); SetConsoleMode(m_console_handle, m_original_console_mode);
if (!m_did_console_exist && m_attach_console) if (!m_did_console_exist)
FreeConsole(); FreeConsole();
} }
@ -104,22 +98,6 @@ namespace big
} }
} }
void logger::open_outstreams()
{
if (m_attach_console)
m_console_out.open("CONOUT$", std::ios_base::out | std::ios_base::app);
m_file_out.open(m_file.get_path(), std::ios_base::out | std::ios_base::trunc);
}
void logger::close_outstreams()
{
if (m_attach_console)
m_console_out.close();
m_file_out.close();
}
const LogColor get_color(const eLogLevel level) const LogColor get_color(const eLogLevel level)
{ {
switch (level) switch (level)

View File

@ -25,38 +25,38 @@ namespace big
class logger final class logger final
{ {
public:
logger(std::string_view console_title, file file, bool attach_console = true);
virtual ~logger();
void initialize();
void destroy();
private: private:
void create_backup(); bool m_attach_console = true;
bool m_did_console_exist = false;
void open_outstreams(); void (logger::*m_console_logger)(const LogMessagePtr msg) = &logger::format_console;
void close_outstreams();
void format_console(const LogMessagePtr msg);
void format_console_simple(const LogMessagePtr msg);
void format_file(const LogMessagePtr msg);
private:
bool m_attach_console;
bool m_did_console_exist;
void (logger::*m_console_logger)(const LogMessagePtr msg);
std::string_view m_console_title; std::string_view m_console_title;
DWORD m_original_console_mode; DWORD m_original_console_mode = 0;
HANDLE m_console_handle; HANDLE m_console_handle;
std::ofstream m_console_out; std::ofstream m_console_out;
std::ofstream m_file_out; std::ofstream m_file_out;
file m_file; file m_file;
public:
logger() = default;
virtual ~logger() = default;
void initialize(const std::string_view console_title, file file, bool attach_console = true);
void destroy();
void toggle_external_console(bool toggle);
private:
void create_backup();
void format_console(const LogMessagePtr msg);
void format_console_simple(const LogMessagePtr msg);
void format_file(const LogMessagePtr msg);
}; };
inline logger* g_log = nullptr; inline logger g_log{};
} }

View File

@ -142,6 +142,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
0, 0,
[](PVOID) -> DWORD { [](PVOID) -> DWORD {
auto handler = exception_handler(); auto handler = exception_handler();
std::srand(std::chrono::system_clock::now().time_since_epoch().count());
while (!FindWindow("grcWindow", nullptr)) while (!FindWindow("grcWindow", nullptr))
std::this_thread::sleep_for(100ms); std::this_thread::sleep_for(100ms);
@ -150,11 +151,10 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
base_dir /= "YimMenu"; base_dir /= "YimMenu";
g_file_manager.init(base_dir); g_file_manager.init(base_dir);
auto logger_instance = std::make_unique<logger>("YimMenu", g_file_manager.get_project_file("./cout.log")); g.init(g_file_manager.get_project_file("./settings.json"));
LOG(INFO) << "Settings Loaded.";
EnableMenuItem(GetSystemMenu(GetConsoleWindow(), 0), SC_CLOSE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); g_log.initialize("YimMenu", g_file_manager.get_project_file("./cout.log"), g.debug.external_console);
std::srand(std::chrono::system_clock::now().time_since_epoch().count());
LOG(INFO) << "Yim's Menu Initializing"; LOG(INFO) << "Yim's Menu Initializing";
LOGF(INFO, "Git Info\n\tBranch:\t{}\n\tHash:\t{}\n\tDate:\t{}", version::GIT_BRANCH, version::GIT_SHA1, version::GIT_DATE); LOGF(INFO, "Git Info\n\tBranch:\t{}\n\tHash:\t{}\n\tDate:\t{}", version::GIT_BRANCH, version::GIT_SHA1, version::GIT_DATE);
@ -179,9 +179,6 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
auto thread_pool_instance = std::make_unique<thread_pool>(); auto thread_pool_instance = std::make_unique<thread_pool>();
LOG(INFO) << "Thread pool initialized."; LOG(INFO) << "Thread pool initialized.";
g.init(g_file_manager.get_project_file("./settings.json"));
LOG(INFO) << "Settings Loaded.";
auto pointers_instance = std::make_unique<pointers>(); auto pointers_instance = std::make_unique<pointers>();
LOG(INFO) << "Pointers initialized."; LOG(INFO) << "Pointers initialized.";
@ -266,7 +263,11 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
g_running = true; g_running = true;
while (g_running) while (g_running)
{
g.attempt_save();
std::this_thread::sleep_for(500ms); std::this_thread::sleep_for(500ms);
}
g_script_mgr.remove_all_scripts(); g_script_mgr.remove_all_scripts();
LOG(INFO) << "Scripts unregistered."; LOG(INFO) << "Scripts unregistered.";
@ -340,8 +341,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
LOG(INFO) << "Thread pool uninitialized."; LOG(INFO) << "Thread pool uninitialized.";
LOG(INFO) << "Farewell!"; LOG(INFO) << "Farewell!";
logger_instance->destroy(); g_log.destroy();
logger_instance.reset();
CloseHandle(g_main_thread); CloseHandle(g_main_thread);
FreeLibraryAndExitThread(g_hmodule, 0); FreeLibraryAndExitThread(g_hmodule, 0);

View File

@ -0,0 +1,83 @@
#include "gui.hpp"
#include "pointers.hpp"
#include "views/view.hpp"
#include "widgets/imgui_hotkey.hpp"
namespace big
{
void select_language()
{
ImGui::SeparatorText("ONBOARDING_SET_LANGUAGE"_T.data());
const auto& language_entries = g_translation_service.available_translations();
const auto& current_pack = g_translation_service.current_language_pack();
if (language_entries.contains(current_pack)
&& ImGui::BeginCombo("VIEW_SETTINGS_MENU_LANGUAGE"_T.data(), language_entries.at(current_pack).name.c_str()))
{
for (auto& i : language_entries)
{
if (ImGui::Selectable(i.second.name.c_str(), i.first == current_pack))
g_translation_service.select_language_pack(i.first);
if (i.first == current_pack)
{
ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
}
void select_menu_open_key()
{
ImGui::SeparatorText("ONBOARDING_SET_MENU_OPEN_KEY"_T.data());
if (ImGui::Hotkey("VIEW_HOTKEY_SETTINGS_MENU_TOGGLE"_T.data(), &g.settings.hotkeys.menu_toggle))
{
g_notification_service->push("ONBOARDING_NOTIFICATION_TITLE"_T.data(), "ONBOARDING_NOTIFICATION_OPEN_KEY"_T.data());
}
}
void developer_console()
{
ImGui::SeparatorText("ONBOARDING_ENABLE_DEVELOPER_CONSOLE"_T.data());
components::command_checkbox<"external_console">();
}
void view::onboarding()
{
static bool onboarding_open = false;
if (g.settings.onboarding_complete)
{
return;
}
if (!onboarding_open)
{
g_gui->toggle(true);
ImGui::OpenPopup("ONBOARDING_WELCOME_TITLE"_T.data());
onboarding_open = true;
}
const auto window_size = ImVec2{600, 400};
const auto window_position = ImVec2{(*g_pointers->m_gta.m_resolution_x - window_size.x) / 2,
(*g_pointers->m_gta.m_resolution_y - window_size.y) / 2};
ImGui::SetNextWindowSize(window_size, ImGuiCond_Always);
ImGui::SetNextWindowPos(window_position, ImGuiCond_Always);
if (ImGui::BeginPopupModal("ONBOARDING_WELCOME_TITLE"_T.data()))
{
select_language();
select_menu_open_key();
developer_console();
if (ImGui::Button("CLOSE"_T.data()))
{
g.settings.onboarding_complete = true;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
}

View File

@ -18,6 +18,8 @@ namespace big
{ {
if (ImGui::BeginTabItem("DEBUG_TAB_MISC"_T.data())) if (ImGui::BeginTabItem("DEBUG_TAB_MISC"_T.data()))
{ {
components::command_checkbox<"external_console">();
components::command_checkbox<"windowhook">("VIEW_DEBUG_MISC_DISABLE_GTA_WINDOW_HOOK"_T); components::command_checkbox<"windowhook">("VIEW_DEBUG_MISC_DISABLE_GTA_WINDOW_HOOK"_T);
ImGui::Text(std::format("{}: {}/{}", "VIEW_DEBUG_MISC_FIBER_POOL_USAGE"_T, g_fiber_pool->get_used_fibers(), g_fiber_pool->get_total_fibers()).c_str()); ImGui::Text(std::format("{}: {}/{}", "VIEW_DEBUG_MISC_FIBER_POOL_USAGE"_T, g_fiber_pool->get_used_fibers(), g_fiber_pool->get_total_fibers()).c_str());

View File

@ -77,12 +77,15 @@ namespace big
static void lua_scripts(); static void lua_scripts();
static void vfx(); static void vfx();
static void onboarding();
static void cmd_executor();
static void player_info(); static void player_info();
static void player_teleport(); static void player_teleport();
static void player_kick(); static void player_kick();
static void player_toxic(); static void player_toxic();
static void player_misc(); static void player_misc();
static void cmd_executor();
static void player_vehicle(); static void player_vehicle();
}; };
} }