summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanninOne <seppleviathan@gmx.de>2015-12-06 13:24:19 +0100
committerTanninOne <seppleviathan@gmx.de>2015-12-06 13:24:19 +0100
commite31cf3f2fd99073d22fdddfdb106a59858e14299 (patch)
treede7bbfd6de6afe830f8ec1a624876cf174aab376
parent688e149c96c29d8249c9db416f5773cfc7baad6d (diff)
parent3670ab2528ff6a129af4e4aeaf50574e2c9080ba (diff)
Merge pull request #372 from ThosRTanner/issue/356
Refactor gameinfo & 'shared' library to use game plugins (9 of 17)
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/SConscript6
-rw-r--r--src/browserdialog.cpp6
-rw-r--r--src/categories.cpp4
-rw-r--r--src/directoryrefresher.cpp9
-rw-r--r--src/downloadmanager.cpp14
-rw-r--r--src/downloadmanager.h6
-rw-r--r--src/executableslist.cpp10
-rw-r--r--src/executableslist.h7
-rw-r--r--src/gameinfoimpl.cpp54
-rw-r--r--src/gameinfoimpl.h39
-rw-r--r--src/installationmanager.cpp7
-rw-r--r--src/loadmechanism.cpp19
-rw-r--r--src/main.cpp206
-rw-r--r--src/mainwindow.cpp100
-rw-r--r--src/mainwindow.h4
-rw-r--r--src/modinfo.cpp37
-rw-r--r--src/modinfo.h7
-rw-r--r--src/modinfodialog.cpp14
-rw-r--r--src/modinfoforeign.cpp8
-rw-r--r--src/modlist.cpp5
-rw-r--r--src/nexusinterface.cpp118
-rw-r--r--src/nexusinterface.h164
-rw-r--r--src/nxmaccessmanager.cpp32
-rw-r--r--src/nxmaccessmanager.h3
-rw-r--r--src/organizer.pro12
-rw-r--r--src/organizercore.cpp77
-rw-r--r--src/organizercore.h19
-rw-r--r--src/organizerproxy.cpp23
-rw-r--r--src/organizerproxy.h10
-rw-r--r--src/pluginlist.cpp12
-rw-r--r--src/pluginlist.h12
-rw-r--r--src/profile.cpp38
-rw-r--r--src/profile.h24
-rw-r--r--src/profilesdialog.cpp12
-rw-r--r--src/profilesdialog.h4
-rw-r--r--src/savegame.cpp81
-rw-r--r--src/savegame.h20
-rw-r--r--src/savegamegamebryo.cpp336
-rw-r--r--src/savegamegamebyro.h42
-rw-r--r--src/selfupdater.cpp48
-rw-r--r--src/selfupdater.h5
-rw-r--r--src/settings.cpp16
-rw-r--r--src/settings.h4
-rw-r--r--src/settingsdialog.cpp14
-rw-r--r--src/shared/fallout3info.cpp43
-rw-r--r--src/shared/fallout3info.h20
-rw-r--r--src/shared/falloutnvinfo.cpp50
-rw-r--r--src/shared/falloutnvinfo.h20
-rw-r--r--src/shared/gameinfo.cpp52
-rw-r--r--src/shared/gameinfo.h70
-rw-r--r--src/shared/oblivioninfo.cpp52
-rw-r--r--src/shared/oblivioninfo.h20
-rw-r--r--src/shared/skyriminfo.cpp66
-rw-r--r--src/shared/skyriminfo.h25
-rw-r--r--src/spawn.cpp8
-rw-r--r--src/syncoverwritedialog.cpp3
-rw-r--r--src/transfersavesdialog.cpp11
-rw-r--r--src/transfersavesdialog.h10
59 files changed, 836 insertions, 1304 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 86d1e4c8..3c786868 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -66,7 +66,6 @@ SET(organizer_SRCS
moapplication.cpp
profileinputdialog.cpp
icondelegate.cpp
- gameinfoimpl.cpp
csvbuilder.cpp
savetextasdialog.cpp
qtgroupingproxy.cpp
@@ -160,7 +159,6 @@ SET(organizer_HDRS
moapplication.h
profileinputdialog.h
icondelegate.h
- gameinfoimpl.h
csvbuilder.h
savetextasdialog.h
qtgroupingproxy.h
diff --git a/src/SConscript b/src/SConscript
index 194df9aa..787561b8 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -96,6 +96,12 @@ env['CPPPATH'] += [
'${BOOSTPATH}',
]
+#########################FUDGE###############################
+env['CPPPATH'] += [
+ '../plugins/gameGamebryo',
+ ]
+#############################################################
+
env.AppendUnique(CPPDEFINES = [
'_UNICODE',
'_CRT_SECURE_NO_WARNINGS',
diff --git a/src/browserdialog.cpp b/src/browserdialog.cpp
index c382c112..bbdf95c5 100644
--- a/src/browserdialog.cpp
+++ b/src/browserdialog.cpp
@@ -18,18 +18,16 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "browserdialog.h"
+
#include "ui_browserdialog.h"
#include "browserview.h"
-
#include "messagedialog.h"
#include "report.h"
#include "persistentcookiejar.h"
-
#include "json.h"
-
#include <utility.h>
-#include <gameinfo.h>
#include "settings.h"
+
#include <QNetworkCookieJar>
#include <QNetworkCookie>
#include <QMenu>
diff --git a/src/categories.cpp b/src/categories.cpp
index 400cc74b..59291a49 100644
--- a/src/categories.cpp
+++ b/src/categories.cpp
@@ -18,9 +18,10 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "categories.h"
+
#include <utility.h>
#include <report.h>
-#include <gameinfo.h>
+
#include <QObject>
#include <QFile>
#include <QDir>
@@ -29,7 +30,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
using namespace MOBase;
-using namespace MOShared;
CategoryFactory* CategoryFactory::s_Instance = nullptr;
diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp
index c253f384..f50a717e 100644
--- a/src/directoryrefresher.cpp
+++ b/src/directoryrefresher.cpp
@@ -18,10 +18,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "directoryrefresher.h"
+
+#include "iplugingame.h"
#include "utility.h"
#include "report.h"
#include "modinfo.h"
-#include <gameinfo.h>
+
+#include <QApplication>
#include <QDir>
#include <QString>
@@ -141,7 +144,9 @@ void DirectoryRefresher::refresh()
m_DirectoryStructure = new DirectoryEntry(L"data", nullptr, 0);
- std::wstring dataDirectory = GameInfo::instance().getGameDirectory() + L"\\data";
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
+
+ std::wstring dataDirectory = QDir::toNativeSeparators(game->dataDirectory().absolutePath()).toStdWString();
m_DirectoryStructure->addFromOrigin(L"data", dataDirectory, 0);
// TODO what was the point of having the priority in this tuple? the list is already sorted by priority
diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp
index 0cc45183..70caaf3e 100644
--- a/src/downloadmanager.cpp
+++ b/src/downloadmanager.cpp
@@ -18,10 +18,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "downloadmanager.h"
+
#include "nxmurl.h"
#include "nexusinterface.h"
#include "nxmaccessmanager.h"
-#include <gameinfo.h>
+#include "iplugingame.h"
#include <nxmurl.h>
#include <taskprogressmanager.h>
#include "utility.h"
@@ -30,6 +31,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "bbcode.h"
#include <utility.h>
#include <report.h>
+
#include <QTimer>
#include <QFileInfo>
#include <QRegExp>
@@ -38,6 +40,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QMessageBox>
#include <QCoreApplication>
#include <QTextDocument>
+
#include <boost/bind.hpp>
#include <regex>
@@ -448,7 +451,7 @@ void DownloadManager::addNXMDownload(const QString &url)
{
NXMUrl nxmInfo(url);
- QString managedGame = ToQString(MOShared::GameInfo::instance().getGameShortName());
+ QString managedGame = m_ManagedGame->getGameShortName();
qDebug("add nxm download: %s", qPrintable(url));
if (nxmInfo.game().compare(managedGame, Qt::CaseInsensitive) != 0) {
qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(managedGame), qPrintable(nxmInfo.game()));
@@ -1242,13 +1245,14 @@ int DownloadManager::startDownloadURLs(const QStringList &urls)
return m_ActiveDownloads.size() - 1;
}
+/* This doesn't appear to be used by anything
int DownloadManager::startDownloadNexusFile(int modID, int fileID)
{
int newID = m_ActiveDownloads.size();
addNXMDownload(QString("nxm://%1/mods/%2/files/%3").arg(ToQString(MOShared::GameInfo::instance().getGameName())).arg(modID).arg(fileID));
return newID;
}
-
+*/
QString DownloadManager::downloadPath(int id)
{
return getFilePath(id);
@@ -1468,3 +1472,7 @@ void DownloadManager::directoryChanged(const QString&)
refreshList();
}
+void DownloadManager::managedGameChanged(MOBase::IPluginGame const *managedGame)
+{
+ m_ManagedGame = managedGame;
+}
diff --git a/src/downloadmanager.h b/src/downloadmanager.h
index 57bd592d..54db4648 100644
--- a/src/downloadmanager.h
+++ b/src/downloadmanager.h
@@ -35,6 +35,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QFileSystemWatcher>
#include <QSettings>
+namespace MOBase { class IPluginGame; }
class NexusInterface;
@@ -328,7 +329,9 @@ public:
virtual int startDownloadURLs(const QStringList &urls);
+ /* This doesn't appear to be used anywhere
virtual int startDownloadNexusFile(int modID, int fileID);
+ */
virtual QString downloadPath(int id);
/**
@@ -414,6 +417,8 @@ public slots:
void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString);
+ void managedGameChanged(MOBase::IPluginGame const *gamePlugin);
+
private slots:
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
@@ -501,6 +506,7 @@ private:
QRegExp m_DateExpression;
+ MOBase::IPluginGame const *m_ManagedGame;
};
diff --git a/src/executableslist.cpp b/src/executableslist.cpp
index 12e3d7aa..a4511ade 100644
--- a/src/executableslist.cpp
+++ b/src/executableslist.cpp
@@ -18,16 +18,18 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "executableslist.h"
-#include <gameinfo.h>
+
+#include "iplugingame.h"
+#include "utility.h"
+
#include <QFileInfo>
#include <QDir>
#include <QDebug>
-#include "utility.h"
+
#include <algorithm>
using namespace MOBase;
-using namespace MOShared;
ExecutablesList::ExecutablesList()
@@ -38,7 +40,7 @@ ExecutablesList::~ExecutablesList()
{
}
-void ExecutablesList::init(IPluginGame *game)
+void ExecutablesList::init(IPluginGame const *game)
{
Q_ASSERT(game != nullptr);
m_Executables.clear();
diff --git a/src/executableslist.h b/src/executableslist.h
index b4054bcc..3d5ba0ed 100644
--- a/src/executableslist.h
+++ b/src/executableslist.h
@@ -20,13 +20,14 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef EXECUTABLESLIST_H
#define EXECUTABLESLIST_H
+#include "executableinfo.h"
#include <vector>
+
#include <QFileInfo>
#include <QMetaType>
-#include <gameinfo.h>
-#include <iplugingame.h>
+namespace MOBase { class IPluginGame; }
/*!
* @brief Information about an executable
@@ -78,7 +79,7 @@ public:
/**
* @brief initialise the list with the executables preconfigured for this game
**/
- void init(MOBase::IPluginGame *game);
+ void init(MOBase::IPluginGame const *game);
/**
* @brief find an executable by its name
diff --git a/src/gameinfoimpl.cpp b/src/gameinfoimpl.cpp
deleted file mode 100644
index 025ce4e6..00000000
--- a/src/gameinfoimpl.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "gameinfoimpl.h"
-#include <gameinfo.h>
-#include <utility.h>
-#include <QDir>
-
-
-using namespace MOBase;
-using namespace MOShared;
-
-
-GameInfoImpl::GameInfoImpl()
-{
-}
-
-IGameInfo::Type GameInfoImpl::type() const
-{
- switch (GameInfo::instance().getType()) {
- case GameInfo::TYPE_OBLIVION: return IGameInfo::TYPE_OBLIVION;
- case GameInfo::TYPE_FALLOUT3: return IGameInfo::TYPE_FALLOUT3;
- case GameInfo::TYPE_FALLOUTNV: return IGameInfo::TYPE_FALLOUTNV;
- case GameInfo::TYPE_SKYRIM: return IGameInfo::TYPE_SKYRIM;
- default: throw MyException(QObject::tr("invalid game type %1").arg(GameInfo::instance().getType()));
- }
-}
-
-
-QString GameInfoImpl::path() const
-{
- return QDir::fromNativeSeparators(ToQString(GameInfo::instance().getGameDirectory()));
-}
-
-QString GameInfoImpl::binaryName() const
-{
- return ToQString(GameInfo::instance().getBinaryName());
-}
diff --git a/src/gameinfoimpl.h b/src/gameinfoimpl.h
deleted file mode 100644
index 3ed7be6b..00000000
--- a/src/gameinfoimpl.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef GAMEINFOIMPL_H
-#define GAMEINFOIMPL_H
-
-
-#include <igameinfo.h>
-#include <QString>
-
-
-class GameInfoImpl : public MOBase::IGameInfo
-{
-public:
- GameInfoImpl();
-
- virtual Type type() const;
- virtual QString path() const;
- virtual QString binaryName() const;
-
-};
-
-#endif // GAMEINFOIMPL_H
diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp
index 9fb9bdbb..7b1f3f37 100644
--- a/src/installationmanager.cpp
+++ b/src/installationmanager.cpp
@@ -18,6 +18,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "installationmanager.h"
+
#include "utility.h"
#include "report.h"
#include "categories.h"
@@ -32,9 +33,9 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "modinfo.h"
#include <scopeguard.h>
#include <installationtester.h>
-#include <gameinfo.h>
#include <utility.h>
#include <scopeguard.h>
+
#include <QFileInfo>
#include <QLibrary>
#include <QInputDialog>
@@ -42,11 +43,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QDir>
#include <QMessageBox>
#include <QSettings>
-#include <Shellapi.h>
#include <QPushButton>
#include <QApplication>
#include <QDateTime>
#include <QDirIterator>
+
+#include <Shellapi.h>
+
#include <boost/assign.hpp>
#include <boost/scoped_ptr.hpp>
diff --git a/src/loadmechanism.cpp b/src/loadmechanism.cpp
index 4d06bea9..99fce3ba 100644
--- a/src/loadmechanism.cpp
+++ b/src/loadmechanism.cpp
@@ -64,7 +64,8 @@ void LoadMechanism::removeHintFile(QDir &targetDirectory)
bool LoadMechanism::isDirectLoadingSupported()
{
- IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
+ //FIXME: Seriously? isn't there a 'do i need steam' thing?
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
if (game->gameName().compare("oblivion", Qt::CaseInsensitive) == 0) {
// oblivion can be loaded directly if it's not the steam variant
return !game->gameDirectory().exists("steam_api.dll");
@@ -76,13 +77,11 @@ bool LoadMechanism::isDirectLoadingSupported()
bool LoadMechanism::isScriptExtenderSupported()
{
- IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
ScriptExtender *extender = game->feature<ScriptExtender>();
// test if there even is an extender for the managed game and if so whether it's installed
- return (extender != nullptr)
- && (game->gameDirectory().exists(extender->name() + "_loader.exe")
- || game->gameDirectory().exists(extender->name() + "_steam_loader.dll"));
+ return extender != nullptr && extender->isInstalled();
}
bool LoadMechanism::isProxyDLLSupported()
@@ -92,7 +91,7 @@ bool LoadMechanism::isProxyDLLSupported()
// plus: the proxy dll hasn't been working for at least the whole 1.12.x versions of MO and
// noone reported it so why maintain an unused feature?
return false;
-/* IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
+/* IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
return game->gameDirectory().exists(QString::fromStdWString(AppConfig::proxyDLLTarget()));*/
}
@@ -124,7 +123,7 @@ bool LoadMechanism::hashIdentical(const QString &fileNameLHS, const QString &fil
void LoadMechanism::deactivateScriptExtender()
{
try {
- IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
ScriptExtender *extender = game->feature<ScriptExtender>();
if (extender == nullptr) {
throw MyException(QObject::tr("game doesn't support a script extender"));
@@ -150,7 +149,7 @@ void LoadMechanism::deactivateScriptExtender()
void LoadMechanism::deactivateProxyDLL()
{
try {
- IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
QString targetPath = game->gameDirectory().absoluteFilePath(QString::fromStdWString(AppConfig::proxyDLLTarget()));
@@ -179,7 +178,7 @@ void LoadMechanism::deactivateProxyDLL()
void LoadMechanism::activateScriptExtender()
{
try {
- IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
ScriptExtender *extender = game->feature<ScriptExtender>();
if (extender == nullptr) {
throw MyException(QObject::tr("game doesn't support a script extender"));
@@ -219,7 +218,7 @@ void LoadMechanism::activateScriptExtender()
void LoadMechanism::activateProxyDLL()
{
try {
- IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
QString targetPath = game->gameDirectory().absoluteFilePath(QString::fromStdWString(AppConfig::proxyDLLTarget()));
diff --git a/src/main.cpp b/src/main.cpp
index 773bfc16..353e7202 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -26,21 +26,16 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <DbgHelp.h>
-#include <cstdarg>
+
#include <inject.h>
#include <appconfig.h>
#include <utility.h>
#include <scopeguard.h>
-#include <stdexcept>
#include "mainwindow.h"
#include <report.h>
#include "modlist.h"
#include "profile.h"
#include "gameinfo.h"
-#include "fallout3info.h"
-#include "falloutnvinfo.h"
-#include "oblivioninfo.h"
-#include "skyriminfo.h"
#include "spawn.h"
#include "executableslist.h"
#include "singleinstance.h"
@@ -51,11 +46,9 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "moapplication.h"
#include "tutorialmanager.h"
#include "nxmaccessmanager.h"
-#include <iostream>
-#include <ShellAPI.h>
#include <eh.h>
#include <windows_error.h>
-#include <boost/scoped_array.hpp>
+
#include <QApplication>
#include <QPushButton>
#include <QListWidget>
@@ -77,6 +70,14 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QLibraryInfo>
#include <QSslSocket>
+#include <boost/scoped_array.hpp>
+
+#include <ShellAPI.h>
+
+#include <cstdarg>
+#include <iostream>
+#include <stdexcept>
+
#pragma comment(linker, "/manifestDependency:\"name='dlls' processorArchitecture='x86' version='1.0.0.0' type='win32' \"")
@@ -86,7 +87,8 @@ using namespace MOShared;
bool createAndMakeWritable(const std::wstring &subPath)
{
- QString fullPath = qApp->property("dataPath").toString() + "/" + QString::fromStdWString(subPath);
+ QString const dataPath = qApp->property("dataPath").toString();
+ QString fullPath = dataPath + "/" + QString::fromStdWString(subPath);
if (!QDir(fullPath).exists()) {
QDir().mkdir(fullPath);
@@ -100,7 +102,7 @@ bool createAndMakeWritable(const std::wstring &subPath)
"will be made writable for the current user account). You will be asked to run "
"\"helper.exe\" with administrative rights."),
QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Yes) {
- if (!Helper::init(GameInfo::instance().getOrganizerDirectory())) {
+ if (!Helper::init(dataPath.toStdWString())) {
return false;
}
} else {
@@ -329,6 +331,124 @@ QString determineProfile(QStringList &arguments, const QSettings &settings)
return selectedProfileName;
}
+MOBase::IPluginGame *selectGame(QSettings &settings, QDir const &gamePath, MOBase::IPluginGame *game)
+{
+ settings.setValue("gameName", game->gameName());
+ //Sadly, hookdll needs gamePath in order to run. So following code block is
+ //commented out
+ /*if (gamePath == game->gameDirectory()) {
+ settings.remove("gamePath");
+ } else*/ {
+ QString gameDir = gamePath.absolutePath();
+ game->setGamePath(gameDir);
+ settings.setValue("gamePath", QDir::toNativeSeparators(gameDir).toUtf8().constData());
+ }
+ return game; //Woot
+}
+
+
+MOBase::IPluginGame *determineCurrentGame(QString const &moPath, QSettings &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, use that.
+ QString gameName = settings.value("gameName", "").toString();
+ if (!gameName.isEmpty()) {
+ MOBase::IPluginGame *game = plugins.managedGame(gameName);
+ if (game == nullptr) {
+ reportError(QObject::tr("Plugin to handle %1 no longer installed").arg(gameName));
+ return nullptr;
+ }
+ QString gamePath = QString::fromUtf8(settings.value("gamePath", "").toByteArray());
+ if (gamePath == "") {
+ gamePath = game->gameDirectory().absolutePath();
+ }
+ QDir gameDir(gamePath);
+ if (game->looksValid(gameDir)) {
+ return selectGame(settings, gameDir, game);
+ }
+ }
+
+ //gameName wasn't set, or otherwise can't be found. Try looking through all
+ //the plugins using the gamePath
+ QString gamePath = QString::fromUtf8(settings.value("gamePath", "").toByteArray());
+ if (!gamePath.isEmpty()) {
+ QDir gameDir(gamePath);
+ //Look to see if one of the installed games binary file exists in the current
+ //game directory.
+ for (IPluginGame * const game : plugins.plugins<IPluginGame>()) {
+ if (game->looksValid(gameDir)) {
+ return selectGame(settings, gameDir, game);
+ }
+ }
+ }
+
+ //OK, we are in a new setup or existing info is useless.
+ //See if MO has been installed inside a game directory
+ for (IPluginGame * const game : plugins.plugins<IPluginGame>()) {
+ if (game->isInstalled() && moPath.startsWith(game->gameDirectory().absolutePath())) {
+ //Found it.
+ return selectGame(settings, game->gameDirectory(), game);
+ }
+ }
+
+ //Try walking up the directory tree to see if MO has been installed inside a game
+ {
+ QDir gameDir(moPath);
+ do {
+ //Look to see if one of the installed games binary file exists in the current
+ //directory.
+ for (IPluginGame * const game : plugins.plugins<IPluginGame>()) {
+ if (game->looksValid(gameDir)) {
+ return selectGame(settings, gameDir, game);
+ }
+ }
+ //OK, chop off the last directory and try again
+ } while (gameDir.cdUp());
+ }
+
+ //Then try a selection dialogue.
+ if (!gamePath.isEmpty() || !gameName.isEmpty()) {
+ reportError(QObject::tr("Could not use configuration settings for game \"%1\", path \"%2\".").
+ arg(gameName).arg(gamePath));
+ }
+
+ SelectionDialog selection(QObject::tr("Please select the game to manage"), nullptr, QSize(32, 32));
+
+ for (IPluginGame *game : plugins.plugins<IPluginGame>()) {
+ 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 *>();
+ if (game != nullptr) {
+ return selectGame(settings, game->gameDirectory(), game);
+ }
+
+ gamePath = QFileDialog::getExistingDirectory(
+ nullptr, QObject::tr("Please select the game to manage"), QString(),
+ QFileDialog::ShowDirsOnly);
+
+ if (!gamePath.isEmpty()) {
+ QDir gameDir(gamePath);
+ for (IPluginGame * const game : plugins.plugins<IPluginGame>()) {
+ if (game->looksValid(gameDir)) {
+ return selectGame(settings, gameDir, game);
+ }
+ }
+ reportError(QObject::tr("No game identified in \"%1\". The directory is required to contain "
+ "the game binary and its launcher.").arg(gamePath));
+ }
+ }
+
+ return nullptr;
+}
+
int main(int argc, char *argv[])
{
MOApplication application(argc, argv);
@@ -341,7 +461,7 @@ int main(int argc, char *argv[])
instanceID = instanceFile.readAll().trimmed();
}
- QString dataPath =
+ QString const dataPath =
instanceID.isEmpty() ? application.applicationDirPath()
: QDir::fromNativeSeparators(
QStandardPaths::writableLocation(QStandardPaths::DataLocation)
@@ -373,7 +493,7 @@ int main(int argc, char *argv[])
QSplashScreen splash(pixmap);
try {
- if (!bootstrap()) { // requires gameinfo to be initialised!
+ if (!bootstrap()) {
return -1;
}
@@ -442,63 +562,19 @@ int main(int argc, char *argv[])
PluginContainer pluginContainer(&organizer);
pluginContainer.loadPlugins();
- QString gamePath = QString::fromUtf8(settings.value("gamePath", "").toByteArray());
- bool done = false;
- while (!done) {
- if (!GameInfo::init(ToWString(application.applicationDirPath()), ToWString(dataPath), ToWString(QDir::toNativeSeparators(gamePath)))) {
- if (!gamePath.isEmpty()) {
- reportError(QObject::tr("No game identified in \"%1\". The directory is required to contain "
- "the game binary and its launcher.").arg(gamePath));
- }
- SelectionDialog selection(QObject::tr("Please select the game to manage"), nullptr, QSize(32, 32));
-
- for (const IPluginGame * const game : pluginContainer.plugins<IPluginGame>()) {
- if (game->isInstalled()) {
- QString path = game->gameDirectory().absolutePath();
- selection.addChoice(game->gameIcon(), game->gameName(), path, path);
- }
- }
-
- selection.addChoice(QString("Browse..."), QString(), QString());
-
- if (selection.exec() == QDialog::Rejected) {
- gamePath = "";
- done = true;
- } else {
- gamePath = QDir::cleanPath(selection.getChoiceData().toString());
- if (gamePath.isEmpty()) {
- gamePath = QFileDialog::getExistingDirectory(
- nullptr, QObject::tr("Please select the game to manage"), QString(),
- QFileDialog::ShowDirsOnly);
- qDebug() << "manually selected path " << gamePath;
- }
- }
- } else {
- done = true;
- gamePath = ToQString(GameInfo::instance().getGameDirectory());
- }
+ MOBase::IPluginGame *game = determineCurrentGame(application.applicationDirPath(), settings, pluginContainer);
+ if (game == nullptr) {
+ return 1;
}
- if (gamePath.isEmpty()) {
- // game not found and user canceled
- return -1;
- } else if (gamePath.length() != 0) {
- // user selected a folder and game was initialised with it
- qDebug("game path: %s", qPrintable(gamePath));
- settings.setValue("gamePath", gamePath.toUtf8().constData());
- }
+ organizer.setManagedGame(game);
- organizer.setManagedGame(ToQString(GameInfo::instance().getGameName()), gamePath);
+ //*sigh just for making it work
+ GameInfo::init(application.applicationDirPath().toStdWString(), game->gameDirectory().absolutePath().toStdWString());
organizer.createDefaultProfile();
- if (pluginContainer.managedGame(ToQString(GameInfo::instance().getGameName())) == nullptr) {
- reportError(QObject::tr("Plugin to handle %1 not installed").arg(ToQString(GameInfo::instance().getGameName())));
- return 1;
- }
-
- IPluginGame *game = organizer.managedGame();
-
+ //See the pragma - we apparently don't use this so not sure why we check it
if (!settings.contains("game_edition")) {
QStringList editions = game->gameVariants();
if (editions.size() > 1) {
@@ -518,7 +594,7 @@ int main(int argc, char *argv[])
#pragma message("edition isn't used?")
- qDebug("managing game at %s", qPrintable(QDir::toNativeSeparators(gamePath)));
+ qDebug("managing game at %s", qPrintable(QDir::toNativeSeparators(game->gameDirectory().absolutePath())));
organizer.updateExecutablesList(settings);
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 9982e928..f30e46f1 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -19,6 +19,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "mainwindow.h"
#include "ui_mainwindow.h"
+
#include "spawn.h"
#include "report.h"
#include "modlist.h"
@@ -52,17 +53,18 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "credentialsdialog.h"
#include "selectiondialog.h"
#include "csvbuilder.h"
-#include "gameinfoimpl.h"
#include "savetextasdialog.h"
#include "problemsdialog.h"
#include "previewdialog.h"
#include "browserdialog.h"
#include "aboutdialog.h"
#include "safewritefile.h"
-#include "organizerproxy.h"
+//?
+//#include "isavegame.h"
+//#include "savegameinfo.h"
+//?
#include "nxmaccessmanager.h"
#include <archive.h>
-#include <gameinfo.h>
#include <appconfig.h>
#include <utility.h>
#include <ipluginproxy.h>
@@ -71,15 +73,12 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <questionboxmemory.h>
#include <taskprogressmanager.h>
#include <util.h>
-#include <map>
-#include <ctime>
-#include <wchar.h>
-#include <utility.h>
+#include <scopeguard.h>
+
#include <QTime>
#include <QInputDialog>
#include <QSettings>
#include <QWhatsThis>
-#include <sstream>
#include <QProcess>
#include <QMenu>
#include <QBuffer>
@@ -101,10 +100,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QtPlugin>
#include <QIdentityProxyModel>
#include <QClipboard>
-#include <Psapi.h>
-#include <shlobj.h>
-#include <ShellAPI.h>
-#include <TlHelp32.h>
#include <QNetworkInterface>
#include <QNetworkProxy>
#include <QJsonDocument>
@@ -119,7 +114,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#endif
#include <QCoreApplication>
#include <QProgressDialog>
-#include <scopeguard.h>
+
#ifndef Q_MOC_RUN
#include <boost/thread.hpp>
#include <boost/algorithm/string.hpp>
@@ -127,8 +122,19 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <boost/foreach.hpp>
#include <boost/assign.hpp>
#endif
+
+#include <Psapi.h>
+#include <shlobj.h>
+#include <ShellAPI.h>
+#include <TlHelp32.h>
+
+#include <sstream>
#include <regex>
#include <functional>
+#include <map>
+#include <ctime>
+#include <wchar.h>
+#include <utility.h>
#ifdef TEST_MODELS
#include "modeltest.h"
@@ -154,7 +160,6 @@ MainWindow::MainWindow(const QString &exeName
, m_ModListGroupingProxy(nullptr)
, m_ModListSortProxy(nullptr)
, m_OldExecutableIndex(-1)
- , m_GamePath(ToQString(GameInfo::instance().getGameDirectory()))
, m_CategoryFactory(CategoryFactory::instance())
, m_ContextItem(nullptr)
, m_ContextAction(nullptr)
@@ -359,7 +364,7 @@ MainWindow::~MainWindow()
void MainWindow::updateWindowTitle(const QString &accountName, bool premium)
{
QString title = QString("%1 Mod Organizer v%2").arg(
- ToQString(GameInfo::instance().getGameName()),
+ m_OrganizerCore.managedGame()->gameName(),
m_OrganizerCore.getVersion().displayString());
if (accountName.isEmpty()) {
@@ -827,7 +832,8 @@ void MainWindow::setBrowserGeometry(const QByteArray &geometry)
SaveGameGamebryo *MainWindow::getSaveGame(const QString &name)
{
- return new SaveGameGamebryo(this, name);
+ IPluginGame const *game = m_OrganizerCore.managedGame();
+ return new SaveGameGamebryo(this, name, game);
}
@@ -1032,9 +1038,9 @@ void MainWindow::on_profileBox_currentIndexChanged(int index)
if (ui->profileBox->currentIndex() == 0) {
ui->profileBox->setCurrentIndex(previousIndex);
- ProfilesDialog(ui->profileBox->currentText(), this).exec();
+ ProfilesDialog(ui->profileBox->currentText(), m_OrganizerCore.managedGame(), this).exec();
while (!refreshProfiles()) {
- ProfilesDialog(ui->profileBox->currentText(), this).exec();
+ ProfilesDialog(ui->profileBox->currentText(), m_OrganizerCore.managedGame(), this).exec();
}
} else {
activateSelectedProfile();
@@ -1259,9 +1265,11 @@ QDir MainWindow::currentSavesDir() const
savesDir.setPath(m_OrganizerCore.currentProfile()->absolutePath() + "/saves");
} else {
wchar_t path[MAX_PATH];
- ::GetPrivateProfileStringW(L"General", L"SLocalSavePath", L"Saves",
- path, MAX_PATH,
- (ToWString(m_OrganizerCore.currentProfile()->absolutePath()) + L"\\" + GameInfo::instance().getIniFileNames().at(0)).c_str());
+ ::GetPrivateProfileStringW(
+ L"General", L"SLocalSavePath", L"Saves",
+ path, MAX_PATH,
+ ToWString(m_OrganizerCore.currentProfile()->absolutePath() + "/" +
+ m_OrganizerCore.managedGame()->getIniFiles()[0]).c_str());
savesDir.setPath(m_OrganizerCore.managedGame()->documentsDirectory().absoluteFilePath(QString::fromWCharArray(path)));
}
@@ -1332,8 +1340,7 @@ void MainWindow::updateBSAList(const QStringList &defaultArchives, const QString
std::vector<std::pair<UINT32, QTreeWidgetItem*>> items;
- IPluginGame *gamePlugin = qApp->property("managed_game").value<IPluginGame*>();
- BSAInvalidation *invalidation = gamePlugin->feature<BSAInvalidation>();
+ BSAInvalidation *invalidation = m_OrganizerCore.managedGame()->feature<BSAInvalidation>();
std::vector<FileEntry::Ptr> files = m_OrganizerCore.directoryStructure()->getFiles();
QStringList plugins = m_OrganizerCore.findFiles("", [] (const QString &fileName) -> bool {
@@ -1819,16 +1826,18 @@ void MainWindow::on_actionInstallMod_triggered()
void MainWindow::on_actionAdd_Profile_triggered()
{
- bool repeat = true;
- while (repeat) {
- ProfilesDialog profilesDialog(m_GamePath, this);
+ for (;;) {
+ //Note: Calling this with an invalid profile name. Not quite sure why
+ ProfilesDialog profilesDialog(m_OrganizerCore.managedGame()->gameDirectory().absolutePath(),
+ m_OrganizerCore.managedGame(),
+ this);
// workaround: need to disable monitoring of the saves directory, otherwise the active
// profile directory is locked
stopMonitorSaves();
profilesDialog.exec();
refreshSaveList(); // since the save list may now be outdated we have to refresh it completely
if (refreshProfiles() && !profilesDialog.failed()) {
- repeat = false;
+ break;
}
}
// addProfile();
@@ -2525,7 +2534,7 @@ void MainWindow::visitOnNexus_clicked()
{
int modID = m_OrganizerCore.modList()->data(m_OrganizerCore.modList()->index(m_ContextRow, 0), Qt::UserRole).toInt();
if (modID > 0) {
- linkClicked(QString("%1/mods/%2").arg(ToQString(GameInfo::instance().getNexusPage(false))).arg(modID));
+ nexusLinkActivated(NexusInterface::instance()->getModURL(modID));
} else {
MessageDialog::showMessage(tr("Nexus ID for this Mod is unknown"), this);
}
@@ -3111,6 +3120,7 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos)
} break;
}
}
+
std::vector<ModInfo::EFlag> flags = info->getFlags();
if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_INVALID) != flags.end()) {
menu->addAction(tr("Ignore missing data"), this, SLOT(ignoreMissingData_clicked()));
@@ -3120,9 +3130,9 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos)
menu->addAction(tr("Visit on Nexus"), this, SLOT(visitOnNexus_clicked()));
}
+ //If a URL is specified which is not the game's URL, pop up 'visit web page'
if (info->getURL() != "" &&
- !GameInfo::instance().isValidModURL(info->getNexusID(),
- info->getURL().toStdWString())) {
+ !NexusInterface::instance()->isModURL(info->getNexusID(), info->getURL())) {
menu->addAction(tr("Visit web page"), this, SLOT(visitWebPage_clicked()));
}
@@ -3188,7 +3198,7 @@ void MainWindow::deleteSavegame_clicked()
foreach (const QModelIndex &idx, selectedIndexes) {
QString name = idx.data().toString();
- SaveGame *save = new SaveGame(this, idx.data(Qt::UserRole).toString());
+ SaveGame *save = new SaveGame(this, idx.data(Qt::UserRole).toString(), m_OrganizerCore.managedGame());
if (count < 10) {
savesMsgLabel += "<li>" + QFileInfo(name).completeBaseName() + "</li>";
@@ -3244,9 +3254,9 @@ void MainWindow::fixMods_clicked()
// search in data
{
- QDir dataDir(m_GamePath + "/data");
+ QDir dataDir(m_OrganizerCore.managedGame()->dataDirectory());
QStringList esps = dataDir.entryList(espFilter);
- foreach (const QString &esp, esps) {
+ for (const QString &esp : esps) {
std::map<QString, std::vector<QString> >::iterator iter = missingPlugins.find(esp);
if (iter != missingPlugins.end()) {
iter->second.push_back("<data>");
@@ -3260,7 +3270,7 @@ void MainWindow::fixMods_clicked()
ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
QStringList esps = QDir(modInfo->absolutePath()).entryList(espFilter);
- foreach (const QString &esp, esps) {
+ for (const QString &esp : esps) {
std::map<QString, std::vector<QString> >::iterator iter = missingPlugins.find(esp);
if (iter != missingPlugins.end()) {
iter->second.push_back(modInfo->name());
@@ -3272,7 +3282,7 @@ void MainWindow::fixMods_clicked()
{
QDir overwriteDir(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::overwritePath()));
QStringList esps = overwriteDir.entryList(espFilter);
- foreach (const QString &esp, esps) {
+ for (const QString &esp : esps) {
std::map<QString, std::vector<QString> >::iterator iter = missingPlugins.find(esp);
if (iter != missingPlugins.end()) {
iter->second.push_back("<overwrite>");
@@ -3436,7 +3446,9 @@ void MainWindow::on_actionSettings_triggered()
void MainWindow::on_actionNexus_triggered()
{
- ::ShellExecuteW(nullptr, L"open", GameInfo::instance().getNexusPage(false).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+ ::ShellExecuteW(nullptr, L"open",
+ NexusInterface::instance()->getGameURL().toStdWString().c_str(),
+ nullptr, nullptr, SW_SHOWNORMAL);
}
@@ -3830,9 +3842,11 @@ void MainWindow::on_actionUpdate_triggered()
void MainWindow::on_actionEndorseMO_triggered()
{
if (QMessageBox::question(this, tr("Endorse Mod Organizer"),
- tr("Do you want to endorse Mod Organizer on %1 now?").arg(ToQString(GameInfo::instance().getNexusPage())),
+ tr("Do you want to endorse Mod Organizer on %1 now?").arg(
+ NexusInterface::instance()->getGameURL()),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- NexusInterface::instance()->requestToggleEndorsement(GameInfo::instance().getNexusModID(), true, this, QVariant(), QString());
+ NexusInterface::instance()->requestToggleEndorsement(
+ m_OrganizerCore.managedGame()->getNexusModOrganizerID(), true, this, QVariant(), QString());
}
}
@@ -3896,7 +3910,7 @@ void MainWindow::nxmUpdatesAvailable(const std::vector<int> &modIDs, QVariant us
QVariantList resultList = resultData.toList();
for (auto iter = resultList.begin(); iter != resultList.end(); ++iter) {
QVariantMap result = iter->toMap();
- if (result["id"].toInt() == GameInfo::instance().getNexusModID()) {
+ if (result["id"].toInt() == m_OrganizerCore.managedGame()->getNexusModOrganizerID()) {
if (!result["voted_by_user"].toBool()) {
ui->actionEndorseMO->setVisible(true);
}
@@ -4412,8 +4426,8 @@ void MainWindow::on_bossButton_clicked()
parameters << "--unattended"
<< "--stdout"
<< "--noreport"
- << "--game" << ToQString(GameInfo::instance().getGameShortName())
- << "--gamePath" << QString("\"%1\"").arg(ToQString(GameInfo::instance().getGameDirectory()))
+ << "--game" << m_OrganizerCore.managedGame()->getGameShortName()
+ << "--gamePath" << QString("\"%1\"").arg(m_OrganizerCore.managedGame()->gameDirectory().absolutePath())
<< "--out" << outPath;
if (m_DidUpdateMasterList) {
@@ -4546,12 +4560,12 @@ void MainWindow::on_bossButton_clicked()
// if the game specifies load order by file time, our own load order file needs to be removed because it's outdated.
// refreshESPList will then use the file time as the load order.
- if (GameInfo::instance().getLoadOrderMechanism() == GameInfo::TYPE_FILETIME) {
+ if (m_OrganizerCore.managedGame()->getLoadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
qDebug("removing loadorder.txt");
QFile::remove(m_OrganizerCore.currentProfile()->getLoadOrderFileName());
}
m_OrganizerCore.refreshESPList();
- if (GameInfo::instance().getLoadOrderMechanism() == GameInfo::TYPE_FILETIME) {
+ if (m_OrganizerCore.managedGame()->getLoadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
// the load order should have been retrieved from file time, now save it to our own format
m_OrganizerCore.savePluginList();
}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 3c7f2258..0cdea807 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -285,15 +285,11 @@ private:
int m_OldExecutableIndex;
- QString m_GamePath;
-
int m_ContextRow;
QPersistentModelIndex m_ContextIdx;
QTreeWidgetItem *m_ContextItem;
QAction *m_ContextAction;
- //int m_SelectedSaveGame;
-
CategoryFactory &m_CategoryFactory;
int m_ModsToUpdate;
diff --git a/src/modinfo.cpp b/src/modinfo.cpp
index fe5098e8..a4a8110c 100644
--- a/src/modinfo.cpp
+++ b/src/modinfo.cpp
@@ -32,6 +32,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "filenamestring.h"
#include "versioninfo.h"
+#include <iplugingame.h>
+#include <versioninfo.h>
+#include <appconfig.h>
+#include <scriptextender.h>
+
#include <QApplication>
#include <QDirIterator>
#include <QMutexLocker>
@@ -197,7 +202,10 @@ unsigned int ModInfo::findMod(const boost::function<bool (ModInfo::Ptr)> &filter
}
-void ModInfo::updateFromDisc(const QString &modDirectory, DirectoryEntry **directoryStructure, bool displayForeign)
+void ModInfo::updateFromDisc(const QString &modDirectory,
+ DirectoryEntry **directoryStructure,
+ bool displayForeign,
+ MOBase::IPluginGame const *game)
{
QMutexLocker lock(&s_Mutex);
s_Collection.clear();
@@ -213,19 +221,25 @@ void ModInfo::updateFromDisc(const QString &modDirectory, DirectoryEntry **direc
}
{ // list plugins in the data directory and make a foreign-managed mod out of each
- std::vector<std::wstring> dlcPlugins = GameInfo::instance().getDLCPlugins();
- QDir dataDir(QDir::fromNativeSeparators(ToQString(GameInfo::instance().getGameDirectory())) + "/data");
- foreach (const QFileInfo &file, dataDir.entryInfoList(QStringList() << "*.esp" << "*.esm")) {
- if ((file.baseName() != "Update") // hide update
- && (file.baseName() != ToQString(GameInfo::instance().getGameName())) // hide the game esp
+ QStringList dlcPlugins = game->getDLCPlugins();
+ QStringList mainPlugins = game->getPrimaryPlugins();
+ QDir dataDir(game->dataDirectory());
+ for (const QString &file : dataDir.entryList({ "*.esp", "*.esm" })) {
+ if (std::find_if(mainPlugins.begin(), mainPlugins.end(),
+ [&file](QString const &p) {
+ return p.compare(file, Qt::CaseInsensitive) == 0; }) == mainPlugins.end()
&& (displayForeign // show non-dlc bundles only if the user wants them
- || std::find(dlcPlugins.begin(), dlcPlugins.end(), ToWString(file.fileName())) != dlcPlugins.end())) {
+ || std::find_if(dlcPlugins.begin(), dlcPlugins.end(),
+ [&file](QString const &p) {
+ return p.compare(file, Qt::CaseInsensitive) == 0; }) != dlcPlugins.end())) {
+
+ QFileInfo f(file); //Just so I can get a basename...
QStringList archives;
- foreach (const QString archiveName, dataDir.entryList(QStringList() << file.baseName() + "*.bsa")) {
+ for (const QString &archiveName : dataDir.entryList({ f.baseName() + "*.bsa" })) {
archives.append(dataDir.absoluteFilePath(archiveName));
}
- createFromPlugin(file.fileName(), archives, directoryStructure);
+ createFromPlugin(file, archives, directoryStructure);
}
}
}
@@ -275,7 +289,10 @@ int ModInfo::checkAllForUpdate(QObject *receiver)
int result = 0;
std::vector<int> modIDs;
- modIDs.push_back(GameInfo::instance().getNexusModID());
+ //I ought to store this, it's used elsewhere
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
+
+ modIDs.push_back(game->getNexusModOrganizerID());
for (const ModInfo::Ptr &mod : s_Collection) {
if (mod->canBeUpdated()) {
diff --git a/src/modinfo.h b/src/modinfo.h
index 7d305c11..ae22ccd8 100644
--- a/src/modinfo.h
+++ b/src/modinfo.h
@@ -22,6 +22,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "imodinterface.h"
#include "versioninfo.h"
+//#include <directoryentry.h>
class QDateTime;
class QDir;
@@ -36,6 +37,7 @@ class QDir;
#include <set>
#include <vector>
+namespace MOBase { class IPluginGame; }
namespace MOShared { class DirectoryEntry; }
/**
@@ -104,7 +106,10 @@ public:
/**
* @brief read the mod directory and Mod ModInfo objects for all subdirectories
**/
- static void updateFromDisc(const QString &modDirectory, MOShared::DirectoryEntry **directoryStructure, bool displayForeign);
+ static void updateFromDisc(const QString &modDirectory,
+ MOShared::DirectoryEntry **directoryStructure,
+ bool displayForeign,
+ MOBase::IPluginGame const *game);
static void clear() { s_Collection.clear(); s_ModsByName.clear(); s_ModsByModID.clear(); }
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp
index 35da228b..feaac2d4 100644
--- a/src/modinfodialog.cpp
+++ b/src/modinfodialog.cpp
@@ -20,6 +20,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "modinfodialog.h"
#include "ui_modinfodialog.h"
+#include "iplugingame.h"
+#include "nexusinterface.h"
#include "report.h"
#include "utility.h"
#include "messagedialog.h"
@@ -27,7 +29,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "questionboxmemory.h"
#include "settings.h"
#include "categories.h"
-#include <gameinfo.h>
#include <QDir>
#include <QDirIterator>
@@ -36,9 +37,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QMessageBox>
#include <QMenu>
#include <QFileSystemModel>
+#include <QInputDialog>
+
#include <Shlwapi.h>
+
#include <sstream>
-#include <QInputDialog>
using namespace MOBase;
@@ -688,7 +691,9 @@ void ModInfoDialog::on_visitNexusLabel_linkActivated(const QString &link)
void ModInfoDialog::linkClicked(const QUrl &url)
{
- if (url.toString().startsWith(ToQString(GameInfo::instance().getNexusPage(false)))) {
+ //Ideally we'd ask the mod for the game and the web service then pass the game
+ //and URL to the web service
+ if (NexusInterface::instance()->isURLGameRelated(url)) {
this->close();
emit nexusLinkActivated(url.toString());
} else {
@@ -832,12 +837,11 @@ void ModInfoDialog::activateNexusTab()
QLineEdit *modIDEdit = findChild<QLineEdit*>("modIDEdit");
int modID = modIDEdit->text().toInt();
if (modID != 0) {
- QString nexusLink = QString("%1/downloads/file.php?id=%2").arg(ToQString(GameInfo::instance().getNexusPage(false))).arg(modID);
+ QString nexusLink = NexusInterface::instance()->getModURL(modID);
QLabel *visitNexusLabel = findChild<QLabel*>("visitNexusLabel");
visitNexusLabel->setText(tr("<a href=\"%1\">Visit on Nexus</a>").arg(nexusLink));
visitNexusLabel->setToolTip(nexusLink);
-
if (m_ModInfo->getNexusDescription().isEmpty() ||
QDateTime::currentDateTime() > m_ModInfo->getLastNexusQuery().addDays(1)) {
refreshNexusData(modID);
diff --git a/src/modinfoforeign.cpp b/src/modinfoforeign.cpp
index c0e769c9..4dbe034b 100644
--- a/src/modinfoforeign.cpp
+++ b/src/modinfoforeign.cpp
@@ -1,8 +1,10 @@
#include "modinfoforeign.h"
-#include "gameinfo.h"
+#include "iplugingame.h"
#include "utility.h"
+#include <QApplication>
+
using namespace MOBase;
using namespace MOShared;
@@ -18,7 +20,9 @@ QDateTime ModInfoForeign::creationTime() const
QString ModInfoForeign::absolutePath() const
{
- return QDir::fromNativeSeparators(ToQString(GameInfo::instance().getGameDirectory())) + "/data";
+ //I ought to store this, it's used elsewhere
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
+ return game->dataDirectory().absolutePath();
}
std::vector<ModInfo::EFlag> ModInfoForeign::getFlags() const
diff --git a/src/modlist.cpp b/src/modlist.cpp
index 197250a3..9d7f32c8 100644
--- a/src/modlist.cpp
+++ b/src/modlist.cpp
@@ -24,15 +24,14 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "qtgroupingproxy.h"
#include "viewmarkingscrollbar.h"
#include "modlistsortproxy.h"
-#include <gameinfo.h>
#include <appconfig.h>
#include <utility.h>
#include <report.h>
+
#include <QFileInfo>
#include <QDir>
#include <QDirIterator>
#include <QMimeData>
-#include <stdexcept>
#include <QStandardItemModel>
#include <QMessageBox>
#include <QStringList>
@@ -44,7 +43,9 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QAbstractItemView>
#include <QSortFilterProxyModel>
#include <QApplication>
+
#include <sstream>
+#include <stdexcept>
#include <algorithm>
diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp
index 25f3d1b4..9bed19b3 100644
--- a/src/nexusinterface.cpp
+++ b/src/nexusinterface.cpp
@@ -18,14 +18,18 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "nexusinterface.h"
+
+#include "iplugingame.h"
#include "nxmaccessmanager.h"
#include "json.h"
#include "selectiondialog.h"
-#include <QApplication>
#include <utility.h>
-#include <regex>
#include <util.h>
+#include <QApplication>
+
+#include <regex>
+
using namespace MOBase;
using namespace MOShared;
@@ -33,34 +37,33 @@ using namespace MOShared;
NexusBridge::NexusBridge(const QString &subModule)
: m_Interface(NexusInterface::instance())
- , m_Url() // lazy initialized
, m_SubModule(subModule)
{
}
void NexusBridge::requestDescription(int modID, QVariant userData)
{
- m_RequestIDs.insert(m_Interface->requestDescription(modID, this, userData, m_SubModule, url()));
+ m_RequestIDs.insert(m_Interface->requestDescription(modID, this, userData, m_SubModule));
}
void NexusBridge::requestFiles(int modID, QVariant userData)
{
- m_RequestIDs.insert(m_Interface->requestFiles(modID, this, userData, m_SubModule, url()));
+ m_RequestIDs.insert(m_Interface->requestFiles(modID, this, userData, m_SubModule));
}
void NexusBridge::requestFileInfo(int modID, int fileID, QVariant userData)
{
- m_RequestIDs.insert(m_Interface->requestFileInfo(modID, fileID, this, userData, m_SubModule, url()));
+ m_RequestIDs.insert(m_Interface->requestFileInfo(modID, fileID, this, userData, m_SubModule));
}
void NexusBridge::requestDownloadURL(int modID, int fileID, QVariant userData)
{
- m_RequestIDs.insert(m_Interface->requestDownloadURL(modID, fileID, this, userData, m_SubModule, url()));
+ m_RequestIDs.insert(m_Interface->requestDownloadURL(modID, fileID, this, userData, m_SubModule));
}
void NexusBridge::requestToggleEndorsement(int modID, bool endorse, QVariant userData)
{
- m_RequestIDs.insert(m_Interface->requestToggleEndorsement(modID, endorse, this, userData, m_SubModule, url()));
+ m_RequestIDs.insert(m_Interface->requestToggleEndorsement(modID, endorse, this, userData, m_SubModule));
}
void NexusBridge::nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID)
@@ -136,13 +139,6 @@ void NexusBridge::nxmRequestFailed(int modID, int fileID, QVariant userData, int
}
}
-QString NexusBridge::url() {
- if (m_Url.isEmpty()) {
- m_Url = MOBase::ToQString(MOShared::GameInfo::instance().getNexusInfoUrl());
- }
- return m_Url;
-}
-
QAtomicInt NexusInterface::NXMRequestInfo::s_NextID(0);
@@ -245,12 +241,43 @@ void NexusInterface::interpretNexusFileName(const QString &fileName, QString &mo
}
}
+bool NexusInterface::isURLGameRelated(const QUrl &url) const
+{
+ QString const name(url.toString());
+ return name.startsWith(getGameURL() + "/") ||
+ name.startsWith(getOldModsURL() + "/");
+}
+
+QString NexusInterface::getGameURL() const
+{
+ return "http://www.nexusmods.com/" + m_Game->getGameShortName().toLower();
+}
+
+QString NexusInterface::getOldModsURL() const
+{
+ return "http://" + m_Game->getGameShortName().toLower() + ".nexusmods.com/mods";
+}
+
+
+QString NexusInterface::getModURL(int modID) const
+{
+ return QString("%1/mods/%2").arg(getGameURL()).arg(modID);
+}
+
+bool NexusInterface::isModURL(int modID, QString const &url) const
+{
+ if (url == getModURL(modID)) {
+ return true;
+ }
+ //Try the alternate (old style) mod name
+ QString alt = QString("%1/%2").arg(getOldModsURL()).arg(modID);
+ return alt == url;
+}
int NexusInterface::requestDescription(int modID, QObject *receiver, QVariant userData,
- const QString &subModule, const QString &url, int nexusGameId)
+ const QString &subModule, MOBase::IPluginGame const *game)
{
- NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_DESCRIPTION, userData, subModule, url,
- nexusGameId == -1 ? GameInfo::instance().getNexusGameID() : nexusGameId);
+ NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_DESCRIPTION, userData, subModule, game);
m_RequestQueue.enqueue(requestInfo);
connect(this, SIGNAL(nxmDescriptionAvailable(int,QVariant,QVariant,int)),
@@ -265,9 +292,9 @@ int NexusInterface::requestDescription(int modID, QObject *receiver, QVariant us
int NexusInterface::requestUpdates(const std::vector<int> &modIDs, QObject *receiver, QVariant userData,
- const QString &subModule, const QString &url)
+ const QString &subModule, MOBase::IPluginGame const *game)
{
- NXMRequestInfo requestInfo(modIDs, NXMRequestInfo::TYPE_GETUPDATES, userData, subModule, url, GameInfo::instance().getNexusGameID());
+ NXMRequestInfo requestInfo(modIDs, NXMRequestInfo::TYPE_GETUPDATES, userData, subModule, game);
m_RequestQueue.enqueue(requestInfo);
connect(this, SIGNAL(nxmUpdatesAvailable(std::vector<int>,QVariant,QVariant,int)),
@@ -301,9 +328,9 @@ void NexusInterface::fakeFiles()
int NexusInterface::requestFiles(int modID, QObject *receiver, QVariant userData,
- const QString &subModule, const QString &url)
+ const QString &subModule, MOBase::IPluginGame const *game)
{
- NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_FILES, userData, subModule, url, GameInfo::instance().getNexusGameID());
+ NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_FILES, userData, subModule, game);
m_RequestQueue.enqueue(requestInfo);
connect(this, SIGNAL(nxmFilesAvailable(int,QVariant,QVariant,int)),
receiver, SLOT(nxmFilesAvailable(int,QVariant,QVariant,int)), Qt::UniqueConnection);
@@ -321,9 +348,9 @@ int NexusInterface::requestFiles(int modID, QObject *receiver, QVariant userData
int NexusInterface::requestFileInfo(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule,
- const QString &url)
+ MOBase::IPluginGame const *game)
{
- NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_FILEINFO, userData, subModule, url, GameInfo::instance().getNexusGameID());
+ NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_FILEINFO, userData, subModule, game);
m_RequestQueue.enqueue(requestInfo);
connect(this, SIGNAL(nxmFileInfoAvailable(int,int,QVariant,QVariant,int)),
@@ -338,9 +365,9 @@ int NexusInterface::requestFileInfo(int modID, int fileID, QObject *receiver, QV
int NexusInterface::requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData,
- const QString &subModule, const QString &url)
+ const QString &subModule, MOBase::IPluginGame const *game)
{
- NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_DOWNLOADURL, userData, subModule, url, GameInfo::instance().getNexusGameID());
+ NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_DOWNLOADURL, userData, subModule, game);
m_RequestQueue.enqueue(requestInfo);
connect(this, SIGNAL(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)),
@@ -355,9 +382,9 @@ int NexusInterface::requestDownloadURL(int modID, int fileID, QObject *receiver,
int NexusInterface::requestToggleEndorsement(int modID, bool endorse, QObject *receiver, QVariant userData,
- const QString &subModule, const QString &url)
+ const QString &subModule, MOBase::IPluginGame const *game)
{
- NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_TOGGLEENDORSEMENT, userData, subModule, url, GameInfo::instance().getNexusGameID());
+ NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_TOGGLEENDORSEMENT, userData, subModule, game);
requestInfo.m_Endorse = endorse;
m_RequestQueue.enqueue(requestInfo);
@@ -558,13 +585,24 @@ void NexusInterface::requestTimeout()
}
}
+void NexusInterface::managedGameChanged(IPluginGame const *game)
+{
+ m_Game = game;
+}
+
+namespace {
+ QString get_management_url(MOBase::IPluginGame const *game)
+ {
+ return "http://nmm.nexusmods.com/" + game->getGameShortName().toLower();
+ }
+}
NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
, NexusInterface::NXMRequestInfo::Type type
, QVariant userData
, const QString &subModule
- , const QString &url
- , int nexusGameId)
+ , MOBase::IPluginGame const *game
+ )
: m_ModID(modID)
, m_FileID(0)
, m_Reply(nullptr)
@@ -573,9 +611,9 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
, m_Timeout(nullptr)
, m_Reroute(false)
, m_ID(s_NextID.fetchAndAddAcquire(1))
- , m_URL(url)
+ , m_URL(get_management_url(game))
, m_SubModule(subModule)
- , m_NexusGameID(nexusGameId)
+ , m_NexusGameID(game->getNexusGameID())
, m_Endorse(false)
{}
@@ -583,8 +621,8 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(std::vector<int> modIDList
, NexusInterface::NXMRequestInfo::Type type
, QVariant userData
, const QString &subModule
- , const QString &url
- , int nexusGameId)
+ , MOBase::IPluginGame const *game
+ )
: m_ModID(-1)
, m_ModIDList(modIDList)
, m_FileID(0)
@@ -594,9 +632,9 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(std::vector<int> modIDList
, m_Timeout(nullptr)
, m_Reroute(false)
, m_ID(s_NextID.fetchAndAddAcquire(1))
- , m_URL(url)
+ , m_URL(get_management_url(game))
, m_SubModule(subModule)
- , m_NexusGameID(nexusGameId)
+ , m_NexusGameID(game->getNexusGameID())
, m_Endorse(false)
{}
@@ -605,8 +643,8 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
, NexusInterface::NXMRequestInfo::Type type
, QVariant userData
, const QString &subModule
- , const QString &url
- , int nexusGameId)
+ , MOBase::IPluginGame const *game
+ )
: m_ModID(modID)
, m_FileID(fileID)
, m_Reply(nullptr)
@@ -615,8 +653,8 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
, m_Timeout(nullptr)
, m_Reroute(false)
, m_ID(s_NextID.fetchAndAddAcquire(1))
- , m_URL(url)
+ , m_URL(get_management_url(game))
, m_SubModule(subModule)
- , m_NexusGameID(nexusGameId)
+ , m_NexusGameID(game->getNexusGameID())
, m_Endorse(false)
{}
diff --git a/src/nexusinterface.h b/src/nexusinterface.h
index c0ee50cd..c9a81134 100644
--- a/src/nexusinterface.h
+++ b/src/nexusinterface.h
@@ -20,20 +20,20 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef NEXUSINTERFACE_H
#define NEXUSINTERFACE_H
-
-
#include <utility.h>
-#include <gameinfo.h>
#include <versioninfo.h>
#include <imodrepositorybridge.h>
+
#include <QNetworkReply>
#include <QNetworkDiskCache>
#include <QQueue>
#include <QVariant>
#include <QTimer>
+
#include <list>
#include <set>
+namespace MOBase { class IPluginGame; }
class NexusInterface;
class NXMAccessManager;
@@ -108,12 +108,7 @@ public slots:
private:
- QString url();
-
-private:
-
NexusInterface *m_Interface;
- QString m_Url;
QString m_SubModule;
std::set<int> m_RequestIDs;
@@ -150,26 +145,64 @@ public:
/**
* @brief request description for a mod
*
+ * @param modID id of the mod caller is interested in (assumed to be for the current game)
+ * @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable)
+ * @param userData user data to be returned with the result
+ * @return int an id to identify the request
+ **/
+ int requestDescription(int modID, QObject *receiver, QVariant userData, const QString &subModule)
+ {
+ return requestDescription(modID, receiver, userData, subModule, m_Game);
+ }
+
+ /**
+ * @brief request description for a mod
+ *
* @param modID id of the mod caller is interested in
* @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable)
* @param userData user data to be returned with the result
- * @param url the url to request from
+ * @param game Game with which the mod is associated
* @return int an id to identify the request
**/
int requestDescription(int modID, QObject *receiver, QVariant userData, const QString &subModule,
- const QString &url = MOBase::ToQString(MOShared::GameInfo::instance().getNexusInfoUrl()),
- int nexusGameId = -1);
+ MOBase::IPluginGame const *game);
+
+ /**
+ * @brief request nexus descriptions for multiple mods at once
+ * @param modIDs a list of ids of mods the caller is interested in (assumed to be for the current game)
+ * @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable)
+ * @param userData user data to be returned with the result
+ * @return int an id to identify the request
+ */
+ int requestUpdates(const std::vector<int> &modIDs, QObject *receiver, QVariant userData, const QString &subModule)
+ {
+ return requestUpdates(modIDs, receiver, userData, subModule, m_Game);
+ }
/**
* @brief request nexus descriptions for multiple mods at once
* @param modIDs a list of ids of mods the caller is interested in
* @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable)
* @param userData user data to be returned with the result
- * @param url the url to request from
+ * @param game the game with which the mods are associated
* @return int an id to identify the request
*/
int requestUpdates(const std::vector<int> &modIDs, QObject *receiver, QVariant userData, const QString &subModule,
- const QString &url = MOBase::ToQString(MOShared::GameInfo::instance().getNexusInfoUrl()));
+ MOBase::IPluginGame const *game);
+
+ /**
+ * @brief request a list of the files belonging to a mod
+ *
+ * @param modID id of the mod caller is interested in (assumed to be for the current game)
+ * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
+ * @param userData user data to be returned with the result
+ * @return int an id to identify the request
+ **/
+ int requestFiles(int modID, QObject *receiver, QVariant userData, const QString &subModule)
+ {
+ return requestFiles(modID, receiver, userData, subModule, m_Game);
+ }
+
/**
* @brief request a list of the files belonging to a mod
@@ -177,24 +210,52 @@ public:
* @param modID id of the mod caller is interested in
* @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
* @param userData user data to be returned with the result
- * @param url the url to request from
+ * @param game the game with which the mods are associated
* @return int an id to identify the request
**/
int requestFiles(int modID, QObject *receiver, QVariant userData, const QString &subModule,
- const QString &url = MOBase::ToQString(MOShared::GameInfo::instance().getNexusInfoUrl()));
+ MOBase::IPluginGame const *game);
/**
* @brief request info about a single file of a mod
*
- * @param modID id of the mod caller is interested in
+ * @param modID id of the mod caller is interested in (assumed to be for the current game)
* @param fileID id of the file the caller is interested in
* @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
* @param userData user data to be returned with the result
- * @param url the url to request from
+ * @return int an id to identify the request
+ **/
+ int requestFileInfo(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule)
+ {
+ return requestFileInfo(modID, fileID, receiver, userData, subModule, m_Game);
+ }
+
+ /**
+ * @brief request info about a single file of a mod
+ *
+ * @param modID id of the mod caller is interested in (assumed to be for the current game)
+ * @param fileID id of the file the caller is interested in
+ * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
+ * @param userData user data to be returned with the result
+ * @param game the game with which the mods are associated
* @return int an id to identify the request
**/
int requestFileInfo(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule,
- const QString &url = MOBase::ToQString(MOShared::GameInfo::instance().getNexusInfoUrl()));
+ MOBase::IPluginGame const *game);
+
+ /**
+ * @brief request the download url of a file
+ *
+ * @param modID id of the mod caller is interested in (assumed to be for the current game)
+ * @param fileID id of the file the caller is interested in
+ * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
+ * @param userData user data to be returned with the result
+ * @return int an id to identify the request
+ **/
+ int requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule)
+ {
+ return requestDownloadURL(modID, fileID, receiver, userData, subModule, m_Game);
+ }
/**
* @brief request the download url of a file
@@ -203,11 +264,23 @@ public:
* @param fileID id of the file the caller is interested in
* @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
* @param userData user data to be returned with the result
- * @param url the url to request from
+ * @param game the game with which the mods are associated
* @return int an id to identify the request
**/
- int requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule,
- const QString &url = MOBase::ToQString(MOShared::GameInfo::instance().getNexusInfoUrl()));
+ int requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
+
+ /**
+ * @brief toggle endorsement state of the mod
+ * @param modID id of the mod (assumed to be for the current game)
+ * @param endorse true if the mod should be endorsed, false for un-endorse
+ * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
+ * @param userData user data to be returned with the result
+ * @return int an id to identify the request
+ */
+ int requestToggleEndorsement(int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule)
+ {
+ return requestToggleEndorsement(modID, endorse, receiver, userData, subModule, m_Game);
+ }
/**
* @brief toggle endorsement state of the mod
@@ -215,11 +288,11 @@ public:
* @param endorse true if the mod should be endorsed, false for un-endorse
* @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
* @param userData user data to be returned with the result
- * @param url the url to request from
+ * @param game the game with which the mods are associated
* @return int an id to identify the request
*/
int requestToggleEndorsement(int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule,
- const QString &url = MOBase::ToQString(MOShared::GameInfo::instance().getNexusInfoUrl()));
+ MOBase::IPluginGame const *game);
/**
* @param directory the directory to store cache files
@@ -247,6 +320,39 @@ public:
*/
static void interpretNexusFileName(const QString &fileName, QString &modName, int &modID, bool query);
+ /**
+ * @brief get the currently managed game
+ */
+ MOBase::IPluginGame const *managedGame() const;
+
+ /**
+ * @brief see if the passed URL is related to the current game
+ *
+ * Arguably, this should optionally take a gameplugin pointer
+ */
+ bool isURLGameRelated(QUrl const &url) const;
+
+ /**
+ * @brief Get the nexus page for the current game
+ *
+ * Arguably, this should optionally take a gameplugin pointer
+ */
+ QString getGameURL() const;
+
+ /**
+ * @brief Get the URL for the mod web page
+ * @param modID
+ */
+ QString getModURL(int modID) const;
+
+ /**
+ * @brief Checks if the specified URL might correspond to a nexus mod
+ * @param modID
+ * @param url
+ * @return
+ */
+ bool isModURL(int modID, QString const &url) const;
+
signals:
void requestNXMDownload(const QString &url);
@@ -261,6 +367,9 @@ signals:
void nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID);
void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString);
+public slots:
+ void managedGameChanged(MOBase::IPluginGame const *game);
+
private slots:
void requestFinished();
@@ -295,9 +404,9 @@ private:
int m_ID;
int m_Endorse;
- NXMRequestInfo(int modID, Type type, QVariant userData, const QString &subModule, const QString &url, int nexusGameId);
- NXMRequestInfo(std::vector<int> modIDList, Type type, QVariant userData, const QString &subModule, const QString &url, int nexusGameId);
- NXMRequestInfo(int modID, int fileID, Type type, QVariant userData, const QString &subModule, const QString &url, int nexusGameId);
+ NXMRequestInfo(int modID, Type type, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
+ NXMRequestInfo(std::vector<int> modIDList, Type type, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
+ NXMRequestInfo(int modID, int fileID, Type type, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
private:
static QAtomicInt s_NextID;
@@ -311,6 +420,7 @@ private:
void nextRequest();
void requestFinished(std::list<NXMRequestInfo>::iterator iter);
bool requiresLogin(const NXMRequestInfo &info);
+ QString getOldModsURL() const;
private:
@@ -324,6 +434,8 @@ private:
MOBase::VersionInfo m_MOVersion;
QString m_NMMVersion;
+ MOBase::IPluginGame const *m_Game;
+
};
#endif // NEXUSINTERFACE_H
diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp
index 0763bb71..c37131eb 100644
--- a/src/nxmaccessmanager.cpp
+++ b/src/nxmaccessmanager.cpp
@@ -18,14 +18,16 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "nxmaccessmanager.h"
+
+#include "iplugingame.h"
#include "nxmurl.h"
#include "report.h"
#include "utility.h"
#include "selfupdater.h"
#include "persistentcookiejar.h"
#include "settings.h"
-#include <gameinfo.h>
#include <json.h>
+
#include <QMessageBox>
#include <QPushButton>
#include <QNetworkProxy>
@@ -39,10 +41,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QJsonDocument>
#include <QJsonArray>
-
using namespace MOBase;
-using namespace MOShared;
+namespace {
+ QString const Nexus_Management_URL("http://nmm.nexusmods.com");
+}
// unfortunately Nexus doesn't seem to document these states, all I know is all these listed
// are considered premium (27 should be lifetime premium)
@@ -96,8 +99,7 @@ QNetworkReply *NXMAccessManager::createRequest(
void NXMAccessManager::showCookies() const
{
- QUrl url(ToQString(GameInfo::instance().getNexusPage()) + "/");
-
+ QUrl url(Nexus_Management_URL + "/");
for (const QNetworkCookie &cookie : cookieJar()->cookiesForUrl(url)) {
qDebug("%s - %s (expires: %s)",
cookie.name().constData(), cookie.value().constData(),
@@ -110,7 +112,7 @@ void NXMAccessManager::startLoginCheck()
{
if (hasLoginCookies()) {
qDebug("validating login cookies");
- QNetworkRequest request(ToQString(GameInfo::instance().getNexusPage()) + "/Sessions/?Validate");
+ QNetworkRequest request(Nexus_Management_URL + "/Sessions/?Validate");
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
request.setRawHeader("User-Agent", userAgent().toUtf8());
@@ -127,9 +129,8 @@ void NXMAccessManager::startLoginCheck()
void NXMAccessManager::retrieveCredentials()
{
qDebug("retrieving credentials");
- QNetworkRequest request(ToQString(GameInfo::instance().getNexusPage())
- + QString("/Core/Libs/Flamework/Entities/User?GetCredentials&game_id=%1"
- ).arg(GameInfo::instance().getNexusGameID()));
+
+ QNetworkRequest request(Nexus_Management_URL + "/Core/Libs/Flamework/Entities/User?GetCredentials");
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
request.setRawHeader("User-Agent", userAgent().toUtf8());
@@ -224,8 +225,9 @@ QString NXMAccessManager::userAgent(const QString &subModule) const
void NXMAccessManager::pageLogin()
{
qDebug("logging %s in on Nexus", qPrintable(m_Username));
- QString requestString = (ToQString(GameInfo::instance().getNexusPage()) + "/Sessions/?Login&uri=%1")
- .arg(QString(QUrl::toPercentEncoding(ToQString(GameInfo::instance().getNexusPage()))));
+
+ QString requestString = (Nexus_Management_URL + "/Sessions/?Login&uri=%1")
+ .arg(QString(QUrl::toPercentEncoding(Nexus_Management_URL)));
QNetworkRequest request(requestString);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -289,15 +291,14 @@ void NXMAccessManager::loginError(QNetworkReply::NetworkError)
bool NXMAccessManager::hasLoginCookies() const
{
- bool sidCookie = false;
- QUrl url(ToQString(GameInfo::instance().getNexusPage()) + "/");
+ QUrl url(Nexus_Management_URL + "/");
QList<QNetworkCookie> cookies = cookieJar()->cookiesForUrl(url);
for (const QNetworkCookie &cookie : cookies) {
if (cookie.name() == "sid") {
- sidCookie = true;
+ return true;
}
}
- return sidCookie;
+ return false;
}
@@ -338,4 +339,3 @@ void NXMAccessManager::loginChecked()
m_LoginReply->deleteLater();
m_LoginReply = nullptr;
}
-
diff --git a/src/nxmaccessmanager.h b/src/nxmaccessmanager.h
index a03dbe36..82bd2bd5 100644
--- a/src/nxmaccessmanager.h
+++ b/src/nxmaccessmanager.h
@@ -27,6 +27,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QProgressDialog>
#include <set>
+namespace MOBase { class IPluginGame; }
/**
* @brief access manager extended to handle nxm links
@@ -84,8 +85,6 @@ private slots:
void loginError(QNetworkReply::NetworkError errorCode);
void loginTimeout();
-public slots:
-
protected:
virtual QNetworkReply *createRequest(
diff --git a/src/organizer.pro b/src/organizer.pro
index adc606fb..1284aa40 100644
--- a/src/organizer.pro
+++ b/src/organizer.pro
@@ -70,7 +70,6 @@ SOURCES += \
moapplication.cpp \
profileinputdialog.cpp \
icondelegate.cpp \
- gameinfoimpl.cpp \
csvbuilder.cpp \
savetextasdialog.cpp \
qtgroupingproxy.cpp \
@@ -150,7 +149,6 @@ HEADERS += \
moapplication.h \
profileinputdialog.h \
icondelegate.h \
- gameinfoimpl.h \
csvbuilder.h \
savetextasdialog.h \
qtgroupingproxy.h \
@@ -244,6 +242,10 @@ INCLUDEPATH += "E:/Visual Leak Detector/include"
LIBS += -L"E:/Visual Leak Detector/lib/Win32"
#DEFINES += LEAK_CHECK_WITH_VLD
+#########################FUDGE###############################
+INCLUDEPATH += ../plugins/gameGamebryo
+#############################################################
+
# custom leak detection
#LIBS += -lDbgHelp
@@ -365,10 +367,10 @@ CONFIG(debug, debug|release) {
}
OTHER_FILES += \
- SConscript
+ SConscript \
+ CMakeLists.txt
DISTFILES += \
tutorials/tutorial_primer_main.js \
tutorials/Tooltip.qml \
- tutorials/TooltipArea.qml \
- SConscript
+ tutorials/TooltipArea.qml
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index a9284e97..06a6dba4 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -1,6 +1,7 @@
#include "organizercore.h"
+
+#include "iplugingame.h"
#include "mainwindow.h"
-#include "gameinfoimpl.h"
#include "messagedialog.h"
#include "logbuffer.h"
#include "credentialsdialog.h"
@@ -19,11 +20,14 @@
#include <appconfig.h>
#include <report.h>
#include <questionboxmemory.h>
+
#include <QNetworkInterface>
#include <QMessageBox>
#include <QDialogButtonBox>
#include <QApplication>
+
#include <Psapi.h>
+
#include <functional>
@@ -118,8 +122,7 @@ QStringList toStringList(InputIterator current, InputIterator end)
OrganizerCore::OrganizerCore(const QSettings &initSettings)
- : m_GameInfo(new GameInfoImpl())
- , m_UserInterface(nullptr)
+ : m_UserInterface(nullptr)
, m_PluginContainer(nullptr)
, m_GameName()
, m_CurrentProfile(nullptr)
@@ -159,7 +162,11 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings)
connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginSuccessful(bool)), this, SLOT(loginSuccessful(bool)));
connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString)));
- connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame*)), &m_Settings, SLOT(managedGameChanged(MOBase::IPluginGame*)));
+ //This seems awfully imperative
+ connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)), &m_Settings, SLOT(managedGameChanged(MOBase::IPluginGame const *)));
+ connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)), &m_DownloadManager, SLOT(managedGameChanged(MOBase::IPluginGame const *)));
+ connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)), &m_PluginList, SLOT(managedGameChanged(MOBase::IPluginGame const *)));
+ connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)), NexusInterface::instance(), SLOT(managedGameChanged(MOBase::IPluginGame const *)));
connect(&m_PluginList, &PluginList::writePluginsList, &m_PluginListsWriter, &DelayedFileWriterBase::write);
@@ -186,7 +193,6 @@ OrganizerCore::~OrganizerCore()
m_ModList.setProfile(nullptr);
NexusInterface::instance()->cleanup();
- delete m_GameInfo;
delete m_DirectoryStructure;
}
@@ -322,7 +328,7 @@ void OrganizerCore::updateExecutablesList(QSettings &settings)
return;
}
- m_ExecutablesList.init(m_PluginContainer->managedGame(ToQString(GameInfo::instance().getGameName())));
+ m_ExecutablesList.init(managedGame());
qDebug("setting up configured executables");
@@ -350,7 +356,7 @@ void OrganizerCore::updateExecutablesList(QSettings &settings)
settings.endArray();
// TODO this has nothing to do with executables list move to an appropriate function!
- ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign());
+ ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign(), managedGame());
}
void OrganizerCore::setUserInterface(IUserInterface *userInterface, QWidget *widget)
@@ -393,6 +399,14 @@ void OrganizerCore::connectPlugins(PluginContainer *container)
m_GamePlugin = m_PluginContainer->managedGame(m_GameName);
emit managedGameChanged(m_GamePlugin);
}
+ //Do this the hard way
+ for (const IPluginGame * const game : container->plugins<IPluginGame>()) {
+ QString n = game->getGameShortName();
+ if (game->getGameShortName() == "Skyrim") {
+ m_Updater.setNexusDownload(game);
+ break;
+ }
+ }
}
void OrganizerCore::disconnectPlugins()
@@ -408,15 +422,12 @@ void OrganizerCore::disconnectPlugins()
m_PluginContainer = nullptr;
}
-void OrganizerCore::setManagedGame(const QString &gameName, const QString &gamePath)
+void OrganizerCore::setManagedGame(MOBase::IPluginGame const *game)
{
- m_GameName = gameName;
- if (m_PluginContainer != nullptr) {
- m_GamePlugin = m_PluginContainer->managedGame(m_GameName);
- m_GamePlugin->setGamePath(gamePath);
- qApp->setProperty("managed_game", QVariant::fromValue(m_GamePlugin));
- emit managedGameChanged(m_GamePlugin);
- }
+ m_GameName = game->gameName();
+ m_GamePlugin = game;
+ qApp->setProperty("managed_game", QVariant::fromValue(m_GamePlugin));
+ emit managedGameChanged(m_GamePlugin);
}
Settings &OrganizerCore::settings()
@@ -555,11 +566,6 @@ void OrganizerCore::setCurrentProfile(const QString &profileName)
refreshDirectoryStructure();
}
-MOBase::IGameInfo &OrganizerCore::gameInfo() const
-{
- return *m_GameInfo;
-}
-
MOBase::IModRepositoryBridge *OrganizerCore::createNexusBridge() const
{
return new NexusBridge();
@@ -593,14 +599,10 @@ MOBase::VersionInfo OrganizerCore::appVersion() const
return m_Updater.getVersion();
}
-MOBase::IModInterface *OrganizerCore::getMod(const QString &name)
+MOBase::IModInterface *OrganizerCore::getMod(const QString &name) const
{
unsigned int index = ModInfo::getIndex(name);
- if (index == UINT_MAX) {
- return nullptr;
- } else {
- return ModInfo::getByIndex(index).data();
- }
+ return index == UINT_MAX ? nullptr : ModInfo::getByIndex(index).data();
}
MOBase::IModInterface *OrganizerCore::createMod(GuessedValue<QString> &name)
@@ -930,12 +932,12 @@ void OrganizerCore::spawnBinary(const QFileInfo &binary, const QString &argument
refreshDirectoryStructure();
// need to remove our stored load order because it may be outdated if a foreign tool changed the
// file time. After removing that file, refreshESPList will use the file time as the order
- if (GameInfo::instance().getLoadOrderMechanism() == GameInfo::TYPE_FILETIME) {
+ if (managedGame()->getLoadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
qDebug("removing loadorder.txt");
QFile::remove(m_CurrentProfile->getLoadOrderFileName());
}
refreshESPList();
- if (GameInfo::instance().getLoadOrderMechanism() == GameInfo::TYPE_FILETIME) {
+ if (managedGame()->getLoadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
// the load order should have been retrieved from file time, now save it to our own format
savePluginList();
}
@@ -961,7 +963,10 @@ HANDLE OrganizerCore::spawnBinaryDirect(const QFileInfo &binary, const QString &
::SetEnvironmentVariableW(L"SteamAPPId", ToWString(m_Settings.getSteamAppID()).c_str());
}
- if ((GameInfo::instance().requiresSteam())
+
+ //This could possibly be extracted somewhere else but it's probably for when
+ //we have more than one provider of game registration.
+ if (QFileInfo(managedGame()->gameDirectory().absoluteFilePath("steam_api.dll")).exists()
&& (m_Settings.getLoadMechanism() == LoadMechanism::LOAD_MODORGANIZER)) {
if (!testForSteam()) {
QWidget *window = qApp->activeWindow();
@@ -1017,7 +1022,7 @@ HANDLE OrganizerCore::startApplication(const QString &executable, const QStringL
binary = QFileInfo(executable);
if (binary.isRelative()) {
// relative path, should be relative to game directory
- binary = QFileInfo(QDir::fromNativeSeparators(ToQString(GameInfo::instance().getGameDirectory())) + "/" + executable);
+ binary = QFileInfo(managedGame()->gameDirectory().absoluteFilePath(executable));
}
if (cwd.length() == 0) {
currentDirectory = binary.absolutePath();
@@ -1133,7 +1138,7 @@ void OrganizerCore::refreshModList(bool saveChanges)
if (saveChanges) {
m_CurrentProfile->modlistWriter().writeImmediately(true);
}
- ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign());
+ ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign(), managedGame());
m_CurrentProfile->refreshModStatus();
@@ -1314,7 +1319,7 @@ PluginListSortProxy *OrganizerCore::createPluginListProxyModel()
return result;
}
-IPluginGame *OrganizerCore::managedGame() const
+IPluginGame const *OrganizerCore::managedGame() const
{
return m_GamePlugin;
}
@@ -1375,7 +1380,7 @@ void OrganizerCore::directory_refreshed()
void OrganizerCore::profileRefresh()
{
// have to refresh mods twice (again in refreshModList), otherwise the refresh isn't complete. Not sure why
- ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign());
+ ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign(), managedGame());
m_CurrentProfile->refreshModStatus();
refreshModList();
@@ -1571,10 +1576,10 @@ void OrganizerCore::prepareStart() {
storeSettings();
}
+/*
std::vector<std::pair<QString, QString>> OrganizerCore::fileMapping()
{
- IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
- return fileMapping(game->dataDirectory().absolutePath(),
+ return fileMapping(managedGame()->dataDirectory().absolutePath(),
directoryStructure(),
directoryStructure());
}
@@ -1610,4 +1615,4 @@ std::vector<std::pair<QString, QString>> OrganizerCore::fileMapping(
return result;
}
-
+*/
diff --git a/src/organizercore.h b/src/organizercore.h
index 85f0e0c4..5cfbaca4 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -73,7 +73,7 @@ public:
void connectPlugins(PluginContainer *container);
void disconnectPlugins();
- void setManagedGame(const QString &gameName, const QString &gamePath);
+ void setManagedGame(const MOBase::IPluginGame *game);
void updateExecutablesList(QSettings &settings);
@@ -99,7 +99,7 @@ public:
ModListSortProxy *createModListProxyModel();
PluginListSortProxy *createPluginListProxyModel();
- MOBase::IPluginGame *managedGame() const;
+ MOBase::IPluginGame const *managedGame() const;
bool isArchivesInit() const { return m_ArchivesInit; }
@@ -126,13 +126,12 @@ public:
MOBase::DelayedFileWriter &pluginsWriter() { return m_PluginListsWriter; }
public:
- MOBase::IGameInfo &gameInfo() const;
MOBase::IModRepositoryBridge *createNexusBridge() const;
QString profileName() const;
QString profilePath() const;
QString downloadsPath() const;
MOBase::VersionInfo appVersion() const;
- MOBase::IModInterface *getMod(const QString &name);
+ MOBase::IModInterface *getMod(const QString &name) const;
MOBase::IModInterface *createMod(MOBase::GuessedValue<QString> &name);
bool removeMod(MOBase::IModInterface *mod);
void modDataChanged(MOBase::IModInterface *mod);
@@ -157,7 +156,7 @@ public:
bool onFinishedRun(const std::function<void (const QString &, unsigned int)> &func);
void refreshModList(bool saveChanges = true);
- std::vector<std::pair<QString, QString> > fileMapping();
+ //std::vector<std::pair<QString, QString> > fileMapping();
public: // IPluginDiagnose interface
@@ -194,7 +193,7 @@ signals:
*/
void modInstalled(const QString &modName);
- void managedGameChanged(MOBase::IPluginGame *gamePlugin);
+ void managedGameChanged(MOBase::IPluginGame const *gamePlugin);
private:
@@ -210,9 +209,11 @@ private:
bool testForSteam();
- std::vector<std::pair<QString, QString>> fileMapping(const QString &dataPath,
+ /*
+ * std::vector<std::pair<QString, QString>> fileMapping(const QString &dataPath,
const MOShared::DirectoryEntry *base,
const MOShared::DirectoryEntry *directoryEntry);
+*/
private slots:
@@ -229,12 +230,10 @@ private:
private:
- MOBase::IGameInfo *m_GameInfo;
-
IUserInterface *m_UserInterface;
PluginContainer *m_PluginContainer;
QString m_GameName;
- MOBase::IPluginGame *m_GamePlugin;
+ MOBase::IPluginGame const *m_GamePlugin;
Profile *m_CurrentProfile;
diff --git a/src/organizerproxy.cpp b/src/organizerproxy.cpp
index 095cb0bb..ba07c154 100644
--- a/src/organizerproxy.cpp
+++ b/src/organizerproxy.cpp
@@ -1,7 +1,8 @@
#include "organizerproxy.h"
-#include <gameinfo.h>
+
#include <appconfig.h>
+#include <QApplication>
using namespace MOBase;
using namespace MOShared;
@@ -13,11 +14,6 @@ OrganizerProxy::OrganizerProxy(OrganizerCore *organizer, const QString &pluginNa
{
}
-IGameInfo &OrganizerProxy::gameInfo() const
-{
- return m_Proxied->gameInfo();
-}
-
IModRepositoryBridge *OrganizerProxy::createNexusBridge() const
{
return new NexusBridge(m_PluginName);
@@ -40,7 +36,7 @@ QString OrganizerProxy::downloadsPath() const
QString OrganizerProxy::overwritePath() const
{
- return QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory()))
+ return QDir::fromNativeSeparators(qApp->property("dataPath").toString())
+ "/"
+ ToQString(AppConfig::overwritePath());
}
@@ -50,7 +46,7 @@ VersionInfo OrganizerProxy::appVersion() const
return m_Proxied->appVersion();
}
-IModInterface *OrganizerProxy::getMod(const QString &name)
+IModInterface *OrganizerProxy::getMod(const QString &name) const
{
return m_Proxied->getMod(name);
}
@@ -155,17 +151,22 @@ QList<MOBase::IOrganizer::FileInfo> OrganizerProxy::findFileInfos(const QString
return m_Proxied->findFileInfos(path, filter);
}
-MOBase::IDownloadManager *OrganizerProxy::downloadManager()
+MOBase::IDownloadManager *OrganizerProxy::downloadManager() const
{
return m_Proxied->downloadManager();
}
-MOBase::IPluginList *OrganizerProxy::pluginList()
+MOBase::IPluginList *OrganizerProxy::pluginList() const
{
return m_Proxied->pluginList();
}
-MOBase::IModList *OrganizerProxy::modList()
+MOBase::IModList *OrganizerProxy::modList() const
{
return m_Proxied->modList();
}
+
+MOBase::IPluginGame const *OrganizerProxy::managedGame() const
+{
+ return m_Proxied->managedGame();
+}
diff --git a/src/organizerproxy.h b/src/organizerproxy.h
index fb502a7f..62a35498 100644
--- a/src/organizerproxy.h
+++ b/src/organizerproxy.h
@@ -12,14 +12,13 @@ public:
OrganizerProxy(OrganizerCore *organizer, const QString &pluginName);
- virtual MOBase::IGameInfo &gameInfo() const;
virtual MOBase::IModRepositoryBridge *createNexusBridge() const;
virtual QString profileName() const;
virtual QString profilePath() const;
virtual QString downloadsPath() const;
virtual QString overwritePath() const;
virtual MOBase::VersionInfo appVersion() const;
- virtual MOBase::IModInterface *getMod(const QString &name);
+ virtual MOBase::IModInterface *getMod(const QString &name) const;
virtual MOBase::IModInterface *createMod(MOBase::GuessedValue<QString> &name);
virtual bool removeMod(MOBase::IModInterface *mod);
virtual void modDataChanged(MOBase::IModInterface *mod);
@@ -35,9 +34,9 @@ public:
virtual QStringList getFileOrigins(const QString &fileName) const;
virtual QList<FileInfo> findFileInfos(const QString &path, const std::function<bool(const FileInfo&)> &filter) const;
- virtual MOBase::IDownloadManager *downloadManager();
- virtual MOBase::IPluginList *pluginList();
- virtual MOBase::IModList *modList();
+ virtual MOBase::IDownloadManager *downloadManager() const;
+ virtual MOBase::IPluginList *pluginList() const;
+ virtual MOBase::IModList *modList() const;
virtual HANDLE startApplication(const QString &executable, const QStringList &args = QStringList(), const QString &cwd = "", const QString &profile = "");
virtual bool waitForApplication(HANDLE handle, LPDWORD exitCode = nullptr) const;
virtual void refreshModList(bool saveChanges);
@@ -46,6 +45,7 @@ public:
virtual bool onFinishedRun(const std::function<void (const QString&, unsigned int)> &func);
virtual bool onModInstalled(const std::function<void (const QString&)> &func);
+ virtual MOBase::IPluginGame const *managedGame() const;
private:
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp
index e7d493a7..7a609374 100644
--- a/src/pluginlist.cpp
+++ b/src/pluginlist.cpp
@@ -24,7 +24,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "scopeguard.h"
#include "modinfo.h"
#include <utility.h>
-#include <gameinfo.h>
#include <iplugingame.h>
#include <espfile.h>
#include <report.h>
@@ -128,7 +127,7 @@ void PluginList::refresh(const QString &profileName
m_ESPsByPriority.clear();
m_ESPs.clear();
- QStringList primaryPlugins = qApp->property("managed_game").value<IPluginGame*>()->getPrimaryPlugins();
+ QStringList primaryPlugins = m_GamePlugin->getPrimaryPlugins();
m_CurrentProfile = profileName;
@@ -313,7 +312,7 @@ bool PluginList::readLoadOrder(const QString &fileName)
int priority = 0;
- QStringList primaryPlugins = qApp->property("managed_game").value<IPluginGame*>()->getPrimaryPlugins();
+ QStringList primaryPlugins = m_GamePlugin->getPrimaryPlugins();
for (const QString &plugin : primaryPlugins) {
if (availableESPs.find(plugin) != availableESPs.end()) {
m_ESPLoadOrder[plugin] = priority++;
@@ -504,7 +503,7 @@ void PluginList::saveTo(const QString &pluginFileName
bool PluginList::saveLoadOrder(DirectoryEntry &directoryStructure)
{
- if (GameInfo::instance().getLoadOrderMechanism() != GameInfo::TYPE_FILETIME) {
+ if (m_GamePlugin->getLoadOrderMechanism() != IPluginGame::LoadOrderMechanism::FileTime) {
// nothing to do
return true;
}
@@ -1210,3 +1209,8 @@ PluginList::ESPInfo::ESPInfo(const QString &name, bool enabled,
m_IsDummy = false;
}
}
+
+void PluginList::managedGameChanged(IPluginGame const *gamePlugin)
+{
+ m_GamePlugin = gamePlugin;
+}
diff --git a/src/pluginlist.h b/src/pluginlist.h
index f8972f05..9fe6eeac 100644
--- a/src/pluginlist.h
+++ b/src/pluginlist.h
@@ -22,16 +22,20 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <directoryentry.h>
#include <ipluginlist.h>
+namespace MOBase { class IPluginGame; }
+
#include <QString>
#include <QListWidget>
#include <QTimer>
#include <QTemporaryFile>
+
#pragma warning(push)
#pragma warning(disable: 4100)
#ifndef Q_MOC_RUN
#include <boost/signals2.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#endif
+
#include <vector>
#include <map>
@@ -253,6 +257,12 @@ public slots:
**/
void disableAll();
+ /**
+ * @brief The currently managed game has changed
+ * @param gamePlugin
+ */
+ void managedGameChanged(MOBase::IPluginGame const *gamePlugin);
+
signals:
/**
@@ -337,6 +347,8 @@ private:
QTemporaryFile m_TempFile;
+ MOBase::IPluginGame const *m_GamePlugin;
+
};
#pragma warning(pop)
diff --git a/src/profile.cpp b/src/profile.cpp
index b990fbc1..77f6ebd1 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -18,7 +18,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "profile.h"
-#include "gameinfo.h"
+
#include "windows_error.h"
#include "modinfo.h"
#include "safewritefile.h"
@@ -30,26 +30,22 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <report.h>
#include <bsainvalidation.h>
#include <dataarchives.h>
+
#include <QMessageBox>
#include <QApplication>
#include <QSettings>
#include <QTemporaryFile>
+
#include <functional>
+#include <stdexcept>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shlobj.h>
-#include <stdexcept>
using namespace MOBase;
using namespace MOShared;
-
-Profile::Profile()
- : m_ModListWriter(std::bind(&Profile::writeModlistNow, this))
-{
-}
-
void Profile::touchFile(QString fileName)
{
QFile modList(m_Directory.filePath(fileName));
@@ -58,7 +54,7 @@ void Profile::touchFile(QString fileName)
}
}
-Profile::Profile(const QString &name, IPluginGame *gamePlugin, bool useDefaultSettings)
+Profile::Profile(const QString &name, IPluginGame const *gamePlugin, bool useDefaultSettings)
: m_ModListWriter(std::bind(&Profile::writeModlistNow, this))
, m_GamePlugin(gamePlugin)
{
@@ -99,8 +95,9 @@ Profile::Profile(const QString &name, IPluginGame *gamePlugin, bool useDefaultSe
}
-Profile::Profile(const QDir &directory, IPluginGame *gamePlugin)
+Profile::Profile(const QDir &directory, IPluginGame const *gamePlugin)
: m_Directory(directory)
+ , m_GamePlugin(gamePlugin)
, m_ModListWriter(std::bind(&Profile::writeModlistNow, this))
{
assert(gamePlugin != nullptr);
@@ -125,6 +122,8 @@ Profile::Profile(const QDir &directory, IPluginGame *gamePlugin)
Profile::Profile(const Profile &reference)
: m_Directory(reference.m_Directory)
, m_ModListWriter(std::bind(&Profile::writeModlistNow, this))
+ , m_GamePlugin(reference.m_GamePlugin)
+
{
refreshModStatus();
}
@@ -486,7 +485,7 @@ void Profile::setModPriority(unsigned int index, int &newPriority)
m_ModListWriter.write();
}
-Profile *Profile::createPtrFrom(const QString &name, const Profile &reference, MOBase::IPluginGame *gamePlugin)
+Profile *Profile::createPtrFrom(const QString &name, const Profile &reference, MOBase::IPluginGame const *gamePlugin)
{
QString profileDirectory = qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::profilesPath()) + "/" + name;
reference.copyFilesTo(profileDirectory);
@@ -568,10 +567,8 @@ void Profile::mergeTweaks(ModInfo::Ptr modInfo, const QString &tweakedIni) const
bool Profile::invalidationActive(bool *supported) const
{
- IPluginGame *gamePlugin = qApp->property("managed_game").value<IPluginGame*>();
-
- BSAInvalidation *invalidation = gamePlugin->feature<BSAInvalidation>();
- DataArchives *dataArchives = gamePlugin->feature<DataArchives>();
+ BSAInvalidation *invalidation = m_GamePlugin->feature<BSAInvalidation>();
+ DataArchives *dataArchives = m_GamePlugin->feature<DataArchives>();
if ((invalidation != nullptr) && (dataArchives != nullptr)) {
if (supported != nullptr) {
@@ -593,9 +590,7 @@ bool Profile::invalidationActive(bool *supported) const
void Profile::deactivateInvalidation()
{
- IPluginGame *gamePlugin = qApp->property("managed_game").value<IPluginGame*>();
-
- BSAInvalidation *invalidation = gamePlugin->feature<BSAInvalidation>();
+ BSAInvalidation *invalidation = m_GamePlugin->feature<BSAInvalidation>();
if (invalidation != nullptr) {
invalidation->deactivate(this);
@@ -605,9 +600,7 @@ void Profile::deactivateInvalidation()
void Profile::activateInvalidation()
{
- IPluginGame *gamePlugin = qApp->property("managed_game").value<IPluginGame*>();
-
- BSAInvalidation *invalidation = gamePlugin->feature<BSAInvalidation>();
+ BSAInvalidation *invalidation = m_GamePlugin->feature<BSAInvalidation>();
if (invalidation != nullptr) {
invalidation->activate(this);
@@ -681,8 +674,7 @@ QString Profile::getDeleterFileName() const
QString Profile::getIniFileName() const
{
- std::wstring primaryIniFile = *(GameInfo::instance().getIniFileNames().begin());
- return m_Directory.absoluteFilePath(ToQString(primaryIniFile));
+ return m_Directory.absoluteFilePath(m_GamePlugin->getIniFiles()[0]);
}
QString Profile::getProfileTweaks() const
diff --git a/src/profile.h b/src/profile.h
index 342b6fa0..b306e0c5 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -24,17 +24,16 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "modinfo.h"
#include <iprofile.h>
#include <delayedfilewriter.h>
+
#include <QString>
#include <QDir>
-#include <QMetaType>
#include <QSettings>
+
#include <vector>
#include <tuple>
-namespace MOBase {
- class IPluginGame;
-}
+namespace MOBase { class IPluginGame; }
/**
* @brief represents a profile
@@ -51,12 +50,6 @@ public:
public:
/**
- * @brief default constructor
- * @todo This constructor initialised nothing, the resulting object is not usable
- **/
- Profile();
-
- /**
* @brief constructor
*
* This constructor is used to create a new profile so it is to be assumed a profile
@@ -64,7 +57,8 @@ public:
* @param name name of the new profile
* @param filter save game filter. Defaults to &lt;no filter&gt;.
**/
- Profile(const QString &name, MOBase::IPluginGame *gamePlugin, bool useDefaultSettings);
+ Profile(const QString &name, MOBase::IPluginGame const *gamePlugin, bool useDefaultSettings);
+
/**
* @brief constructor
*
@@ -73,7 +67,7 @@ public:
* invoking this should always produce a working profile
* @param directory directory to read the profile from
**/
- Profile(const QDir &directory, MOBase::IPluginGame *gamePlugin);
+ Profile(const QDir &directory, MOBase::IPluginGame const *gamePlugin);
Profile(const Profile &reference);
@@ -88,7 +82,7 @@ public:
* @param name of the new profile
* @param reference profile to copy from
**/
- static Profile *createPtrFrom(const QString &name, const Profile &reference, MOBase::IPluginGame *gamePlugin);
+ static Profile *createPtrFrom(const QString &name, const Profile &reference, MOBase::IPluginGame const *gamePlugin);
MOBase::DelayedFileWriter &modlistWriter() { return m_ModListWriter; }
@@ -308,7 +302,7 @@ private:
QDir m_Directory;
- MOBase::IPluginGame *m_GamePlugin;
+ MOBase::IPluginGame const * const m_GamePlugin;
mutable QByteArray m_LastModlistHash;
std::vector<ModStatus> m_ModStatus;
@@ -319,7 +313,5 @@ private:
};
-Q_DECLARE_METATYPE(Profile)
-
#endif // PROFILE_H
diff --git a/src/profilesdialog.cpp b/src/profilesdialog.cpp
index 58be5448..b21aee53 100644
--- a/src/profilesdialog.cpp
+++ b/src/profilesdialog.cpp
@@ -42,10 +42,11 @@ using namespace MOShared;
Q_DECLARE_METATYPE(Profile::Ptr)
-ProfilesDialog::ProfilesDialog(const QString &profileName, QWidget *parent)
+ProfilesDialog::ProfilesDialog(const QString &profileName, MOBase::IPluginGame const *game, QWidget *parent)
: TutorableDialog("Profiles", parent)
, ui(new Ui::ProfilesDialog)
, m_FailState(false)
+ , m_Game(game)
{
ui->setupUi(this);
@@ -65,7 +66,6 @@ ProfilesDialog::ProfilesDialog(const QString &profileName, QWidget *parent)
QCheckBox *invalidationBox = findChild<QCheckBox*>("invalidationBox");
- IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
BSAInvalidation *invalidation = game->feature<BSAInvalidation>();
if (invalidation == nullptr) {
@@ -104,7 +104,7 @@ QListWidgetItem *ProfilesDialog::addItem(const QString &name)
QDir profileDir(name);
QListWidgetItem *newItem = new QListWidgetItem(profileDir.dirName(), m_ProfilesList);
try {
- newItem->setData(Qt::UserRole, QVariant::fromValue(Profile::Ptr(new Profile(profileDir, qApp->property("managed_game").value<IPluginGame*>()))));
+ newItem->setData(Qt::UserRole, QVariant::fromValue(Profile::Ptr(new Profile(profileDir, m_Game))));
m_FailState = false;
} catch (const std::exception& e) {
reportError(tr("failed to create profile: %1").arg(e.what()));
@@ -117,7 +117,7 @@ void ProfilesDialog::createProfile(const QString &name, bool useDefaultSettings)
try {
QListWidget *profilesList = findChild<QListWidget*>("profilesList");
QListWidgetItem *newItem = new QListWidgetItem(name, profilesList);
- newItem->setData(Qt::UserRole, QVariant::fromValue(Profile::Ptr(new Profile(name, qApp->property("managed_game").value<IPluginGame*>(), useDefaultSettings))));
+ newItem->setData(Qt::UserRole, QVariant::fromValue(Profile::Ptr(new Profile(name, m_Game, useDefaultSettings))));
profilesList->addItem(newItem);
m_FailState = false;
} catch (const std::exception&) {
@@ -131,7 +131,7 @@ void ProfilesDialog::createProfile(const QString &name, const Profile &reference
try {
QListWidget *profilesList = findChild<QListWidget*>("profilesList");
QListWidgetItem *newItem = new QListWidgetItem(name, profilesList);
- newItem->setData(Qt::UserRole, QVariant::fromValue(Profile::Ptr(Profile::createPtrFrom(name, reference, qApp->property("managed_game").value<IPluginGame*>()))));
+ newItem->setData(Qt::UserRole, QVariant::fromValue(Profile::Ptr(Profile::createPtrFrom(name, reference, m_Game))));
profilesList->addItem(newItem);
m_FailState = false;
} catch (const std::exception&) {
@@ -324,6 +324,6 @@ void ProfilesDialog::on_localSavesBox_stateChanged(int state)
void ProfilesDialog::on_transferButton_clicked()
{
const Profile::Ptr currentProfile = m_ProfilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
- TransferSavesDialog transferDialog(*currentProfile, qApp->property("managed_game").value<IPluginGame*>(), this);
+ TransferSavesDialog transferDialog(*currentProfile, m_Game, this);
transferDialog.exec();
}
diff --git a/src/profilesdialog.h b/src/profilesdialog.h
index 6dd0c1d4..26476883 100644
--- a/src/profilesdialog.h
+++ b/src/profilesdialog.h
@@ -50,7 +50,7 @@ public:
* @param parent parent widget
* @todo the game path could be retrieved from GameInfo just as easily
**/
- explicit ProfilesDialog(const QString &profileName, QWidget *parent = 0);
+ explicit ProfilesDialog(const QString &profileName, MOBase::IPluginGame const *game, QWidget *parent = 0);
~ProfilesDialog();
/**
@@ -93,7 +93,7 @@ private:
Ui::ProfilesDialog *ui;
QListWidget *m_ProfilesList;
bool m_FailState;
-
+ MOBase::IPluginGame const *m_Game;
};
#endif // PROFILESDIALOG_H
diff --git a/src/savegame.cpp b/src/savegame.cpp
index 1cdabb2d..2b125575 100644
--- a/src/savegame.cpp
+++ b/src/savegame.cpp
@@ -18,50 +18,28 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "savegame.h"
-#include <QFile>
-#include <QBuffer>
-#include <set>
-#include <QFileInfo>
-#include <QDateTime>
-#include <utility.h>
-#include <limits>
-#include "gameinfo.h"
-
-
-SaveGame::SaveGame(QObject *parent)
- : QObject(parent), m_FileName(), m_PCName(), m_PCLevel(0), m_PCLocation(), m_SaveNumber(0), m_Screenshot()
-{
-}
+#include "iplugingame.h"
+#include "scriptextender.h"
+#include "utility.h"
-SaveGame::SaveGame(QObject *parent, const QString &filename)
- : QObject(parent), m_FileName(filename), m_PCName(), m_PCLevel(0), m_PCLocation(), m_SaveNumber(0), m_Screenshot()
-{
-}
-
+#include <QApplication>
+#include <QDateTime>
+#include <QFile>
+#include <QFileInfo>
-SaveGame::SaveGame(const SaveGame& reference)
- : m_FileName(reference.m_FileName), m_PCName(reference.m_PCName), m_PCLevel(reference.m_PCLevel),
- m_PCLocation(reference.m_PCLocation), m_SaveNumber(reference.m_SaveNumber),
- m_Screenshot(reference.m_Screenshot)
-{
-}
+#include <limits>
+#include <set>
+using namespace MOBase;
-SaveGame& SaveGame::operator=(const SaveGame &reference)
+SaveGame::SaveGame(QObject *parent, const QString &filename, const MOBase::IPluginGame *game)
+ : QObject(parent)
+ , m_FileName(filename)
+ , m_Game(game)
{
- if (&reference != this) {
- m_FileName = reference.m_FileName;
- m_PCName = reference.m_PCName;
- m_PCLevel = reference.m_PCLevel;
- m_PCLocation = reference.m_PCLocation;
- m_SaveNumber = reference.m_SaveNumber;
- m_Screenshot = reference.m_Screenshot;
- }
- return *this;
}
-
SaveGame::~SaveGame()
{
}
@@ -69,11 +47,14 @@ SaveGame::~SaveGame()
QStringList SaveGame::attachedFiles() const
{
QStringList result;
- foreach (const std::wstring &ext, MOShared::GameInfo::instance().getSavegameAttachmentExtensions()) {
- QFileInfo fi(fileName());
- fi.setFile(fi.canonicalPath() + "/" + fi.completeBaseName() + "." + MOBase::ToQString(ext));
- if (fi.exists()) {
- result.append(fi.filePath());
+ ScriptExtender const *extender = m_Game->feature<ScriptExtender>();
+ if (extender != nullptr) {
+ for (QString const &ext : extender->saveGameAttachmentExtensions()) {
+ QFileInfo fi(fileName());
+ fi.setFile(fi.canonicalPath() + "/" + fi.completeBaseName() + "." + ext);
+ if (fi.exists()) {
+ result.append(fi.filePath());
+ }
}
}
@@ -86,21 +67,3 @@ QStringList SaveGame::saveFiles() const
result.append(fileName());
return result;
}
-
-
-void SaveGame::setCreationTime(const QString &fileName)
-{
- QFileInfo creationTime(fileName);
- QDateTime modified = creationTime.lastModified();
- memset(&m_CreationTime, 0, sizeof(SYSTEMTIME));
-
- m_CreationTime.wDay = static_cast<WORD>(modified.date().day());
- m_CreationTime.wDayOfWeek = static_cast<WORD>(modified.date().dayOfWeek());
- m_CreationTime.wMonth = static_cast<WORD>(modified.date().month());
- m_CreationTime.wYear =static_cast<WORD>( modified.date().year());
-
- m_CreationTime.wHour = static_cast<WORD>(modified.time().hour());
- m_CreationTime.wMinute = static_cast<WORD>(modified.time().minute());
- m_CreationTime.wSecond = static_cast<WORD>(modified.time().second());
- m_CreationTime.wMilliseconds = static_cast<WORD>(modified.time().msec());
-}
diff --git a/src/savegame.h b/src/savegame.h
index 1fd2f7ab..d1bf4691 100644
--- a/src/savegame.h
+++ b/src/savegame.h
@@ -31,6 +31,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
+namespace MOBase { class IPluginGame; }
/**
* @brief represents a single save game
@@ -42,22 +43,13 @@ Q_OBJECT
public:
/**
- * @brief construct an empty object
- **/
- SaveGame(QObject *parent = 0);
-
- /**
* @brief construct a save game and immediately read out information from the file
*
* @param filename absolute path of the save game file
**/
- SaveGame(QObject *parent, const QString &filename);
-
- SaveGame(const SaveGame& reference);
-
- SaveGame& operator=(const SaveGame &reference);
+ SaveGame(QObject *parent, const QString &filename, MOBase::IPluginGame const *game);
- ~SaveGame();
+ virtual ~SaveGame();
/**
* @brief read out information from a savegame
@@ -111,10 +103,6 @@ public:
**/
const QImage &screenshot() const { return m_Screenshot; }
-private:
-
- void setCreationTime(const QString &fileName);
-
protected:
QString m_FileName;
@@ -125,6 +113,8 @@ protected:
SYSTEMTIME m_CreationTime;
QImage m_Screenshot;
+private:
+ MOBase::IPluginGame const * const m_Game;
};
diff --git a/src/savegamegamebryo.cpp b/src/savegamegamebryo.cpp
index 7b012e22..68ed30af 100644
--- a/src/savegamegamebryo.cpp
+++ b/src/savegamegamebryo.cpp
@@ -18,321 +18,49 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "savegamegamebyro.h"
-#include "gameinfo.h"
-#include <QFile>
-#include <QBuffer>
-#include <set>
-#include <QFileInfo>
-#include <QDateTime>
-#include <limits>
-
-
-using namespace MOShared;
-
-
-template <typename T>
-static void FileRead(QFile &file, T &value)
-{
- int read = file.read(reinterpret_cast<char*>(&value), sizeof(T));
- if (read != sizeof(T)) {
- throw std::runtime_error("unexpected end of file");
- }
-}
-
-
-template <typename T>
-static void FileSkip(QFile &file, int count = 1)
-{
- char ignore[sizeof(T)];
- for (int i = 0; i < count; ++i) {
- if (file.read(ignore, sizeof(T)) != sizeof(T)) {
- throw std::runtime_error("unexpected end of file");
- }
- }
-}
-
-
-static QString ReadBString(QFile &file)
-{
- char buffer[256];
- file.read(buffer, 1); // size including zero termination
- unsigned char size = buffer[0];
- file.read(buffer, size);
- return QString::fromLatin1(buffer, size);
-}
-
-
-static QString ReadFOSString(QFile &file, bool delimiter)
-{
- union {
- char lengthBuffer[2];
- unsigned short length;
- };
-
- file.read(lengthBuffer, 2);
- if (delimiter) {
- FileSkip<char>(file); // 0x7c
- }
- char *buffer = new char[length];
- file.read(buffer, length);
-
- QString result = QString::fromLatin1(buffer, length);
- delete [] buffer;
-
- return result;
-}
-
-
-SaveGameGamebryo::SaveGameGamebryo(QObject *parent)
- : SaveGame(parent), m_Plugins()
-{
-}
-
-
-SaveGameGamebryo::SaveGameGamebryo(QObject *parent, const QString &fileName)
- : SaveGame(parent, fileName), m_Plugins()
-{
- readFile(fileName);
-}
-
-
-SaveGameGamebryo::SaveGameGamebryo(const SaveGameGamebryo& reference)
- : SaveGame(reference), m_Plugins(reference.m_Plugins)
-{
-}
-
-
-SaveGameGamebryo& SaveGameGamebryo::operator=(const SaveGameGamebryo &reference)
-{
- if (&reference != this) {
- SaveGame::operator =(reference);
- m_Plugins = reference.m_Plugins;
- }
- return *this;
-}
-
-
-SaveGameGamebryo::~SaveGameGamebryo()
-{
-}
-
-
-
-
-
-void SaveGameGamebryo::readSkyrimFile(QFile &saveFile)
-{
- char fileID[14];
- saveFile.read(fileID, 13);
- fileID[13] = '\0';
- if (strncmp(fileID, "TESV_SAVEGAME", 13) != 0) {
- throw std::runtime_error(QObject::tr("wrong file format").toUtf8().constData());
- }
-
- FileSkip<unsigned long>(saveFile); // header size
- FileSkip<unsigned long>(saveFile); // header version, -> 8
- FileRead(saveFile, m_SaveNumber);
-
- m_PCName = ReadFOSString(saveFile, false);
-
- unsigned long temp;
- FileRead(saveFile, temp); // player level
- m_PCLevel = static_cast<unsigned short>(temp);
-
- m_PCLocation = ReadFOSString(saveFile, false);
- ReadFOSString(saveFile, false); // playtime as ascii hhh.mm.ss
- ReadFOSString(saveFile, false); // race name (i.e. BretonRace)
-
-
- FileSkip<unsigned short>(saveFile); // ???
- FileSkip<float>(saveFile, 2); // ???
- FileSkip<unsigned char>(saveFile, 8); // filetime
+#include "isavegame.h"
+#include "savegameinfo.h"
+#include "iplugingame.h"
+#include "gamebryosavegame.h"
-// FileSkip<unsigned char>(saveFile, 18); // ??? 18 bytes of data. not completely random, maybe a time stamp? maybe
-
- unsigned long width, height;
- FileRead(saveFile, width); // 320
- FileRead(saveFile, height); // 192
-
- QScopedArrayPointer<unsigned char> buffer(new unsigned char[width * height * 3]);
- saveFile.read(reinterpret_cast<char*>(buffer.data()), width * height * 3);
- // why do I have to copy here? without the copy, the buffer seems to get deleted after the
- // temporary vanishes, but Qts implicit sharing should handle that?
- m_Screenshot = QImage(buffer.data(), width, height, QImage::Format_RGB888).copy();
-
- FileSkip<unsigned char>(saveFile); // form version
- FileSkip<unsigned long>(saveFile); // plugin info size
+#include <limits>
+#include <set>
- unsigned char pluginCount;
- FileRead(saveFile, pluginCount);
+using namespace MOBase;
- for (int i = 0; i < pluginCount; ++i) {
- m_Plugins.push_back(ReadFOSString(saveFile, false));
- }
-}
-
-void SaveGameGamebryo::readESSFile(QFile &saveFile)
+SaveGameGamebryo::SaveGameGamebryo(QObject *parent, const QString &fileName, IPluginGame const *game)
+ : SaveGame(parent, fileName, game)
+ , m_Plugins()
{
- char fileID[13];
- unsigned char versionMinor;
- unsigned long headerVersion, saveHeaderSize;
-// *** format is different for fallout!
- saveFile.read(fileID, 12);
- fileID[12] = '\0';
- FileSkip<unsigned char>(saveFile); FileRead(saveFile, versionMinor);
- FileSkip<SYSTEMTIME>(saveFile); // modified time
- FileRead(saveFile, headerVersion); FileRead(saveFile, saveHeaderSize);
-
- if (strncmp(fileID, "TES4SAVEGAME", 12) != 0) {
- throw std::runtime_error(QObject::tr("wrong file format").toUtf8().constData());
- }
-
- FileRead(saveFile, m_SaveNumber);
+ SaveGameInfo const *info = game->feature<SaveGameInfo>();
+ if (info != nullptr) {
+ ISaveGame const *save = info->getSaveGameInfo(fileName);
+ m_Save = save;
- m_PCName = ReadBString(saveFile);
+ //Kludgery
+ GamebryoSaveGame const *s = dynamic_cast<GamebryoSaveGame const *>(save);
+ m_PCName = s->getPCName();
+ m_PCLevel = s->getPCLevel();
+ m_PCLocation = s->getPCLocation();
+ m_SaveNumber = s->getSaveNumber();
- FileRead(saveFile, m_PCLevel);
- m_PCLocation = ReadBString(saveFile);
- FileSkip<float>(saveFile); // game days
- FileSkip<unsigned long>(saveFile); // game ticks
- FileRead(saveFile, m_CreationTime);
+ QDateTime modified = s->getCreationTime();
+ memset(&m_CreationTime, 0, sizeof(SYSTEMTIME));
- unsigned long size;
- FileRead(saveFile, size); // screenshot size
+ m_CreationTime.wDay = static_cast<WORD>(modified.date().day());
+ m_CreationTime.wDayOfWeek = static_cast<WORD>(modified.date().dayOfWeek());
+ m_CreationTime.wMonth = static_cast<WORD>(modified.date().month());
+ m_CreationTime.wYear =static_cast<WORD>( modified.date().year());
- unsigned long width, height;
- FileRead(saveFile, width); FileRead(saveFile, height);
- QScopedArrayPointer<unsigned char> buffer(new unsigned char[width * height * 3]);
- saveFile.read(reinterpret_cast<char*>(buffer.data()), width * height * 3);
- // why do I have to copy here? without the copy, the buffer seems to get deleted after the
- // temporary vanishes, but Qts implicit sharing should handle that?
- m_Screenshot = QImage(buffer.data(), width, height, QImage::Format_RGB888).copy();
+ m_CreationTime.wHour = static_cast<WORD>(modified.time().hour());
+ m_CreationTime.wMinute = static_cast<WORD>(modified.time().minute());
+ m_CreationTime.wSecond = static_cast<WORD>(modified.time().second());
+ m_CreationTime.wMilliseconds = static_cast<WORD>(modified.time().msec());
- unsigned char pluginCount;
- FileRead(saveFile, pluginCount);
-
- for (int i = 0; i < pluginCount; ++i) {
- QString name = ReadBString(saveFile);
- m_Plugins.push_back(name);
- }
-}
+ m_Screenshot = s->getScreenshot();
-
-void SaveGameGamebryo::readFOSFile(QFile &saveFile, bool newVegas)
-{
- char fileID[13];
- saveFile.read(fileID, 12);
- // the signature is only 11 characters, the 12th is random?
- fileID[11] = '\0';
-
- if (strncmp(fileID, "FO3SAVEGAME", 11) != 0) {
- throw std::runtime_error(QObject::tr("wrong file format").toUtf8().constData());
- }
-
- char ignore = 0x00;
- while (ignore != 0x7c) {
- FileRead<char>(saveFile, ignore); // unknown
- }
- if (newVegas) {
- ignore = 0x00;
- // in new vegas there is another block of uninteresting (?) information
- FileSkip<char>(saveFile); // 0x7c
- while (ignore != 0x7c) {
- FileRead<char>(saveFile, ignore); // unknown
- }
+ m_Plugins = s->getPlugins();
}
-
- unsigned long width, height;
- FileRead(saveFile, width);
- FileSkip<char>(saveFile); // 0x7c
- FileRead(saveFile, height);
- FileSkip<char>(saveFile); // 0x7c
-
- FileRead(saveFile, m_SaveNumber);
- FileSkip<char>(saveFile); // 0x7c
-
- m_PCName = ReadFOSString(saveFile, true);
- FileSkip<char>(saveFile); // 0x7c
-
- ReadFOSString(saveFile, true);
- FileSkip<char>(saveFile); // 0x7c
-
- long Level;
- FileRead(saveFile, Level);
- m_PCLevel = Level;
- FileSkip<char>(saveFile); // 0x7c
-
- m_PCLocation = ReadFOSString(saveFile, true);
- FileSkip<char>(saveFile); // 0x7c
-
- ReadFOSString(saveFile, true); // playtime
-
- FileSkip<char>(saveFile);
-
- QScopedArrayPointer<unsigned char> buffer(new unsigned char[width * height * 3]);
- saveFile.read(reinterpret_cast<char*>(buffer.data()), width * height * 3);
- // why do I have to copy here? without the copy, the buffer seems to get deleted after the
- // temporary vanishes, but Qts implicit sharing should handle that?
- m_Screenshot = QImage(buffer.data(), width, height, QImage::Format_RGB888).scaledToWidth(256);
-
- FileSkip<char>(saveFile, 5); // unknown
-
- unsigned char pluginCount = 0;
- FileRead(saveFile, pluginCount);
- FileSkip<char>(saveFile); // 0x7c
-
- for (int i = 0; i < pluginCount; ++i) {
- QString name = ReadFOSString(saveFile, true);
- m_Plugins.push_back(name);
- FileSkip<char>(saveFile); // 0x7c
- }
-}
-
-
-void SaveGameGamebryo::setCreationTime(const QString &fileName)
-{
- QFileInfo creationTime(fileName);
- QDateTime modified = creationTime.lastModified();
- memset(&m_CreationTime, 0, sizeof(SYSTEMTIME));
-
- m_CreationTime.wDay = static_cast<WORD>(modified.date().day());
- m_CreationTime.wDayOfWeek = static_cast<WORD>(modified.date().dayOfWeek());
- m_CreationTime.wMonth = static_cast<WORD>(modified.date().month());
- m_CreationTime.wYear =static_cast<WORD>( modified.date().year());
-
- m_CreationTime.wHour = static_cast<WORD>(modified.time().hour());
- m_CreationTime.wMinute = static_cast<WORD>(modified.time().minute());
- m_CreationTime.wSecond = static_cast<WORD>(modified.time().second());
- m_CreationTime.wMilliseconds = static_cast<WORD>(modified.time().msec());
-}
-
-
-void SaveGameGamebryo::readFile(const QString &fileName)
-{
- m_FileName = fileName;
- QFile saveFile(fileName);
- if (!saveFile.open(QIODevice::ReadOnly)) {
- throw std::runtime_error(QObject::tr("failed to open %1").arg(fileName).toUtf8().constData());
- }
- switch (GameInfo::instance().getType()) {
- case GameInfo::TYPE_FALLOUT3: {
- setCreationTime(fileName);
- readFOSFile(saveFile, false);
- } break;
- case GameInfo::TYPE_FALLOUTNV: {
- setCreationTime(fileName);
- readFOSFile(saveFile, true);
- } break;
- case GameInfo::TYPE_OBLIVION: {
- readESSFile(saveFile);
- } break;
- case GameInfo::TYPE_SKYRIM: {
- setCreationTime(fileName);
- readSkyrimFile(saveFile);
- } break;
- }
-
- saveFile.close();
}
diff --git a/src/savegamegamebyro.h b/src/savegamegamebyro.h
index e08e1044..bce08018 100644
--- a/src/savegamegamebyro.h
+++ b/src/savegamegamebyro.h
@@ -20,17 +20,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef SAVEGAMEGAMEBRYO_H
#define SAVEGAMEGAMEBRYO_H
-
#include "savegame.h"
-#include <QString>
-#include <QObject>
#include <QMetaType>
-#include <QFile>
-
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
+#include <QObject>
+#include <QString>
+namespace MOBase { class IPluginGame; class ISaveGame; }
/**
* @brief represents a single save game
@@ -42,30 +38,20 @@ Q_OBJECT
public:
/**
- * @brief construct an empty object
- **/
- SaveGameGamebryo(QObject *parent = 0);
-
- /**
* @brief construct a save game and immediately read out information from the file
*
* @param filename absolute path of the save game file
**/
- SaveGameGamebryo(QObject *parent, const QString &filename);
+ SaveGameGamebryo(QObject *parent, const QString &filename, MOBase::IPluginGame const *game);
+ /*
SaveGameGamebryo(const SaveGameGamebryo &reference);
SaveGameGamebryo &operator=(const SaveGameGamebryo &reference);
~SaveGameGamebryo();
-
- /**
- * @brief read out information from a savegame
- *
- * @param fileName absolute path of the save game file
- **/
- virtual void readFile(const QString &fileName);
+ */
/**
* @return number of plugins that were enabled when the save game was created
@@ -80,22 +66,12 @@ public:
**/
const QString &plugin(int index) const { return m_Plugins.at(index); }
-
private:
- void readESSFile(QFile &saveFile);
- void readFOSFile(QFile &saveFile, bool newVegas);
- void readSkyrimFile(QFile &saveFile);
-
- void setCreationTime(const QString &fileName);
-
-private:
-
- std::vector<QString> m_Plugins;
+ QStringList m_Plugins;
+ //Note: This isn't owned by us so safe to copy
+ MOBase::ISaveGame const *m_Save;
};
-Q_DECLARE_METATYPE(SaveGameGamebryo)
-Q_DECLARE_METATYPE(SaveGameGamebryo*)
-
#endif // SAVEGAMEGAMEBRYO_H
diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp
index 5cd6cf36..11478fbc 100644
--- a/src/selfupdater.cpp
+++ b/src/selfupdater.cpp
@@ -18,16 +18,18 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "selfupdater.h"
+
#include "utility.h"
#include "installationmanager.h"
+#include "iplugingame.h"
#include "messagedialog.h"
#include "downloadmanager.h"
#include "nexusinterface.h"
#include "nxmaccessmanager.h"
#include <versioninfo.h>
-#include <gameinfo.h>
-#include <skyriminfo.h>
#include <report.h>
+#include <util.h>
+
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
@@ -35,7 +37,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QLibrary>
#include <QProcess>
#include <QApplication>
-#include <util.h>
#include <boost/bind.hpp>
@@ -62,6 +63,7 @@ SelfUpdater::SelfUpdater(NexusInterface *nexusInterface)
, m_UpdateRequestID(-1)
, m_Reply(nullptr)
, m_Attempts(3)
+ , m_NexusDownload(nullptr)
{
QLibrary archiveLib("dlls\\archive.dll");
if (!archiveLib.load()) {
@@ -101,12 +103,10 @@ void SelfUpdater::testForUpdate()
emit updateAvailable();
return;
}
-
- if (m_UpdateRequestID == -1) {
+ if (m_UpdateRequestID == -1 && m_NexusDownload != nullptr) {
m_UpdateRequestID = m_Interface->requestDescription(
- SkyrimInfo::getNexusModIDStatic(), this, QVariant(),
- QString(), ToQString(SkyrimInfo::getNexusInfoUrlStatic()),
- SkyrimInfo::getNexusGameIDStatic());
+ m_NexusDownload->getNexusModOrganizerID(), this, QVariant(),
+ QString(), m_NexusDownload);
}
}
@@ -123,9 +123,9 @@ void SelfUpdater::startUpdate()
if (QMessageBox::question(m_Parent, tr("Update"),
tr("An update is available (newest version: %1), do you want to install it?").arg(m_NewestVersion),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- m_UpdateRequestID = m_Interface->requestFiles(SkyrimInfo::getNexusModIDStatic(),
- this, m_NewestVersion,
- ToQString(SkyrimInfo::getNexusInfoUrlStatic()));
+ m_UpdateRequestID = m_Interface->requestFiles(m_NexusDownload->getNexusModOrganizerID(),
+ this, m_NewestVersion, "",
+ m_NexusDownload);
}
}
}
@@ -159,7 +159,7 @@ void SelfUpdater::download(const QString &downloadLink, const QString &fileName)
QNetworkRequest request(dlUrl);
m_Canceled = false;
m_Reply = accessManager->get(request);
- m_UpdateFile.setFileName(QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory()).append("\\").append(fileName)));
+ m_UpdateFile.setFileName(QDir::fromNativeSeparators(qApp->property("dataPath").toString()).append("/").append(fileName));
m_UpdateFile.open(QIODevice::WriteOnly);
showProgress();
@@ -243,7 +243,7 @@ void SelfUpdater::downloadCancel()
void SelfUpdater::installUpdate()
{
- const QString mopath = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory()));
+ const QString mopath = QDir::fromNativeSeparators(qApp->property("dataPath").toString());
QString backupPath = mopath + "/update_backup";
QDir().mkdir(backupPath);
@@ -280,9 +280,7 @@ void SelfUpdater::installUpdate()
}
// now unpack the archive into the mo directory
- if (!m_ArchiveHandler->extract(QString::fromStdWString(GameInfo::instance().getOrganizerDirectory()),
- nullptr,
- nullptr,
+ if (!m_ArchiveHandler->extract(mopath, nullptr, nullptr,
new MethodCallback<SelfUpdater, void, QString const &>(this, &SelfUpdater::report7ZipError))) {
throw std::runtime_error("extracting failed");
}
@@ -418,18 +416,18 @@ void SelfUpdater::nxmFilesAvailable(int, QVariant userData, QVariant resultData,
if (updateFileID != -1) {
qDebug("update available: %d", updateFileID);
- m_UpdateRequestID = m_Interface->requestDownloadURL(SkyrimInfo::getNexusModIDStatic(),
- updateFileID, this, updateFileName,
- ToQString(SkyrimInfo::getNexusInfoUrlStatic()));
+ m_UpdateRequestID = m_Interface->requestDownloadURL(m_NexusDownload->getNexusModOrganizerID(),
+ updateFileID, this, updateFileName, "",
+ m_NexusDownload);
} else if (mainFileID != -1) {
qDebug("full download required: %d", mainFileID);
if (QMessageBox::question(m_Parent, tr("Update"),
tr("No incremental update available for this version, "
"the complete package needs to be downloaded (%1 kB)").arg(mainFileSize),
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
- m_UpdateRequestID = m_Interface->requestDownloadURL(SkyrimInfo::getNexusModIDStatic(),
- mainFileID, this, mainFileName,
- ToQString(SkyrimInfo::getNexusInfoUrlStatic()));
+ m_UpdateRequestID = m_Interface->requestDownloadURL(m_NexusDownload->getNexusModOrganizerID(),
+ mainFileID, this, mainFileName, "",
+ m_NexusDownload);
}
} else {
qCritical("no file for update found");
@@ -473,3 +471,9 @@ void SelfUpdater::nxmDownloadURLsAvailable(int, int, QVariant userData, QVariant
}
}
}
+
+/** Set the game check for updates */
+void SelfUpdater::setNexusDownload(MOBase::IPluginGame const *game)
+{
+ m_NexusDownload = game;
+}
diff --git a/src/selfupdater.h b/src/selfupdater.h
index f804f63c..446778fb 100644
--- a/src/selfupdater.h
+++ b/src/selfupdater.h
@@ -29,6 +29,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QFile>
#include <QProgressDialog>
+namespace MOBase { class IPluginGame; }
class NexusInterface;
@@ -83,6 +84,9 @@ public:
**/
MOBase::VersionInfo getVersion() const { return m_MOVersion; }
+ /** Set the game check for updates */
+ void setNexusDownload(MOBase::IPluginGame const *game);
+
public slots:
/**
@@ -143,6 +147,7 @@ private:
Archive *m_ArchiveHandler;
+ MOBase::IPluginGame const *m_NexusDownload;
};
diff --git a/src/settings.cpp b/src/settings.cpp
index 4c2a34c8..e175b210 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -23,25 +23,21 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "utility.h"
#include "helper.h"
#include "json.h"
-#include <gameinfo.h>
#include <appconfig.h>
#include <utility.h>
#include <iplugingame.h>
#include <QCheckBox>
-#include <QLineEdit>
-#include <QDirIterator>
-#include <QRegExp>
#include <QCoreApplication>
-#include <QMessageBox>
#include <QDesktopServices>
+#include <QDirIterator>
+#include <QLineEdit>
+#include <QMessageBox>
+#include <QRegExp>
#include <memory>
-
using namespace MOBase;
-using namespace MOShared;
-
template <typename T>
class QListWidgetItemEx : public QListWidgetItem {
@@ -112,7 +108,7 @@ void Settings::registerAsNXMHandler(bool force)
std::wstring nxmPath = ToWString(QCoreApplication::applicationDirPath() + "/nxmhandler.exe");
std::wstring executable = ToWString(QCoreApplication::applicationFilePath());
std::wstring mode = force ? L"forcereg" : L"reg";
- std::wstring parameters = mode + L" " + GameInfo::instance().getGameShortName() + L" \"" + executable + L"\"";
+ std::wstring parameters = mode + L" " + m_GamePlugin->getGameShortName().toStdWString() + L" \"" + executable + L"\"";
HINSTANCE res = ::ShellExecuteW(nullptr, L"open", nxmPath.c_str(), parameters.c_str(), nullptr, SW_SHOWNORMAL);
if ((int)res <= 32) {
QMessageBox::critical(nullptr, tr("Failed"),
@@ -120,7 +116,7 @@ void Settings::registerAsNXMHandler(bool force)
}
}
-void Settings::managedGameChanged(IPluginGame *gamePlugin)
+void Settings::managedGameChanged(IPluginGame const *gamePlugin)
{
m_GamePlugin = gamePlugin;
}
diff --git a/src/settings.h b/src/settings.h
index def1dc5c..b6f25a6d 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -299,7 +299,7 @@ public:
public slots:
- void managedGameChanged(MOBase::IPluginGame *gamePlugin);
+ void managedGameChanged(MOBase::IPluginGame const *gamePlugin);
private:
@@ -420,7 +420,7 @@ private:
static Settings *s_Instance;
- MOBase::IPluginGame *m_GamePlugin;
+ MOBase::IPluginGame const *m_GamePlugin;
QSettings m_Settings;
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index 765858f5..8bc1dbc6 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -18,22 +18,24 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "settingsdialog.h"
+
#include "ui_settingsdialog.h"
#include "categoriesdialog.h"
#include "helper.h"
#include "noeditdelegate.h"
-#include <gameinfo.h>
+#include "iplugingame.h"
+#include "settings.h"
+
#include <QDirIterator>
#include <QFileDialog>
#include <QMessageBox>
#include <QShortcut>
+
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
-#include "settings.h"
using namespace MOBase;
-using namespace MOShared;
SettingsDialog::SettingsDialog(QWidget *parent)
@@ -87,7 +89,11 @@ void SettingsDialog::on_categoriesBtn_clicked()
void SettingsDialog::on_bsaDateBtn_clicked()
{
- Helper::backdateBSAs(GameInfo::instance().getOrganizerDirectory(), GameInfo::instance().getGameDirectory().append(L"\\data"));
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
+ QDir dir = game->dataDirectory();
+
+ Helper::backdateBSAs(qApp->property("dataPath").toString().toStdWString(),
+ dir.absolutePath().toStdWString());
}
void SettingsDialog::on_browseDownloadDirBtn_clicked()
diff --git a/src/shared/fallout3info.cpp b/src/shared/fallout3info.cpp
index f0776a7d..797d68ec 100644
--- a/src/shared/fallout3info.cpp
+++ b/src/shared/fallout3info.cpp
@@ -30,8 +30,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
namespace MOShared {
-Fallout3Info::Fallout3Info(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gameDirectory)
- : GameInfo(moDirectory, moDataDirectory, gameDirectory)
+Fallout3Info::Fallout3Info(const std::wstring &gameDirectory)
+ : GameInfo(gameDirectory)
{
identifyMyGamesDirectory(L"fallout3");
}
@@ -63,21 +63,6 @@ std::wstring Fallout3Info::getRegPathStatic()
}
-std::vector<std::wstring> Fallout3Info::getDLCPlugins() const
-{
- return boost::assign::list_of (L"ThePitt.esm")
- (L"Anchorage.esm")
- (L"BrokenSteel.esm")
- (L"PointLookout.esm")
- (L"Zeta.esm")
- ;
-}
-
-std::vector<std::wstring> Fallout3Info::getSavegameAttachmentExtensions() const
-{
- return std::vector<std::wstring>();
-}
-
std::vector<std::wstring> Fallout3Info::getIniFileNames() const
{
return boost::assign::list_of(L"fallout.ini")(L"falloutprefs.ini");
@@ -88,25 +73,6 @@ std::wstring Fallout3Info::getReferenceDataFile() const
return L"Fallout - Meshes.bsa";
}
-std::wstring Fallout3Info::getNexusPage(bool nmmScheme) const
-{
- if (nmmScheme) {
- return L"http://nmm.nexusmods.com/fallout3";
- } else {
- return L"http://www.nexusmods.com/fallout3";
- }
-}
-
-std::wstring Fallout3Info::getNexusInfoUrlStatic()
-{
- return L"http://nmm.nexusmods.com/fallout3";
-}
-
-int Fallout3Info::getNexusModIDStatic()
-{
- return 16348;
-}
-
bool Fallout3Info::rerouteToProfile(const wchar_t *fileName, const wchar_t*) const
{
static LPCWSTR profileFiles[] = { L"fallout.ini", L"falloutprefs.ini", L"plugins.txt", nullptr };
@@ -119,9 +85,4 @@ bool Fallout3Info::rerouteToProfile(const wchar_t *fileName, const wchar_t*) con
return false;
}
-bool Fallout3Info::isValidModURL(int modID, const std::wstring &url) const
-{
- return GameInfo::isValidModURL(modID, url, L"http://fallout3.nexusmods.com");
-}
-
} // namespace MOShared
diff --git a/src/shared/fallout3info.h b/src/shared/fallout3info.h
index 0a2b0ebe..5cf98e3b 100644
--- a/src/shared/fallout3info.h
+++ b/src/shared/fallout3info.h
@@ -36,37 +36,19 @@ public:
static std::wstring getRegPathStatic();
virtual std::wstring getRegPath() const { return getRegPathStatic(); }
- virtual std::wstring getBinaryName() const { return L"Fallout3.exe"; }
-
- virtual GameInfo::Type getType() const { return TYPE_FALLOUT3; }
-
- virtual std::wstring getGameName() const { return L"Fallout 3"; }
- virtual std::wstring getGameShortName() const { return L"Fallout3"; }
-
- virtual std::vector<std::wstring> getDLCPlugins() const;
- virtual std::vector<std::wstring> getSavegameAttachmentExtensions() const;
// file name of this games ini (no path)
virtual std::vector<std::wstring> getIniFileNames() const;
virtual std::wstring getReferenceDataFile() const;
- virtual std::wstring getNexusPage(bool nmmScheme = true) const;
- static std::wstring getNexusInfoUrlStatic();
- virtual std::wstring getNexusInfoUrl() const { return getNexusInfoUrlStatic(); }
- static int getNexusModIDStatic();
- virtual int getNexusModID() const { return getNexusModIDStatic(); }
- virtual int getNexusGameID() const { return 120; }
-
virtual bool rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) const;
virtual std::wstring archiveListKey() const { return L"SArchiveList"; }
- virtual bool isValidModURL(int modID, std::wstring const &url) const;
-
private:
- Fallout3Info(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gameDirectory);
+ Fallout3Info(const std::wstring &gameDirectory);
static bool identifyGame(const std::wstring &searchPath);
diff --git a/src/shared/falloutnvinfo.cpp b/src/shared/falloutnvinfo.cpp
index f6de72e3..6347224d 100644
--- a/src/shared/falloutnvinfo.cpp
+++ b/src/shared/falloutnvinfo.cpp
@@ -31,8 +31,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
namespace MOShared {
-FalloutNVInfo::FalloutNVInfo(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gameDirectory)
- : GameInfo(moDirectory, moDataDirectory, gameDirectory)
+FalloutNVInfo::FalloutNVInfo(const std::wstring &gameDirectory)
+ : GameInfo(gameDirectory)
{
identifyMyGamesDirectory(L"falloutnv");
}
@@ -63,25 +63,6 @@ std::wstring FalloutNVInfo::getRegPathStatic()
}
}
-std::vector<std::wstring> FalloutNVInfo::getDLCPlugins() const
-{
- return boost::assign::list_of (L"DeadMoney.esm")
- (L"HonestHearts.esm")
- (L"OldWorldBlues.esm")
- (L"LonesomeRoad.esm")
- (L"GunRunnersArsenal.esm")
- (L"CaravanPack.esm")
- (L"ClassicPack.esm")
- (L"MercenaryPack.esm")
- (L"TribalPack.esm")
- ;
-}
-
-std::vector<std::wstring> FalloutNVInfo::getSavegameAttachmentExtensions() const
-{
- return std::vector<std::wstring>();
-}
-
std::vector<std::wstring> FalloutNVInfo::getIniFileNames() const
{
return boost::assign::list_of(L"fallout.ini")(L"falloutprefs.ini");
@@ -92,28 +73,6 @@ std::wstring FalloutNVInfo::getReferenceDataFile() const
return L"Fallout - Meshes.bsa";
}
-std::wstring FalloutNVInfo::getNexusPage(bool nmmScheme) const
-{
- if (nmmScheme) {
- return L"http://nmm.nexusmods.com/newvegas";
- } else {
- return L"http://www.nexusmods.com/newvegas";
- }
-}
-
-
-std::wstring FalloutNVInfo::getNexusInfoUrlStatic()
-{
- return L"http://nmm.nexusmods.com/newvegas";
-}
-
-
-int FalloutNVInfo::getNexusModIDStatic()
-{
- return 42572;
-}
-
-
bool FalloutNVInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t*) const
{
static LPCWSTR profileFiles[] = { L"fallout.ini", L"falloutprefs.ini", L"plugins.txt", nullptr };
@@ -126,9 +85,4 @@ bool FalloutNVInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t*) co
return false;
}
-bool FalloutNVInfo::isValidModURL(int modID, std::wstring const &url) const
-{
- return GameInfo::isValidModURL(modID, url, L"http://newvegas.nexusmods.com");
-}
-
} // namespace MOShared
diff --git a/src/shared/falloutnvinfo.h b/src/shared/falloutnvinfo.h
index d03add9c..04c13c7d 100644
--- a/src/shared/falloutnvinfo.h
+++ b/src/shared/falloutnvinfo.h
@@ -37,37 +37,19 @@ public:
static std::wstring getRegPathStatic();
virtual std::wstring getRegPath() const { return getRegPathStatic(); }
- virtual std::wstring getBinaryName() const { return L"FalloutNV.exe"; }
-
- virtual GameInfo::Type getType() const { return TYPE_FALLOUTNV; }
-
- virtual std::wstring getGameName() const { return L"New Vegas"; }
- virtual std::wstring getGameShortName() const { return L"FalloutNV"; }
-
- virtual std::vector<std::wstring> getDLCPlugins() const;
- virtual std::vector<std::wstring> getSavegameAttachmentExtensions() const;
// file name of this games ini (no path)
virtual std::vector<std::wstring> getIniFileNames() const;
virtual std::wstring getReferenceDataFile() const;
- virtual std::wstring getNexusPage(bool nmmScheme = true) const;
- static std::wstring getNexusInfoUrlStatic();
- virtual std::wstring getNexusInfoUrl() const { return getNexusInfoUrlStatic(); }
- static int getNexusModIDStatic();
- virtual int getNexusModID() const { return getNexusModIDStatic(); }
- virtual int getNexusGameID() const { return 130; }
-
virtual bool rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) const;
virtual std::wstring archiveListKey() const { return L"SArchiveList"; }
- virtual bool isValidModURL(int modID, const std::wstring &url) const;
-
private:
- FalloutNVInfo(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gameDirectory);
+ FalloutNVInfo(const std::wstring &gameDirectory);
static bool identifyGame(const std::wstring &searchPath);
};
diff --git a/src/shared/gameinfo.cpp b/src/shared/gameinfo.cpp
index 5338c069..5c13a520 100644
--- a/src/shared/gameinfo.cpp
+++ b/src/shared/gameinfo.cpp
@@ -40,8 +40,8 @@ namespace MOShared {
GameInfo* GameInfo::s_Instance = nullptr;
-GameInfo::GameInfo(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gameDirectory)
- : m_GameDirectory(gameDirectory), m_OrganizerDirectory(moDirectory), m_OrganizerDataDirectory(moDataDirectory)
+GameInfo::GameInfo(const std::wstring &gameDirectory)
+ : m_GameDirectory(gameDirectory)
{
atexit(&cleanup);
}
@@ -86,50 +86,36 @@ void GameInfo::identifyMyGamesDirectory(const std::wstring &file)
}
}
-bool GameInfo::isValidModURL(int modID, const std::wstring &url, const std::wstring &alt) const
-{
- std::wostringstream os;
- os << getNexusPage(false) << "/mods/" << modID;
- if (url == os.str()) {
- return true;
- }
- os.clear();
- os.str(L"");
- os << alt << "/mods/" << modID;
- return url == os.str();
-}
-
-
-bool GameInfo::identifyGame(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &searchPath)
+bool GameInfo::identifyGame(const std::wstring &searchPath)
{
if (OblivionInfo::identifyGame(searchPath)) {
- s_Instance = new OblivionInfo(moDirectory, moDataDirectory, searchPath);
+ s_Instance = new OblivionInfo(searchPath);
} else if (Fallout3Info::identifyGame(searchPath)) {
- s_Instance = new Fallout3Info(moDirectory, moDataDirectory, searchPath);
+ s_Instance = new Fallout3Info(searchPath);
} else if (FalloutNVInfo::identifyGame(searchPath)) {
- s_Instance = new FalloutNVInfo(moDirectory, moDataDirectory, searchPath);
+ s_Instance = new FalloutNVInfo(searchPath);
} else if (SkyrimInfo::identifyGame(searchPath)) {
- s_Instance = new SkyrimInfo(moDirectory, moDataDirectory, searchPath);
+ s_Instance = new SkyrimInfo(searchPath);
}
return s_Instance != nullptr;
}
-bool GameInfo::init(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gamePath)
+bool GameInfo::init(const std::wstring &moDirectory, const std::wstring &gamePath)
{
if (s_Instance == nullptr) {
if (gamePath.length() == 0) {
// search upward in the directory until a recognized game-binary is found
std::wstring searchPath(moDirectory);
- while (!identifyGame(moDirectory, moDataDirectory, searchPath)) {
+ while (!identifyGame(searchPath)) {
size_t lastSep = searchPath.find_last_of(L"/\\");
if (lastSep == std::string::npos) {
return false;
}
searchPath.erase(lastSep);
}
- } else if (!identifyGame(moDirectory, moDataDirectory, gamePath)) {
+ } else if (!identifyGame(gamePath)) {
return false;
}
}
@@ -148,24 +134,6 @@ std::wstring GameInfo::getGameDirectory() const
return m_GameDirectory;
}
-bool GameInfo::requiresSteam() const
-{
- return FileExists(getGameDirectory() + L"\\steam_api.dll");
-}
-
-std::wstring GameInfo::getLocalAppFolder() const
-{
- wchar_t localAppFolder[MAX_PATH];
- memset(localAppFolder, '\0', MAX_PATH * sizeof(wchar_t));
-
- if (::SHGetFolderPathW(nullptr, CSIDL_LOCAL_APPDATA, nullptr, SHGFP_TYPE_CURRENT, localAppFolder) == S_OK) {
- return localAppFolder;
- } else {
- // fallback: try the registry
- return getSpecialPath(L"Local AppData");
- }
-}
-
std::wstring GameInfo::getSpecialPath(LPCWSTR name) const
{
HKEY key;
diff --git a/src/shared/gameinfo.h b/src/shared/gameinfo.h
index 8caa5937..7bc86d3a 100644
--- a/src/shared/gameinfo.h
+++ b/src/shared/gameinfo.h
@@ -40,81 +40,41 @@ class GameInfo
public:
- enum Type {
- TYPE_OBLIVION,
- TYPE_FALLOUT3,
- TYPE_FALLOUTNV,
- TYPE_SKYRIM
- };
-
- enum LoadOrderMechanism {
- TYPE_FILETIME,
- TYPE_PLUGINSTXT
- };
-
-public:
-
virtual ~GameInfo() {}
- std::wstring getOrganizerDirectory() const { return m_OrganizerDirectory; }
-
- virtual std::wstring getRegPath() const = 0;
- virtual std::wstring getBinaryName() const = 0;
-
- virtual GameInfo::Type getType() const = 0;
-
- virtual std::wstring getGameName() const = 0;
- virtual std::wstring getGameShortName() const = 0;
+ //**USED IN HOOKDLL and at startup to set up for hookdll to work
+ // initialise with the path to the mo directory (needs to be where hook.dll is stored). This
+ // needs to be called before the instance can be retrieved
+ static bool init(const std::wstring &moDirectory, const std::wstring &gamePath = L"");
- /// determine the load order mechanism used by this game. this may throw an
- /// exception if the mechanism can't be determined
- virtual LoadOrderMechanism getLoadOrderMechanism() const { return TYPE_FILETIME; }
+ //**USED ONLY IN HOOKDLL
+ static GameInfo& instance();
+ //**USED ONLY IN HOOKDLL
virtual std::wstring getGameDirectory() const;
- virtual bool requiresSteam() const;
-
- // get a list of file extensions for additional files belonging to a save game
- virtual std::vector<std::wstring> getSavegameAttachmentExtensions() const = 0;
-
- // get a set of esp/esm files that are part of known dlcs
- virtual std::vector<std::wstring> getDLCPlugins() const = 0;
+ //**USED ONLY IN HOOKDLL
+ virtual std::wstring getRegPath() const = 0;
+ //**USED ONLY IN HOOKDLL
// file name of this games ini file(s)
virtual std::vector<std::wstring> getIniFileNames() const = 0;
+ //**USED ONLY IN HOOKDLL
virtual std::wstring getReferenceDataFile() const = 0;
- virtual std::wstring getNexusPage(bool nmmScheme = true) const = 0;
- virtual std::wstring getNexusInfoUrl() const = 0;
- virtual int getNexusModID() const = 0;
- virtual int getNexusGameID() const = 0;
-
+ //**USED ONLY IN HOOKDLL
virtual bool rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) const = 0;
- virtual bool isValidModURL(int modID, std::wstring const &url) const = 0;
-
-public:
-
- // initialise with the path to the mo directory (needs to be where hook.dll is stored). This
- // needs to be called before the instance can be retrieved
- static bool init(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gamePath = L"");
-
- static GameInfo& instance();
-
protected:
- GameInfo(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gameDirectory);
+ GameInfo(const std::wstring &gameDirectory);
- std::wstring getLocalAppFolder() const;
- const std::wstring &getMyGamesDirectory() const { return m_MyGamesDirectory; }
void identifyMyGamesDirectory(const std::wstring &file);
- bool isValidModURL(int modID, const std::wstring &url, const std::wstring &alt) const;
-
private:
- static bool identifyGame(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &searchPath);
+ static bool identifyGame(const std::wstring &searchPath);
std::wstring getSpecialPath(LPCWSTR name) const;
static void cleanup();
@@ -126,8 +86,6 @@ private:
std::wstring m_MyGamesDirectory;
std::wstring m_GameDirectory;
- std::wstring m_OrganizerDirectory;
- std::wstring m_OrganizerDataDirectory;
};
diff --git a/src/shared/oblivioninfo.cpp b/src/shared/oblivioninfo.cpp
index 730c186b..b50f1daa 100644
--- a/src/shared/oblivioninfo.cpp
+++ b/src/shared/oblivioninfo.cpp
@@ -31,8 +31,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
namespace MOShared {
-OblivionInfo::OblivionInfo(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gameDirectory)
- : GameInfo(moDirectory, moDataDirectory, gameDirectory)
+OblivionInfo::OblivionInfo(const std::wstring &gameDirectory)
+ : GameInfo(gameDirectory)
{
identifyMyGamesDirectory(L"oblivion");
}
@@ -63,54 +63,11 @@ std::wstring OblivionInfo::getRegPathStatic()
}
}
-std::vector<std::wstring> OblivionInfo::getDLCPlugins() const
-{
- return boost::assign::list_of (L"DLCShiveringIsles.esp")
- (L"Knights.esp")
- (L"DLCFrostcrag.esp")
- (L"DLCSpellTomes.esp")
- (L"DLCMehrunesRazor.esp")
- (L"DLCOrrery.esp")
- (L"DLCSpellTomes.esp")
- (L"DLCThievesDen.esp")
- (L"DLCVileLair.esp")
- (L"DLCHorseArmor.esp")
- ;
-}
-
-
-std::vector<std::wstring> OblivionInfo::getSavegameAttachmentExtensions() const
-{
- return boost::assign::list_of(L"obse");
-}
-
-
std::vector<std::wstring> OblivionInfo::getIniFileNames() const
{
return boost::assign::list_of(L"oblivion.ini")(L"oblivionprefs.ini");
}
-std::wstring OblivionInfo::getNexusPage(bool nmmScheme) const
-{
- if (nmmScheme) {
- return L"http://nmm.nexusmods.com/oblivion";
- } else {
- return L"http://www.nexusmods.com/oblivion";
- }
-}
-
-
-std::wstring OblivionInfo::getNexusInfoUrlStatic()
-{
- return L"http://nmm.nexusmods.com/oblivion";
-}
-
-
-int OblivionInfo::getNexusModIDStatic()
-{
- return 38277;
-}
-
bool OblivionInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t*) const
{
static LPCWSTR profileFiles[] = { L"oblivion.ini", L"oblivionprefs.ini", L"plugins.txt", nullptr };
@@ -128,9 +85,4 @@ std::wstring OblivionInfo::getReferenceDataFile() const
return L"Oblivion - Meshes.bsa";
}
-bool OblivionInfo::isValidModURL(int modID, const std::wstring &url) const
-{
- return GameInfo::isValidModURL(modID, url, L"http://oblivion.nexusmods.com");
-}
-
} // namespace MOShared
diff --git a/src/shared/oblivioninfo.h b/src/shared/oblivioninfo.h
index 1adf9cab..bf0b2707 100644
--- a/src/shared/oblivioninfo.h
+++ b/src/shared/oblivioninfo.h
@@ -35,37 +35,19 @@ public:
static std::wstring getRegPathStatic();
virtual std::wstring getRegPath() const { return getRegPathStatic(); }
- virtual std::wstring getBinaryName() const { return L"Oblivion.exe"; }
-
- virtual GameInfo::Type getType() const { return TYPE_OBLIVION; }
-
- virtual std::wstring getGameName() const { return L"Oblivion"; }
- virtual std::wstring getGameShortName() const { return L"Oblivion"; }
-
- virtual std::vector<std::wstring> getDLCPlugins() const;
- virtual std::vector<std::wstring> getSavegameAttachmentExtensions() const;
// file name of this games ini (no path)
virtual std::vector<std::wstring> getIniFileNames() const;
virtual std::wstring getReferenceDataFile() const;
- virtual std::wstring getNexusPage(bool nmmScheme = true) const;
- static std::wstring getNexusInfoUrlStatic();
- virtual std::wstring getNexusInfoUrl() const { return getNexusInfoUrlStatic(); }
- static int getNexusModIDStatic();
- virtual int getNexusModID() const { return getNexusModIDStatic(); }
- virtual int getNexusGameID() const { return 101; }
-
virtual bool rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) const;
virtual std::wstring archiveListKey() const { return L"SArchiveList"; }
- virtual bool isValidModURL(int modID, std::wstring const &url) const;
-
private:
- OblivionInfo(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gameDirectory);
+ OblivionInfo(const std::wstring &gameDirectory);
static bool identifyGame(const std::wstring &searchPath);
diff --git a/src/shared/skyriminfo.cpp b/src/shared/skyriminfo.cpp
index 7c85fe10..9662e66d 100644
--- a/src/shared/skyriminfo.cpp
+++ b/src/shared/skyriminfo.cpp
@@ -33,8 +33,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
namespace MOShared {
-SkyrimInfo::SkyrimInfo(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gameDirectory)
- : GameInfo(moDirectory, moDataDirectory, gameDirectory)
+SkyrimInfo::SkyrimInfo(const std::wstring &gameDirectory)
+ : GameInfo(gameDirectory)
{
identifyMyGamesDirectory(L"skyrim");
@@ -73,40 +73,6 @@ std::wstring SkyrimInfo::getRegPathStatic()
}
}
-GameInfo::LoadOrderMechanism SkyrimInfo::getLoadOrderMechanism() const
-{
- std::wstring fileName = getGameDirectory() + L"\\TESV.exe";
-
- try {
- VS_FIXEDFILEINFO versionInfo = GetFileVersion(fileName);
- if ((versionInfo.dwFileVersionMS > 0x10004) || // version >= 1.5.x?
- ((versionInfo.dwFileVersionMS == 0x10004) && (versionInfo.dwFileVersionLS >= 0x1A0000))) { // version >= ?.4.26
- return TYPE_PLUGINSTXT;
- } else {
- return TYPE_FILETIME;
- }
- } catch (const std::exception &e) {
- log("TESV.exe is invalid: %s", e.what());
- return TYPE_FILETIME;
- }
-}
-
-std::vector<std::wstring> SkyrimInfo::getDLCPlugins() const
-{
- return boost::assign::list_of (L"Dawnguard.esm")
- (L"Dragonborn.esm")
- (L"HearthFires.esm")
- (L"HighResTexturePack01.esp")
- (L"HighResTexturePack02.esp")
- (L"HighResTexturePack03.esp")
- ;
-}
-
-std::vector<std::wstring> SkyrimInfo::getSavegameAttachmentExtensions() const
-{
- return boost::assign::list_of(L"skse");
-}
-
std::vector<std::wstring> SkyrimInfo::getIniFileNames() const
{
return boost::assign::list_of(L"skyrim.ini")(L"skyrimprefs.ini");
@@ -117,28 +83,6 @@ std::wstring SkyrimInfo::getReferenceDataFile() const
return L"Skyrim - Meshes.bsa";
}
-
-std::wstring SkyrimInfo::getNexusPage(bool nmmScheme) const
-{
- if (nmmScheme) {
- return L"http://nmm.nexusmods.com/skyrim";
- } else {
- return L"http://www.nexusmods.com/skyrim";
- }
-}
-
-
-std::wstring SkyrimInfo::getNexusInfoUrlStatic()
-{
- return L"http://nmm.nexusmods.com/skyrim";
-}
-
-
-int SkyrimInfo::getNexusModIDStatic()
-{
- return 1334;
-}
-
bool SkyrimInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) const
{
static LPCWSTR profileFiles[] = { L"skyrim.ini", L"skyrimprefs.ini", L"loadorder.txt", nullptr };
@@ -157,10 +101,4 @@ bool SkyrimInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPa
return false;
}
-bool SkyrimInfo::isValidModURL(int modID, const std::wstring &url) const
-{
- return GameInfo::isValidModURL(modID, url, L"http://skyrim.nexusmods.com");
-}
-
-
} // namespace MOShared
diff --git a/src/shared/skyriminfo.h b/src/shared/skyriminfo.h
index e2766688..bd329403 100644
--- a/src/shared/skyriminfo.h
+++ b/src/shared/skyriminfo.h
@@ -37,40 +37,17 @@ public:
static std::wstring getRegPathStatic();
virtual std::wstring getRegPath() const { return getRegPathStatic(); }
- virtual std::wstring getBinaryName() const { return L"TESV.exe"; }
-
- virtual GameInfo::Type getType() const { return TYPE_SKYRIM; }
-
- virtual std::wstring getGameName() const { return L"Skyrim"; }
- virtual std::wstring getGameShortName() const { return L"Skyrim"; }
-
- virtual LoadOrderMechanism getLoadOrderMechanism() const;
-
- virtual std::vector<std::wstring> getDLCPlugins() const;
-
- virtual std::vector<std::wstring> getSavegameAttachmentExtensions() const;
// file name of this games ini (no path)
virtual std::vector<std::wstring> getIniFileNames() const;
virtual std::wstring getReferenceDataFile() const;
- virtual std::wstring getNexusPage(bool nmmScheme = true) const;
-
- static std::wstring getNexusInfoUrlStatic();
- virtual std::wstring getNexusInfoUrl() const { return getNexusInfoUrlStatic(); }
- static int getNexusModIDStatic();
- virtual int getNexusModID() const { return getNexusModIDStatic(); }
- static int getNexusGameIDStatic() { return 110; }
- virtual int getNexusGameID() const { return getNexusGameIDStatic(); }
-
virtual bool rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) const;
- virtual bool isValidModURL(int modID, std::wstring const &url) const;
-
private:
- SkyrimInfo(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gameDirectory);
+ SkyrimInfo(const std::wstring &gameDirectory);
static bool identifyGame(const std::wstring &searchPath);
diff --git a/src/spawn.cpp b/src/spawn.cpp
index c79714bb..49e89a8b 100644
--- a/src/spawn.cpp
+++ b/src/spawn.cpp
@@ -18,18 +18,20 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "spawn.h"
+
#include "report.h"
#include "utility.h"
-#include <boost/scoped_array.hpp>
-#include <gameinfo.h>
#include <report.h>
#include <inject.h>
-#include <Shellapi.h>
#include <appconfig.h>
#include <windows_error.h>
+
#include <QApplication>
#include <QMessageBox>
+#include <Shellapi.h>
+
+#include <boost/scoped_array.hpp>
using namespace MOBase;
using namespace MOShared;
diff --git a/src/syncoverwritedialog.cpp b/src/syncoverwritedialog.cpp
index 0e3e98d7..aeed0a55 100644
--- a/src/syncoverwritedialog.cpp
+++ b/src/syncoverwritedialog.cpp
@@ -18,10 +18,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "syncoverwritedialog.h"
+
#include "ui_syncoverwritedialog.h"
#include <utility.h>
#include <report.h>
-#include <gameinfo.h>
+
#include <QDir>
#include <QDirIterator>
#include <QComboBox>
diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp
index 73267f75..48fc4548 100644
--- a/src/transfersavesdialog.cpp
+++ b/src/transfersavesdialog.cpp
@@ -18,12 +18,15 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "transfersavesdialog.h"
+
#include "ui_transfersavesdialog.h"
+#include "iplugingame.h"
#include "savegamegamebyro.h"
#include "utility.h"
-#include <gameinfo.h>
+
#include <QDir>
#include <QMessageBox>
+
#include <Shlwapi.h>
#include <shlobj.h>
@@ -32,7 +35,7 @@ using namespace MOBase;
using namespace MOShared;
-TransferSavesDialog::TransferSavesDialog(const Profile &profile, IPluginGame *gamePlugin, QWidget *parent)
+TransferSavesDialog::TransferSavesDialog(const Profile &profile, IPluginGame const *gamePlugin, QWidget *parent)
: TutorableDialog("TransferSaves", parent)
, ui(new Ui::TransferSavesDialog)
, m_Profile(profile)
@@ -60,7 +63,7 @@ void TransferSavesDialog::refreshGlobalSaves()
QStringList files = savesDir.entryList(QDir::Files, QDir::Time);
for (const QString &filename : files) {
- SaveGameGamebryo *save = new SaveGameGamebryo(this, savesDir.absoluteFilePath(filename));
+ SaveGameGamebryo *save = new SaveGameGamebryo(this, savesDir.absoluteFilePath(filename), m_GamePlugin);
save->setParent(this);
m_GlobalSaves.push_back(save);
}
@@ -78,7 +81,7 @@ void TransferSavesDialog::refreshLocalSaves()
QStringList files = savesDir.entryList(QDir::Files, QDir::Time);
foreach (const QString &filename, files) {
- SaveGameGamebryo *save = new SaveGameGamebryo(this, savesDir.absoluteFilePath(filename));
+ SaveGameGamebryo *save = new SaveGameGamebryo(this, savesDir.absoluteFilePath(filename), m_GamePlugin);
save->setParent(this);
m_LocalSaves.push_back(save);
}
diff --git a/src/transfersavesdialog.h b/src/transfersavesdialog.h
index b9265b6a..e2c556b4 100644
--- a/src/transfersavesdialog.h
+++ b/src/transfersavesdialog.h
@@ -22,11 +22,9 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "tutorabledialog.h"
#include "profile.h"
-#include <iplugingame.h>
-namespace Ui {
-class TransferSavesDialog;
-}
+namespace Ui { class TransferSavesDialog; }
+namespace MOBase { class IPluginGame; }
class SaveGame;
@@ -35,7 +33,7 @@ class TransferSavesDialog : public MOBase::TutorableDialog
Q_OBJECT
public:
- explicit TransferSavesDialog(const Profile &profile, MOBase::IPluginGame *gamePlugin, QWidget *parent = 0);
+ explicit TransferSavesDialog(const Profile &profile, MOBase::IPluginGame const *gamePlugin, QWidget *parent = 0);
~TransferSavesDialog();
private slots:
@@ -76,7 +74,7 @@ private:
Profile m_Profile;
- MOBase::IPluginGame *m_GamePlugin;
+ MOBase::IPluginGame const *m_GamePlugin;
std::vector<SaveGame*> m_GlobalSaves;
std::vector<SaveGame*> m_LocalSaves;