From 3bca0e761597f590fa3b1c6a57ee325e774e3f49 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sun, 10 Jan 2021 22:06:38 -0500 Subject: split run() into setup() and run() this is so command line processing can happen outside of MOApplication many important objects were local to run(), so they're not members of MOApplication instead --- src/instancemanager.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/instancemanager.cpp') diff --git a/src/instancemanager.cpp b/src/instancemanager.cpp index 18604bf1..a9905b75 100644 --- a/src/instancemanager.cpp +++ b/src/instancemanager.cpp @@ -544,7 +544,7 @@ void InstanceManager::clearOverrides() m_overrideProfileName = {}; } -std::optional InstanceManager::currentInstance() const +std::unique_ptr InstanceManager::currentInstance() const { const QString profile = m_overrideProfileName ? *m_overrideProfileName : ""; @@ -555,20 +555,20 @@ std::optional InstanceManager::currentInstance() const if (!allowedToChangeInstance()) { // force portable instance - return Instance(portablePath(), true, profile); + return std::make_unique(portablePath(), true, profile); } if (name.isEmpty()) { if (portableInstanceExists()) { // use portable - return Instance(portablePath(), true, profile); + return std::make_unique(portablePath(), true, profile); } else { // no instance set return {}; } } - return Instance(instancePath(name), false, profile); + return std::make_unique(instancePath(name), false, profile); } void InstanceManager::clearCurrentInstance() @@ -772,7 +772,7 @@ bool InstanceManager::validInstanceName(const QString& instanceName) const -std::optional selectInstance() +std::unique_ptr selectInstance() { auto& m = InstanceManager::singleton(); -- cgit v1.3.1 From 6feab2ea8f96704e44a14c212a635dc17f4ba71e Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sun, 17 Jan 2021 21:26:21 -0500 Subject: moved criticalOnTop() to uibase changed all calls to reportError(), which now uses the main window if it exists as a parent, or calls criticalOnTop() added errors when running something from the command line for a different instance/profile removed unused crap --- src/CMakeLists.txt | 3 - src/commandline.cpp | 7 +- src/instancemanager.cpp | 9 ++- src/moapplication.cpp | 33 +++++++-- src/organizercore.cpp | 5 +- src/profile.cpp | 1 - src/shared/error_report.cpp | 64 ----------------- src/shared/error_report.h | 44 ------------ src/shared/leaktrace.cpp | 68 ------------------ src/shared/leaktrace.h | 24 ------- src/shared/stackdata.cpp | 169 -------------------------------------------- src/shared/stackdata.h | 50 ------------- 12 files changed, 37 insertions(+), 440 deletions(-) delete mode 100644 src/shared/error_report.cpp delete mode 100644 src/shared/error_report.h delete mode 100644 src/shared/leaktrace.cpp delete mode 100644 src/shared/leaktrace.h delete mode 100644 src/shared/stackdata.cpp delete mode 100644 src/shared/stackdata.h (limited to 'src/instancemanager.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a5d15740..e8c52721 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -212,12 +212,9 @@ add_filter(NAME src/utilities GROUPS shared/appconfig bbcode csvbuilder - shared/error_report - shared/leaktrace persistentcookiejar serverinfo spawn - shared/stackdata shared/util usvfsconnector shared/windows_error diff --git a/src/commandline.cpp b/src/commandline.cpp index 97d54b92..477bfba1 100644 --- a/src/commandline.cpp +++ b/src/commandline.cpp @@ -5,7 +5,6 @@ #include "multiprocess.h" #include "loglist.h" #include "shared/util.h" -#include "shared/error_report.h" #include "shared/appconfig.h" #include #include @@ -807,7 +806,7 @@ std::optional RunCommand::runPostOrganizer(OrganizerCore& core) if (itor == exes.end()) { // not found - MOShared::criticalOnTop( + reportError( QObject::tr("Executable '%1' not found in instance '%2'.") .arg(program) .arg(InstanceManager::singleton().currentInstance()->name())); @@ -833,7 +832,7 @@ std::optional RunCommand::runPostOrganizer(OrganizerCore& core) const auto r = p.run(); if (r == ProcessRunner::Error) { - MOShared::criticalOnTop( + reportError( QObject::tr("Failed to run '%1'. The logs might have more information.").arg(program)); return 1; @@ -842,7 +841,7 @@ std::optional RunCommand::runPostOrganizer(OrganizerCore& core) return 0; } catch (const std::exception &e) { - MOShared::criticalOnTop( + reportError( QObject::tr("Failed to run '%1'. The logs might have more information. %2") .arg(program).arg(e.what())); diff --git a/src/instancemanager.cpp b/src/instancemanager.cpp index a9905b75..8add4af8 100644 --- a/src/instancemanager.cpp +++ b/src/instancemanager.cpp @@ -28,7 +28,6 @@ along with Mod Organizer. If not, see . #include "createinstancedialogpages.h" #include "shared/appconfig.h" #include "shared/util.h" -#include "shared/error_report.h" #include #include #include @@ -896,7 +895,7 @@ SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc) // unreadable ini, there's not much that can be done, select another // instance - MOShared::criticalOnTop( + reportError( QObject::tr("Cannot open instance '%1', failed to read INI file %2.") .arg(instance.name()).arg(instance.iniPath())); @@ -911,7 +910,7 @@ SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc) // // ask the user for the game managed by this instance - MOShared::criticalOnTop( + reportError( QObject::tr( "Cannot open instance '%1', the managed game was not found in the INI " "file %2. Select the game managed by this instance.") @@ -925,7 +924,7 @@ SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc) // there is no plugin that can handle the game name/directory from the // ini, so this instance is unusable - MOShared::criticalOnTop( + reportError( QObject::tr( "Cannot open instance '%1', the game plugin '%2' doesn't exist. It " "may have been deleted by an antivirus. Select another instance.") @@ -939,7 +938,7 @@ SetupInstanceResults setupInstance(Instance& instance, PluginContainer& pc) // the game directory doesn't exist or the plugin doesn't recognize it; // ask the user for the game managed by this instance - MOShared::criticalOnTop( + reportError( QObject::tr( "Cannot open instance '%1', the game directory '%2' doesn't exist or " "the game plugin '%3' doesn't recognize it. Select the game managed " diff --git a/src/moapplication.cpp b/src/moapplication.cpp index da45e26c..91cac2b1 100644 --- a/src/moapplication.cpp +++ b/src/moapplication.cpp @@ -32,7 +32,6 @@ along with Mod Organizer. If not, see . #include "sanitychecks.h" #include "mainwindow.h" #include "messagedialog.h" -#include "shared/error_report.h" #include "shared/util.h" #include #include @@ -204,7 +203,7 @@ int MOApplication::setup(MOMultiProcess& multiProcess) setProperty("dataPath", dataPath); if (!setLogDirectory(dataPath)) { - reportError("Failed to create log folder"); + reportError(tr("Failed to create log folder.")); InstanceManager::singleton().clearCurrentInstance(); return 1; } @@ -271,7 +270,7 @@ int MOApplication::setup(MOMultiProcess& multiProcess) m_core.reset(new OrganizerCore(*m_settings)); if (!m_core->bootstrap()) { - reportError("failed to set up data paths"); + reportError(tr("Failed to set up data paths.")); InstanceManager::singleton().clearCurrentInstance(); return 1; } @@ -412,6 +411,30 @@ void MOApplication::externalMessage(const QString& message) return; } + if (auto i=cl.instance()) { + const auto ci = InstanceManager::singleton().currentInstance(); + + if (*i != ci->name()) { + reportError(tr( + "This shortcut or command line is for instance '%1', but the current " + "instance is '%2'.") + .arg(*i).arg(ci->name())); + + return; + } + } + + if (auto p=cl.profile()) { + if (*p != m_core->profileName()) { + reportError(tr( + "This shortcut or command line is for profile '%1', but the current " + "profile is '%2'.") + .arg(*p).arg(m_core->profileName())); + + return; + } + } + cl.runPostOrganizer(*m_core); } } @@ -436,11 +459,11 @@ std::unique_ptr MOApplication::getCurrentInstance() m.clearOverrides(); if (m.hasAnyInstances()) { - MOShared::criticalOnTop(QObject::tr( + reportError(QObject::tr( "Instance at '%1' not found. Select another instance.") .arg(currentInstance->directory())); } else { - MOShared::criticalOnTop(QObject::tr( + reportError(QObject::tr( "Instance at '%1' not found. You must create a new instance") .arg(currentInstance->directory())); } diff --git a/src/organizercore.cpp b/src/organizercore.cpp index c7c1f828..d3e817a5 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -37,7 +37,6 @@ #include "shared/filesorigin.h" #include "shared/fileentry.h" #include "shared/util.h" -#include "shared/error_report.h" #include #include @@ -562,7 +561,7 @@ void OrganizerCore::setCurrentProfile(const QString &profileName) log::error("picked profile '{}' instead", QDir(profileDir).dirName()); - MOShared::criticalOnTop( + reportError( tr("The selected profile '%1' does not exist. The profile '%2' will be used instead") .arg(profileName).arg(QDir(profileDir).dirName())); } @@ -812,7 +811,7 @@ ModInfo::Ptr OrganizerCore::installDownload(int index, int priority) } } } catch (const std::exception &e) { - reportError(e.what()); + reportError(QString(e.what())); } return nullptr; diff --git a/src/profile.cpp b/src/profile.cpp index 3cc1a2a3..695cd3ae 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -22,7 +22,6 @@ along with Mod Organizer. If not, see . #include "modinfo.h" #include "settings.h" #include -#include "shared/error_report.h" #include "shared/appconfig.h" #include #include diff --git a/src/shared/error_report.cpp b/src/shared/error_report.cpp deleted file mode 100644 index 09fdcb49..00000000 --- a/src/shared/error_report.cpp +++ /dev/null @@ -1,64 +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 . -*/ - -#include "error_report.h" -#include -#include - -namespace MOShared { - -void reportError(LPCSTR format, ...) -{ - char buffer[1025]; - memset(buffer, 0, sizeof(char) * 1025); - - va_list argList; - va_start(argList, format); - - vsnprintf(buffer, 1024, format, argList); - va_end(argList); - - MessageBoxA(nullptr, buffer, "Error", MB_OK | MB_ICONERROR); -} - -void reportError(LPCWSTR format, ...) -{ - WCHAR buffer[1025]; - memset(buffer, 0, sizeof(WCHAR) * 1025); - - va_list argList; - va_start(argList, format); - - _vsnwprintf_s(buffer, 1024, format, argList); - va_end(argList); - - MessageBoxW(nullptr, buffer, L"Error", MB_OK | MB_ICONERROR); -} - -void criticalOnTop(const QString& message) -{ - QMessageBox mb(QMessageBox::Critical, QObject::tr("Mod Organizer"), message); - - mb.show(); - mb.activateWindow(); - mb.raise(); - mb.exec(); -} - -} // namespace MOShared diff --git a/src/shared/error_report.h b/src/shared/error_report.h deleted file mode 100644 index 9343d3da..00000000 --- a/src/shared/error_report.h +++ /dev/null @@ -1,44 +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 . -*/ - -#ifndef MODORGANIZER_SHARED_ERROR_REPORT_INCLUDED -#define MODORGANIZER_SHARED_ERROR_REPORT_INCLUDED - -#include -#define WIN32_LEAN_AND_MEAN -#include -#include - -namespace MOShared -{ - -void reportError(LPCSTR format, ...); -void reportError(LPCWSTR format, ...); - -// shows a critical message box that's raised to the top of the zorder, useful -// for messages without a main window, which sometimes makes them pop up behind -// all other windows -// -// the dialog is not topmost, it's just raised once when shown -// -void criticalOnTop(const QString& message); - -} // namespace MOShared - -#endif // MODORGANIZER_SHARED_ERROR_REPORT_INCLUDED diff --git a/src/shared/leaktrace.cpp b/src/shared/leaktrace.cpp deleted file mode 100644 index 466162a4..00000000 --- a/src/shared/leaktrace.cpp +++ /dev/null @@ -1,68 +0,0 @@ -//disable warning messages 4302 , 4311 and 4312 -#pragma warning( disable : 4302 ) -#pragma warning( disable : 4311 ) -#pragma warning( disable : 4312 ) - -#include "leaktrace.h" -#include "stackdata.h" -#include -#include -#include -#include -#include -#include -#include - - -using namespace MOShared; - - -static struct __TraceData { - void regTrace(void *pointer, const char *functionName, int line) { - m_Traces[reinterpret_cast(pointer)] = StackData(functionName, line); - } - void deregTrace(void *pointer) { - auto iter = m_Traces.find(reinterpret_cast(pointer)); - if (iter != m_Traces.end()) { - m_Traces.erase(iter); - } - } - - ~__TraceData() { - std::map > result; - for (auto iter = m_Traces.begin(); iter != m_Traces.end(); ++iter) { - result[iter->second].push_back(iter->first); - } - for (auto iter = result.begin(); iter != result.end(); ++iter) { - printf("-----------------------------------\n" - "%d objects not freed, allocated at:\n%s", - static_cast(iter->second.size()), iter->first.toString().c_str()); - printf("Addresses: "); - for (int i = 0; - i < (std::min)(5, static_cast(iter->second.size())); ++i) { - printf("%p, ", reinterpret_cast(iter->second[i])); - } - printf("\n"); - } - } - - std::map m_Traces; - -} __trace; - - -void LeakTrace::TraceAlloc(void *ptr, const char *functionName, int line) -{ - __trace.regTrace(ptr, functionName, line); -} - -void LeakTrace::TraceDealloc(void *ptr) -{ - __trace.deregTrace(ptr); -} - -//re-enable warning messages 4302 , 4311 and 4312 -#pragma warning( default : 4302 ) -#pragma warning( default : 4311 ) -#pragma warning( default : 4312 ) - diff --git a/src/shared/leaktrace.h b/src/shared/leaktrace.h deleted file mode 100644 index 4985925e..00000000 --- a/src/shared/leaktrace.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef LEAKTRACE_H -#define LEAKTRACE_H - - -namespace LeakTrace { - -void TraceAlloc(void *ptr, const char *functionName, int line); -void TraceDealloc(void *ptr); - -}; - -#ifdef TRACE_LEAKS - -#define LEAK_TRACE LeakTrace::TraceAlloc(this, __FUNCTION__, __LINE__) -#define LEAK_UNTRACE LeakTrace::TraceDealloc(this) - -#else // TRACE_LEAKS - -#define LEAK_TRACE -#define LEAK_UNTRACE - -#endif // TRACE_LEAKS - -#endif // LEAKTRACE_H diff --git a/src/shared/stackdata.cpp b/src/shared/stackdata.cpp deleted file mode 100644 index b336593a..00000000 --- a/src/shared/stackdata.cpp +++ /dev/null @@ -1,169 +0,0 @@ -#include "stackdata.h" - -#include "util.h" -#include -#include -#include -#include -#include "error_report.h" -#include - - -using namespace MOShared; - -#if defined _MSC_VER - -static void initDbgIfNecess() -{ - HANDLE process = ::GetCurrentProcess(); - static std::set initialized; - if (initialized.find(::GetCurrentProcessId()) == initialized.end()) { - static bool firstCall = true; - if (firstCall) { - ::SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); - firstCall = false; - } - if (!::SymInitialize(process, NULL, TRUE)) { - printf("failed to initialize symbols: %lu", ::GetLastError()); - } - initialized.insert(::GetCurrentProcessId()); - } -} - - - -StackData::StackData() - : m_Count(0) - , m_Function() - , m_Line(-1) -{ - initTrace(); -} - -StackData::StackData(const char *function, int line) - : m_Count(0) - , m_Function(function) - , m_Line(line) -{ - -} - -std::string StackData::toString() const { - initDbgIfNecess(); - - char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; - PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - symbol->MaxNameLen = MAX_SYM_NAME; - - std::ostringstream stackStream; - - if (m_Function.length() > 0) { - stackStream << "[" << m_Function << ":" << m_Line << "]\n"; - } - - for(unsigned int i = 0; i < m_Count; ++i) { - DWORD64 displacement = 0; - if (!::SymFromAddr(::GetCurrentProcess(), (DWORD64)m_Stack[i], &displacement, symbol)) { - stackStream << m_Count - i - 1 << ": [" << m_Stack[i] << "]\n"; - } else { - stackStream << m_Count - i - 1 << ": " << symbol->Name << "\n"; - } - } - return stackStream.str(); -} - -void StackData::load_modules(HANDLE process, DWORD processID) { - HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID); - if (snap == INVALID_HANDLE_VALUE) - return; - - MODULEENTRY32 entry; - entry.dwSize = sizeof(entry); - - if (Module32First(snap, &entry)) { - do { - std::string fileName = ToString(entry.szExePath, false); - std::string moduleName = ToString(entry.szModule, false); - SymLoadModule64(process, NULL, fileName.c_str(), moduleName.c_str(), (DWORD64) entry.modBaseAddr, entry.modBaseSize); - } while (Module32Next(snap, &entry)); - } - CloseHandle(snap); -} - -#pragma warning( disable : 4748 ) - -void StackData::initTrace() { -#ifdef _X86_ - load_modules(::GetCurrentProcess(), ::GetCurrentProcessId()); - CONTEXT context; - std::memset(&context, 0, sizeof(CONTEXT)); - context.ContextFlags = CONTEXT_CONTROL; - //Why only for 64 bit? -#if BOOST_ARCH_X86_64 || defined(__clang__) - ::RtlCaptureContext(&context); -#else - __asm - { - Label: - mov [context.Ebp], ebp; - mov [context.Esp], esp; - mov eax, [Label]; - mov [context.Eip], eax; - } -#endif - - STACKFRAME64 stackFrame; - ::ZeroMemory(&stackFrame, sizeof(STACKFRAME64)); - stackFrame.AddrPC.Offset = context.Eip; - stackFrame.AddrPC.Mode = AddrModeFlat; - stackFrame.AddrFrame.Offset = context.Ebp; - stackFrame.AddrFrame.Mode = AddrModeFlat; - stackFrame.AddrStack.Offset = context.Esp; - stackFrame.AddrStack.Mode = AddrModeFlat; - m_Count = 0; - while (m_Count < FRAMES_TO_CAPTURE) { - if (!StackWalk64(IMAGE_FILE_MACHINE_I386, ::GetCurrentProcess(), - ::GetCurrentThread(), &stackFrame, &context, NULL, - &SymFunctionTableAccess64, &SymGetModuleBase64, NULL)) { - break; - } - - if (stackFrame.AddrPC.Offset == 0) { - continue; - break; - } - - m_Stack[m_Count++] = reinterpret_cast(stackFrame.AddrPC.Offset); - } -#endif -} - - -bool MOShared::operator==(const StackData &LHS, const StackData &RHS) { - if (LHS.m_Count != RHS.m_Count) { - return false; - } else { - for (int i = 0; i < LHS.m_Count; ++i) { - if (LHS.m_Stack[i] != RHS.m_Stack[i]) { - return false; - } - } - } - return true; -} - - -bool MOShared::operator<(const StackData &LHS, const StackData &RHS) { - if (LHS.m_Count != RHS.m_Count) { - return LHS.m_Count < RHS.m_Count; - } else { - for (int i = 0; i < LHS.m_Count; ++i) { - if (LHS.m_Stack[i] != RHS.m_Stack[i]) { - return LHS.m_Stack[i] < RHS.m_Stack[i]; - } - } - } - return false; -} -#endif diff --git a/src/shared/stackdata.h b/src/shared/stackdata.h deleted file mode 100644 index 7151699c..00000000 --- a/src/shared/stackdata.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef STACKDATA_H -#define STACKDATA_H - - -#include -#include - - -namespace MOShared { - - -class StackData { - friend bool operator==(const StackData &LHS, const StackData &RHS); - friend bool operator<(const StackData &LHS, const StackData &RHS); -public: - - StackData(); - StackData(const char *function, int line); - - std::string toString() const; - -private: - - void load_modules(HANDLE process, DWORD processID); - - void initTrace(); - -private: - - static const int FRAMES_TO_SKIP = 1; - static const int FRAMES_TO_CAPTURE = 20; - -private: - - LPVOID m_Stack[FRAMES_TO_CAPTURE]; - USHORT m_Count; - std::string m_Function; - int m_Line; - -}; - - -bool operator==(const StackData &LHS, const StackData &RHS); - -bool operator<(const StackData &LHS, const StackData &RHS); - -} // namespace MOShared - - -#endif // STACKDATA_H -- cgit v1.3.1