diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2020-07-23 01:32:53 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2020-11-03 11:39:03 -0500 |
| commit | 5b13704275fc3cf02f6c3f4d4bd77d32425ad2c9 (patch) | |
| tree | 27362fc36d32843d7ce68534511e539e2a16f9d4 /src | |
| parent | 2c915429d84a9df0e9c512db248fb5c8ec6663f7 (diff) | |
moved profile, current game and game edition checks to InstanceManager
trying to centralize all of this stuff
Diffstat (limited to 'src')
| -rw-r--r-- | src/instancemanager.cpp | 232 | ||||
| -rw-r--r-- | src/instancemanager.h | 18 | ||||
| -rw-r--r-- | src/main.cpp | 234 |
3 files changed, 255 insertions, 229 deletions
diff --git a/src/instancemanager.cpp b/src/instancemanager.cpp index 6c7f797e..9bcd0f3c 100644 --- a/src/instancemanager.cpp +++ b/src/instancemanager.cpp @@ -20,9 +20,14 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "instancemanager.h" #include "selectiondialog.h" +#include "settings.h" +#include "shared/appconfig.h" +#include "plugincontainer.h" +#include <report.h> +#include <iplugingame.h> #include <utility.h> #include <log.h> -#include "shared/appconfig.h" + #include <QCoreApplication> #include <QDir> #include <QStandardPaths> @@ -54,6 +59,11 @@ void InstanceManager::overrideInstance(const QString& instanceName) m_overrideInstance = true; } +void InstanceManager::overrideProfile(const QString& profileName) +{ + m_overrideProfileName = profileName; + m_overrideProfile = true; +} QString InstanceManager::currentInstance() const { @@ -357,6 +367,226 @@ QString InstanceManager::determineDataPath() } } +QString InstanceManager::determineProfile(const Settings &settings) +{ + auto selectedProfileName = settings.game().selectedProfileName(); + + if (m_overrideProfile) { + log::debug("profile overwritten on command line"); + selectedProfileName = m_overrideProfileName; + } + + if (!selectedProfileName) { + log::debug("no configured profile"); + selectedProfileName = "Default"; + } + + return *selectedProfileName; +} + +bool InstanceManager::determineGameEdition( + Settings& settings, IPluginGame* game) +{ + QString edition; + + if (auto v=settings.game().edition()) { + edition = *v; + } else { + QStringList editions = game->gameVariants(); + if (editions.size() < 2) { + edition = ""; + return true; + } + + SelectionDialog selection( + QObject::tr("Please select the game edition you have (MO can't " + "start the game correctly if this is set " + "incorrectly!)"), + nullptr); + + selection.setWindowFlag(Qt::WindowStaysOnTopHint, true); + + int index = 0; + for (const QString &edition : editions) { + selection.addChoice(edition, "", index++); + } + + if (selection.exec() == QDialog::Rejected) { + return false; + } + + edition = selection.getChoiceString(); + settings.game().setEdition(edition); + } + + game->setGameVariant(edition); + + return true; +} + +MOBase::IPluginGame *selectGame( + Settings &settings, QDir const &gamePath, MOBase::IPluginGame *game) +{ + settings.game().setName(game->gameName()); + + QString gameDir = gamePath.absolutePath(); + game->setGamePath(gameDir); + + settings.game().setDirectory(gameDir); + + return game; +} + +MOBase::IPluginGame* InstanceManager::determineCurrentGame( + const QString& moPath, Settings& settings, const PluginContainer &plugins) +{ + //Determine what game we are running where. Be very paranoid in case the + //user has done something odd. + + //If the game name has been set up, try to use that. + const auto gameName = settings.game().name(); + const bool gameConfigured = (gameName.has_value() && *gameName != ""); + + if (gameConfigured) { + MOBase::IPluginGame *game = plugins.managedGame(*gameName); + if (game == nullptr) { + reportError( + QObject::tr("Plugin to handle %1 no longer installed. An antivirus might have deleted files.") + .arg(*gameName)); + + return nullptr; + } + + auto gamePath = settings.game().directory(); + if (!gamePath || *gamePath == "") { + gamePath = game->gameDirectory().absolutePath(); + } + + QDir gameDir(*gamePath); + QFileInfo directoryInfo(gameDir.path()); + + if (directoryInfo.isSymLink()) { + reportError(QObject::tr("The configured path to the game directory (%1) appears to be a symbolic (or other) link. " + "This setup is incompatible with MO2's VFS and will not run correctly.").arg(*gamePath)); + } + + if (game->looksValid(gameDir)) { + return selectGame(settings, gameDir, game); + } + } + + //If we've made it this far and the instance is already configured for a game, something has gone wrong. + //Tell the user about it. + if (gameConfigured) { + const auto gamePath = settings.game().directory(); + + reportError( + QObject::tr("Could not use configuration settings for game \"%1\", path \"%2\".") + .arg(*gameName).arg(gamePath ? *gamePath : "")); + } + + SelectionDialog selection(gameConfigured ? + QObject::tr("Please select the installation of %1 to manage").arg(*gameName) : + QObject::tr("Please select the game to manage"), nullptr, QSize(32, 32)); + + for (IPluginGame *game : plugins.plugins<IPluginGame>()) { + //If a game is already configured, skip any plugins that are not for that game + if (gameConfigured && gameName->compare(game->gameName(), Qt::CaseInsensitive) != 0) + continue; + + //Only add games that are installed + if (game->isInstalled()) { + QString path = game->gameDirectory().absolutePath(); + selection.addChoice(game->gameIcon(), game->gameName(), path, QVariant::fromValue(game)); + } + } + + selection.addChoice(QString("Browse..."), QString(), QVariant::fromValue(static_cast<IPluginGame *>(nullptr))); + + while (selection.exec() != QDialog::Rejected) { + IPluginGame * game = selection.getChoiceData().value<IPluginGame *>(); + QString gamePath = selection.getChoiceDescription(); + QFileInfo directoryInfo(gamePath); + if (directoryInfo.isSymLink()) { + reportError(QObject::tr("The configured path to the game directory (%1) appears to be a symbolic (or other) link. " + "This setup is incompatible with MO2's VFS and will not run correctly.").arg(gamePath)); + } + if (game != nullptr) { + return selectGame(settings, game->gameDirectory(), game); + } + + gamePath = QFileDialog::getExistingDirectory(nullptr, gameConfigured ? + QObject::tr("Please select the installation of %1 to manage").arg(*gameName) : + QObject::tr("Please select the game to manage"), + QString(), QFileDialog::ShowDirsOnly); + + if (!gamePath.isEmpty()) { + QDir gameDir(gamePath); + QFileInfo directoryInfo(gamePath); + if (directoryInfo.isSymLink()) { + reportError(QObject::tr("The configured path to the game directory (%1) appears to be a symbolic (or other) link. " + "This setup is incompatible with MO2's VFS and will not run correctly.").arg(gamePath)); + } + QList<IPluginGame *> possibleGames; + for (IPluginGame * const game : plugins.plugins<IPluginGame>()) { + //If a game is already configured, skip any plugins that are not for that game + if (gameConfigured && gameName->compare(game->gameName(), Qt::CaseInsensitive) != 0) + continue; + + //Only try plugins that look valid for this directory + if (game->looksValid(gameDir)) { + possibleGames.append(game); + } + } + + if (possibleGames.count() > 1) { + SelectionDialog browseSelection(gameConfigured ? + QObject::tr("Please select the installation of %1 to manage").arg(*gameName) : + QObject::tr("Please select the game to manage"), + nullptr, QSize(32, 32)); + + for (IPluginGame *game : possibleGames) { + browseSelection.addChoice(game->gameIcon(), game->gameName(), gamePath, QVariant::fromValue(game)); + } + + if (browseSelection.exec() == QDialog::Accepted) { + return selectGame(settings, gameDir, browseSelection.getChoiceData().value<IPluginGame *>()); + } else { + reportError(gameConfigured ? + QObject::tr("Canceled finding %1 in \"%2\".").arg(*gameName).arg(gamePath) : + QObject::tr("Canceled finding game in \"%1\".").arg(gamePath)); + } + } else if(possibleGames.count() == 1) { + return selectGame(settings, gameDir, possibleGames[0]); + } else { + if (gameConfigured) { + reportError( + QObject::tr("%1 not identified in \"%2\". The directory is required to contain the game binary.") + .arg(*gameName).arg(gamePath)); + } else { + QString supportedGames; + + for (IPluginGame * const game : plugins.plugins<IPluginGame>()) { + supportedGames += "<li>" + game->gameName() + "</li>"; + } + + QString text = QObject::tr( + "No game identified in \"%1\". The directory is required to " + "contain the game binary.<br><br>" + "<b>These are the games supported by Mod Organizer:</b>" + "<ul>%2</ul>") + .arg(gamePath) + .arg(supportedGames); + + reportError(text); + } + } + } + } + + return nullptr; +} + QString InstanceManager::sanitizeInstanceName(const QString &name) const { diff --git a/src/instancemanager.h b/src/instancemanager.h index 649c2195..2331ebfd 100644 --- a/src/instancemanager.h +++ b/src/instancemanager.h @@ -24,18 +24,26 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include <QString> #include <QSettings> +namespace MOBase { class IPluginGame; } + +class Settings; +class PluginContainer; class InstanceManager { public: - static InstanceManager &instance(); - QString determineDataPath(); - void clearCurrentInstance(); - void overrideInstance(const QString& instanceName); + void overrideProfile(const QString& profileName); + + QString determineDataPath(); + QString determineProfile(const Settings &settings); + bool determineGameEdition(Settings& settings, MOBase::IPluginGame* game); + MOBase::IPluginGame* determineCurrentGame( + const QString& moPath, Settings& settings, const PluginContainer &plugins); + void clearCurrentInstance(); QString currentInstance() const; bool allowedToChangeInstance() const; @@ -69,4 +77,6 @@ private: bool m_Reset {false}; bool m_overrideInstance{false}; QString m_overrideInstanceName; + bool m_overrideProfile{false}; + QString m_overrideProfileName; }; diff --git a/src/main.cpp b/src/main.cpp index 49f3c6c0..5479d5a3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -119,188 +119,6 @@ void setExceptionHandlers() g_prevTerminateHandler = std::set_terminate(onTerminate); } -QString determineProfile(const cl::CommandLine& cl, const Settings &settings) -{ - auto selectedProfileName = settings.game().selectedProfileName(); - - if (cl.profile()) { - log::debug("profile overwritten on command line"); - selectedProfileName = *cl.profile(); - } - - if (!selectedProfileName) { - log::debug("no configured profile"); - selectedProfileName = "Default"; - } - - return *selectedProfileName; -} - -MOBase::IPluginGame *selectGame( - Settings &settings, QDir const &gamePath, MOBase::IPluginGame *game) -{ - settings.game().setName(game->gameName()); - - QString gameDir = gamePath.absolutePath(); - game->setGamePath(gameDir); - - settings.game().setDirectory(gameDir); - - return game; -} - - -MOBase::IPluginGame *determineCurrentGame( - QString const &moPath, Settings &settings, PluginContainer const &plugins) -{ - //Determine what game we are running where. Be very paranoid in case the - //user has done something odd. - - //If the game name has been set up, try to use that. - const auto gameName = settings.game().name(); - const bool gameConfigured = (gameName.has_value() && *gameName != ""); - - if (gameConfigured) { - MOBase::IPluginGame *game = plugins.managedGame(*gameName); - if (game == nullptr) { - reportError( - QObject::tr("Plugin to handle %1 no longer installed. An antivirus might have deleted files.") - .arg(*gameName)); - - return nullptr; - } - - auto gamePath = settings.game().directory(); - if (!gamePath || *gamePath == "") { - gamePath = game->gameDirectory().absolutePath(); - } - - QDir gameDir(*gamePath); - QFileInfo directoryInfo(gameDir.path()); - - if (directoryInfo.isSymLink()) { - reportError(QObject::tr("The configured path to the game directory (%1) appears to be a symbolic (or other) link. " - "This setup is incompatible with MO2's VFS and will not run correctly.").arg(*gamePath)); - } - - if (game->looksValid(gameDir)) { - return selectGame(settings, gameDir, game); - } - } - - //If we've made it this far and the instance is already configured for a game, something has gone wrong. - //Tell the user about it. - if (gameConfigured) { - const auto gamePath = settings.game().directory(); - - reportError( - QObject::tr("Could not use configuration settings for game \"%1\", path \"%2\".") - .arg(*gameName).arg(gamePath ? *gamePath : "")); - } - - SelectionDialog selection(gameConfigured ? - QObject::tr("Please select the installation of %1 to manage").arg(*gameName) : - QObject::tr("Please select the game to manage"), nullptr, QSize(32, 32)); - - for (IPluginGame *game : plugins.plugins<IPluginGame>()) { - //If a game is already configured, skip any plugins that are not for that game - if (gameConfigured && gameName->compare(game->gameName(), Qt::CaseInsensitive) != 0) - continue; - - //Only add games that are installed - if (game->isInstalled()) { - QString path = game->gameDirectory().absolutePath(); - selection.addChoice(game->gameIcon(), game->gameName(), path, QVariant::fromValue(game)); - } - } - - selection.addChoice(QString("Browse..."), QString(), QVariant::fromValue(static_cast<IPluginGame *>(nullptr))); - - while (selection.exec() != QDialog::Rejected) { - IPluginGame * game = selection.getChoiceData().value<IPluginGame *>(); - QString gamePath = selection.getChoiceDescription(); - QFileInfo directoryInfo(gamePath); - if (directoryInfo.isSymLink()) { - reportError(QObject::tr("The configured path to the game directory (%1) appears to be a symbolic (or other) link. " - "This setup is incompatible with MO2's VFS and will not run correctly.").arg(gamePath)); - } - if (game != nullptr) { - return selectGame(settings, game->gameDirectory(), game); - } - - gamePath = QFileDialog::getExistingDirectory(nullptr, gameConfigured ? - QObject::tr("Please select the installation of %1 to manage").arg(*gameName) : - QObject::tr("Please select the game to manage"), - QString(), QFileDialog::ShowDirsOnly); - - if (!gamePath.isEmpty()) { - QDir gameDir(gamePath); - QFileInfo directoryInfo(gamePath); - if (directoryInfo.isSymLink()) { - reportError(QObject::tr("The configured path to the game directory (%1) appears to be a symbolic (or other) link. " - "This setup is incompatible with MO2's VFS and will not run correctly.").arg(gamePath)); - } - QList<IPluginGame *> possibleGames; - for (IPluginGame * const game : plugins.plugins<IPluginGame>()) { - //If a game is already configured, skip any plugins that are not for that game - if (gameConfigured && gameName->compare(game->gameName(), Qt::CaseInsensitive) != 0) - continue; - - //Only try plugins that look valid for this directory - if (game->looksValid(gameDir)) { - possibleGames.append(game); - } - } - - if (possibleGames.count() > 1) { - SelectionDialog browseSelection(gameConfigured ? - QObject::tr("Please select the installation of %1 to manage").arg(*gameName) : - QObject::tr("Please select the game to manage"), - nullptr, QSize(32, 32)); - - for (IPluginGame *game : possibleGames) { - browseSelection.addChoice(game->gameIcon(), game->gameName(), gamePath, QVariant::fromValue(game)); - } - - if (browseSelection.exec() == QDialog::Accepted) { - return selectGame(settings, gameDir, browseSelection.getChoiceData().value<IPluginGame *>()); - } else { - reportError(gameConfigured ? - QObject::tr("Canceled finding %1 in \"%2\".").arg(*gameName).arg(gamePath) : - QObject::tr("Canceled finding game in \"%1\".").arg(gamePath)); - } - } else if(possibleGames.count() == 1) { - return selectGame(settings, gameDir, possibleGames[0]); - } else { - if (gameConfigured) { - reportError( - QObject::tr("%1 not identified in \"%2\". The directory is required to contain the game binary.") - .arg(*gameName).arg(gamePath)); - } else { - QString supportedGames; - - for (IPluginGame * const game : plugins.plugins<IPluginGame>()) { - supportedGames += "<li>" + game->gameName() + "</li>"; - } - - QString text = QObject::tr( - "No game identified in \"%1\". The directory is required to " - "contain the game binary.<br><br>" - "<b>These are the games supported by Mod Organizer:</b>" - "<ul>%2</ul>") - .arg(gamePath) - .arg(supportedGames); - - reportError(text); - } - } - } - } - - return nullptr; -} - - // This adds the `dlls` directory to the path so the dlls can be found. How // MO is able to find dlls in there is a bit convoluted: // @@ -388,45 +206,6 @@ std::unique_ptr<QSplashScreen> createSplash( return splash; } -bool determineGameEdition(Settings& settings, IPluginGame* game) -{ - QString edition; - - if (auto v=settings.game().edition()) { - edition = *v; - } else { - QStringList editions = game->gameVariants(); - if (editions.size() < 2) { - edition = ""; - return true; - } - - SelectionDialog selection( - QObject::tr("Please select the game edition you have (MO can't " - "start the game correctly if this is set " - "incorrectly!)"), - nullptr); - - selection.setWindowFlag(Qt::WindowStaysOnTopHint, true); - - int index = 0; - for (const QString &edition : editions) { - selection.addChoice(edition, "", index++); - } - - if (selection.exec() == QDialog::Rejected) { - return false; - } - - edition = selection.getChoiceString(); - settings.game().setEdition(edition); - } - - game->setGameVariant(edition); - - return true; -} - std::optional<int> handleCommandLine( const cl::CommandLine& cl, OrganizerCore& organizer) { @@ -542,7 +321,8 @@ int runApplication( pluginContainer = std::make_unique<PluginContainer>(&organizer); pluginContainer->loadPlugins(); - MOBase::IPluginGame* game = determineCurrentGame( + MOBase::IPluginGame* game = InstanceManager::instance() + .determineCurrentGame( application.applicationDirPath(), settings, *pluginContainer); if (game == nullptr) { @@ -563,7 +343,7 @@ int runApplication( organizer.setManagedGame(game); organizer.createDefaultProfile(); - if (!determineGameEdition(settings, game)) { + if (!InstanceManager::instance().determineGameEdition(settings, game)) { return 1; } @@ -578,7 +358,13 @@ int runApplication( organizer.updateExecutablesList(); organizer.updateModInfoFromDisc(); - QString selectedProfileName = determineProfile(cl, settings); + if (cl.profile()) { + InstanceManager::instance().overrideProfile(*cl.profile()); + } + + QString selectedProfileName = InstanceManager::instance() + .determineProfile(settings); + organizer.setCurrentProfile(selectedProfileName); if (auto r=handleCommandLine(cl, organizer)) { |
