summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp263
1 files changed, 193 insertions, 70 deletions
diff --git a/src/main.cpp b/src/main.cpp
index fd5a47c9..2a5a3e81 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -27,6 +27,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "instancemanager.h"
#include "instancemanagerdialog.h"
#include "createinstancedialog.h"
+#include "createinstancedialogpages.h"
#include "organizercore.h"
#include "env.h"
#include "envmodule.h"
@@ -273,9 +274,166 @@ std::optional<int> handleCommandLine(
void openInstanceManager(PluginContainer& pc, QWidget* parent);
+std::optional<Instance> selectInstance()
+{
+ NexusInterface ni(nullptr);
+
+ PluginContainer pc(nullptr);
+ pc.loadPlugins();
+
+ InstanceManagerDialog dlg(pc);
+ dlg.setRestartOnSelect(false);
+
+ dlg.show();
+ dlg.activateWindow();
+ dlg.raise();
+
+ if (dlg.exec() != QDialog::Accepted) {
+ return {};
+ }
+
+ return InstanceManager::instance().currentInstance();
+}
+
+enum class SetupInstanceResults
+{
+ Ok,
+ TryAgain,
+ SelectAnother,
+ Exit
+};
+
+
+void criticalOnTop(const QString& message)
+{
+ QMessageBox mb(QMessageBox::Critical, QObject::tr("Mod Organizer"), message);
+
+ mb.show();
+ mb.activateWindow();
+ mb.raise();
+ mb.exec();
+}
+
+
+SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc)
+{
+ const auto setupResult = instance.setup(pc);
+
+ switch (setupResult)
+ {
+ case Instance::SetupResults::Ok:
+ {
+ return SetupInstanceResults::Ok;
+ }
+
+ case Instance::SetupResults::BadIni:
+ {
+ criticalOnTop(
+ QObject::tr("Cannot open instance '%1', failed to read INI file %2.")
+ .arg(instance.name()).arg(instance.iniPath()));
+
+ return SetupInstanceResults::SelectAnother;
+ }
+
+ case Instance::SetupResults::IniMissingGame:
+ {
+ criticalOnTop(
+ QObject::tr(
+ "Cannot open instance '%1', the managed game was not found in the INI "
+ "file %2. Select the game managed by this instance.")
+ .arg(instance.name()).arg(instance.iniPath()));
+
+ CreateInstanceDialog dlg(pc, nullptr);
+ dlg.setSinglePage<cid::GamePage>();
+
+ dlg.show();
+ dlg.activateWindow();
+ dlg.raise();
+
+ if (dlg.exec() != QDialog::Accepted) {
+ return SetupInstanceResults::Exit;
+ }
+
+ instance.setGame(
+ dlg.creationInfo().game->gameName(),
+ dlg.creationInfo().game->gameDirectory().absolutePath());
+
+ return SetupInstanceResults::TryAgain;
+ }
+
+ case Instance::SetupResults::PluginGone:
+ {
+ criticalOnTop(
+ QObject::tr(
+ "Cannot open instance '%1', the game plugin '%2' doesn't exist. It "
+ "may have been deleted by an antivirus. Select another instance.")
+ .arg(instance.name()).arg(instance.gameName()));
+
+ return SetupInstanceResults::SelectAnother;
+ }
+
+ case Instance::SetupResults::GameGone:
+ {
+ criticalOnTop(
+ QObject::tr(
+ "Cannot open instance '%1', the game directory '%2' doesn't exist or "
+ "the game plugin '%3' doesn't recognize it. Select the game managed "
+ "by this instance.")
+ .arg(instance.name())
+ .arg(instance.gameDirectory())
+ .arg(instance.gameName()));
+
+ CreateInstanceDialog dlg(pc, nullptr);
+ dlg.setSinglePage<cid::GamePage>();
+
+ dlg.show();
+ dlg.activateWindow();
+ dlg.raise();
+
+ if (dlg.exec() != QDialog::Accepted) {
+ return SetupInstanceResults::Exit;
+ }
+
+ instance.setGame(
+ dlg.creationInfo().game->gameName(),
+ dlg.creationInfo().game->gameDirectory().absolutePath());
+
+ return SetupInstanceResults::TryAgain;
+ }
+
+ case Instance::SetupResults::MissingVariant:
+ {
+ CreateInstanceDialog dlg(pc, nullptr);
+
+ dlg.getPage<cid::GamePage>()->select(
+ instance.gamePlugin(), instance.gameDirectory());
+
+ dlg.setSinglePage<cid::VariantsPage>();
+
+ dlg.show();
+ dlg.activateWindow();
+ dlg.raise();
+
+ if (dlg.exec() != QDialog::Accepted) {
+ return SetupInstanceResults::Exit;
+ }
+
+ instance.setVariant(dlg.creationInfo().gameVariant);
+
+ return SetupInstanceResults::TryAgain;
+ }
+
+ default:
+ {
+ return SetupInstanceResults::Exit;
+ }
+ }
+}
+
int runApplication(
MOApplication &application, const cl::CommandLine& cl,
- SingleInstance &instance, const QString &dataPath)
+ SingleInstance &instance, const QString &dataPath,
+ Instance& currentInstance)
{
TimeThis tt("runApplication() to exec()");
@@ -345,57 +503,48 @@ int runApplication(
pluginContainer = std::make_unique<PluginContainer>(&organizer);
pluginContainer->loadPlugins();
- MOBase::IPluginGame* game = InstanceManager::instance()
- .determineCurrentGame(
- application.applicationDirPath(), settings, *pluginContainer);
-
- if (game == nullptr) {
- InstanceManager &instance = InstanceManager::instance();
- QString instanceName = instance.currentInstance();
+ for (;;)
+ {
+ const auto setupResult = setupInstance(currentInstance, *pluginContainer);
- if (instanceName.compare("Portable", Qt::CaseInsensitive) != 0) {
- instance.clearCurrentInstance();
+ if (setupResult == SetupInstanceResults::Ok) {
+ break;
+ } else if (setupResult == SetupInstanceResults::TryAgain) {
+ continue;
+ } else if (setupResult == SetupInstanceResults::SelectAnother) {
+ InstanceManager::instance().clearCurrentInstance();
return RestartExitCode;
+ } else {
+ return 1;
}
-
- return 1;
}
- checkPathsForSanity(*game, settings);
-
+ checkPathsForSanity(*currentInstance.gamePlugin(), settings);
- organizer.setManagedGame(game);
+ organizer.setManagedGame(currentInstance.gamePlugin());
organizer.createDefaultProfile();
- if (!InstanceManager::instance().determineGameEdition(settings, game)) {
- return 1;
- }
-
log::info(
"using game plugin '{}' ('{}', variant {}, steam id '{}') at {}",
- game->gameName(), game->gameShortName(),
+ currentInstance.gamePlugin()->gameName(),
+ currentInstance.gamePlugin()->gameShortName(),
(settings.game().edition().value_or("").isEmpty() ?
"(none)" : *settings.game().edition()),
- game->steamAPPId(), game->gameDirectory().absolutePath());
+ currentInstance.gamePlugin()->steamAPPId(),
+ currentInstance.gamePlugin()->gameDirectory().absolutePath());
+
CategoryFactory::instance().loadCategories();
organizer.updateExecutablesList();
organizer.updateModInfoFromDisc();
- if (cl.profile()) {
- InstanceManager::instance().overrideProfile(*cl.profile());
- }
-
- QString selectedProfileName = InstanceManager::instance()
- .determineProfile(settings);
-
- organizer.setCurrentProfile(selectedProfileName);
+ organizer.setCurrentProfile(currentInstance.profileName());
if (auto r=handleCommandLine(cl, organizer)) {
return *r;
}
- auto splash = createSplash(settings, dataPath, game);
+ auto splash = createSplash(settings, dataPath, currentInstance.gamePlugin());
QString apiKey;
if (GlobalSettings::nexusApiKey(apiKey)) {
@@ -438,11 +587,6 @@ int runApplication(
tt.stop();
- QTimer::singleShot(std::chrono::milliseconds(1), [&]
- {
- openInstanceManager(*pluginContainer, &mainWindow);
- });
-
res = application.exec();
mainWindow.close();
@@ -488,28 +632,6 @@ void resetForRestart(cl::CommandLine& cl)
cl.clear();
}
-QString determineDataPath(const cl::CommandLine& cl)
-{
- try
- {
- InstanceManager& instanceManager = InstanceManager::instance();
-
- if (cl.instance())
- instanceManager.overrideInstance(*cl.instance());
-
- return instanceManager.determineDataPath();
- }
- catch (const std::exception &e)
- {
- if (strcmp(e.what(),"Canceled")) {
- QMessageBox::critical(nullptr, QObject::tr("Failed to set up instance"), e.what());
- }
-
- return {};
- }
-}
-
-
int doOneRun(
cl::CommandLine& cl, MOApplication& application, SingleInstance& instance)
{
@@ -518,24 +640,25 @@ int doOneRun(
// resets things when MO is "restarted"
resetForRestart(cl);
+ if (cl.instance())
+ InstanceManager::instance().overrideInstance(*cl.instance());
- //{
- // NexusInterface ni(nullptr);
- //
- // PluginContainer pc(nullptr);
- // pc.loadPlugins();
- //
- // CreateInstanceDialog dlg(pc, nullptr);
- // dlg.exec();
- //}
+ if (cl.profile()) {
+ InstanceManager::instance().overrideProfile(*cl.profile());
+ }
+ auto currentInstance = InstanceManager::instance().currentInstance();
- const QString dataPath = determineDataPath(cl);
- if (dataPath.isEmpty()) {
- return 1;
+ if (!currentInstance)
+ {
+ currentInstance = selectInstance();
+ if (!currentInstance)
+ return 1;
}
+ const QString dataPath = currentInstance->directory().path();
application.setProperty("dataPath", dataPath);
+
setExceptionHandlers();
if (!setLogDirectory(dataPath)) {
@@ -548,7 +671,7 @@ int doOneRun(
tt.stop();
- return runApplication(application, cl, instance, dataPath);
+ return runApplication(application, cl, instance, dataPath, *currentInstance);
}
int main(int argc, char *argv[])