From 30a2680cad771516f1fd5e601a84d631c4db3824 Mon Sep 17 00:00:00 2001 From: SAMURAI <66764345+xesdoog@users.noreply.github.com> Date: Fri, 9 Jan 2026 11:58:11 +0100 Subject: [PATCH] feat(auto-inject): add more checks - Check menu state before injecting. - Check current game version vs supported menu version and abort on mismatch. --- src/core/YimMenu/yimmenu.hpp | 80 +++++++++++++++++++++++++++++++++--- src/core/memory/procmon.cpp | 38 ++++++++++++++++- 2 files changed, 112 insertions(+), 6 deletions(-) diff --git a/src/core/YimMenu/yimmenu.hpp b/src/core/YimMenu/yimmenu.hpp index 31498ab..1f7a31a 100644 --- a/src/core/YimMenu/yimmenu.hpp +++ b/src/core/YimMenu/yimmenu.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2025 SAMURAI (xesdoog) & Contributors +// Copyright (C) 2025 SAMURAI (xesdoog) & Contributors // This file is part of YLP. // // YLP is free software: you can redistribute it and/or modify @@ -100,12 +100,17 @@ namespace YLP m_DllPath = path / m_DllName; m_Exists = IO::Exists(m_DllPath); m_ChecksumPath = path / (m_Name + ".sha256"); + m_SupportedVersionPath = path / (m_Name + ".version"); + + ReadSupportedGameVersion(); if (Config().gtaExePaths.contains(m_TargetProcess)) m_ExePath = Config().gtaExePaths[m_TargetProcess]; if (m_Exists && !ReadChecksum()) - UpdateChecksum(); + ThreadManager::Run([this]() { + UpdateChecksum(); + }); } bool ReadChecksum() @@ -139,7 +144,7 @@ namespace YLP } } - void GetCommitHash() + void UpdateCommitHash() { m_LastCommitHash = Utils::RegexMatchHtml( m_ReleaseUrl.first, @@ -148,6 +153,67 @@ namespace YLP 1); } + void UpdateSupportedGameVersion() + { + std::string match; + + if (m_Version == YimMenuV2) + { + match = "Unknown"; + } + else + { + match = Utils::RegexMatchHtml( + L"raw.githubusercontent.com", + L"Mr-X-GTA/YimMenu/refs/heads/master/src/pointers.cpp", + R"(#define GTA_VERSION_TARGET\s+\"(.*?)\")", 1); + } + + if (match.empty()) + { + Notify("Failed to fetch supported game version from GitHub!", Notifier::Error, true); + match = "Unknown"; + } + + std::ofstream f(m_SupportedVersionPath); + if (f.is_open()) + { + f << match; + f.close(); + } + + m_SupportedGameVersion = match; + } + + void ReadSupportedGameVersion() + { + if (!IO::Exists(m_SupportedVersionPath)) + return; + + std::ifstream f(m_SupportedVersionPath); + if (!f.is_open()) + { + LOG_WARN("{}: Failed to read supported game version from file.", m_Name); + return; + } + + std::getline(f, m_SupportedGameVersion); + f.close(); + } + + std::string GetSupportedGameVersion() const + { + return m_SupportedGameVersion; + } + + bool MatchGameVersion(const std::string& online, const std::string& build) const + { + if (m_SupportedGameVersion.empty() || m_SupportedGameVersion == "Unknown") + return false; + + return m_SupportedGameVersion == (online + "-" + build); + } + void Download() { std::scoped_lock lock(m_Mutex); @@ -171,7 +237,8 @@ namespace YLP } UpdateChecksum(); - GetCommitHash(); + UpdateCommitHash(); + UpdateSupportedGameVersion(); ResetState(); m_Exists = IO::Exists(m_DllPath); LOG_INFO("{}: Done.", m_Name); @@ -213,6 +280,7 @@ namespace YLP if (!pendingUpdate) { LOG_INFO("[{}]: No new releases found.", m_Name); + UpdateSupportedGameVersion(); // sometimes the supported version changes without a new release m_State = Idle; } else @@ -222,7 +290,7 @@ namespace YLP } if (m_LastCommitHash.empty()) - GetCommitHash(); + UpdateCommitHash(); } catch (const std::exception& e) { @@ -245,6 +313,7 @@ namespace YLP std::filesystem::path m_BasePath{}; std::filesystem::path m_ChecksumPath{}; + std::filesystem::path m_SupportedVersionPath{}; std::pair m_ReleaseUrl{}; std::pair m_DownloadUrl{}; std::mutex m_Mutex; @@ -259,6 +328,7 @@ namespace YLP std::string m_DllName{}; std::string m_Checksum{}; std::string m_LastCommitHash{}; + std::string m_SupportedGameVersion{}; std::string m_TargetProcess{}; std::string m_Url{}; std::filesystem::path m_DllPath{}; diff --git a/src/core/memory/procmon.cpp b/src/core/memory/procmon.cpp index 6654fa4..dad886b 100644 --- a/src/core/memory/procmon.cpp +++ b/src/core/memory/procmon.cpp @@ -121,7 +121,8 @@ namespace YLP bool ProcessMonitor::AutoInject() { - if (m_MonitorMode == MonitorEnhanced) // not supported yet + if (m_MonitorMode == MonitorEnhanced) + // Not supported yet. This only needs a pattern for GameState so help with it would be appreciated. I don't have GTA V Enhanced return false; if (!m_Scanner || !m_Menu) @@ -139,6 +140,34 @@ namespace YLP return false; } + while (true) + { + auto state = m_Menu->GetState(); + if (state == YimMenu::eMenuViewState::Idle) + break; + + switch (state) + { + case YimMenu::eMenuViewState::Error: + LOG_ERROR("[ProcMon]: Aborting auto-inject! Failed to verify DLL state."); + return false; + case YimMenu::eMenuViewState::Checking: + std::this_thread::sleep_for(250ms); + break; + case YimMenu::eMenuViewState::PendingUpdate: + LOG_INFO("[ProcMon]: Updating DLL..."); + m_Menu->Download(); + std::this_thread::sleep_for(500ms); + break; + case YimMenu::eMenuViewState::Downloading: + std::this_thread::sleep_for(1s); + break; + default: + LOG_WARN("[ProcMon]: Unknown menu state! Aborting."); + return false; + } + } + LOG_INFO("[ProcMon]: Preparing to auto-inject..."); auto& pointers = (m_MonitorMode == MonitorLegacy) ? g_Pointers.Legacy : g_Pointers.Enhanced; @@ -148,6 +177,13 @@ namespace YLP return false; } + if (!m_Menu->MatchGameVersion(pointers.OnlineVersion, pointers.GameVersion)) + { + LOG_WARN("[ProcMon]: Game version mismatch! Auto-inject aborted but you can still inject manually."); + Notifier::Add("ProcMon", "Game version mismatch! Auto-inject aborted but you can still inject manually.", Notifier::Warning); + return false; + } + bool attempted_inject = false; std::string last_log;