diff --git a/resources/report/js/plugin.js b/resources/report/js/plugin.js index c2c3b6bf..04e9fec0 100644 --- a/resources/report/js/plugin.js +++ b/resources/report/js/plugin.js @@ -100,17 +100,6 @@ function Plugin(obj) { return priorityText; } - Plugin.prototype.getConflictingPlugins = function() { - var request = JSON.stringify({ - name: 'getConflictingPlugins', - args: [ - this.name - ] - }); - - loot.query(request).catch(processCefError); - } - Plugin.prototype.createCard = function() { var card = new PluginCard(); this.card = card; diff --git a/resources/report/js/script.js b/resources/report/js/script.js index 5b38d679..8d02667a 100644 --- a/resources/report/js/script.js +++ b/resources/report/js/script.js @@ -101,6 +101,24 @@ function toggleDisplayCSS(evt) { } } +function getConflictingPluginsFromFilter() { + if (document.getElementById('showOnlyConflicts').checked) { + var conflictsPlugin = document.getElementById('conflictsPlugin'); + if (conflictsPlugin.value.length != 0) { + + var request = JSON.stringify({ + name: 'getConflictingPlugins', + args: [ + conflictsPlugin.value + ] + }); + + return loot.query(request).then(JSON.parse).catch(processCefError); + } + } + + return Promise.resolve([]); +} function togglePlugins(evt) { var sections = document.getElementById('main').children; var entries = document.getElementById('pluginsNav').children; @@ -109,65 +127,63 @@ function togglePlugins(evt) { if (sections.length - 2 != entries.length) { throw "Error: Number of plugins in sidebar doesn't match number of plugins in main area!"; } - /* Check if the conflict filter is enabled, and if a plugin has been given. */ - var conflicts = []; - if (document.getElementById('showOnlyConflicts').checked) { - var plugin = document.getElementById('conflictsPlugin').value; - if (plugin.length != 0) { - conflicts = getConflictingPlugins(plugin); - } - } - /* Start at 3rd section to skip summary and general messages. */ - for (var i = 2; i < sections.length; ++i) { - var isConflictingPlugin = false; - var isMessageless = true; - var hasInactivePluginMessages = false; - var messages = sections[i].getElementsByTagName('ul')[0].getElementsByTagName('li'); - if (sections[i].getAttribute('data-active') == 'false') { - hasInactivePluginMessages = true; - } - if (conflicts.indexOf(sections[i].getElementsByTagName('h1')[0].textContent) != -1) { - isConflictingPlugin = true; - } - for (var j = 0; j < messages.length; ++j) { - var hasPluginMessages = false; - var hasNotes = false; - var hasDoNotCleanMessages = false; - if (messages[j].parentElement.parentElement.id != 'generalMessages') { - hasPluginMessages = true; + /* The conflict filter, if enabled, executes C++ code, so needs to be + handled using a promise, so the rest of the function should wait until + it is completed. + */ + getConflictingPluginsFromFilter().then(function(conflicts) { + /* Start at 3rd section to skip summary and general messages. */ + for (var i = 2; i < sections.length; ++i) { + var isConflictingPlugin = false; + var isMessageless = true; + var hasInactivePluginMessages = false; + var messages = sections[i].getElementsByTagName('ul')[0].getElementsByTagName('li'); + if (sections[i].getAttribute('data-active') == 'false') { + hasInactivePluginMessages = true; } - if (messages[j].className.indexOf('say') != -1) { - hasNotes = true; + if (conflicts.indexOf(sections[i].getElementsByTagName('h1')[0].textContent) != -1) { + isConflictingPlugin = true; } - if (messages[j].textContent.indexOf('Do not clean.') != -1) { - hasDoNotCleanMessages = true; + for (var j = 0; j < messages.length; ++j) { + var hasPluginMessages = false; + var hasNotes = false; + var hasDoNotCleanMessages = false; + if (messages[j].parentElement.parentElement.id != 'generalMessages') { + hasPluginMessages = true; + } + if (messages[j].className.indexOf('say') != -1) { + hasNotes = true; + } + if (messages[j].textContent.indexOf('Do not clean.') != -1) { + hasDoNotCleanMessages = true; + } + if ((document.getElementById('hideAllPluginMessages').checked && hasPluginMessages) + || (document.getElementById('hideNotes').checked && hasNotes) + || (document.getElementById('hideDoNotCleanMessages').checked && hasDoNotCleanMessages) + || (document.getElementById('hideInactivePluginMessages').checked && hasInactivePluginMessages)) { + hideElement(messages[j]); + ++hiddenMessageNo; + } else { + showElement(messages[j]); + } + if (messages[j].className.indexOf('hidden') == -1) { + isMessageless = false; + break; + } } - if ((document.getElementById('hideAllPluginMessages').checked && hasPluginMessages) - || (document.getElementById('hideNotes').checked && hasNotes) - || (document.getElementById('hideDoNotCleanMessages').checked && hasDoNotCleanMessages) - || (document.getElementById('hideInactivePluginMessages').checked && hasInactivePluginMessages)) { - hideElement(messages[j]); - ++hiddenMessageNo; + if ((document.getElementById('hideMessagelessPlugins').checked && isMessageless) + || conflicts.length > 0 && !isConflictingPlugin) { + hideElement(sections[i]); + hideElement(entries[i - 2]); + ++hiddenPluginNo; } else { - showElement(messages[j]); - } - if (messages[j].className.indexOf('hidden') == -1) { - isMessageless = false; - break; + showElement(sections[i]); + showElement(entries[i - 2]); } } - if ((document.getElementById('hideMessagelessPlugins').checked && isMessageless) - || conflicts.length > 0 && !isConflictingPlugin) { - hideElement(sections[i]); - hideElement(entries[i - 2]); - ++hiddenPluginNo; - } else { - showElement(sections[i]); - showElement(entries[i - 2]); - } - } - document.getElementById('hiddenMessageNo').textContent = hiddenMessageNo; - document.getElementById('hiddenPluginNo').textContent = hiddenPluginNo; + document.getElementById('hiddenMessageNo').textContent = hiddenMessageNo; + document.getElementById('hiddenPluginNo').textContent = hiddenPluginNo; + }); } function closeMessageDialog(evt) { var ret = evt.target.returnValue == 'true'; diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp index b68e7781..837ec271 100644 --- a/src/gui/handler.cpp +++ b/src/gui/handler.cpp @@ -137,6 +137,7 @@ namespace loot { } catch (exception &e) { BOOST_LOG_TRIVIAL(error) << "Failed to parse CEF query request \"" << request << "\": " << e.what(); + callback->Failure(-1, e.what()); return false; } @@ -165,15 +166,40 @@ namespace loot { BOOST_LOG_TRIVIAL(info) << "Changing game to that with folder: " << folder; g_app_state.ChangeGame(folder); - BOOST_LOG_TRIVIAL(info) << "Setting LOOT window title bar text to include game name: " << g_app_state.CurrentGame().Name(); #if defined(OS_WIN) + BOOST_LOG_TRIVIAL(info) << "Setting LOOT window title bar text to include game name: " << g_app_state.CurrentGame().Name(); HWND handle = browser->GetHost()->GetWindowHandle(); SetWindowText(handle, ToWinWide("LOOT: " + g_app_state.CurrentGame().Name()).c_str()); #endif callback->Success(GetGameData()); return true; + } + else if (requestName == "getConflictingPlugins") { + // Has one arg, which is the name of the plugin to get conflicts for. + const string pluginName = req["args"][0].as(); + BOOST_LOG_TRIVIAL(debug) << "Searching for plugins that conflict with " << pluginName; + auto pluginIt = g_app_state.CurrentGame().plugins.find(pluginName); + + // Checking for FormID overlap will only work if the plugins have been loaded, so check if + // the first plugin has any FormIDs in memory, and if not load all plugins. + if (g_app_state.CurrentGame().plugins.begin()->second.FormIDs().size() == 0) + g_app_state.CurrentGame().LoadPlugins(false); + + vector conflictingPlugins; + if (pluginIt != g_app_state.CurrentGame().plugins.end()) { + for (const auto& pluginPair : g_app_state.CurrentGame().plugins) { + if (pluginIt->second.DoFormIDsOverlap(pluginPair.second)) { + BOOST_LOG_TRIVIAL(debug) << "Found conflicting plugin: " << pluginPair.first; + conflictingPlugins.push_back(pluginPair.first); + } + } + } + + YAML::Node temp(conflictingPlugins); + callback->Success(JSON::stringify(temp)); + return true; } }