mirror of
https://github.com/ModOrganizer2/modorganizer-diagnose_basic.git
synced 2026-07-27 14:03:10 -07:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f114b3ee60 | ||
|
|
182ec5f85d | ||
|
|
41eb0d50d4 | ||
|
|
9cb9c2cc56 | ||
|
|
dd2203f647 | ||
|
|
926cdedf8c | ||
|
|
7ea85f751e | ||
|
|
fb4eacabed | ||
|
|
4bf94e9fda | ||
|
|
6f73fe05a4 | ||
|
|
41bd8cc0cd | ||
|
|
f0957919a5 |
@@ -10,9 +10,7 @@ TEMPLATE = lib
|
||||
CONFIG += plugins
|
||||
CONFIG += dll
|
||||
|
||||
contains(QT_VERSION, "^5.*") {
|
||||
QT += widgets
|
||||
}
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
DEFINES += DIAGNOSEBASIC_LIBRARY
|
||||
DEFINES += NOMINMAX
|
||||
@@ -26,7 +24,7 @@ HEADERS += diagnosebasic.h
|
||||
|
||||
include(../plugin_template.pri)
|
||||
|
||||
INCLUDEPATH += "$(BOOSTPATH)"
|
||||
INCLUDEPATH += "$${BOOSTPATH}"
|
||||
|
||||
#CONFIG += dll
|
||||
|
||||
|
||||
+85
-26
@@ -45,6 +45,7 @@ using namespace MOBase;
|
||||
|
||||
|
||||
DiagnoseBasic::DiagnoseBasic()
|
||||
: m_MOInfo(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -70,7 +71,7 @@ bool DiagnoseBasic::init(IOrganizer *moInfo)
|
||||
|
||||
QString DiagnoseBasic::name() const
|
||||
{
|
||||
return tr("Basic diagnosis plugin");
|
||||
return "Basic diagnosis plugin";
|
||||
}
|
||||
|
||||
QString DiagnoseBasic::author() const
|
||||
@@ -85,7 +86,7 @@ QString DiagnoseBasic::description() const
|
||||
|
||||
VersionInfo DiagnoseBasic::version() const
|
||||
{
|
||||
return VersionInfo(1, 1, 0, VersionInfo::RELEASE_FINAL);
|
||||
return VersionInfo(1, 1, 2, VersionInfo::RELEASE_FINAL);
|
||||
}
|
||||
|
||||
bool DiagnoseBasic::isActive() const
|
||||
@@ -95,7 +96,13 @@ bool DiagnoseBasic::isActive() const
|
||||
|
||||
QList<PluginSetting> DiagnoseBasic::settings() const
|
||||
{
|
||||
return QList<PluginSetting>();
|
||||
return QList<PluginSetting>()
|
||||
<< PluginSetting("check_errorlog", tr("Warn when an error occured last time an application was run"), true)
|
||||
<< PluginSetting("check_overwrite", tr("Warn when there are files in the overwrite directory"), true)
|
||||
<< PluginSetting("check_font", tr("Warn when the font configuration refers to files that aren't installed"), true)
|
||||
<< PluginSetting("check_conflict", tr("Warn when mods are installed that conflict with MO functionality"), true)
|
||||
<< PluginSetting("check_modorder", tr("Warn when MO determins the mod order may cause problems"), true)
|
||||
<< PluginSetting("check_missingmasters", tr("Warn when there are esps with missing masters"), true);
|
||||
}
|
||||
|
||||
|
||||
@@ -213,6 +220,9 @@ void DiagnoseBasic::topoSort(std::vector<DiagnoseBasic::ListElement> &list) cons
|
||||
|
||||
// figure out disconnected components of the graph
|
||||
std::vector<int> component(num_vertices(graph));
|
||||
if (component.size() == 0) {
|
||||
throw MyException(tr("failed to sort"));
|
||||
}
|
||||
connected_components(graph, &component[0]);
|
||||
for (int i = 0; i != component.size(); ++i) {
|
||||
list[i].sortGroup = component[i];
|
||||
@@ -242,7 +252,8 @@ void DiagnoseBasic::Sorter::sortGroup(std::vector<ListElement> modList)
|
||||
|
||||
auto iter = modList.begin() + 1;
|
||||
for (; iter != modList.end(); ++iter) {
|
||||
if (iter->modPriority < curSeqEnd->modPriority) {
|
||||
if ((iter->pluginPriority != curSeqEnd->pluginPriority)
|
||||
&& (iter->modPriority < curSeqEnd->modPriority)) {
|
||||
// sequence ends
|
||||
// use this sequence of correctly sorted mods if it is longer than the previously longest
|
||||
// sequence and doesn't have fewer mods that don't want to move. Thus the need for mods to
|
||||
@@ -284,7 +295,8 @@ void DiagnoseBasic::Sorter::sortGroup(std::vector<ListElement> modList)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (!found
|
||||
&& (iter->pluginPriority != (*sorted.rbegin()).pluginPriority)) {
|
||||
// add to end!
|
||||
moves.push_back(Move(*iter, *sorted.rbegin(), Move::AFTER));
|
||||
}
|
||||
@@ -339,19 +351,21 @@ bool DiagnoseBasic::assetOrder() const
|
||||
[] (const QString &fileName) -> bool { return fileName.endsWith(".esp", Qt::CaseInsensitive)
|
||||
|| fileName.endsWith(".esm", Qt::CaseInsensitive); });
|
||||
foreach (const QString &esp, esps) {
|
||||
ListElement ele;
|
||||
foreach (const QString origin, m_MOInfo->getFileOrigins(esp)) {
|
||||
ListElement ele;
|
||||
|
||||
ele.espName = QFileInfo(esp).fileName();
|
||||
ele.modName = m_MOInfo->pluginList()->origin(ele.espName);
|
||||
ele.pluginPriority = m_MOInfo->pluginList()->priority(ele.espName);
|
||||
ele.modPriority = m_MOInfo->modList()->priority(ele.modName);
|
||||
IModList::ModStates state = m_MOInfo->modList()->state(ele.modName);
|
||||
ele.avoidMove = state.testFlag(IModList::STATE_ESSENTIAL);
|
||||
auto iter = scriptMods.find(ele.modName);
|
||||
if (state.testFlag(IModList::STATE_EXISTS)
|
||||
&& (iter != scriptMods.end())) {
|
||||
ele.relevantScripts = iter->second;
|
||||
modList.push_back(ele);
|
||||
ele.espName = QFileInfo(esp).fileName();
|
||||
ele.modName = origin;
|
||||
ele.pluginPriority = m_MOInfo->pluginList()->priority(ele.espName);
|
||||
ele.modPriority = m_MOInfo->modList()->priority(ele.modName);
|
||||
IModList::ModStates state = m_MOInfo->modList()->state(ele.modName);
|
||||
ele.avoidMove = state.testFlag(IModList::STATE_ESSENTIAL);
|
||||
auto iter = scriptMods.find(ele.modName);
|
||||
if (state.testFlag(IModList::STATE_EXISTS)
|
||||
&& (iter != scriptMods.end())) {
|
||||
ele.relevantScripts = iter->second;
|
||||
modList.push_back(ele);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,6 +387,10 @@ bool DiagnoseBasic::assetOrder() const
|
||||
}
|
||||
}
|
||||
|
||||
if (distinctModList.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// sort the list by plugin priority. This step is probably unnecessary as the list was already sorted when we removed duplicates
|
||||
std::sort(distinctModList.begin(), distinctModList.end(),
|
||||
[] (const ListElement &lhs, const ListElement &rhs) -> bool { return lhs.pluginPriority < rhs.pluginPriority; });
|
||||
@@ -386,6 +404,36 @@ bool DiagnoseBasic::assetOrder() const
|
||||
return m_SuggestedMoves.size() > 0;
|
||||
}
|
||||
|
||||
bool DiagnoseBasic::missingMasters() const
|
||||
{
|
||||
std::set<QString> enabledPlugins;
|
||||
|
||||
QStringList esps = m_MOInfo->findFiles("",
|
||||
[] (const QString &fileName) -> bool { return fileName.endsWith(".esp", Qt::CaseInsensitive)
|
||||
|| fileName.endsWith(".esm", Qt::CaseInsensitive); });
|
||||
// gather enabled masters first
|
||||
foreach (const QString &esp, esps) {
|
||||
QString baseName = QFileInfo(esp).fileName();
|
||||
if (m_MOInfo->pluginList()->state(baseName) == IPluginList::STATE_ACTIVE) {
|
||||
enabledPlugins.insert(baseName.toLower());
|
||||
}
|
||||
}
|
||||
|
||||
m_MissingMasters.clear();
|
||||
// for each required master in each esp, test if it's in the list of enabled masters.
|
||||
foreach (const QString &esp, esps) {
|
||||
QString baseName = QFileInfo(esp).fileName();
|
||||
if (m_MOInfo->pluginList()->state(baseName) == IPluginList::STATE_ACTIVE) {
|
||||
foreach (const QString master, m_MOInfo->pluginList()->masters(baseName)) {
|
||||
if (enabledPlugins.find(master.toLower()) == enabledPlugins.end()) {
|
||||
m_MissingMasters.insert(master);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return !m_MissingMasters.empty();
|
||||
}
|
||||
|
||||
bool DiagnoseBasic::invalidFontConfig() const
|
||||
{
|
||||
if (m_MOInfo->gameInfo().type() != IGameInfo::TYPE_SKYRIM) {
|
||||
@@ -430,26 +478,28 @@ bool DiagnoseBasic::invalidFontConfig() const
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::vector<unsigned int> DiagnoseBasic::activeProblems() const
|
||||
{
|
||||
std::vector<unsigned int> result;
|
||||
|
||||
if (errorReported()) {
|
||||
if (m_MOInfo->pluginSetting(name(), "check_errorlog").toBool() && errorReported()) {
|
||||
result.push_back(PROBLEM_ERRORLOG);
|
||||
}
|
||||
if (overwriteFiles()) {
|
||||
if (m_MOInfo->pluginSetting(name(), "check_overwrite").toBool() && overwriteFiles()) {
|
||||
result.push_back(PROBLEM_OVERWRITE);
|
||||
}
|
||||
if (invalidFontConfig()) {
|
||||
if (m_MOInfo->pluginSetting(name(), "check_font").toBool() && invalidFontConfig()) {
|
||||
result.push_back(PROBLEM_INVALIDFONT);
|
||||
}
|
||||
if (nitpickInstalled()) {
|
||||
if (m_MOInfo->pluginSetting(name(), "check_conflict").toBool() && nitpickInstalled()) {
|
||||
result.push_back(PROBLEM_NITPICKINSTALLED);
|
||||
}
|
||||
if (assetOrder()) {
|
||||
if (m_MOInfo->pluginSetting(name(), "check_modorder").toBool() && assetOrder()) {
|
||||
result.push_back(PROBLEM_ASSETORDER);
|
||||
}
|
||||
if (m_MOInfo->pluginSetting(name(), "check_missingmasters").toBool() && missingMasters()) {
|
||||
result.push_back(PROBLEM_MISSINGMASTERS);
|
||||
}
|
||||
if (QFile::exists(m_MOInfo->profilePath() + "/profile_tweaks.ini")) {
|
||||
result.push_back(PROBLEM_PROFILETWEAKS);
|
||||
}
|
||||
@@ -472,6 +522,8 @@ QString DiagnoseBasic::shortDescription(unsigned int key) const
|
||||
return tr("Potential Mod order problem");
|
||||
case PROBLEM_PROFILETWEAKS:
|
||||
return tr("Ini Tweaks overwritten");
|
||||
case PROBLEM_MISSINGMASTERS:
|
||||
return tr("Missing Masters");
|
||||
default:
|
||||
throw MyException(tr("invalid problem key %1").arg(key));
|
||||
}
|
||||
@@ -498,15 +550,17 @@ QString DiagnoseBasic::fullDescription(unsigned int key) const
|
||||
"Worse: The two solutions may conflict so it's strongly suggested you remove this plugin.");
|
||||
case PROBLEM_ASSETORDER: {
|
||||
QString res = tr("The conflict resolution order for some mods containing scripts differs from that of the corresponding esp.<br>"
|
||||
"This may lead to subtle, hard to locate bugs. You should re-order the affected mods (left list!).<br>"
|
||||
"This may lead to subtle, hard to locate bugs. <b>You should re-order the affected mods (<font color=\"red\">left list!</font>).</b><br>"
|
||||
"There is no way to reliably know if each of these changes is absolutely necessary but its definitively safer.<br>"
|
||||
"If someone suggested you ignore this message, please give them a proper slapping from me. <b>Do not ignore this warning</b><br>"
|
||||
"The following changes should prevent these kinds of errors:") + "<ul>";
|
||||
foreach(const Move &op, m_SuggestedMoves) {
|
||||
QString itemName = m_MOInfo->modList()->displayName(op.item.modName);
|
||||
QString referenceName = m_MOInfo->modList()->displayName(op.reference.modName);
|
||||
if (op.type == Move::BEFORE) {
|
||||
res += "<li>" + tr("Move %1 before %2").arg(op.item.modName).arg(op.reference.modName) + "</li>";
|
||||
res += "<li>" + tr("Move %1 before %2").arg(itemName).arg(referenceName) + "</li>";
|
||||
} else {
|
||||
res += "<li>" + tr("Move %1 after %2").arg(op.item.modName).arg(op.reference.modName) + "</li>";
|
||||
res += "<li>" + tr("Move %1 after %2").arg(itemName).arg(referenceName) + "</li>";
|
||||
}
|
||||
}
|
||||
res += "</ul>";
|
||||
@@ -522,6 +576,11 @@ QString DiagnoseBasic::fullDescription(unsigned int key) const
|
||||
"Hitting the <i>Fix</i> button will delete that file")
|
||||
+ "<hr><i>profile_tweaks.ini:</i><pre>" + fileContent + "</pre>";
|
||||
} break;
|
||||
case PROBLEM_MISSINGMASTERS: {
|
||||
return tr("The masters for some plugins (esp/esm) are not enabled.<br>"
|
||||
"The game will crash unless you install and enable the following plugins: ")
|
||||
+ "<ul><li>" + SetJoin(m_MissingMasters, "</li><li>") + "</li></ul>";
|
||||
} break;
|
||||
default:
|
||||
throw MyException(tr("invalid problem key %1").arg(key));
|
||||
}
|
||||
|
||||
+4
-1
@@ -29,7 +29,7 @@ along with this plugin. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <QSet>
|
||||
|
||||
|
||||
class DiagnoseBasic : public QObject, MOBase::IPlugin, MOBase::IPluginDiagnose
|
||||
class DiagnoseBasic : public QObject, public MOBase::IPlugin, public MOBase::IPluginDiagnose
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(MOBase::IPlugin MOBase::IPluginDiagnose)
|
||||
@@ -66,6 +66,7 @@ private:
|
||||
bool invalidFontConfig() const;
|
||||
bool nitpickInstalled() const;
|
||||
bool assetOrder() const;
|
||||
bool missingMasters() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -75,6 +76,7 @@ private:
|
||||
static const unsigned int PROBLEM_NITPICKINSTALLED = 4;
|
||||
static const unsigned int PROBLEM_ASSETORDER = 5;
|
||||
static const unsigned int PROBLEM_PROFILETWEAKS = 7;
|
||||
static const unsigned int PROBLEM_MISSINGMASTERS = 8;
|
||||
|
||||
static const unsigned int NUM_CONTEXT_ROWS = 5;
|
||||
|
||||
@@ -129,6 +131,7 @@ private:
|
||||
mutable QString m_ErrorMessage;
|
||||
mutable std::vector <Move> m_SuggestedMoves;
|
||||
mutable QString m_NewestModlistBackup;
|
||||
mutable std::set<QString> m_MissingMasters;
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user