diff --git a/resources/report/js/script.js b/resources/report/js/script.js
index ee23c87d..18c10f24 100644
--- a/resources/report/js/script.js
+++ b/resources/report/js/script.js
@@ -22,6 +22,7 @@
.
*/
'use strict';
+var loot = {};
function isStorageSupported() {
try {
return ('localStorage' in window && window['localStorage'] !== null && window['localStorage'] !== undefined);
@@ -683,15 +684,18 @@ function initUI() {
settingsLangSelect.value = loot.settings.language;
debugVerbositySelect.value = loot.settings.debugVerbosity;
}
-var loot;
-function initJavascriptVars() {
+function initGlobalVars() {
// Create and send a new query.
var request_id = window.cefQuery({
- request: 'initJavascriptVars',
+ request: 'initGlobalVars',
persistent: false,
onSuccess: function(response) {
try {
- loot = JSON.parse(response);
+ var temp = JSON.parse(response);
+ loot.version = temp.version;
+ loot.settings = temp.settings;
+ loot.gameTypes = temp.gameTypes;
+ loot.languages = temp.languages;
} catch (e) {
console.log(e);
console.log('Response: ' + response);
@@ -703,164 +707,173 @@ function initJavascriptVars() {
}
});
}
-function processURLParams() {
- /* Get the data path from the URL and load it. */
- /*var pos = document.URL.indexOf("?data=");*/
- var pos = 0;
- if (pos != -1) {
- /*var datapath = 'file:///' + document.URL.substring(pos+6);*/
- var datapath = 'testdata';
- require([datapath], function(){
- var totalMessageNo = 0;
- var warnMessageNo = 0;
- var errorMessageNo = 0;
- var activePluginNo = 0;
- var dirtyPluginNo = 0;
- /* Fill report with data. */
- document.getElementById('masterlistRevision').textContent = data.masterlist.revision.substr(0, 9);
- document.getElementById('masterlistDate').textContent = data.masterlist.date;
- var generalMessagesList = document.getElementById('generalMessages').getElementsByTagName('ul')[0];
- for (var i = 0; i < data.globalMessages.length; ++i) {
- var li = document.createElement('li');
- li.className = data.globalMessages[i].type;
- /* innerHTML is open to abuse, but for hyperlinking it's too useful. */
- li.innerHTML = data.globalMessages[i].content;
- generalMessagesList.appendChild(li);
+function updateInterfaceWithGameInfo(response) {
- if (li.className == 'warn') {
+ try {
+ loot.game = JSON.parse(response);
+ } catch (e) {
+ console.log(e);
+ console.log('Response: ' + response);
+ }
+
+ var totalMessageNo = 0;
+ var warnMessageNo = 0;
+ var errorMessageNo = 0;
+ var activePluginNo = 0;
+ var dirtyPluginNo = 0;
+
+ /* Fill report with data. */
+ document.getElementById('masterlistRevision').textContent = loot.game.masterlist.revision;
+ document.getElementById('masterlistDate').textContent = loot.game.masterlist.date;
+
+ var generalMessagesList = document.getElementById('generalMessages').getElementsByTagName('ul')[0];
+ for (var i = 0; i < loot.game.globalMessages.length; ++i) {
+ var li = document.createElement('li');
+ li.className = loot.game.globalMessages[i].type;
+ /* innerHTML is open to abuse, but for hyperlinking it's too useful. */
+ li.innerHTML = loot.game.globalMessages[i].content[0].str;
+ generalMessagesList.appendChild(li);
+
+ if (li.className == 'warn') {
+ warnMessageNo++;
+ } else if (li.className == 'error') {
+ errorMessageNo++;
+ }
+ }
+ totalMessageNo = loot.game.globalMessages.length;
+ var pluginsList = document.getElementById('main');
+ var pluginsNav = document.getElementById('pluginsNav');
+ for (var i = 0; i < loot.game.plugins.length; ++i) {
+ var content, clone;
+ /* First add link to navbar. */
+ content = document.getElementById('pluginNav').content;
+ clone = document.importNode(content, true);
+ pluginsNav.appendChild(clone);
+ clone = pluginsNav.lastElementChild;
+
+ clone.getElementsByClassName('name')[0].textContent = loot.game.plugins[i].name;
+ clone.getElementsByTagName('a')[0].href = '#' + loot.game.plugins[i].name.replace(/\s+/g, '');
+ //clone.getElementsByClassName('priority')[0].textContent = 'Priority: 500, Global: ✓'; // Or '✗'.
+
+ if (loot.game.plugins[i].isDummy) {
+ clone.getElementsByClassName('dummyPlugin')[0].className += ' fa fa-eye-slash';
+ }
+
+ if (loot.game.plugins[i].loadsBSA) {
+ clone.getElementsByClassName('loadsBSA')[0].className += ' fa fa-paperclip';
+ }
+
+
+ /*// This won't actually be handled anything like this in the real data implementation.
+ if (data.plugins[i].hasUserEdits) {
+ clone.getElementsByClassName('hasUserEdits')[0].className += ' fa fa-user';
+ }*/
+
+ /* Now add plugin 'card'. */
+ content = document.getElementById('pluginSection').content;
+ clone = document.importNode(content, true);
+ pluginsList.appendChild(clone);
+ clone = pluginsList.lastElementChild;
+
+ clone.setAttribute('data-active', loot.game.plugins[i].isActive);
+ clone.id = loot.game.plugins[i].name.replace(/\s+/g, '');
+
+ if (loot.game.plugins[i].isActive) {
+ ++activePluginNo;
+ }
+
+ /*if (loot.game.plugins[i].isDirty) {
+ ++dirtyPluginNo;
+ }*/
+
+ clone.getElementsByTagName('h1')[0].textContent = loot.game.plugins[i].name;
+
+ if (loot.game.plugins[i].crc != 0) {
+ clone.getElementsByClassName('crc')[0].textContent = 'CRC: ' + loot.game.plugins[i].crc;
+ } else {
+ clone.getElementsByClassName('crc')[0].textContent = '';
+ }
+
+ if (loot.game.plugins[i].isDummy) {
+ showElement(clone.getElementsByClassName('dummyPlugin')[0]);
+ }
+
+ if (loot.game.plugins[i].loadsBSA) {
+ showElement(clone.getElementsByClassName('loadsBSA')[0]);
+ }
+
+ /*// This won't actually be handled anything like this in the real data implementation.
+ if (data.plugins[i].hasUserEdits) {
+ showElement(clone.getElementsByClassName('hasUserEdits')[0]);
+ }*/
+
+ if (loot.game.plugins[i].version) {
+ clone.getElementsByClassName('version')[0].textContent = 'Version: ' + loot.game.plugins[i].version;
+ } else {
+ hideElement(clone.getElementsByClassName('version')[0]);
+ }
+
+ /*if (data.plugins[i].tagsAdd && data.plugins[i].tagsAdd.length != 0) {
+ clone.getElementsByClassName('tag add')[0].textContent = data.plugins[i].tagsAdd.join(', ');
+ } else {*/
+ hideElement(clone.getElementsByClassName('tag add')[0]);
+ //}
+
+ /*if (data.plugins[i].tagRemove && data.plugins[i].tagRemove.length != 0) {
+ clone.getElementsByClassName('tag remove')[0].textContent = data.plugins[i].tagsRemove.join(', ');
+ } else {*/
+ hideElement(clone.getElementsByClassName('tag remove')[0]);
+ //}
+
+ clone.getElementsByClassName('editMetadata')[0].setAttribute('data-target', clone.id);
+ clone.getElementsByClassName('copyMetadata')[0].setAttribute('data-target', clone.id);
+ clone.getElementsByClassName('clearMetadata')[0].setAttribute('data-target', clone.id);
+
+ /*if (data.plugins[i].messages && data.plugins[i].messages.length != 0) {
+ for (var j = 0; j < data.plugins[i].messages.length; ++j) {
+ var messageLi = document.createElement('li');
+ messageLi.className = data.plugins[i].messages[j].type;
+ // innerHTML is open to abuse, but for hyperlinking it's too useful.
+ messageLi.innerHTML = data.plugins[i].messages[j].content;
+ clone.getElementsByTagName('ul')[0].appendChild(messageLi);
+
+ if (messageLi.className == 'warn') {
warnMessageNo++;
- } else if (li.className == 'error') {
+ } else if (messageLi.className == 'error') {
errorMessageNo++;
}
+ totalMessageNo++;
}
- totalMessageNo = data.globalMessages.length;
- var pluginsList = document.getElementById('main');
- var pluginsNav = document.getElementById('pluginsNav');
- for (var i = 0; i < data.plugins.length; ++i) {
- var content, clone;
- /* First add link to navbar. */
- content = document.getElementById('pluginNav').content;
- clone = document.importNode(content, true);
- pluginsNav.appendChild(clone);
- clone = pluginsNav.lastElementChild;
-
- clone.getElementsByClassName('name')[0].textContent = data.plugins[i].name;
- clone.getElementsByTagName('a')[0].href = '#' + data.plugins[i].name.replace(/\s+/g, '');
- clone.getElementsByClassName('priority')[0].textContent = 'Priority: 500, Global: ✓'; // Or '✗'.
-
- if (data.plugins[i].isDummy) {
- clone.getElementsByClassName('dummyPlugin')[0].className += ' fa fa-eye-slash';
- }
-
- if (data.plugins[i].loadsBSA) {
- clone.getElementsByClassName('loadsBSA')[0].className += ' fa fa-paperclip';
- }
-
- if (data.plugins[i].hasUserEdits) {
- /* This won't actually be handled anything like this in the real data implementation. */
- clone.getElementsByClassName('hasUserEdits')[0].className += ' fa fa-user';
- }
-
- /* Now add plugin 'card'. */
- content = document.getElementById('pluginSection').content;
- clone = document.importNode(content, true);
- pluginsList.appendChild(clone);
- clone = pluginsList.lastElementChild;
-
- clone.setAttribute('data-active', data.plugins[i].isActive);
- clone.id = data.plugins[i].name.replace(/\s+/g, '');
-
- if (data.plugins[i].isActive) {
- ++activePluginNo;
- }
-
- if (data.plugins[i].isDirty) {
- ++dirtyPluginNo;
- }
-
- clone.getElementsByTagName('h1')[0].textContent = data.plugins[i].name;
-
- clone.getElementsByClassName('crc')[0].textContent = 'CRC: ' + data.plugins[i].crc;
-
- if (data.plugins[i].isDummy) {
- showElement(clone.getElementsByClassName('dummyPlugin')[0]);
- }
-
- if (data.plugins[i].loadsBSA) {
- showElement(clone.getElementsByClassName('loadsBSA')[0]);
- }
-
- if (data.plugins[i].hasUserEdits) {
- /* This won't actually be handled anything like this in the real data implementation. */
- showElement(clone.getElementsByClassName('hasUserEdits')[0]);
- }
-
- if (data.plugins[i].version) {
- clone.getElementsByClassName('version')[0].textContent = 'Version: ' + data.plugins[i].version;
- } else {
- hideElement(clone.getElementsByClassName('version')[0]);
- }
-
- if (data.plugins[i].tagsAdd && data.plugins[i].tagsAdd.length != 0) {
- clone.getElementsByClassName('tag add')[0].textContent = data.plugins[i].tagsAdd.join(', ');
- } else {
- hideElement(clone.getElementsByClassName('tag add')[0]);
- }
-
- if (data.plugins[i].tagRemove && data.plugins[i].tagRemove.length != 0) {
- clone.getElementsByClassName('tag remove')[0].textContent = data.plugins[i].tagsRemove.join(', ');
- } else {
- hideElement(clone.getElementsByClassName('tag remove')[0]);
- }
-
- clone.getElementsByClassName('editMetadata')[0].setAttribute('data-target', clone.id);
- clone.getElementsByClassName('copyMetadata')[0].setAttribute('data-target', clone.id);
- clone.getElementsByClassName('clearMetadata')[0].setAttribute('data-target', clone.id);
-
- if (data.plugins[i].messages && data.plugins[i].messages.length != 0) {
- for (var j = 0; j < data.plugins[i].messages.length; ++j) {
- var messageLi = document.createElement('li');
- messageLi.className = data.plugins[i].messages[j].type;
- /* innerHTML is open to abuse, but for hyperlinking it's too useful. */
- messageLi.innerHTML = data.plugins[i].messages[j].content;
- clone.getElementsByTagName('ul')[0].appendChild(messageLi);
-
- if (messageLi.className == 'warn') {
- warnMessageNo++;
- } else if (messageLi.className == 'error') {
- errorMessageNo++;
- }
- totalMessageNo++;
- }
- } else {
- clone.getElementsByTagName('ul')[0].className += ' hidden';
- }
- }
- document.getElementById('filterTotalMessageNo').textContent = totalMessageNo;
- document.getElementById('totalMessageNo').textContent = totalMessageNo;
- document.getElementById('totalWarningNo').textContent = warnMessageNo;
- document.getElementById('totalErrorNo').textContent = errorMessageNo;
- document.getElementById('filterTotalPluginNo').textContent = data.plugins.length;
- document.getElementById('totalPluginNo').textContent = data.plugins.length;
- document.getElementById('activePluginNo').textContent = activePluginNo;
- document.getElementById('dirtyPluginNo').textContent = dirtyPluginNo;
-
- /* Now apply translated UI strings. */
- for (var id in data.l10n) {
- var elem = document.getElementById(id);
- if (elem) {
- elem.textContent = data.l10n[id];
- }
- }
-
- /* Now initialise the rest of the report. */
- initJavascriptVars();
- setupEventHandlers();
- if (isStorageSupported()) {
- loadSettings();
- }
- showElement(document.getElementsByTagName('section')[0]);
- });
+ } else {*/
+ clone.getElementsByTagName('ul')[0].className += ' hidden';
+ //}
}
+ document.getElementById('filterTotalMessageNo').textContent = totalMessageNo;
+ document.getElementById('totalMessageNo').textContent = totalMessageNo;
+ document.getElementById('totalWarningNo').textContent = warnMessageNo;
+ document.getElementById('totalErrorNo').textContent = errorMessageNo;
+ document.getElementById('filterTotalPluginNo').textContent = loot.game.plugins.length;
+ document.getElementById('totalPluginNo').textContent = loot.game.plugins.length;
+ document.getElementById('activePluginNo').textContent = activePluginNo;
+ document.getElementById('dirtyPluginNo').textContent = dirtyPluginNo;
+
+ // Now set up event handlers, as they depend on the plugin cards having been created.
+ setupEventHandlers();
+}
+function initGameVars() {
+ // Create and send a new query.
+ var request_id = window.cefQuery({
+ request: 'initGameVars',
+ persistent: false,
+ onSuccess: updateInterfaceWithGameInfo,
+ onFailure: function(error_code, error_message) {
+ showMessageBox('error', "Error", "Error code: " + error_code + "; " + error_message);
+ }
+ });
+}
+
+initGlobalVars();
+initGameVars();
+if (isStorageSupported()) {
+ loadSettings();
}
-processURLParams();
diff --git a/resources/report/testdata.js b/resources/report/testdata.js
deleted file mode 100644
index 0bcdaf36..00000000
--- a/resources/report/testdata.js
+++ /dev/null
@@ -1,958 +0,0 @@
-var data = {
- "masterlist": {
- "revision": "f66688fbe946396bc8fa1d5dadb7c8211c189cee",
- "date": "2014-05-10"
- },
- "plugins": [
- {
- "name": "Skyrim.esm",
- "isActive": true,
- "crc": "C665FD56"
- },
- {
- "name": "Update.esm",
- "loadsBSA": true,
- "isActive": true,
- "hasUserEdits": true,
- "crc": "E5B67BDA",
- "tagsAdd": ["Delev",
- "Relev"], "messages": [{"type": "warn",
- "content": "Warning: Contains 3 UDR records. Clean with TES5Edit."}]
- },
- {
- "name": "Unofficial Skyrim Patch.esp",
- "loadsBSA": true,
- "isActive": false,
- "crc": "29D2C7DF",
- "version": "2.0.0a",
- "tagsAdd": ["Delev",
- "Relev"]
- },
- {
- "name": "Unofficial Dawnguard Patch.esp",
- "isActive": false,
- "crc": "FF134167",
- "version": "2.0.0b",
- "tagsAdd": ["Delev",
- "Relev"], "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "Unofficial Hearthfire Patch.esp",
- "isActive": false,
- "crc": "F913F25E",
- "version": "2.0.0",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"HearthFires.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "Dragonborn.esm",
- "loadsBSA": true,
- "isActive": true,
- "crc": "A9F83BFF",
- "messages": [{"type": "warn",
- "content": "Warning: Contains 61 ITM records, 8 UDR records and 1 deleted navmeshes. Clean with TES5Edit."}]
- },
- {
- "name": "Unofficial Dragonborn Patch.esp",
- "loadsBSA": true,
- "isActive": true,
- "crc": "DA46F3C8",
- "version": "2.0.0",
- "tagsAdd": ["Delev"]
- },
- {
- "name": "Wyrmstooth.esp",
- "loadsBSA": true,
- "isActive": false,
- "crc": "6629BE21",
- "version": "1.10",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin is incompatible with \"Dragonborn.esm\", but both are present."}]
- },
- {
- "name": "EnchantingAwakened.esp",
- "isActive": false,
- "crc": "4E2FE0C1",
- "version": "1.60"
- },
- {
- "name": "SPIKE.esm",
- "isActive": false,
- "crc": "418D8B2F"
- },
- {
- "name": "UndergroundBathhouse.esm",
- "loadsBSA": true,
- "isActive": false,
- "crc": "2838692F"
- },
- {
- "name": "Xvision Children.esm",
- "isActive": false,
- "crc": "A159E35B"
- },
- {
- "name": "Cutting Room Floor.esp",
- "isActive": false,
- "crc": "1BA027FF",
- "version": "1.0.2",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Unofficial Skyrim Patch.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "Run For Your Lives.esp",
- "isActive": false,
- "crc": "1931B1F5",
- "version": "1.2.3"
- },
- {
- "name": "WATER DB.esp",
- "isActive": false,
- "crc": "1765B1A6",
- "version": "1.87"
- },
- {
- "name": "MorePP.esp",
- "loadsBSA": true,
- "isActive": true,
- "crc": "EA659B06"
- },
- {
- "name": "Follower Trap Safety.esp",
- "isDummy": true,
- "loadsBSA": true,
- "isActive": false,
- "crc": "36016080"
- },
- {
- "name": "STEP-part6.esp",
- "isDummy": true,
- "loadsBSA": true,
- "isActive": false,
- "crc": "2994FBF7"
- },
- {
- "name": "AnimeticaNymph.esp",
- "isActive": false,
- "crc": "50263C4C"
- },
- {
- "name": "AnimeticaMikuAppend.esp",
- "isActive": false,
- "crc": "89C4E907"
- },
- {
- "name": "dD-No Twitching Dragon Death Animation.esp",
- "isActive": false,
- "crc": "49CDAE6D"
- },
- {
- "name": "AnimeticaTenshi.esp",
- "isActive": false,
- "crc": "44EB184D"
- },
- {
- "name": "BFSEffects.esp",
- "isActive": false,
- "crc": "543D56D4",
- "version": "3.6",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "STEP-part2.esp",
- "isDummy": true,
- "loadsBSA": true,
- "isActive": false,
- "crc": "2994FBF7"
- },
- {
- "name": "AMatterOftime.esp",
- "isActive": false,
- "crc": "75025A7E",
- "version": "1.00"
- },
- {
- "name": "STEP-part5.esp",
- "isDummy": true,
- "loadsBSA": true,
- "isActive": false,
- "crc": "2994FBF7"
- },
- {
- "name": "Footprints.esp",
- "isActive": false,
- "crc": "BFAF15E8"
- },
- {
- "name": "Book Covers Dragonborn.esp",
- "isActive": false,
- "crc": "65CBDF50"
- },
- {
- "name": "dD - Enhanced Blood Main.esp",
- "isActive": false,
- "crc": "7AFD4E3E",
- "messages": [{"type": "say",
- "content": "Note: Requires: Dragonborn Compatibility_Patch."}]
- },
- {
- "name": "dD - Realistic Ragdoll Force - Reduced.esp",
- "isActive": false,
- "crc": "AFCAAEAB",
- "messages": [{"type": "say",
- "content": "Note: Ragdolls will conflict with other mods that change the skeleton.nif. Check Custom Skeleton Replacers for compatibly with other skeleton.nif."}]
- },
- {
- "name": "Dynamic TimeScale.esp",
- "isActive": false,
- "crc": "B518ED06",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "Brawl Bugs CE.esp",
- "isDummy": true,
- "loadsBSA": true,
- "isActive": false,
- "crc": "D284ACF"
- },
- {
- "name": "AnimeticaIkaros.esp",
- "isActive": false,
- "crc": "45DB135A"
- },
- {
- "name": "Dragons no LODs.esp",
- "isActive": false,
- "crc": "7F627C16",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "AnimeticaFate.esp",
- "isActive": false,
- "crc": "FC012D4E"
- },
- {
- "name": "EK_RingLimiter.esp",
- "isActive": false,
- "crc": "4E44A8B5"
- },
- {
- "name": "Auto Unequip Ammo.esp",
- "isActive": false,
- "crc": "4B399546"
- },
- {
- "name": "RaceMenu.esp",
- "isActive": false,
- "crc": "2765B7D0"
- },
- {
- "name": "dD-Dragonborn-Dawnguard-EBT Patch.esp",
- "isActive": false,
- "crc": "FE5C3763",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"dD - Enhanced Blood Main.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "AnimeticaAstrea.esp",
- "isActive": false,
- "crc": "26772B36"
- },
- {
- "name": "foobar.esp",
- "isDummy": true,
- "loadsBSA": true,
- "isActive": false
- },
- {
- "name": "AnimeticaHaruhi.esp",
- "isActive": false,
- "crc": "70D4E89A"
- },
- {
- "name": "EpisodeParallax.esp",
- "isActive": false,
- "crc": "A5B27576"
- },
- {
- "name": "fFastTravelSpeedMult_4.esp",
- "isActive": false,
- "crc": "CC1A0B4E",
- "version": "1.0"
- },
- {
- "name": "BarenziahQuestMarkers_Droppable.esp",
- "isActive": false,
- "crc": "39EA9697"
- },
- {
- "name": "dD-No Spinning Death Animation.esp",
- "isActive": false,
- "crc": "94E02E5A"
- },
- {
- "name": "Guard Dialogue Overhaul.esp",
- "isActive": false,
- "crc": "BD421FB8",
- "messages": [{"type": "say",
- "content": "Note: Do not clean. \"Dirty\" edits are intentional and required for the mod to function."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"SPIKE.esm\" to be active, but it is inactive."}]
- },
- {
- "name": "kuerteeSimpleMultipleFollowers.esp",
- "isActive": false,
- "crc": "5C99F173"
- },
- {
- "name": "HearthfireMoveKidsfix.esp",
- "isActive": false,
- "crc": "BA0EB4C5",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"HearthFires.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "iHUD.esp",
- "isActive": false,
- "crc": "6633B25E"
- },
- {
- "name": "imp_helm.esp",
- "isActive": false,
- "crc": "5604D208",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "LFox Alchemists Have Ingredients Light.esp",
- "isActive": false,
- "crc": "74F94A53",
- "tagsAdd": ["Relev"], "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "Lightweight Potions and Poisons.esp",
- "isActive": false,
- "crc": "276314FF",
- "version": "0.1."
- },
- {
- "name": "No Empty Tag on Containers.esp",
- "isActive": false,
- "crc": "77E800E"
- },
- {
- "name": "Footprints - Ash.esp",
- "isActive": false,
- "crc": "D3E16A61",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Footprints.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "STEP-part3.esp",
- "isDummy": true,
- "loadsBSA": true,
- "isActive": false,
- "crc": "2994FBF7"
- },
- {
- "name": "MoreRainWindy66percentLessView.esp",
- "isActive": false,
- "crc": "50B2CC8F"
- },
- {
- "name": "Piratelords Loot Adjustments.esp",
- "isActive": false,
- "crc": "66D0C4C7",
- "tagsAdd": ["Delev",
- "Relev"], "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"HearthFires.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "Book Covers Dawnguard.esp",
- "isActive": false,
- "crc": "819C137E",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "Book Covers Skyrim.esp",
- "isActive": false,
- "crc": "4075148A"
- },
- {
- "name": "Ars Metallica.esp",
- "isActive": false,
- "crc": "8D03ECC0",
- "version": "1.2.1"
- },
- {
- "name": "Ars Metallica - Dawnguard.esp",
- "isActive": false,
- "crc": "FE8960A3",
- "version": "1.2.1",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"Ars Metallica.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "Ars Metallica - Hearthfire.esp",
- "isActive": false,
- "crc": "18A5C66B",
- "version": "1.2.1",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"HearthFires.esm\" to be installed, but it is missing."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"Ars Metallica.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "Book Covers Hearthfire.esp",
- "isActive": false,
- "crc": "D306DE27",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"HearthFires.esm\" to be installed, but it is missing."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"Book Covers Skyrim.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "Moss Rocks.esp",
- "isActive": false,
- "crc": "D7FF66AC"
- },
- {
- "name": "moveitLWT.esp",
- "isActive": false,
- "crc": "1CBC50DC"
- },
- {
- "name": "PersonalizedMusic_v4.0.esp",
- "isActive": false,
- "crc": "74D7D28B"
- },
- {
- "name": "NoPsychicLockKnowledge.esp",
- "isActive": false,
- "crc": "336B524B"
- },
- {
- "name": "Radiant and Unique Potions Poisons and Booze.esp",
- "isActive": false,
- "crc": "EA004B82"
- },
- {
- "name": "Reduced Distance NPC Greetings.esp",
- "isActive": false,
- "crc": "24658104",
- "version": "50"
- },
- {
- "name": "SkyUI.esp",
- "loadsBSA": true,
- "isActive": true,
- "crc": "9330CAF7",
- "version": "4.1"
- },
- {
- "name": "AnimeticaKobato.esp",
- "isActive": false,
- "crc": "3B0B19DD"
- },
- {
- "name": "Smithing Flexible Tree.esp",
- "isActive": false,
- "crc": "965889B3",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "SoS - The Wilds.esp",
- "isActive": false,
- "crc": "49F5E301",
- "version": "1.13",
- "messages": [{"type": "say",
- "content": "Note: Do not use the Crash Fix ESP for this mod. It is flagged as a master and is only meant as a last resort for fixing crashes."}]
- },
- {
- "name": "SkyFalls Plus SkyMills - All DLC.esp",
- "isActive": false,
- "crc": "4040AFD0",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "SFO - Dragonborn.esp",
- "isActive": false,
- "crc": "C9DB0844"
- },
- {
- "name": "Distant DetailHF.esp",
- "isActive": false,
- "crc": "29C8DF7B",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"HearthFires.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "Bring Out Your Dead.esp",
- "isActive": false,
- "crc": "3ABC3315",
- "version": "1.2.2",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Unofficial Skyrim Patch.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "Xvision Children - Complete.esp",
- "isActive": false,
- "crc": "4A786D54",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"HearthFires.esm\" to be installed, but it is missing."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"Xvision Children.esm\" to be active, but it is inactive."}]
- },
- {
- "name": "Xvision Children - USKP.esp",
- "isActive": false,
- "crc": "A4ACB325",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"unofficial skyrim patch.esp\" to be active, but it is inactive."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"Xvision Children.esm\" to be active, but it is inactive."}]
- },
- {
- "name": "ExpandedSnowSystems.esp",
- "isActive": false,
- "crc": "739AC421",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "SoS - The Dungeons.esp",
- "isActive": false,
- "crc": "79377267",
- "version": "1.23",
- "messages": [{"type": "say",
- "content": "Note: Do not use the Crash Fix ESP for this mod. It is flagged as a master and is only meant as a last resort for fixing crashes."}]
- },
- {
- "name": "Oblivion Gates v3 - Skyrim + Dawnguard DLC.esp",
- "isActive": false,
- "crc": "C56B1AEE",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "BirdsHFclean.esp",
- "isActive": false,
- "crc": "5CA1AC97",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"HearthFires.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "EMCompViljaSkyrim.esp",
- "isActive": false,
- "crc": "A2A7E570"
- },
- {
- "name": "EMViljaInSolstheimAddOn.esp",
- "isActive": false,
- "crc": "FA24307A",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"EMCompViljaSkyrim.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "A Thane-Worthy Breezehome.esp",
- "isActive": false,
- "crc": "28A7A956",
- "messages": [{"type": "warn",
- "content": "Warning: This file contains 1 deleted NavMesh record(s) that TES5Edit cannot repair automatically and it may cause problems with your game. NavMesh deletions should be reported to the mod author. A guide to repairing NavMesh deletions with TES5Edit is located here."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"HearthFires.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "NoxUE2.00.esp",
- "isActive": false,
- "crc": "D62F798B",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "AnimeticaSena.esp",
- "isActive": false,
- "crc": "5837DA98"
- },
- {
- "name": "Soul Gems Differ - E.esp",
- "isActive": false,
- "crc": "D85F580A"
- },
- {
- "name": "AetherSuite.esp",
- "isActive": false,
- "crc": "F9553087"
- },
- {
- "name": "SplashofRain.esp",
- "isActive": false,
- "crc": "363772B6",
- "version": "1.04"
- },
- {
- "name": "Unique Grasses.esp",
- "isActive": false,
- "crc": "24202A6D"
- },
- {
- "name": "SPTDiverseMuscleTones.esp",
- "isActive": false,
- "crc": "2D5C68FE",
- "version": "5.1"
- },
- {
- "name": "SPTDiverseMuscleTonesViljaPatch.esp",
- "isActive": false,
- "crc": "117758E3",
- "version": "5.0",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"EMCompViljaSkyrim.esp\" to be active, but it is inactive."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"SPTDiverseMuscleTones.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "SPTDiverseMuscleTonesDawnguardDragonborn.esp",
- "isActive": false,
- "crc": "F4927D22",
- "version": "5.0",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"SPTDiverseMuscleTones.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "SPTDiverseMuscleTonesNPCs.esp",
- "isActive": false,
- "crc": "554F1CAB",
- "version": "5.0",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Unofficial Skyrim Patch.esp\" to be active, but it is inactive."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"Cutting Room Floor.esp\" to be active, but it is inactive."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"Bring Out Your Dead.esp\" to be active, but it is inactive."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"SPTDiverseMuscleTones.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "SPTDiverseGuardsSkyrim.esp",
- "isActive": false,
- "crc": "682A3893",
- "version": "4.6",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"SPTDiverseMuscleTones.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "SPTConsistentOlderPeople.esp",
- "isActive": false,
- "crc": "CAF3C1BE",
- "version": "1.8",
- "messages": [{"type": "say",
- "content": "Note: If this is not newer than v1.3, update to the latest version."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"Cutting Room Floor.esp\" to be active, but it is inactive."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"Bring Out Your Dead.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "EnchantingAwakenedAWEPatch.esp",
- "isActive": false,
- "crc": "DDDCC598",
- "version": "1.50",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Animated Weapon Enchants.esp\" to be installed, but it is missing."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"EnchantingAwakened.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "AnimeticaMiko.esp",
- "isActive": false,
- "crc": "1538B6B7"
- },
- {
- "name": "Better Dynamic Snow.esp",
- "isActive": false,
- "crc": "F3204EF1"
- },
- {
- "name": "StaticMeshImprovementMod.esp",
- "isActive": false,
- "crc": "EC37D3CE"
- },
- {
- "name": "Ars Metallica - Dragonborn.esp",
- "isActive": false,
- "crc": "1091DB21",
- "version": "1.2.1",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Ars Metallica.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "SPTDiverseMuscleTonesPlayer.esp",
- "isActive": false,
- "crc": "5EA9E4D7",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"SPTDiverseMuscleTones.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "STEP-part1.esp",
- "isDummy": true,
- "loadsBSA": true,
- "isActive": false,
- "crc": "2994FBF7"
- },
- {
- "name": "STEP-part4.esp",
- "isDummy": true,
- "loadsBSA": true,
- "isActive": false,
- "crc": "2994FBF7"
- },
- {
- "name": "fs_swordandshield.esp",
- "loadsBSA": true,
- "isActive": false,
- "crc": "8D438E3",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin is incompatible with \"MorePP.esp\", but both are present."}]
- },
- {
- "name": "SwiftPotion.esp",
- "isActive": false,
- "crc": "E08D9F45"
- },
- {
- "name": "TheChoiceIsYours.esp",
- "isActive": false,
- "crc": "58BC5ABB"
- },
- {
- "name": "Point The Way.esp",
- "isActive": false,
- "crc": "F372CBC2",
- "version": "1.0.2"
- },
- {
- "name": "SkyrimImprovedPuddles-DG-HF-DB.esp",
- "isActive": false,
- "crc": "D0427B6",
- "version": "1.1",
- "messages": [{"type": "say",
- "content": "Note: Use only one SkyrimImprovedPuddles esp."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"HearthFires.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "The Paarthurnax Dilemma.esp",
- "isActive": false,
- "crc": "9E446FBD",
- "version": "1.2.5"
- },
- {
- "name": "TheTownIsSafe.esp",
- "isActive": false,
- "crc": "B5AAAF6B",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin is incompatible with \"When Vampires Attack.esp\", but both are present."}]
- },
- {
- "name": "TradeBarter.esp",
- "isActive": false,
- "crc": "AC24F58B",
- "tagsAdd": ["Delev",
- "Relev"], "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"HearthFires.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "Tamriel Compendium - Skill Books.esp",
- "isActive": false,
- "crc": "1F348D90",
- "version": "1.1",
- "tagsAdd": ["Relev"]
- },
- {
- "name": "WATER.esp",
- "isActive": false,
- "crc": "AFE4A968",
- "version": "1.87"
- },
- {
- "name": "WetandCold.esp",
- "isActive": false,
- "crc": "E034A81F",
- "version": "1.321"
- },
- {
- "name": "WetandCold - Ashes.esp",
- "isActive": false,
- "crc": "8C003085",
- "version": "1.06",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"WetandCold.esp\" to be active, but it is inactive."}]
- },
- {
- "name": "When Vampires Attack.esp",
- "isActive": false,
- "crc": "4743D674",
- "version": "1.1",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin is incompatible with \"TheTownIsSafe.esp\", but both are present."}]
- },
- {
- "name": "whiteruntrees.esp",
- "isActive": false,
- "crc": "6265C55E"
- },
- {
- "name": "Map Markers Complete.esp",
- "isActive": false,
- "crc": "D48714FB"
- },
- {
- "name": "Oblivion Gates in Cities.esp",
- "isActive": false,
- "crc": "E7D68506",
- "version": "1.0"
- },
- {
- "name": "Gildergreen Regrown.esp",
- "isActive": false,
- "crc": "7AFAAD00",
- "version": "1.2.5"
- },
- {
- "name": "TheChoiceIsYours_Dawnguard.esp",
- "isActive": false,
- "crc": "8BD6B852",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]
- },
- {
- "name": "SPTKatlaSailReangle.esp",
- "isActive": false,
- "crc": "10511ED2"
- },
- {
- "name": "Warburg's 3D Paper World Map - Texture 1.esp",
- "isActive": false,
- "crc": "26ADE83C",
- "messages": [{"type": "say",
- "content": "Note: In case of persistent zoom-in issues, consider creating and using a Userlist to load the map lower, below any dynamic plugin(s)."}]
- },
- {
- "name": "Bashed Patch, 0.esp",
- "isActive": false,
- "crc": "C2306BE5",
- "version": "2013-12-13 13:55:02",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"TradeBarter.esp\" to be active, but it is inactive."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"Ars Metallica.esp\" to be active, but it is inactive."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"Piratelords Loot Adjustments.esp\" to be active, but it is inactive."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"SPTConsistentOlderPeople.esp\" to be active, but it is inactive."
- },
- {
- "type": "warn",
- "content": "Warning: This plugin requires \"SPTDiverseMuscleTonesFemaleVariety.esp\" to be installed, but it is missing."}]
- },
- {
- "name": "warburg's 3d paper world map - dawnguard.esp",
- "isActive": false,
- "crc": "53E8693D",
- "messages": [{"type": "warn",
- "content": "Warning: This plugin requires \"Dawnguard.esm\" to be installed, but it is missing."}]}
- ],
- "globalMessages": [
- {
- "type": "say",
- "content": "Note: There have been no changes in the Details tab since LOOT was last run for this game."
- },
- {
- "type": "say",
- "content": "Note: Latest LOOT thread."
- },
- {
- "type": "say",
- "content": "Note: Your SKSE is up-to-date."
- },
- {
- "type": "warn",
- "content": "Warning: The load order displayed in the Details tab was not applied as sorting was canceled."
- }
- ],
-}
\ No newline at end of file
diff --git a/src/backend/json.h b/src/backend/json.h
new file mode 100644
index 00000000..f6cbb256
--- /dev/null
+++ b/src/backend/json.h
@@ -0,0 +1,65 @@
+/* LOOT
+
+A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
+Fallout: New Vegas.
+
+Copyright (C) 2014 WrinklyNinja
+
+This file is part of LOOT.
+
+LOOT 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.
+
+LOOT 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 LOOT. If not, see
+.
+*/
+
+#ifndef __LOOT_JSON__
+#define __LOOT_JSON__
+
+
+#include
+
+namespace loot {
+
+ // Handy class for turning YAML objects into JSON and vice-versa.
+ class JSON {
+ public:
+
+ inline static YAML::Node parse(std::string& json) {
+ return YAML::Load(json);
+ }
+
+ inline static std::string stringify(YAML::Node& yaml) {
+
+ YAML::Emitter out;
+ out.SetOutputCharset(YAML::EscapeNonAscii);
+ out.SetStringFormat(YAML::DoubleQuoted);
+ out.SetBoolFormat(YAML::TrueFalseBool);
+ out.SetSeqFormat(YAML::Flow);
+ out.SetMapFormat(YAML::Flow);
+
+ out << yaml;
+
+ // yaml-cpp produces `!` artifacts in its output, so remove them.
+ std::string json = out.c_str();
+ boost::replace_all(json, "!", "");
+ // There's also a bit of weirdness where there are some \x escapes and some \u escapes.
+ // They should all be \u, so transform them.
+ boost::replace_all(json, "\\x", "\\u00");
+
+ return json;
+ }
+ };
+}
+
+
+#endif
\ No newline at end of file
diff --git a/src/gui/app.cpp b/src/gui/app.cpp
index dec06baf..33c302f4 100644
--- a/src/gui/app.cpp
+++ b/src/gui/app.cpp
@@ -132,6 +132,8 @@ namespace loot {
// LootState member functions
//---------------------------
+ LootState::LootState() : _currentGame(0) {}
+
void LootState::Init(const std::string& cmdLineGame) {
string initError;
@@ -226,23 +228,25 @@ namespace loot {
BOOST_LOG_TRIVIAL(debug) << "Selecting game.";
- size_t gameIndex(0);
try {
- gameIndex = SelectGame(_settings, _games, cmdLineGame);
+ _currentGame = SelectGame(_settings, _games, cmdLineGame);
}
catch (exception &) {
BOOST_LOG_TRIVIAL(error) << "None of the supported games were detected.";
}
- BOOST_LOG_TRIVIAL(debug) << "Game selected is " << _games[gameIndex].Name();
+ BOOST_LOG_TRIVIAL(debug) << "Game selected is " << _games[_currentGame].Name();
//Now that game is selected, initialise it.
BOOST_LOG_TRIVIAL(debug) << "Initialising game-specific settings.";
try {
- _games[gameIndex].Init();
+ _games[_currentGame].Init();
}
catch (std::exception& e) {
BOOST_LOG_TRIVIAL(error) << "Game-specific settings could not be initialised. " << e.what();
}
}
+ Game& LootState::CurrentGame() {
+ return _games[_currentGame];
+ }
}
\ No newline at end of file
diff --git a/src/gui/app.h b/src/gui/app.h
index c5bf8f7b..56a4baf4 100644
--- a/src/gui/app.h
+++ b/src/gui/app.h
@@ -72,11 +72,14 @@ namespace loot {
class LootState {
public:
+ LootState();
void Init(const std::string& cmdLineGame);
+ Game& CurrentGame();
YAML::Node _settings;
std::vector _games;
+ size_t _currentGame;
};
extern LootState g_app_state;
diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp
index cc413984..f8de31a1 100644
--- a/src/gui/handler.cpp
+++ b/src/gui/handler.cpp
@@ -26,11 +26,17 @@
#include "resource.h"
#include "app.h"
+#include "../backend/json.h"
+#include "../backend/parsers.h"
+
#include
#include
#include
#include
+#include
+#include
+#include
#include
#include
@@ -38,6 +44,11 @@
using namespace std;
+using boost::format;
+
+namespace fs = boost::filesystem;
+namespace loc = boost::locale;
+
namespace loot {
namespace {
@@ -75,7 +86,7 @@ namespace loot {
callback->Failure((int)ret, "Shell execute failed.");
return true;
}
- else if (request == "initJavascriptVars") {
+ else if (request == "initGlobalVars") {
// Convert the _settings YAML object to a JSON string, and also add members for the LOOT version, game types and languages.
if (g_app_state._games.empty()) {
@@ -123,28 +134,109 @@ namespace loot {
temp["languages"] = Language::Names();
- // Now output as JSON.
+ // Now output as JSON
+ //-------------------
- YAML::Emitter tempout;
- tempout.SetOutputCharset(YAML::EscapeNonAscii);
- tempout.SetStringFormat(YAML::DoubleQuoted);
- tempout.SetBoolFormat(YAML::TrueFalseBool);
- tempout.SetSeqFormat(YAML::Flow);
- tempout.SetMapFormat(YAML::Flow);
-
- tempout << temp;
-
- // yaml-cpp produces `!` artifacts in its output, so remove them.
- std::string json = tempout.c_str();
- boost::replace_all(json, "!", "");
- // There's also a bit of weirdness where there are some \x escapes and some \u escapes.
- // They should all be \u, so transform them.
- boost::replace_all(json, "\\x", "\\u00");
-
- callback->Success(json);
+ callback->Success(JSON::stringify(temp));
return true;
}
+ else if (request == "initGameVars") {
+ // Get masterlist revision info and parse if it exists. Also get plugin headers info and parse userlist if it exists.
+
+ if (g_app_state._games.empty()) {
+ BOOST_LOG_TRIVIAL(warning) << "Application state not yet initialised, initialising now...";
+ g_app_state.Init("");
+ BOOST_LOG_TRIVIAL(info) << "Application state initialised.";
+ }
+
+ g_app_state.CurrentGame().LoadPlugins(true);
+
+ //Sort plugins into their load order.
+ list installed;
+ list loadOrder;
+ g_app_state.CurrentGame().GetLoadOrder(loadOrder);
+ for (const auto &pluginName : loadOrder) {
+ const auto pos = g_app_state.CurrentGame().plugins.find(pluginName);
+
+ if (pos != g_app_state.CurrentGame().plugins.end())
+ installed.push_back(pos->second);
+ }
+
+ //Parse masterlist, don't update it.
+ if (fs::exists(g_app_state.CurrentGame().MasterlistPath())) {
+ BOOST_LOG_TRIVIAL(debug) << "Parsing masterlist.";
+ g_app_state.CurrentGame().masterlist.MetadataList::Load(g_app_state.CurrentGame().MasterlistPath());
+ }
+
+ //Parse userlist.
+ if (fs::exists(g_app_state.CurrentGame().UserlistPath())) {
+ BOOST_LOG_TRIVIAL(debug) << "Parsing userlist.";
+ g_app_state.CurrentGame().userlist.Load(g_app_state.CurrentGame().UserlistPath());
+ }
+
+ // Now convert to a single object that can be turned into a JSON string
+ //---------------------------------------------------------------------
+
+ // The data structure is to be set as 'loot.game'.
+ YAML::Node gameNode;
+
+ // ID the game using its folder value.
+ gameNode["folder"] = g_app_state.CurrentGame().FolderName();
+
+ // Store the masterlist revision and date.
+ gameNode["masterlist"]["revision"] = g_app_state.CurrentGame().masterlist.GetRevision(g_app_state.CurrentGame().MasterlistPath());
+ gameNode["masterlist"]["date"] = g_app_state.CurrentGame().masterlist.GetDate(g_app_state.CurrentGame().MasterlistPath());
+
+ // Now store plugin data.
+ for (const auto& plugin : g_app_state.CurrentGame().plugins) {
+ // Test data has 'hasUserEdits', and 'tagsAdd', 'tagsRemove' keys, but
+ // the first will be handled by userlist lookups, and the other two are probably
+ // going to get moved around, haven't decided how best to handle the split between masterlist, userlist and plugin-sourced metadata.
+ YAML::Node pluginNode;
+ pluginNode["name"] = plugin.second.Name();
+ pluginNode["isActive"] = g_app_state.CurrentGame().IsActive(plugin.first);
+ pluginNode["isDummy"] = (plugin.second.FormIDs().size() == 0);
+ pluginNode["loadsBSA"] = plugin.second.LoadsBSA(g_app_state.CurrentGame());
+ pluginNode["crc"] = IntToHexString(plugin.second.Crc());
+ pluginNode["version"] = plugin.second.Version();
+
+ gameNode["plugins"].push_back(pluginNode);
+ }
+
+ //Set language.
+ unsigned int language;
+ if (g_app_state._settings["Language"])
+ language = Language(g_app_state._settings["Language"].as()).Code();
+ else
+ language = loot::Language::any;
+
+ BOOST_LOG_TRIVIAL(info) << "Using message language: " << Language(language).Name();
+
+ //Evaluate any conditions in the global messages.
+ BOOST_LOG_TRIVIAL(debug) << "Evaluating global message conditions.";
+ try {
+ list::iterator it = g_app_state.CurrentGame().masterlist.messages.begin();
+ while (it != g_app_state.CurrentGame().masterlist.messages.end()) {
+ if (!it->EvalCondition(g_app_state.CurrentGame(), language))
+ it = g_app_state.CurrentGame().masterlist.messages.erase(it);
+ else
+ ++it;
+ }
+ }
+ catch (std::exception& e) {
+ BOOST_LOG_TRIVIAL(error) << "A global message contains a condition that could not be evaluated. Details: " << e.what();
+ g_app_state.CurrentGame().masterlist.messages.push_back(loot::Message(loot::Message::error, (format(loc::translate("A global message contains a condition that could not be evaluated. Details: %1%")) % e.what()).str()));
+ }
+
+ // Now store global messages from masterlist.
+ gameNode["globalMessages"] = g_app_state.CurrentGame().masterlist.messages;
+
+ callback->Success(JSON::stringify(gameNode));
+
+ return true;
+
+ }
return false;
}