diff options
| author | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-04-13 14:18:17 -0500 |
|---|---|---|
| committer | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-04-13 14:18:17 -0500 |
| commit | 145fc7f610cc4607c42ad55c37317bdd93223fbf (patch) | |
| tree | 2e990f13cf0e85c33e9dd1c9d344925d30fa1012 /src | |
| parent | a2fd27434339913124f4d0a88eb19b13a70e19a4 (diff) | |
Remove Fix Game Registries button, fix BethINI New Vegas detection
The auto-prompt in organizercore already offers to fix the registry
on launch, so the manual button is redundant.
BethINI Pie plugin compared against managedGame()->gameName(), but
GameFalloutNV returns "New Vegas" while BethINI's app folder is
"Fallout New Vegas" — add an alias map so NV is detected correctly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/src/settingsdialog.ui | 12 | ||||
| -rw-r--r-- | src/src/settingsdialogproton.cpp | 262 | ||||
| -rw-r--r-- | src/src/settingsdialogproton.h | 2 |
3 files changed, 1 insertions, 275 deletions
diff --git a/src/src/settingsdialog.ui b/src/src/settingsdialog.ui index 6b4ebc6..cb158f2 100644 --- a/src/src/settingsdialog.ui +++ b/src/src/settingsdialog.ui @@ -1783,17 +1783,7 @@ If you disable this feature, MO will only display official DLCs this way. Please </property> </widget> </item> - <item row="3" column="0" colspan="2"> - <widget class="QPushButton" name="fixGameRegistriesButton"> - <property name="text"> - <string>Fix Game Registries</string> - </property> - <property name="toolTip"> - <string>Re-apply Wine registry settings for the current prefix. Use this if games fail to detect their installation or have registry-related issues.</string> - </property> - </widget> - </item> - <item row="3" column="2" colspan="2"> + <item row="3" column="0" colspan="4"> <widget class="QPushButton" name="winetricksButton"> <property name="text"> <string>Winetricks</string> diff --git a/src/src/settingsdialogproton.cpp b/src/src/settingsdialogproton.cpp index 2117a09..5217092 100644 --- a/src/src/settingsdialogproton.cpp +++ b/src/src/settingsdialogproton.cpp @@ -8,23 +8,18 @@ #include <QtConcurrent/QtConcurrentRun> #include <log.h> #include <uibase/utility.h> -#include "knowngames.h" #include "steamdetection.h" -#include "gamedetection.h" #include "slrmanager.h" #include <atomic> -#include <QCheckBox> #include <QComboBox> #include <QCoreApplication> #include <QDateTime> #include <QDialog> -#include <QDialogButtonBox> #include <QDir> #include <QFileDialog> #include <QFileInfo> #include <QHBoxLayout> #include <QLabel> -#include <QLineEdit> #include <QMessageBox> #include <QPushButton> #include <QtConcurrent/QtConcurrent> @@ -40,128 +35,6 @@ namespace { std::atomic<ProtonSettingsTab*> g_activeInstallTab = nullptr; - -/// Find the wine binary inside a Proton installation directory. -static QString findWineBinary(const QString& protonPath) -{ - for (const char* subdir : {"files/bin", "dist/bin"}) { - const QString candidate = - QDir(protonPath).filePath(QString::fromLatin1(subdir) + "/wine"); - if (QFileInfo::exists(candidate)) - return candidate; - } - return {}; -} - -/// Apply a single game's registry entry via wine regedit. -/// -/// Looks up the game by name in NaK's KNOWN_GAMES, builds a .reg file that -/// maps the install path to the game's registry key, and imports it with -/// wine regedit (wrapped in SLR if available). -static QString applyGameRegistryNative(const QString& prefixPath, - const QString& protonPath, - const QString& gameName, - const QString& installPath, - void (*logCb)(const char*)) -{ - // Find wine binary. - const QString wineBin = findWineBinary(protonPath); - if (wineBin.isEmpty()) - return QStringLiteral("Wine binary not found in Proton at %1").arg(protonPath); - - // Look up registry path/value from known games. - const KnownGame* foundGame = nullptr; - for (int i = 0; i < KNOWN_GAMES_COUNT; ++i) { - if (gameName == QString::fromLatin1(KNOWN_GAMES[i].name)) { - foundGame = &KNOWN_GAMES[i]; - break; - } - } - - if (!foundGame || !foundGame->registry_path || !foundGame->registry_value) - return QStringLiteral("Unknown game: %1").arg(gameName); - - const QString rPath = QString::fromLatin1(foundGame->registry_path); - const QString rVal = QString::fromLatin1(foundGame->registry_value); - - // Convert Linux path → Wine Z: drive path with escaped backslashes for .reg. - const QString winePath = "Z:" + QString(installPath).replace('/', "\\\\"); - - // Wow6432Node key: strip the leading "Software\" prefix. - const int firstBackslash = rPath.indexOf('\\'); - const QString wow64Key = - (firstBackslash >= 0) ? rPath.mid(firstBackslash + 1) : rPath; - - const QString regContent = QStringLiteral( - "Windows Registry Editor Version 5.00\n\n" - "[HKEY_LOCAL_MACHINE\\%1]\n\"%2\"=\"%3\"\n\n" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\%4]\n\"%5\"=\"%6\"\n\n") - .arg(rPath, rVal, winePath, wow64Key, rVal, winePath); - - // Write temp .reg file. - const QString tmpDir = fluorineDataDir() + "/tmp"; - QDir().mkpath(tmpDir); - const QString regFile = tmpDir + "/game_reg_apply.reg"; - - { - QFile f(regFile); - if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) - return QStringLiteral("Failed to write registry file: %1").arg(regFile); - f.write(regContent.toUtf8()); - } - - if (logCb) { - const QByteArray msg = - QStringLiteral("Applying registry for %1...").arg(gameName).toUtf8(); - logCb(msg.constData()); - } - - // Build the command — wrap in SLR if available. - QProcess proc; - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - env.insert("WINEPREFIX", prefixPath); - env.insert("WINEDLLOVERRIDES", "mshtml=d"); - env.insert("PROTON_USE_XALIA", "0"); - proc.setProcessEnvironment(env); - - const QString slr = getSlrRunScript(); - if (!slr.isEmpty()) { - - QStringList args; - // Expose directories to the container. - const QString wineDir = QFileInfo(wineBin).absolutePath(); - if (!wineDir.isEmpty()) - args << QStringLiteral("--filesystem=%1").arg(wineDir); - if (!prefixPath.isEmpty()) - args << QStringLiteral("--filesystem=%1").arg(prefixPath); - if (!protonPath.isEmpty()) - args << QStringLiteral("--filesystem=%1").arg(protonPath); - if (QDir(tmpDir).exists()) - args << QStringLiteral("--filesystem=%1").arg(tmpDir); - args << "--" << wineBin << "regedit" << regFile; - - proc.setProgram(slr); - proc.setArguments(args); - } else { - proc.setProgram(wineBin); - proc.setArguments({"regedit", regFile}); - } - - proc.setProcessChannelMode(QProcess::MergedChannels); - proc.start(); - proc.waitForFinished(60000); - QFile::remove(regFile); - - if (proc.exitStatus() != QProcess::NormalExit || proc.exitCode() != 0) - return QStringLiteral("wine regedit failed (exit code %1)").arg(proc.exitCode()); - - if (logCb) { - const QByteArray msg = - QStringLiteral("Registry applied for %1").arg(gameName).toUtf8(); - logCb(msg.constData()); - } - return {}; // success -} } ProtonSettingsTab::ProtonSettingsTab(Settings& s, SettingsDialog& d) @@ -218,8 +91,6 @@ ProtonSettingsTab::ProtonSettingsTab(Settings& s, SettingsDialog& d) &ProtonSettingsTab::onRecreatePrefix); QObject::connect(ui->openPrefixFolderButton, &QPushButton::clicked, this, &ProtonSettingsTab::onOpenPrefixFolder); - QObject::connect(ui->fixGameRegistriesButton, &QPushButton::clicked, this, - &ProtonSettingsTab::onFixGameRegistries); QObject::connect(ui->winetricksButton, &QPushButton::clicked, this, &ProtonSettingsTab::onWinetricks); QObject::connect(ui->prefixLocationBrowseButton, &QPushButton::clicked, this, @@ -310,7 +181,6 @@ void ProtonSettingsTab::refreshState() ui->deletePrefixButton->setEnabled(!m_busy && active); ui->recreatePrefixButton->setEnabled(!m_busy && active); ui->openPrefixFolderButton->setEnabled(!m_busy && active); - ui->fixGameRegistriesButton->setEnabled(!m_busy && active); ui->winetricksButton->setEnabled(!m_busy && active); ui->protonVersionCombo->setEnabled(!m_busy); } @@ -623,138 +493,6 @@ void ProtonSettingsTab::onWinetricks() proc.startDetached(); } -void ProtonSettingsTab::onFixGameRegistries() -{ - if (m_busy) { - return; - } - - showGameRegistryDialog(); -} - -void ProtonSettingsTab::showGameRegistryDialog() -{ - auto cfg = FluorineConfig::load(); - if (!cfg.has_value() || !cfg->prefixExists()) { - ui->protonStatusLabel->setText(tr("No existing prefix")); - refreshState(); - return; - } - - QDialog dialog(parentWidget()); - dialog.setWindowTitle(tr("Fix Game Registries")); - dialog.setMinimumWidth(500); - - auto* layout = new QVBoxLayout(&dialog); - - layout->addWidget(new QLabel(tr("Select the game to apply registry settings for:"), - &dialog)); - - auto* gameCombo = new QComboBox(&dialog); - - for (int i = 0; i < KNOWN_GAMES_COUNT; ++i) { - const QString name = QString::fromLatin1(KNOWN_GAMES[i].name); - if (!name.isEmpty()) { - gameCombo->addItem(name); - } - } - - layout->addWidget(gameCombo); - - // Game installation path - layout->addWidget(new QLabel(tr("Game installation path:"), &dialog)); - - auto* pathLayout = new QHBoxLayout(); - auto* pathEdit = new QLineEdit(&dialog); - pathEdit->setPlaceholderText(tr("e.g. /home/user/.local/share/Steam/steamapps/common/Skyrim Special Edition")); - auto* browseBtn = new QPushButton(tr("Browse..."), &dialog); - pathLayout->addWidget(pathEdit); - pathLayout->addWidget(browseBtn); - layout->addLayout(pathLayout); - - QObject::connect(browseBtn, &QPushButton::clicked, &dialog, [&dialog, pathEdit]() { - const QString dir = QFileDialog::getExistingDirectory( - &dialog, QObject::tr("Select Game Installation Folder"), - pathEdit->text().isEmpty() ? QDir::homePath() : pathEdit->text()); - if (!dir.isEmpty()) { - pathEdit->setText(dir); - } - }); - - // Try to auto-detect path when game selection changes - auto autoDetect = [pathEdit, gameCombo]() { - const QString gameName = gameCombo->currentText(); - if (gameName.isEmpty()) return; - - // Use detectAllGames to find the install path - const GameScanResult scanResult = detectAllGames(); - for (int i = 0; i < scanResult.games.size(); ++i) { - const DetectedGame& detected = scanResult.games[i]; - if (detected.name.contains(gameName, Qt::CaseInsensitive) || - gameName.contains(detected.name, Qt::CaseInsensitive)) { - if (!detected.install_path.isEmpty()) { - pathEdit->setText(detected.install_path); - break; - } - } - } - }; - - QObject::connect(gameCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), - &dialog, autoDetect); - // Auto-detect for initially selected game - autoDetect(); - - auto* buttons = - new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog); - layout->addWidget(buttons); - - QObject::connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); - QObject::connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); - - if (dialog.exec() != QDialog::Accepted) { - return; - } - - const QString selectedGame = gameCombo->currentText(); - const QString gamePath = pathEdit->text(); - const QString prefixPath = cfg->prefix_path; - const QString protonName = cfg->proton_name; - const QString protonPath = cfg->proton_path; - - if (gamePath.isEmpty()) { - QMessageBox::warning(parentWidget(), tr("No Path"), - tr("Please provide the game installation path.")); - return; - } - - setBusy(true); - ui->protonStatusLabel->setText(tr("Fixing game registries...")); - ui->nakInstallLog->clear(); - ui->nakInstallLog->setVisible(true); - ui->toggleInstallLog->setChecked(true); - - g_activeInstallTab.store(this); - - m_pendingPrefixPath = prefixPath; - m_pendingProtonName = protonName; - m_pendingProtonPath = protonPath; - - m_installWatcher.setFuture( - QtConcurrent::run([prefixPath, protonPath, - selectedGame, gamePath]() -> InstallResult { - const QString err = applyGameRegistryNative( - prefixPath, protonPath, selectedGame, gamePath, - &ProtonSettingsTab::logCallback); - - InstallResult r; - if (!err.isEmpty()) - r.error = err; - - return r; - })); -} - void ProtonSettingsTab::runPrefixSetupDialog(uint32_t appId, const QString& prefixPath, const QString& protonName, diff --git a/src/src/settingsdialogproton.h b/src/src/settingsdialogproton.h index db0770c..966a980 100644 --- a/src/src/settingsdialogproton.h +++ b/src/src/settingsdialogproton.h @@ -30,12 +30,10 @@ private: void onDeletePrefix(); void onRecreatePrefix(); void onOpenPrefixFolder(); - void onFixGameRegistries(); void onWinetricks(); void onBrowsePrefixLocation(); void onDownloadSLR(); - void showGameRegistryDialog(); QString ensureWinetricks(); QString findProtonWine(const QString& protonPath); |
