diff options
| author | Tannin <devnull@localhost> | 2015-01-04 10:33:37 +0100 |
|---|---|---|
| committer | Tannin <devnull@localhost> | 2015-01-04 10:33:37 +0100 |
| commit | b415db619ed027ec2acd283983624293274b090f (patch) | |
| tree | 3b09112799f2728229ed98bca7b342f1e8d1232a /src/main.cpp | |
| parent | bd8267993d1ed0292200f3052e3c30d4fc9c84f7 (diff) | |
| parent | b2d04d70fc6284797e1bf29f55a375cb59d012be (diff) | |
Merge
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 199 |
1 files changed, 68 insertions, 131 deletions
diff --git a/src/main.cpp b/src/main.cpp index 4aab45b5..a3ddac20 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -82,14 +82,13 @@ using namespace MOBase; using namespace MOShared;
-// set up required folders (for a first install or after an update or to fix a broken installation)
bool bootstrap()
{
GameInfo &gameInfo = GameInfo::instance();
// remove the temporary backup directory in case we're restarting after an update
QString moDirectory = QDir::fromNativeSeparators(ToQString(gameInfo.getOrganizerDirectory()));
- QString backupDirectory = moDirectory.mid(0).append("/update_backup");
+ QString backupDirectory = moDirectory + "/update_backup";
if (QDir(backupDirectory).exists()) {
shellDelete(QStringList(backupDirectory));
}
@@ -97,56 +96,15 @@ bool bootstrap() // cycle logfile
removeOldFiles(ToQString(GameInfo::instance().getLogDir()), "ModOrganizer*.log", 5, QDir::Name);
- // create organizer directories
- QString dirNames[] = {
- QDir::fromNativeSeparators(ToQString(gameInfo.getProfilesDir())),
- QDir::fromNativeSeparators(ToQString(gameInfo.getModsDir())),
- QDir::fromNativeSeparators(ToQString(gameInfo.getDownloadDir())),
- QDir::fromNativeSeparators(ToQString(gameInfo.getOverwriteDir())),
- QDir::fromNativeSeparators(ToQString(gameInfo.getLogDir())),
- QDir::fromNativeSeparators(ToQString(gameInfo.getTutorialDir()))
- };
- static const int NUM_DIRECTORIES = sizeof(dirNames) / sizeof(QString);
-
- // optimistic run: try to simply create the directories:
- for (int i = 0; i < NUM_DIRECTORIES; ++i) {
- if (!QDir(dirNames[i]).exists()) {
- QDir().mkdir(dirNames[i]);
- }
- }
-
- // verify all directories exist and are writable,
- // otherwise invoke the helper to create them and make them writable
- for (int i = 0; i < NUM_DIRECTORIES; ++i) {
- QFileInfo fileInfo(dirNames[i]);
- if (!fileInfo.exists() || !fileInfo.isWritable()) {
- if (QMessageBox::question(NULL, QObject::tr("Permissions required"),
- QObject::tr("The current user account doesn't have the required access rights to run "
- "Mod Organizer. The neccessary changes can be made automatically (the MO directory "
- "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())) {
- return false;
- }
- } else {
- return false;
- }
- // no matter which directory didn't exist/wasn't writable, the helper
- // should have created them all so we can break the loop
- break;
- }
- }
-
// verify the hook-dll exists
QString dllName = qApp->applicationDirPath() + "/" + ToQString(AppConfig::hookDLLName());
- if (::GetModuleHandleW(ToWString(dllName).c_str()) != NULL) {
+ if (::GetModuleHandleW(ToWString(dllName).c_str()) != nullptr) {
throw std::runtime_error("hook.dll already loaded! You can't start Mod Organizer from within itself (not even indirectly)");
}
HMODULE dllMod = ::LoadLibraryW(ToWString(dllName).c_str());
- if (dllMod == NULL) {
+ if (dllMod == nullptr) {
throw windows_error("hook.dll is missing or invalid");
}
::FreeLibrary(dllMod);
@@ -154,28 +112,6 @@ bool bootstrap() return true;
}
-
-void cleanupDir()
-{
- // files from previous versions of MO that are no longer
- // required (in that location)
- QString fileNames[] = {
- "plugins/helloWorld.dll",
- "plugins/testnexus.py"
- };
-
- static const int NUM_FILES = sizeof(fileNames) / sizeof(QString);
-
- qDebug("cleaning up unused files");
-
- for (int i = 0; i < NUM_FILES; ++i) {
- if (QFile::remove(QApplication::applicationDirPath().append("/").append(fileNames[i]))) {
- qDebug("%s removed in cleanup",
- QApplication::applicationDirPath().append("/").append(fileNames[i]).toUtf8().constData());
- }
- }
-}
-
bool isNxmLink(const QString &link)
{
return link.left(6).toLower() == "nxm://";
@@ -199,7 +135,7 @@ LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *exceptionPtrs FuncMiniDumpWriteDump funcDump = (FuncMiniDumpWriteDump)::GetProcAddress(dbgDLL, "MiniDumpWriteDump");
if (funcDump) {
- if (QMessageBox::question(NULL, QObject::tr("Woops"),
+ if (QMessageBox::question(nullptr, QObject::tr("Woops"),
QObject::tr("ModOrganizer has crashed! Should a diagnostic file be created? If you send me this file "
"(%1) to sherb@gmx.net, the bug is a lot more likely to be fixed. "
"Please include a short description of what you were doing when the crash happened").arg(qApp->applicationFilePath().append(".dmp")),
@@ -208,14 +144,14 @@ LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *exceptionPtrs std::wstring dumpName = ToWString(qApp->applicationFilePath().append(".dmp"));
HANDLE dumpFile = ::CreateFile(dumpName.c_str(),
- GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (dumpFile != INVALID_HANDLE_VALUE) {
_MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = ::GetCurrentThreadId();
exceptionInfo.ExceptionPointers = exceptionPtrs;
- exceptionInfo.ClientPointers = NULL;
+ exceptionInfo.ClientPointers = false;
- BOOL success = funcDump(::GetCurrentProcess(), ::GetCurrentProcessId(), dumpFile, MiniDumpNormal, &exceptionInfo, NULL, NULL);
+ BOOL success = funcDump(::GetCurrentProcess(), ::GetCurrentProcessId(), dumpFile, MiniDumpNormal, &exceptionInfo, nullptr, nullptr);
::FlushFileBuffers(dumpFile);
::CloseHandle(dumpFile);
@@ -238,7 +174,7 @@ LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *exceptionPtrs _snprintf(errorBuffer, errorLen, "dbghelp.dll not found");
}
- QMessageBox::critical(NULL, QObject::tr("Woops"),
+ QMessageBox::critical(nullptr, QObject::tr("Woops"),
QObject::tr("ModOrganizer has crashed! Unfortunately I was not able to write a diagnostic file: %1").arg(errorBuffer));
return result;
}
@@ -255,14 +191,14 @@ bool HaveWriteAccess(const std::wstring &path) const static SECURITY_INFORMATION requestedFileInformation = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
DWORD length = 0;
- if (!::GetFileSecurityW(path.c_str(), requestedFileInformation, NULL, NULL, &length)
+ if (!::GetFileSecurityW(path.c_str(), requestedFileInformation, nullptr, 0UL, &length)
&& (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
std::string tempBuffer;
tempBuffer.reserve(length);
PSECURITY_DESCRIPTOR security = (PSECURITY_DESCRIPTOR)tempBuffer.data();
if (security
&& ::GetFileSecurity(path.c_str(), requestedFileInformation, security, length, &length)) {
- HANDLE token = NULL;
+ HANDLE token = nullptr;
const static DWORD tokenDesiredAccess = TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ;
if (!::OpenThreadToken(::GetCurrentThread(), tokenDesiredAccess, TRUE, &token)) {
if (!::OpenProcessToken(::GetCurrentProcess(), tokenDesiredAccess, &token)) {
@@ -270,7 +206,7 @@ bool HaveWriteAccess(const std::wstring &path) }
}
- HANDLE impersonatedToken = NULL;
+ HANDLE impersonatedToken = nullptr;
if (::DuplicateToken(token, SecurityImpersonation, &impersonatedToken)) {
GENERIC_MAPPING mapping = { 0xFFFFFFFF };
mapping.GenericRead = FILE_GENERIC_READ;
@@ -298,6 +234,27 @@ bool HaveWriteAccess(const std::wstring &path) }
+QString determineProfile(QStringList arguments, const QSettings &settings)
+{
+ QString selectedProfileName = QString::fromUtf8(settings.value("selected_profile", "").toByteArray());
+ { // see if there is a profile on the command line
+ int profileIndex = arguments.indexOf("-p", 1);
+ if ((profileIndex != -1) && (profileIndex < arguments.size() - 1)) {
+ qDebug("profile overwritten on command line");
+ selectedProfileName = arguments.at(profileIndex + 1);
+ }
+ arguments.removeAt(profileIndex);
+ arguments.removeAt(profileIndex);
+ }
+ if (selectedProfileName.isEmpty()) {
+ qDebug("no configured profile");
+ } else {
+ qDebug("configured profile: %s", qPrintable(selectedProfileName));
+ }
+
+ return selectedProfileName;
+}
+
int main(int argc, char *argv[])
{
MOApplication application(argc, argv);
@@ -308,16 +265,17 @@ int main(int argc, char *argv[]) QFile instanceFile(application.applicationDirPath() + "/INSTANCE");
if (instanceFile.open(QIODevice::ReadOnly)) {
instanceID = instanceFile.readAll().trimmed();
- }
+ }
- QString dataPath = instanceID.isEmpty() ? application.applicationDirPath()
- : QDir::fromNativeSeparators(
+ QString dataPath =
+ instanceID.isEmpty() ? application.applicationDirPath()
+ : QDir::fromNativeSeparators(
#if QT_VERSION >= 0x050000
- QStandardPaths::writableLocation(QStandardPaths::DataLocation)
+ QStandardPaths::writableLocation(QStandardPaths::DataLocation)
#else
- QDesktopServices::storageLocation(QDesktopServices::DataLocation)
+ QDesktopServices::storageLocation(QDesktopServices::DataLocation)
#endif
- ) + "/" + instanceID;
+ );
application.setProperty("dataPath", dataPath);
#if QT_VERSION >= 0x050000
@@ -339,7 +297,7 @@ int main(int argc, char *argv[]) if (!HaveWriteAccess(ToWString(application.applicationDirPath()))) {
QStringList arguments = application.arguments();
arguments.pop_front();
- ::ShellExecuteW( NULL
+ ::ShellExecuteW( nullptr
, L"runas"
, ToWString(QString("\"%1\"").arg(QCoreApplication::applicationFilePath())).c_str()
, ToWString(arguments.join(" ")).c_str()
@@ -390,7 +348,7 @@ int main(int argc, char *argv[]) instance.sendMessage(arguments.at(1));
return 0;
} else if (arguments.size() == 1) {
- QMessageBox::information(NULL, QObject::tr("Mod Organizer"), QObject::tr("An instance of Mod Organizer is already running"));
+ QMessageBox::information(nullptr, QObject::tr("Mod Organizer"), QObject::tr("An instance of Mod Organizer is already running"));
return 0;
}
} // we continue for the primary instance OR if MO has been called with parameters
@@ -412,7 +370,7 @@ int main(int argc, char *argv[]) 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"), NULL);
+ SelectionDialog selection(QObject::tr("Please select the game to manage"), nullptr);
{ // add options
QString skyrimPath = ToQString(SkyrimInfo::getRegPathStatic());
@@ -441,7 +399,7 @@ int main(int argc, char *argv[]) } else {
gamePath = QDir::cleanPath(selection.getChoiceData().toString());
if (gamePath.isEmpty()) {
- gamePath = QFileDialog::getExistingDirectory(NULL, QObject::tr("Please select the game to manage"), QString(),
+ gamePath = QFileDialog::getExistingDirectory(nullptr, QObject::tr("Please select the game to manage"), QString(),
QFileDialog::ShowDirsOnly);
}
}
@@ -460,10 +418,15 @@ int main(int argc, char *argv[]) settings.setValue("gamePath", gamePath.toUtf8().constData());
}
+ if (pluginContainer.managedGame(ToQString(GameInfo::instance().getGameName())) == nullptr) {
+ reportError(QObject::tr("Plugin to handle %1 not installed").arg(ToQString(GameInfo::instance().getGameName())));
+ return 1;
+ }
+
if (!settings.contains("game_edition")) {
std::vector<std::wstring> editions = GameInfo::instance().getSteamVariants();
if (editions.size() > 1) {
- SelectionDialog selection(QObject::tr("Please select the game edition you have (MO can't start the game correctly if this is set incorrectly!)"), NULL);
+ SelectionDialog selection(QObject::tr("Please select the game edition you have (MO can't start the game correctly if this is set incorrectly!)"), nullptr);
int index = 0;
for (auto iter = editions.begin(); iter != editions.end(); ++iter) {
selection.addChoice(ToQString(*iter), "", index++);
@@ -484,7 +447,25 @@ int main(int argc, char *argv[]) return -1;
}
- cleanupDir();
+ QString selectedProfileName = determineProfile(arguments, settings);
+ organizer.setCurrentProfile(selectedProfileName);
+
+ // if we have a command line parameter, it is either a nxm link or
+ // a binary to start
+ if ((arguments.size() > 1) && (!isNxmLink(arguments.at(1)))) {
+ QString exeName = arguments.at(1);
+ qDebug("starting %s from command line", qPrintable(exeName));
+ arguments.removeFirst(); // remove application name (ModOrganizer.exe)
+ arguments.removeFirst(); // remove binary name
+ // pass the remaining parameters to the binary
+ try {
+ organizer.startApplication(exeName, arguments, QString(), QString());
+ return 0;
+ } catch (const std::exception &e) {
+ reportError(QObject::tr("failed to start application: %1").arg(e.what()));
+ return 1;
+ }
+ }
qDebug("initializing tutorials");
TutorialManager::init(QDir::fromNativeSeparators(ToQString(GameInfo::instance().getTutorialDir())).append("/"));
@@ -504,52 +485,8 @@ int main(int argc, char *argv[]) mainWindow.readSettings();
- QString selectedProfileName = QString::fromUtf8(settings.value("selected_profile", "").toByteArray());
-
- { // see if there is a profile on the command line
- int profileIndex = arguments.indexOf("-p", 1);
- if ((profileIndex != -1) && (profileIndex < arguments.size() - 1)) {
- qDebug("profile overwritten on command line");
- selectedProfileName = arguments.at(profileIndex + 1);
- }
- arguments.removeAt(profileIndex);
- arguments.removeAt(profileIndex);
- }
- if (selectedProfileName.isEmpty()) {
- qDebug("no configured profile");
- } else {
- qDebug("configured profile: %s", qPrintable(selectedProfileName));
- }
-
- // if we have a command line parameter, it is either a nxm link or
- // a binary to start
- if ((arguments.size() > 1) && (!isNxmLink(arguments.at(1)))) {
- QString exeName = arguments.at(1);
- qDebug("starting %s from command line", qPrintable(exeName));
- arguments.removeFirst(); // remove application name (ModOrganizer.exe)
- arguments.removeFirst(); // remove binary name
- // pass the remaining parameters to the binary
- try {
- organizer.startApplication(exeName, arguments, QString(), selectedProfileName);
- } catch (const std::exception &e) {
- reportError(QObject::tr("failed to start application: %1").arg(e.what()));
- }
-
- return 0;
- }
-
mainWindow.createFirstProfile();
- if (selectedProfileName.length() != 0) {
- if (!mainWindow.setCurrentProfile(selectedProfileName)) {
- mainWindow.setCurrentProfile(1);
- qWarning("failed to set profile: %s",
- selectedProfileName.toUtf8().constData());
- }
- } else {
- mainWindow.setCurrentProfile(1);
- }
-
qDebug("displaying main window");
mainWindow.show();
|
