66#include " workers/indexdownloadworker.h"
77#include " workers/luadownloadworker.h"
88#include " workers/generatorworker.h"
9+ #include " workers/dllpatchworker.h"
910#include " workers/fixdownloadworker.h"
1011#include " workers/restartworker.h"
1112#include " utils/colors.h"
@@ -91,7 +92,9 @@ MainWindow::MainWindow(QWidget* parent)
9192 , m_syncWorker(nullptr )
9293 , m_dlWorker(nullptr )
9394 , m_genWorker(nullptr )
95+ , m_dllWorker(nullptr )
9496 , m_restartWorker(nullptr )
97+ , m_patchMode(PatchMode::SteamTools)
9598 , m_fetchingNames(false )
9699 , m_nameFetchSearchId(0 )
97100{
@@ -304,6 +307,28 @@ void MainWindow::initUI() {
304307 sidebarLayout->addWidget (m_btnRemove);
305308
306309 sidebarLayout->addSpacing (6 );
310+
311+ // Patch mode toggle
312+ m_btnPatchMode = new GlassButton (MaterialIcons::Flash, " Mode: SteamTools" , " Click to switch patch mode" , Colors::OUTLINE);
313+ m_btnPatchMode->setFixedHeight (44 );
314+ connect (m_btnPatchMode, &QPushButton::clicked, this , [this ]() {
315+ if (m_patchMode == PatchMode::SteamTools) {
316+ m_patchMode = PatchMode::YasoHook;
317+ m_btnPatchMode->setText (" Mode: YasoHook" );
318+ m_btnPatchMode->setDescription (" Patches game folder directly" );
319+ m_btnPatchMode->setColor (Colors::ACCENT_GREEN);
320+ m_statusLabel->setText (" Switched to YasoHook mode (no SteamTools needed)" );
321+ } else {
322+ m_patchMode = PatchMode::SteamTools;
323+ m_btnPatchMode->setText (" Mode: SteamTools" );
324+ m_btnPatchMode->setDescription (" Uses Lua scripts in stplug-in" );
325+ m_btnPatchMode->setColor (Colors::OUTLINE);
326+ m_statusLabel->setText (" Switched to SteamTools mode" );
327+ }
328+ });
329+ sidebarLayout->addWidget (m_btnPatchMode);
330+
331+ sidebarLayout->addSpacing (4 );
307332 m_btnRestart = new GlassButton (MaterialIcons::RestartAlt, " Restart Steam" , " Apply Changes" , Colors::PRIMARY);
308333 m_btnRestart->setFixedHeight (52 );
309334 connect (m_btnRestart, &QPushButton::clicked, this , &MainWindow::doRestart);
@@ -493,9 +518,10 @@ void MainWindow::displayLibrary() {
493518 cancelNameFetches ();
494519 m_pendingNameFetchIds.clear ();
495520
496- QStringList pluginDirs = Config::getAllSteamPluginDirs ();
497521 QSet<QString> installedAppIds;
498522
523+ // Scan SteamTools patches (stplug-in .lua files)
524+ QStringList pluginDirs = Config::getAllSteamPluginDirs ();
499525 for (const QString& dirPath : pluginDirs) {
500526 QDir dir (dirPath);
501527 QStringList luaFiles = dir.entryList ({" *.lua" }, QDir::Files);
@@ -504,6 +530,12 @@ void MainWindow::displayLibrary() {
504530 if (!appId.isEmpty ()) installedAppIds.insert (appId);
505531 }
506532 }
533+
534+ // Scan YasoHook patches (dwmapi.dll in game directories)
535+ QStringList dllPatched = Config::getAllDllPatchedGameIds ();
536+ for (const QString& appId : dllPatched) {
537+ installedAppIds.insert (appId);
538+ }
507539
508540 if (installedAppIds.isEmpty ()) {
509541 m_statusLabel->setText (" No patches installed found." );
@@ -916,7 +948,14 @@ void MainWindow::onCardClicked(GameCard* card) {
916948void MainWindow::doAddGame () {
917949 if (m_selectedGame.isEmpty ()) return ;
918950 bool isSupported = (m_selectedGame[" supported" ] == " true" );
919- if (isSupported) runPatchLogic (); else runGenerateLogic ();
951+
952+ if (m_patchMode == PatchMode::YasoHook) {
953+ // YasoHook mode: copy dwmapi.dll to game directory (works for all games)
954+ runDllPatchLogic ();
955+ } else {
956+ // SteamTools mode: download .lua or generate
957+ if (isSupported) runPatchLogic (); else runGenerateLogic ();
958+ }
920959}
921960
922961void MainWindow::doRemoveGame () {
@@ -925,12 +964,13 @@ void MainWindow::doRemoveGame() {
925964 QString name = m_selectedGame[" name" ];
926965
927966 if (QMessageBox::question (this , " Remove Patch" ,
928- QString (" Are you sure you want to remove the patch for %1?\n This will delete the lua file from your Steam plugin folder. " ).arg (name),
967+ QString (" Are you sure you want to remove the patch for %1?" ).arg (name),
929968 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return ;
930969
931- QStringList pluginDirs = Config::getAllSteamPluginDirs ();
932970 bool deleted = false ;
933971
972+ // Try removing SteamTools patch (.lua from stplug-in)
973+ QStringList pluginDirs = Config::getAllSteamPluginDirs ();
934974 for (const QString& dirPath : pluginDirs) {
935975 QDir dir (dirPath);
936976 QString filePath = dir.filePath (appId + " .lua" );
@@ -939,6 +979,22 @@ void MainWindow::doRemoveGame() {
939979 }
940980 }
941981
982+ // Try removing YasoHook patch (dwmapi.dll from game directory)
983+ QString gameDir = Config::findGameInstallDir (appId);
984+ if (!gameDir.isEmpty ()) {
985+ QString dllPath = gameDir + " /dwmapi.dll" ;
986+ if (QFile::exists (dllPath)) {
987+ if (QFile::remove (dllPath)) {
988+ deleted = true ;
989+ // Restore backup if it exists
990+ QString backupPath = gameDir + " /dwmapi.dll.bak" ;
991+ if (QFile::exists (backupPath)) {
992+ QFile::rename (backupPath, dllPath);
993+ }
994+ }
995+ }
996+ }
997+
942998 if (deleted) {
943999 m_statusLabel->setText (QString (" Removed patch for %1" ).arg (name));
9441000 displayLibrary ();
@@ -1014,6 +1070,36 @@ void MainWindow::onPatchError(QString error) {
10141070 m_terminalDialog->setFinished (false );
10151071}
10161072
1073+ void MainWindow::runDllPatchLogic () {
1074+ if (m_selectedGame.isEmpty ()) return ;
1075+ m_btnAddToLibrary->setEnabled (false );
1076+ m_progress->setValue (0 );
1077+ m_progress->show ();
1078+ m_terminalDialog->clear ();
1079+ m_terminalDialog->appendLog (QString (" [YasoHook] Initializing patch for: %1 (%2)" ).arg (m_selectedGame[" name" ]).arg (m_selectedGame[" appid" ]), " INFO" );
1080+ m_terminalDialog->show ();
1081+
1082+ m_dllWorker = new DllPatchWorker (m_selectedGame[" appid" ], this );
1083+ connect (m_dllWorker, &DllPatchWorker::finished, this , &MainWindow::onDllPatchDone);
1084+ connect (m_dllWorker, &DllPatchWorker::progress, [this ](qint64 dl, qint64 total) {
1085+ if (total > 0 ) m_progress->setValue (static_cast <int >(dl * 100 / total));
1086+ });
1087+ connect (m_dllWorker, &DllPatchWorker::status, [this ](QString msg) { m_statusLabel->setText (msg); });
1088+ connect (m_dllWorker, &DllPatchWorker::log, m_terminalDialog, &TerminalDialog::appendLog);
1089+ connect (m_dllWorker, &DllPatchWorker::error, this , &MainWindow::onPatchError);
1090+ m_dllWorker->start ();
1091+ }
1092+
1093+ void MainWindow::onDllPatchDone (QString gameDir) {
1094+ m_progress->hide ();
1095+ m_btnAddToLibrary->setEnabled (true );
1096+ m_statusLabel->setText (" YasoHook Patch Installed!" );
1097+ m_terminalDialog->appendLog (QString (" DLL installed to: %1" ).arg (gameDir), " SUCCESS" );
1098+ m_terminalDialog->setFinished (true );
1099+ m_btnAddToLibrary->setDescription (QString (" Re-patch %1" ).arg (m_selectedGame[" name" ]));
1100+ m_btnAddToLibrary->setColor (Colors::ACCENT_GREEN);
1101+ }
1102+
10171103void MainWindow::runGenerateLogic () {
10181104 if (m_selectedGame.isEmpty ()) return ;
10191105 m_btnAddToLibrary->setEnabled (false );
0 commit comments