Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 75 additions & 5 deletions src/core/YimMenu/yimmenu.hpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -139,7 +144,7 @@ namespace YLP
}
}

void GetCommitHash()
void UpdateCommitHash()
{
m_LastCommitHash = Utils::RegexMatchHtml(
m_ReleaseUrl.first,
Expand All @@ -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);
Expand All @@ -171,7 +237,8 @@ namespace YLP
}

UpdateChecksum();
GetCommitHash();
UpdateCommitHash();
UpdateSupportedGameVersion();
ResetState();
m_Exists = IO::Exists(m_DllPath);
LOG_INFO("{}: Done.", m_Name);
Expand Down Expand Up @@ -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
Expand All @@ -222,7 +290,7 @@ namespace YLP
}

if (m_LastCommitHash.empty())
GetCommitHash();
UpdateCommitHash();
}
catch (const std::exception& e)
{
Expand All @@ -245,6 +313,7 @@ namespace YLP

std::filesystem::path m_BasePath{};
std::filesystem::path m_ChecksumPath{};
std::filesystem::path m_SupportedVersionPath{};
std::pair<std::wstring, std::wstring> m_ReleaseUrl{};
std::pair<std::wstring, std::wstring> m_DownloadUrl{};
std::mutex m_Mutex;
Expand All @@ -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{};
Expand Down
38 changes: 37 additions & 1 deletion src/core/memory/procmon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand All @@ -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;

Expand Down