summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/aboutdialog.ui17
-rw-r--r--src/downloadmanager.cpp91
-rw-r--r--src/downloadmanager.h4
-rw-r--r--src/env.cpp39
-rw-r--r--src/env.h4
-rw-r--r--src/envfs.cpp25
-rw-r--r--src/envfs.h5
-rw-r--r--src/envmodule.cpp23
-rw-r--r--src/envmodule.h4
-rw-r--r--src/moapplication.cpp5
-rw-r--r--src/nxmaccessmanager.cpp18
-rw-r--r--src/profile.cpp8
-rw-r--r--src/sanitychecks.cpp62
-rw-r--r--src/settings.cpp57
-rw-r--r--src/settings.h4
-rw-r--r--src/shared/appconfig.inc2
-rw-r--r--src/shared/directoryentry.cpp2
-rw-r--r--src/shared/util.cpp5
18 files changed, 282 insertions, 93 deletions
diff --git a/src/aboutdialog.ui b/src/aboutdialog.ui
index 7a7627a0..e1f7aef3 100644
--- a/src/aboutdialog.ui
+++ b/src/aboutdialog.ui
@@ -441,12 +441,17 @@
</item>
<item>
<property name="text">
- <string notr="true">DoubleYou</string>
+ <string notr="true">BlueAmulet</string>
</property>
</item>
<item>
<property name="text">
- <string notr="true">Drew Warwick</string>
+ <string notr="true">Bridger</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string notr="true">Brixified</string>
</property>
</item>
<item>
@@ -456,12 +461,12 @@
</item>
<item>
<property name="text">
- <string notr="true">Bridger</string>
+ <string notr="true">DoubleYou</string>
</property>
</item>
<item>
<property name="text">
- <string notr="true">Brixified</string>
+ <string notr="true">Drew Warwick</string>
</property>
</item>
<item>
@@ -536,12 +541,12 @@
</item>
<item>
<property name="text">
- <string notr="true">z929669</string>
+ <string notr="true">thosrtanner</string>
</property>
</item>
<item>
<property name="text">
- <string notr="true">thosrtanner</string>
+ <string notr="true">z929669</string>
</property>
</item>
</widget>
diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp
index 762e3cdb..c912464d 100644
--- a/src/downloadmanager.cpp
+++ b/src/downloadmanager.cpp
@@ -24,11 +24,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "nexusinterface.h"
#include "nxmaccessmanager.h"
#include "iplugingame.h"
+#include "envfs.h"
#include <nxmurl.h>
#include <taskprogressmanager.h>
#include "utility.h"
#include "selectiondialog.h"
#include "bbcode.h"
+#include "shared/util.h"
#include <utility.h>
#include <report.h>
@@ -77,7 +79,9 @@ DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createNew(const Mo
return info;
}
-DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createFromMeta(const QString &filePath, bool showHidden, const QString outputDirectory)
+DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createFromMeta(
+ const QString &filePath, bool showHidden, const QString outputDirectory,
+ std::optional<uint64_t> fileSize)
{
DownloadInfo *info = new DownloadInfo;
@@ -113,7 +117,7 @@ DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createFromMeta(con
info->m_DownloadID = s_NextDownloadID++;
info->m_Output.setFileName(filePath);
- info->m_TotalSize = QFileInfo(filePath).size();
+ info->m_TotalSize = fileSize ? *fileSize : QFileInfo(filePath).size();
info->m_PreResumeSize = info->m_TotalSize;
info->m_CurrentUrl = 0;
info->m_Urls = metaFile.value("url", "").toString().split(";");
@@ -325,13 +329,15 @@ void DownloadManager::refreshList()
}
}
- QStringList supportedExtensions = m_OrganizerCore->installationManager()->getSupportedExtensions();
- QStringList nameFilters(supportedExtensions);
+ const QStringList supportedExtensions = m_OrganizerCore->installationManager()->getSupportedExtensions();
+ std::vector<std::wstring> nameFilters;
for (const auto& extension : supportedExtensions) {
- nameFilters.append("*." + extension);
+ nameFilters.push_back(L"." + extension.toLower().toStdWString());
}
- nameFilters.append(QString("*").append(UNFINISHED));
+ nameFilters.push_back(QString(UNFINISHED).toLower().toStdWString());
+
+
QDir dir(QDir::fromNativeSeparators(m_OutputDirectory));
// find orphaned meta files and delete them (sounds cruel but it's better for everyone)
@@ -348,28 +354,65 @@ void DownloadManager::refreshList()
shellDelete(orphans, true);
}
- // add existing downloads to list
- foreach (QString file, dir.entryList(nameFilters, QDir::Files, QDir::Time)) {
- bool Exists = false;
- for (QVector<DownloadInfo*>::const_iterator Iter = m_ActiveDownloads.begin(); Iter != m_ActiveDownloads.end() && !Exists; ++Iter) {
- if (QString::compare((*Iter)->m_FileName, file, Qt::CaseInsensitive) == 0) {
- Exists = true;
- } else if (QString::compare(QFileInfo((*Iter)->m_Output.fileName()).fileName(), file, Qt::CaseInsensitive) == 0) {
- Exists = true;
- }
- }
- if (Exists) {
- continue;
- }
- QString fileName = QDir::fromNativeSeparators(m_OutputDirectory) + "/" + file;
+ std::set<std::wstring> seen;
- DownloadInfo *info = DownloadInfo::createFromMeta(fileName, m_ShowHidden, m_OutputDirectory);
- if (info != nullptr) {
- m_ActiveDownloads.push_front(info);
- }
+ struct Context
+ {
+ DownloadManager& self;
+ std::set<std::wstring>& seen;
+ std::vector<std::wstring>& extensions;
+ };
+
+ Context cx = {*this, seen, nameFilters};
+
+ for (auto&& d : m_ActiveDownloads) {
+ cx.seen.insert(d->m_FileName.toLower().toStdWString());
+ cx.seen.insert(QFileInfo(d->m_Output.fileName()).fileName().toLower().toStdWString());
}
+
+ env::forEachEntry(
+ QDir::toNativeSeparators(m_OutputDirectory).toStdWString(), &cx, nullptr, nullptr,
+ [](void* data, std::wstring_view f, FILETIME, uint64_t size) {
+ auto& cx = *static_cast<Context*>(data);
+
+ std::wstring lc = MOShared::ToLowerCopy(f);
+
+ bool interestingExt = false;
+ for (auto&& ext : cx.extensions) {
+ if (lc.ends_with(ext)) {
+ interestingExt = true;
+ break;
+ }
+ }
+
+ if (!interestingExt) {
+ return;
+ }
+
+ if (cx.seen.contains(lc)) {
+ return;
+ }
+
+ QString fileName =
+ QDir::fromNativeSeparators(cx.self.m_OutputDirectory) + "/" +
+ QString::fromWCharArray(f.data(), f.size());
+
+ DownloadInfo *info = DownloadInfo::createFromMeta(
+ fileName, cx.self.m_ShowHidden, cx.self.m_OutputDirectory, size);
+
+ if (info == nullptr) {
+ return;
+ }
+
+ cx.self.m_ActiveDownloads.push_front(info);
+ cx.seen.insert(std::move(lc));
+ cx.seen.insert(QFileInfo(info->m_Output.fileName()).fileName().toLower().toStdWString());
+ });
+
+ log::debug("saw {} downloads", m_ActiveDownloads.size());
+
emit update(-1);
//let watcher trigger refreshes again
diff --git a/src/downloadmanager.h b/src/downloadmanager.h
index 953ab88b..5e126f4b 100644
--- a/src/downloadmanager.h
+++ b/src/downloadmanager.h
@@ -104,7 +104,9 @@ private:
bool m_Hidden;
static DownloadInfo *createNew(const MOBase::ModRepositoryFileInfo *fileInfo, const QStringList &URLs);
- static DownloadInfo *createFromMeta(const QString &filePath, bool showHidden, const QString outputDirectory);
+ static DownloadInfo *createFromMeta(
+ const QString &filePath, bool showHidden, const QString outputDirectory,
+ std::optional<uint64_t> fileSize={});
/**
* @brief rename the file
diff --git a/src/env.cpp b/src/env.cpp
index 98d2e6ea..76473dfb 100644
--- a/src/env.cpp
+++ b/src/env.cpp
@@ -6,6 +6,7 @@
#include "envwindows.h"
#include "envdump.h"
#include "settings.h"
+#include "shared/util.h"
#include <log.h>
#include <utility.h>
@@ -344,7 +345,9 @@ void Environment::dump(const Settings& s) const
log::debug("modules loaded in process:");
for (const auto& m : loadedModules()) {
- log::debug(" . {}", m.toString());
+ if (m.interesting()) {
+ log::debug(" . {}", m.toString());
+ }
}
log::debug("displays:");
@@ -1009,7 +1012,7 @@ bool registryValueExists(const QString& keyName, const QString& valueName)
// returns the filename of the given process or the current one
//
-std::wstring processFilename(HANDLE process=INVALID_HANDLE_VALUE)
+std::filesystem::path processPath(HANDLE process=INVALID_HANDLE_VALUE)
{
// double the buffer size 10 times
const int MaxTries = 10;
@@ -1045,7 +1048,7 @@ std::wstring processFilename(HANDLE process=INVALID_HANDLE_VALUE)
const std::wstring s(buffer.get(), writtenSize);
const std::filesystem::path path(s);
- return path.filename().native();
+ return path;
}
}
@@ -1062,6 +1065,21 @@ std::wstring processFilename(HANDLE process=INVALID_HANDLE_VALUE)
return {};
}
+std::wstring processFilename(HANDLE process=INVALID_HANDLE_VALUE)
+{
+ const auto p = processPath(process);
+ if (p.empty()) {
+ return {};
+ }
+
+ return p.filename().native();
+}
+
+std::filesystem::path thisProcessPath()
+{
+ return processPath();
+}
+
DWORD findOtherPid()
{
const std::wstring defaultName = L"ModOrganizer.exe";
@@ -1126,6 +1144,19 @@ std::wstring tempDir()
return std::wstring(buffer, buffer + written);
}
+std::wstring safeVersion()
+{
+ try
+ {
+ // this can throw
+ return MOShared::createVersionInfo().displayString(3).toStdWString() + L"-";
+ }
+ catch(...)
+ {
+ return {};
+ }
+}
+
HandlePtr tempFile(const std::wstring dir)
{
// maximum tries of incrementing the counter
@@ -1139,7 +1170,7 @@ HandlePtr tempFile(const std::wstring dir)
// i can go until MaxTries
std::wostringstream oss;
oss
- << L"ModOrganizer-"
+ << L"ModOrganizer-" << safeVersion()
<< std::setw(4) << (1900 + tm->tm_year)
<< std::setw(2) << std::setfill(L'0') << (tm->tm_mon + 1)
<< std::setw(2) << std::setfill(L'0') << tm->tm_mday << "T"
diff --git a/src/env.h b/src/env.h
index e9cb7a36..2152a40d 100644
--- a/src/env.h
+++ b/src/env.h
@@ -309,6 +309,10 @@ bool registryValueExists(const QString& key, const QString& value);
//
void deleteRegistryKeyIfEmpty(const QString& name);
+// returns the path to this process
+//
+std::filesystem::path thisProcessPath();
+
} // namespace env
#endif // ENV_ENV_H
diff --git a/src/envfs.cpp b/src/envfs.cpp
index 20ba4229..9317eb70 100644
--- a/src/envfs.cpp
+++ b/src/envfs.cpp
@@ -298,14 +298,17 @@ void forEachEntryImpl(
ObjectName.MaximumLength = ObjectName.Length;
if (DirInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- dirStartF(cx, toStringView(&oa));
- forEachEntryImpl(cx, hc, buffers, &oa, depth+1, dirStartF, dirEndF, fileF);
- dirEndF(cx, toStringView(&oa));
+ if (dirStartF && dirEndF) {
+ dirStartF(cx, toStringView(&oa));
+ forEachEntryImpl(cx, hc, buffers, &oa, depth+1, dirStartF, dirEndF, fileF);
+ dirEndF(cx, toStringView(&oa));
+ }
} else {
FILETIME ft;
ft.dwLowDateTime = DirInfo->LastWriteTime.LowPart;
ft.dwHighDateTime = DirInfo->LastWriteTime.HighPart;
- fileF(cx, toStringView(&oa), ft);
+
+ fileF(cx, toStringView(&oa), ft, DirInfo->AllocationSize.QuadPart);
}
}
@@ -380,20 +383,20 @@ Directory getFilesAndDirs(const std::wstring& path)
cx->current.pop();
},
- [](void* pcx, std::wstring_view path, FILETIME ft) {
+ [](void* pcx, std::wstring_view path, FILETIME ft, uint64_t s) {
Context* cx = (Context*)pcx;
- cx->current.top()->files.push_back(File(path, ft));
+ cx->current.top()->files.push_back(File(path, ft, s));
}
);
return root;
}
-File::File(std::wstring_view n, FILETIME ft) :
+File::File(std::wstring_view n, FILETIME ft, uint64_t s) :
name(n.begin(), n.end()),
lcname(MOShared::ToLowerCopy(name)),
- lastModified(ft)
+ lastModified(ft), size(s)
{
}
@@ -429,7 +432,11 @@ void getFilesAndDirsWithFindImpl(const std::wstring& path, Directory& d)
getFilesAndDirsWithFindImpl(newPath, d.dirs.back());
}
} else {
- d.files.push_back(File(findData.cFileName, findData.ftLastWriteTime));
+ const auto size =
+ (findData.nFileSizeHigh * (MAXDWORD+1)) + findData.nFileSizeLow;
+
+ d.files.push_back(File(
+ findData.cFileName, findData.ftLastWriteTime, size));
}
result = ::FindNextFileW(searchHandle, &findData);
diff --git a/src/envfs.h b/src/envfs.h
index e4d98d71..62540e18 100644
--- a/src/envfs.h
+++ b/src/envfs.h
@@ -12,8 +12,9 @@ struct File
std::wstring name;
std::wstring lcname;
FILETIME lastModified;
+ uint64_t size;
- File(std::wstring_view name, FILETIME ft);
+ File(std::wstring_view name, FILETIME ft, uint64_t size);
};
struct Directory
@@ -174,7 +175,7 @@ private:
using DirStartF = void (void*, std::wstring_view);
using DirEndF = void (void*, std::wstring_view);
-using FileF = void (void*, std::wstring_view, FILETIME);
+using FileF = void (void*, std::wstring_view, FILETIME, uint64_t);
void setHandleCloserThreadCount(std::size_t n);
diff --git a/src/envmodule.cpp b/src/envmodule.cpp
index 5f2a5f5a..81cbad8a 100644
--- a/src/envmodule.cpp
+++ b/src/envmodule.cpp
@@ -308,6 +308,29 @@ QDateTime Module::getTimestamp(const VS_FIXEDFILEINFO& fi) const
QTime(utc.wHour, utc.wMinute, utc.wSecond, utc.wMilliseconds));
}
+bool Module::interesting() const
+{
+ static const auto windir = []() -> QString {
+ try
+ {
+ return QDir::toNativeSeparators(
+ MOBase::getKnownFolder(FOLDERID_Windows).path()) + "\\";
+ }
+ catch(...)
+ {
+ return "c:\\windows\\";
+ }
+ }();
+
+
+ if (m_path.startsWith(windir, Qt::CaseInsensitive)) {
+ return false;
+ }
+
+ return true;
+}
+
+
QString Module::getMD5() const
{
static const std::set<QString> ignore = {
diff --git a/src/envmodule.h b/src/envmodule.h
index c2829b32..4b85d737 100644
--- a/src/envmodule.h
+++ b/src/envmodule.h
@@ -66,6 +66,10 @@ public:
//
QString timestampString() const;
+ // returns false for modules in the Windows root directory
+ //
+ bool interesting() const;
+
// returns a string with all the above information on one line
//
QString toString() const;
diff --git a/src/moapplication.cpp b/src/moapplication.cpp
index e7ac3926..88b5710f 100644
--- a/src/moapplication.cpp
+++ b/src/moapplication.cpp
@@ -254,7 +254,10 @@ int MOApplication::doOneRun(MOMultiProcess& multiProcess)
sanity::checkEnvironment(env);
const auto moduleNotification = env.onModuleLoaded(qApp, [](auto&& m) {
- log::debug("loaded module {}", m.toString());
+ if (m.interesting()) {
+ log::debug("loaded module {}", m.toString());
+ }
+
sanity::checkIncompatibleModule(m);
});
diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp
index 6c8b9054..79c067a2 100644
--- a/src/nxmaccessmanager.cpp
+++ b/src/nxmaccessmanager.cpp
@@ -376,7 +376,7 @@ void ValidationAttempt::start(NXMAccessManager& m, const QString& key)
m_timeout.start();
log::debug(
- "validator: attempt started with timeout of {} seconds", timeout().count());
+ "nexus: attempt started with timeout of {} seconds", timeout().count());
}
bool ValidationAttempt::sendRequest(
@@ -458,11 +458,11 @@ void ValidationAttempt::onFinished()
return;
}
- log::debug("validator attempt: request has finished");
+ log::debug("nexus: request has finished");
if (!m_reply) {
// shouldn't happen
- log::error("validator attempt: reply is null");
+ log::error("nexus: reply is null");
setFailure(HardError, QObject::tr("Internal error"));
return;
}
@@ -472,7 +472,7 @@ void ValidationAttempt::onFinished()
if (code == 0) {
// request wasn't even sent
- log::error("validator attempt: code is 0");
+ log::error("nexus: code is 0");
setFailure(SoftError, m_reply->errorString());
return;
}
@@ -539,7 +539,7 @@ void ValidationAttempt::onFinished()
void ValidationAttempt::onSslErrors(const QList<QSslError>& errors)
{
- log::error("validator attempt: ssl errors");
+ log::error("nexus: ssl errors");
for (auto& e : errors) {
log::error(" . {}", e.errorString());
@@ -557,7 +557,7 @@ void ValidationAttempt::setFailure(Result r, const QString& error)
{
if (r != Cancelled) {
// don't spam the log
- log::error("validator attempt: {}", error);
+ log::error("nexus: {}", error);
}
cleanup();
@@ -572,7 +572,7 @@ void ValidationAttempt::setFailure(Result r, const QString& error)
void ValidationAttempt::setSuccess(const APIUserAccount& user)
{
- log::debug("validator attempt successful");
+ log::debug("nexus connection successful");
cleanup();
m_result = Success;
@@ -617,7 +617,7 @@ std::vector<std::chrono::seconds> NexusKeyValidator::getTimeouts() const
void NexusKeyValidator::start(const QString& key, Behaviour b)
{
if (isActive()) {
- log::debug("validator: trying to start while ongoing; ignoring");
+ log::debug("nexus: trying to start while ongoing; ignoring");
return;
}
@@ -655,7 +655,7 @@ void NexusKeyValidator::createAttempts(
void NexusKeyValidator::cancel()
{
- log::debug("validator: cancelled");
+ log::debug("nexus: connection cancelled");
for (auto&& a : m_attempts) {
a->cancel();
diff --git a/src/profile.cpp b/src/profile.cpp
index 92f2abce..3cc1a2a3 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -1123,10 +1123,6 @@ void Profile::debugDump() const
for (const auto& status : m_ModStatus) {
- if (status.m_Overwrite) {
- continue;
- }
-
auto index = m_ModIndexByPriority.find(status.m_Priority);
if (index == m_ModIndexByPriority.end()) {
log::error("mod with priority {} not in priority map", status.m_Priority);
@@ -1139,6 +1135,10 @@ void Profile::debugDump() const
continue;
}
+ if (m->hasFlag(ModInfo::FLAG_OVERWRITE)) {
+ continue;
+ }
+
add(total, status);
if (m->hasFlag(ModInfo::FLAG_BACKUP)) {
diff --git a/src/sanitychecks.cpp b/src/sanitychecks.cpp
index 613e4b26..1e673ff9 100644
--- a/src/sanitychecks.cpp
+++ b/src/sanitychecks.cpp
@@ -220,46 +220,53 @@ int checkMissingFiles()
int checkBadOSDs(const env::Module& m)
{
- // these dlls seems to interfere mostly with dialogs, like the mod info
- // dialog: it renders dialogs fully white and makes it impossible to interact
- // with them
+ // these dlls seem to interfere mostly with dialogs, like the mod info
+ // dialog: they render some dialogs fully white and make it impossible to
+ // interact with them
//
- // the dlls is usually loaded on startup, but there has been some reports
- // where it got loaded later, so this is also called every time a new module
+ // the dlls is usually loaded on startup, but there has been some reports
+ // where they got loaded later, so this is also called every time a new module
// is loaded into this process
- const char* nahimic =
- "Nahimic (also known as SonicSuite, SonicRadar, SteelSeries, A-Volute, etc.)";
+ const std::string nahimic =
+ "Nahimic (also known as SonicSuite, SonicRadar, "
+ "SteelSeries, A-Volute, etc.)";
- static const std::map<QString, QString> names = {
- {"NahimicOSD.dll", nahimic},
- {"nahimicmsiosd.dll", nahimic},
- {"cassinimlkosd.dll", nahimic},
- {"SS3DevProps.dll", nahimic},
- {"ss2devprops.dll", nahimic},
- {"ss2osd.dll", nahimic},
- {"RTSSHooks64.dll", "RivaTuner Statistics Server"},
- {"SSAudioOSD.dll", "SteelSeries Audio"},
- {"specialk64.dll", "SpecialK"},
- {"corsairosdhook.x64.dll", "Corsair Utility Engine"},
- {"gtii-osd64-vk.dll", "ASUS GPU Tweak 2"},
- {"easyhook64.dll", "Razer Cortex"},
- {"k_fps64.dll", "Razer Cortex"}
+ auto p = [](std::string re, std::string s) {
+ return std::make_pair(std::regex(re, std::regex::icase), s);
+ };
+
+ static const std::vector<std::pair<std::regex, std::string>> list = {
+ p("nahimic(.*)osd\\.dll", nahimic),
+ p("cassini(.*)osd\\.dll", nahimic),
+ p(".+devprops.*.dll", nahimic),
+ p("ss2osd\\.dll", nahimic),
+ p("RTSSHooks64\\.dll", "RivaTuner Statistics Server"),
+ p("SSAudioOSD\\.dll", "SteelSeries Audio"),
+ p("specialk64\\.dll", "SpecialK"),
+ p("corsairosdhook\\.x64\\.dll", "Corsair Utility Engine"),
+ p("gtii-osd64-vk\\.dll", "ASUS GPU Tweak 2"),
+ p("easyhook64\\.dll", "Razer Cortex"),
+ p("k_fps64\\.dll", "Razer Cortex"),
+ p("fw1fontwrapper\\.dll", "Gigabyte 3D OSD"),
+ p("gfxhook64\\.dll", "Gigabyte 3D OSD")
};
const QFileInfo file(m.path());
int n = 0;
- for (auto&& p : names) {
- if (file.fileName().compare(p.first, Qt::CaseInsensitive) == 0) {
+ for (auto&& p : list) {
+ std::smatch m;
+ const auto filename = file.fileName().toStdString();
+
+ if (std::regex_match(filename, m, p.first)) {
log::warn("{}", QObject::tr(
"%1 is loaded.\nThis program is known to cause issues with "
"Mod Organizer, such as freezing or blank windows. Consider "
"uninstalling it.")
- .arg(p.second));
+ .arg(QString::fromStdString(p.second)));
log::warn("{}", file.absoluteFilePath());
-
++n;
}
}
@@ -272,7 +279,8 @@ int checkUsvfsIncompatibilites(const env::Module& m)
// these dlls seems to interfere with usvfs
static const std::map<QString, QString> names = {
- {"mactype64.dll", "Mactype"}
+ {"mactype64.dll", "Mactype"},
+ {"epclient64.dll", "Citrix ICA Client"}
};
const QFileInfo file(m.path());
@@ -283,7 +291,7 @@ int checkUsvfsIncompatibilites(const env::Module& m)
log::warn("{}", QObject::tr(
"%1 is loaded. This program is known to cause issues with "
"Mod Organizer and its virtual filesystem, such script extenders "
- "refusing to run. Consider uninstalling it.")
+ "or others programs refusing to run. Consider uninstalling it.")
.arg(p.second));
log::warn("{}", file.absoluteFilePath());
diff --git a/src/settings.cpp b/src/settings.cpp
index 85aa5f2f..ebb4fabe 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -21,6 +21,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "settingsutilities.h"
#include "serverinfo.h"
#include "executableslist.h"
+#include "instancemanager.h"
#include "shared/appconfig.h"
#include "env.h"
#include "envmetrics.h"
@@ -479,7 +480,9 @@ QSettings::Status Settings::iniStatus() const
void Settings::dump() const
{
static const QStringList ignore({
- "username", "password", "nexus_api_key", "nexus_username", "nexus_password"
+ "username", "password",
+ "nexus_api_key", "nexus_username", "nexus_password",
+ "steam_username"
});
log::debug("settings:");
@@ -497,6 +500,7 @@ void Settings::dump() const
}
m_Network.dump();
+ m_Nexus.dump();
}
void Settings::managedGameChanged(IPluginGame const *gamePlugin)
@@ -1524,7 +1528,7 @@ std::map<QString, QString> PathSettings::recent() const
if (name.isValid() && dir.isValid()) {
map.emplace(name.toString(), dir.toString());
}
- });
+ });
return map;
}
@@ -1891,7 +1895,10 @@ void NexusSettings::setTrackedIntegration(bool b) const
void NexusSettings::registerAsNXMHandler(bool force)
{
- const auto nxmPath = QCoreApplication::applicationDirPath() + "/nxmhandler.exe";
+ const auto nxmPath =
+ QCoreApplication::applicationDirPath() + "/" +
+ QString::fromStdWString(AppConfig::nxmHandlerExe());
+
const auto executable = QCoreApplication::applicationFilePath();
QString mode = force ? "forcereg" : "reg";
@@ -1944,6 +1951,50 @@ std::vector<std::chrono::seconds> NexusSettings::validationTimeouts() const
return v;
}
+void NexusSettings::dump() const
+{
+ const auto iniPath =
+ InstanceManager::singleton().globalInstancesRootPath() + "/" +
+ QString::fromStdWString(AppConfig::nxmHandlerIni());
+
+ if (!QFileInfo(iniPath).exists()) {
+ log::debug("nxm ini not found at {}", iniPath);
+ return;
+ }
+
+ QSettings s(iniPath, QSettings::IniFormat);
+ if (const auto st=s.status(); st != QSettings::NoError) {
+ log::debug("can't read nxm ini from {}", iniPath);
+ return;
+ }
+
+ log::debug("nxmhandler settings:");
+
+ QSettings handler("HKEY_CURRENT_USER\\Software\\Classes\\nxm\\", QSettings::NativeFormat);
+ log::debug(" . primary: {}", handler.value("shell/open/command/Default").toString());
+
+ const auto noregister = getOptional<bool>(s, "General", "noregister");
+
+ if (noregister) {
+ log::debug(" . noregister: {}", *noregister);
+ } else {
+ log::debug(" . noregister: (not found)");
+ }
+
+ ScopedReadArray sra(s, "handlers");
+
+ sra.for_each([&] {
+ const auto games = sra.get<QVariant>("games");
+ const auto executable = sra.get<QVariant>("executable");
+ const auto arguments = sra.get<QVariant>("arguments");
+
+ log::debug(" . handler:");
+ log::debug(" . games: {}", games.toString());
+ log::debug(" . executable: {}", executable.toString());
+ log::debug(" . arguments: {}", arguments.toString());
+ });
+}
+
SteamSettings::SteamSettings(Settings& parent, QSettings& settings)
: m_Parent(parent), m_Settings(settings)
diff --git a/src/settings.h b/src/settings.h
index 48aefc27..82c3a615 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -528,6 +528,10 @@ public:
std::vector<std::chrono::seconds> validationTimeouts() const;
+ // dumps nxmhandler stuff
+ //
+ void dump() const;
+
private:
Settings& m_Parent;
QSettings& m_Settings;
diff --git a/src/shared/appconfig.inc b/src/shared/appconfig.inc
index 5839c2f4..9058bf18 100644
--- a/src/shared/appconfig.inc
+++ b/src/shared/appconfig.inc
@@ -18,6 +18,8 @@ APPPARAM(std::wstring, proxyDLLOrig, L"steam_api_orig.dll") // needs to be ident
APPPARAM(std::wstring, proxyDLLSource, L"proxy.dll")
APPPARAM(std::wstring, vfs32DLLName, L"usvfs_x86.dll")
APPPARAM(std::wstring, vfs64DLLName, L"usvfs_x64.dll")
+APPPARAM(std::wstring, nxmHandlerExe, L"nxmhandler.exe")
+APPPARAM(std::wstring, nxmHandlerIni, L"nxmhandler.ini")
APPPARAM(std::wstring, portableLockFileName, L"portable.txt")
APPPARAM(const wchar_t*, localSavePlaceholder, L"__MOProfileSave__\\")
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp
index c4b467d6..0d275844 100644
--- a/src/shared/directoryentry.cpp
+++ b/src/shared/directoryentry.cpp
@@ -636,7 +636,7 @@ void DirectoryEntry::addFiles(
onDirectoryEnd((Context*)pcx, path);
},
- [](void* pcx, std::wstring_view path, FILETIME ft)
+ [](void* pcx, std::wstring_view path, FILETIME ft, uint64_t)
{
onFile((Context*)pcx, path, ft);
}
diff --git a/src/shared/util.cpp b/src/shared/util.cpp
index f316549e..54c6b841 100644
--- a/src/shared/util.cpp
+++ b/src/shared/util.cpp
@@ -210,12 +210,13 @@ std::wstring GetFileVersionString(const std::wstring &fileName)
VersionInfo createVersionInfo()
{
- VS_FIXEDFILEINFO version = GetFileVersion(QApplication::applicationFilePath().toStdWString());
+ VS_FIXEDFILEINFO version = GetFileVersion(env::thisProcessPath().native());
if (version.dwFileFlags & VS_FF_PRERELEASE)
{
// Pre-release builds need annotating
- QString versionString = QString::fromStdWString(GetFileVersionString(QApplication::applicationFilePath().toStdWString()));
+ QString versionString = QString::fromStdWString(
+ GetFileVersionString(env::thisProcessPath().native()));
// The pre-release flag can be set without the string specifying what type of pre-release
bool noLetters = true;