// ==UserScript==
// @name GOTA Extender
// @namespace gota_extender
// @author Panayot Ivanov
// @description Game of Thrones Ascent Extender
// @include http://gota.disruptorbeam.com/*
// @include http://gota-www.disruptorbeam.com/*
// @include https://gota.disruptorbeam.com/*
// @include https://gota-www.disruptorbeam.com/*
// @include https://games.disruptorbeam.com/gamethrones/
// @exclude http://gota.disruptorbeam.com/users/login*
// @exclude http://gota-www.disruptorbeam.com/users/login*
// @license WTFPL (more at http://www.wtfpl.net/)
// @require http://code.jquery.com/jquery-2.1.3.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js
// @require https://greasyfork.org/scripts/5279-greasemonkey-SuperValues/code/GreaseMonkey_SuperValues.js?_dc=548
// @require https://greasyfork.org/scripts/7573-storage-prototype-extension/code/StoragePrototype_extension.js?_dc=117
// @require https://greasyfork.org/scripts/5427-gota-extender-constants/code/GOTA_Extender_Constants.js?_dc=111
// @resource custom https://greasyfork.org/scripts/5426-gota-extender-custom/code/GOTA_Extender_Custom.js?_dc=222
// @resource auxiliary https://greasyfork.org/scripts/5618-gota-extender-auxiliary/code/GOTA_Extender_Auxiliary.js?_dc=911
// @resource original https://greasyfork.org/scripts/6702-gota-extender-original/code/GOTA_Extender_Original.js?_dc=318
// @resource production https://greasyfork.org/scripts/7611-gota-extender-production/code/GOTA_Extender_Production.js?_dc=557
// @version 7.2.3
// @grant unsafeWindow
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_openInTab
// @grant GM_xmlhttpRequest
// @grant GM_getResourceText
// @grant GM_getResourceURL
// @grant GM_registerMenuCommand
// ==/UserScript==
// Resolves conflicts of different jQuery versions
$ = this.$ = this.jQuery = jQuery.noConflict(true);
var cloneInto = cloneInto || warn("No function for cloning objects found. This is vital if the script runs on Firefox!", "Components");
var exportFunction = exportFunction || warn("No function for exporting functions found. This is vital if the script runs on Firefox!", "Components");
var unsafeWindow = unsafeWindow || error("This script requires access to the unsafeWindow.", "Greasemonkey");
var GM_getValue = GM_getValue || error("This script requires access to the GM_getValue.", "Greasemonkey");
var GM_setValue = GM_setValue || error("This script requires access to the GM_setValue.", "Greasemonkey");
var GM_openInTab = GM_openInTab || error("This script requires access to the GM_openInTab function.", "Greasemonkey");
var GM_xmlhttpRequest = GM_xmlhttpRequest || error("This script requires access to the GM_xmlhttpRequest.", "Greasemonkey");
var GM_getResourceText = GM_getResourceText || error("This script requires access to the GM_getResourceText function.", "Greasemonkey");
var GM_getResourceURL = GM_getResourceURL || error("This script requires access to the GM_getResourceURL function.", "Greasemonkey");
var GM_registerMenuCommand = GM_registerMenuCommand || error("This script requires access to the GM_registerMenuCommand function.", "Greasemonkey");
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || error("This script requires access to the GM_registerMenuCommand function.", "Observer");
// --> Register menu commands
(function(){
GM_registerMenuCommand("HOME", openHome);
function openHome() {
GM_openInTab("https://greasyfork.org/en/scripts/3788-gota-extender");
}
GM_registerMenuCommand("DEBUG", enterDebugMode);
function enterDebugMode() {
options.debugMode = true;
options.set("debugMode");
alert("Debug mode has been enabled. Extender will now reload.");
window.location.reload(true);
}
GM_registerMenuCommand("CHECK", checkScript);
function checkScript() {
options.checkScript = true;
options.set("checkScript");
alert("Extender will check for game function updates.\nPress OK to reload.");
window.location.reload(true);
}
GM_registerMenuCommand("CLEAN", clean);
function clean() {
if(window.confirm("This will delete your locally stored data, but not your preferences.\nAre you sure?")){
localStorage.clear();
sessionStorage.clear();
alert("Extender revived your storage.");
}
}
}());
// <-- End of menu commands
// --> Initialization
$(window).bind("load", function () {
// Kill logging first prior to init
inject.code("window.doLog = function() {};");
inject.code('(' + overrideFinishLoader.toString() + ')()');
});
function overrideFinishLoader(){
window.finishExtenderLoad = window.finishLoader;
window.finishLoader = function() {
var event = new Event('initEX');
window.dispatchEvent(event);
}
}
var initialization = {
inform: function (msg, progress, info) {
var exalert = $("h2#loadinginfo-l:visible");
var expinfo = $("em#preloader_message:visible");
var exprogress = $("div.loadingbar-inner:visible");
var progresspercent = $("h2#loadinginfo-r:visible");
if (exalert.length) { // shown
msg &&
exalert.html(msg + ":");
info && expinfo &&
expinfo.html(info);
progress && exprogress &&
progresspercent.html(progress + "%");
exprogress.css("width", progress + "%");
}
},
error: function (msg, type) {
var exalert = $("h2#loadinginfo-l:visible");
var expinfo = $("em#preloader_message:visible");
if (!type)
type = "extender";
var prefix = type.toString().toUpperCase() + " - ERROR <" + new Date().toLocaleTimeString() + "> ";
console.error(prefix + msg);
if (expinfo.length) { // shown
exalert.html("ERROR:");
msg && expinfo.html(msg);
}
setTimeout(function(){
unsafeWindow.finishExtenderLoad();
}, 1E3);
},
begin: function () {
window.removeEventListener("initEX", initialization.begin);
$('#loadingbg').show();
this.current = -1;
initialization.next();
initialization.inform("EXTENDER", 1, "Begin...");
},
next: function () {
try {
this.current++;
var percent = ((this.current + 1) / this.functions.length) * 100;
initialization.inform(false, percent, false);
if (typeof this.functions[this.current] == "function") {
// Invoke next init function
this.functions[this.current]();
} else {
initialization.inform("DONE", 100, "happy hacking!");
setTimeout(function(){
unsafeWindow.finishExtenderLoad();
}, 1E3);
}
} catch (eMsg) {
initialization.error("Fatal error, initialization failed: " + eMsg, "INITIALIZATION");
initialization.inform("ERROR", false, "Fatal error, initialization failed: " + eMsg);
}
},
current: -1,
functions: [
// CleanUp
function () {
// Clean up
console.clear();
initialization.next();
},
// Init logger
function icnsl(retry) {
if (retry == void 0) {
initialization.inform("", false, "Initializing message system...");
inject.console();
}
if (typeof unsafeWindow.log == "function") {
log("Messaging system initialized successfully.", "INITIALIZATION");
initialization.next();
} else {
setTimeout(function () {
retry
? (retry < 7
? icnsl(++retry)
: initialization.error("Messaging system failed to initialize.", "INITIALIZATION"))
: icnsl(1);
}, 500);
}
},
// Init options
function () {
// Get all GM values
initialization.inform("", false, "Fetching preferences...");
options.get();
// Check script if scheduled
if (options.checkScript) {
initialization.inform("CHECK", 50, "Script scheduled for update check...");
checkSource();
initialization.inform("DONE", 100, "Reloading...");
options.checkScript = false;
options.set("checkScript");
window.location.reload(true);
return;
}
initialization.next();
},
// Init styles
function istys(retry) {
if (retry == void 0) {
// Add global styles
initialization.inform("", false, "Injecting styles...");
styles.addAllStyles();
}
if ($("style#extenderStyles").length) {
log("Styles initialized successfully.", "INITIALIZATION");
initialization.next();
} else {
setTimeout(function () {
retry
? (retry < 7
? istys(++retry)
: initialization.error("Styles failed to initialize.", "INITIALIZATION"))
: istys(1);
}, 500);
}
},
// Init storage
// prototype extensions
function spex(retry) {
if (retry == void 0) {
// Inject Storage extension functions (for use in the page)
initialization.inform("", false, "Injecting storage...");
inject.outSource("https://greasyfork.org/scripts/7573-storage-prototype-extension/code/StoragePrototype_extension.js");
}
if (typeof unsafeWindow.localStorage.get == "function") {
log("Storage initialized successfully.", "INITIALIZATION");
console.log("Debugging Components: " +
"cloneInto ? ", (typeof cloneInto),
"exportFunction ? ", (typeof exportFunction));
//if (options.useLocalDbOnly) {
//
// if (typeof exportFunction == "function") {
// //if (false) {
// unsafeWindow.Storage.prototype.set =
// exportFunction(GM_SuperValue.set, unsafeWindow, {defineAs: "ExtenderSet"});
// unsafeWindow.Storage.prototype.get =
// exportFunction(GM_SuperValue.get, unsafeWindow, {defineAs: "ExtenderGet"});
// } else {
// unsafeWindow.Storage.prototype.set = GM_SuperValue.set;
// unsafeWindow.Storage.prototype.get = GM_SuperValue.get;
// }
//
// log("Storage configured to use only SQLite.", "INITIALIZATION");
//}
initialization.next();
} else {
setTimeout(function () {
retry
? (retry < 7
? spex(++retry)
: initialization.error("Storage extension failed to initialize.", "INITIALIZATION"))
: spex(1);
}, 500);
}
},
// Init page override
function aux(retry) {
if (retry == void 0) {
// Inject auxiliary code
initialization.inform("", false, "Overriding page functions...");
inject.code(GM_getResourceText("custom"));
inject.code(GM_getResourceText("auxiliary"));
inject.code(GM_getResourceText("production"));
}
if (unsafeWindow.extender != void 0) {
log("Injection sequence successful.", "INITIALIZATION");
initialization.next();
} else {
setTimeout(function () {
retry
? (retry < 7
? aux(++retry)
: initialization.error("Injection sequence failed.", "INITIALIZATION"))
: aux(1);
}, 500);
}
},
// Init observable & constants
function oci(retry) {
if (retry == void 0) {
// Try an injection sequence
initialization.inform("", false, "Injecting console & constants...");
inject.observable();
inject.constants();
}
if ($("textarea#observable").length) {
log("Observable console & constants initialized successfully.", "INITIALIZATION");
initialization.next();
} else {
setTimeout(function () {
retry
? (retry < 7
? oci(++retry)
: initialization.error("Observable console and/or constants failed to initialize.", "INITIALIZATION"))
: oci(1);
}, 500);
}
},
// Init modules
function () {
initialization.inform("", false, "Loading modules...");
unsafeWindow.production.init(options.export(["queueDelay", "superiorMaterials", "doSpeedUp"]));
unsafeWindow.bossChallenger.init(options.export(["autoBossChallenge"]));
unsafeWindow.worldEvent.init(options.export(["weManagerEnabled", "worldEventDelay"]));
// TODO: Uncomment when questMan ready
//unsafeWindow.questMan.init(options.export(["questManagerDelay", "questManagerEnabled"]));
initialization.next();
},
// Init game
function ingex(retry) {
if (retry == void 0) {
initialization.inform("", false, "Loading extender...");
} else {
initialization.inform("", false, "Loading extender (" + retry + ") ...");
}
//console.log("Debugging extender load: ", unsafeWindow.userContext);
if (unsafeWindow.userContext == void 0) {
setTimeout(function () {
retry
? (retry < 21
? ingex(++retry)
: initialization.error("Failed to load extender after 21 retries.", "INITIALIZATION"))
: ingex(1);
}, 500);
return;
}
// Toggle
toggleAll();
// Claim
quarterMasterDo();
// Claim favours
acceptAllFavors();
// Send out gifts
sendGifts();
// Store all sworn swords
getSwornSwords();
// Sort player inventory
unsafeWindow.sort();
setTimeout(function () {
initialization.next();
}, 500);
}
]
};
window.addEventListener("initEX", initialization.begin);
// <-- End of initialization
// --> Main toolbar mutations observer
// Observers construction
var mainToolbarObserver = new MutationObserver(main_toolbar_buttons_changed);
// define what element should be observed by the observer
// and what types of mutations trigger the callback
mainToolbarObserver.observe(document.getElementById("main_toolbar_buttons"), {
// childList: true,
attributes: true,
// characterData: true,
subtree: true,
attributeOldValue: true
// if attributes
// characterDataOldValue: true, // if characterData
// attributeFilter: ["id", "dir"], // if attributes
});
function main_toolbar_buttons_changed() {
// log("Mutation on main toolbar buttons.");
var menu = $("#extender-menu");
var container = $("#navmenubox");
if (container.length > 0 && menu.length == 0) {
container.append(templates.menuBtn);
}
}
// <-- End of mutations observer
// --> Page command handling
var signalObserver = new MutationObserver(signal_acknowledged);
function signal_acknowledged() {
var observable = $("textarea#observable");
if (!observable) {
error("The observable DOM element was not found in the page.");
return;
}
var msg = "Error: Unknown command.";
var commandObj = JSON.parse(observable.attr("command"));
var prefix = "COMMAND ACKNOWLEDGED" + " | " + new Date().toLocaleTimeString() + " | ";
if (!commandObj || typeof commandObj != "object") {
msg = "Error: Cannot parse the command object given.";
observable.val(prefix + msg);
error(msg);
return;
}
if (typeof commandObj.name !== "string") {
msg = "Error: Command does not have a name specified.";
observable.val(prefix + msg);
error(msg);
return;
}
var args = commandObj.args;
// Parse command
switch (commandObj.name) {
case "option":
//console.debug(commandObj);
// Rely on the second check only
if (options.hasOwnProperty(args[0]) && typeof options[args[0]] === typeof args[1]) {
options[args[0]] = args[1];
options.set(args[0]);
observable.val(prefix + "Option " + args[0] + " set to " + args[1] + " successfully.");
log("Option " + args[0] + " set to " + args[1] + " successfully.", "COMMAND")
return;
}
if (options.hasOwnProperty(args[0])) {
if (typeof options[args[0]] == "object") {
log(args[0] + " is a composite object:", "COMMAND");
console.log(typeof cloneInto == "function" ? cloneInto(options[args[0]], unsafeWindow) : options[args[0]]);
} else {
log(args[0] + ": " + options[args[0]], "COMMAND");
}
observable.val(prefix + "See console for requested option.");
return;
}
msg = "Warning: Lack of or incorrect parameters passed to command.";
observable.val(prefix + msg);
warn(msg, "COMMAND");
break;
case "collect":
log("Immediate collect attempt.", "COMMAND");
collectTax();
break;
case "import":
options.import(unsafeWindow.extender.options);
log("Options imported successfully.", "COMMAND");
break;
default:
observable.val(prefix + msg);
error(msg, "COMMAND");
break;
}
}
// <-- Page command handling
// TODO: Implement..
//var PERSISTABLE = {
//
// get queue() {
// return localStorage.get("productionQueue", []);
// },
//
// set queue(val) {
// localStorage.set("productionQueue", val);
// }
//};
// --> Options object
var options = {
swornSwords: [],
default_swornSwords: [],
// Non-tweakable options
lastIdChecked: 2,
default_lastIdChecked: 1,
doSpeedUp: true,
default_doSpeedUp: true,
logLevel: ["QMASTER", "FAVOR", "DAILY", "ADVENTURE"],
default_logLevel: ["QMASTER", "FAVOR", "DAILY", "ADVENTURE"],
outputLogAsText: false,
default_outputLogAsText: false,
logLevelTimestamp: "all_time",
default_logLevelTimestamp: "all_time",
appendLastSeen: true,
default_appendLastSeen: true,
debugMode: true,
default_debugMode: true,
checkScript: false,
default_checkScript: false,
baseDelay: 4,
default_baseDelay: 4,
queueDelay: 4,
default_queueDelay: 4,
autoCollectInterval: 60,
default_autoCollectInterval: 60,
superiorMaterials: true,
default_superiorMaterials: true,
queueTimerInterval: 30,
default_queueTimerInterval: 30,
bruteWounds: 1,
default_bruteWounds: 1,
bruteSwitchOff: true,
default_bruteSwitchOff: true,
doTooltips: false,
default_doTooltips: false,
neverSpendGold: true,
default_neverSpendGold: true,
autoReloadInterval: 6,
default_autoReloadInterval: 6,
boonsSortBy: "available_quantity",
default_boonsSortBy: "available_quantity",
boonsSortBy2: "rarity",
default_boonsSortBy2: "rarity",
shopSortBy: "price",
default_shopSortBy: "price",
shopSortBy2: "rarity",
default_shopSortBy2: "rarity",
sendAllAction: "all",
default_sendAllAction: "all",
autoBossChallenge: false,
default_autoBossChallenge: false,
featureTesting: false,
default_featureTesting: false,
hideLockedBuildings: true,
default_hideLockedBuildings: true,
selectedAction: null,
default_selectedAction: null,
autoQMaster: true,
default_autoQMaster: true,
avaSendSubcamps: false,
default_avaSendSubcamps: false,
weManagerEnabled: false,
default_weManagerEnabled: false,
worldEventDelay: 6,
default_worldEventDelay: 6,
defaultBattle: "fight",
default_defaultBattle: "fight",
defaultTrade: "barter",
default_defaultTrade: "barter",
defaultIntrigue: "spy",
default_defaultIntrigue: "spy",
useLocalDbOnly: false,
default_useLocalDbOnly: false,
get: function () {
// --> NOTE !!! SEPARATE HOSTS ARE NO LONGER SUPPORTED !!!
//var prefix = "";
// Separate variable retrieval for both hosts
//if (unsafeWindow.location.host === "gota-www.disruptorbeam.com") {
// prefix = "gota-";
//}
// <-- NOTE !!! SEPARATE HOSTS ARE NO LONGER SUPPORTED !!!
for (var property in this) {
if (this.hasOwnProperty(property) && property.indexOf("default_") == -1 && typeof this[property] != "function") {
// console.debug("Retrieving " + prefix + property + " with default value of " + this["default_" + property]);
this[property] = GM_SuperValue.get(property, this["default_" + property]);
// console.debug("Property " + property + " has a value of " + this[property]);
}
}
},
set: function (opt) {
// --> NOTE !!! SEPARATE HOSTS ARE NO LONGER SUPPORTED !!!
//var prefix = "";
//// Separate variable set for both hosts
//if (unsafeWindow.location.host === "gota-www.disruptorbeam.com") {
// prefix = "gota-";
//}
// <-- NOTE !!! SEPARATE HOSTS ARE NO LONGER SUPPORTED !!!
if (opt && this.hasOwnProperty(opt)) {
GM_SuperValue.set(opt, this[opt]);
return;
}
// Store all properties
for (var prop in this) {
if (this.hasOwnProperty(prop) && prop.indexOf("default_") > -1)
continue;
if (this.hasOwnProperty(prop) && typeof this[prop] != "function") {
GM_SuperValue.set(prop, this[prop]);
}
}
},
reset: function () {
for (var property in this) {
if (this.hasOwnProperty(property) && property.indexOf("default_") == -1 && typeof this[property] != "function") {
this[property] = this["default_" + property];
}
}
this.set();
},
import: function(o){
try {
if (!o || typeof o !== "object") {
error("Cannot import options. Incorrect parameter passed.");
return;
}
for (var p in o) {
if (!this.hasOwnProperty(p))
continue;
//console.debug(this[p] instanceof Array, o[p] instanceof unsafeWindow.Array);
if (this[p] instanceof Array && o[p] instanceof unsafeWindow.Array) {
if (this[p].length != o[p].length) {
//console.debug("Import ", p, " with value ", o[p]);
this[p] = o[p];
this.set(p);
}
continue;
}
if (this[p] !== o[p]) {
//console.debug("Import ", p, " with value ", o[p]);
this[p] = o[p];
this.set(p);
}
}
} catch (err) {
error("Importing failure: " + err, "OPTIONS");
}
},
export: function(params){
try {
var exportObject = {};
if (params == void 0) {
for (var opt in this) {
if (this.hasOwnProperty(opt) && opt.indexOf("default_") == -1 && typeof this[opt] != "function") {
exportObject[opt] = this[opt];
}
}
return typeof cloneInto == "function"
? cloneInto(exportObject, unsafeWindow) // return structured clone
: exportObject; // regular object (no need of cloning)
}
if (typeof params == "object" && params instanceof Array) {
for (var i = 0; i < params.length; i++) {
var exportProperty = params[i];
if (this.hasOwnProperty(exportProperty) && this[exportProperty] != "function") {
exportObject[exportProperty] = this[exportProperty];
}
}
return typeof cloneInto == "function"
? cloneInto(exportObject, unsafeWindow) // return structured clone
: exportObject; // regular object (no need of cloning)
}
// Further cases regard string only
if (typeof params != "string") {
warn("Cannot resolve export parameters.");
return null;
}
if (this.hasOwnProperty(params) && this[params] != "function")
return typeof cloneInto == "function"
? cloneInto(this[params], unsafeWindow) // return structured clone
: this[params]; // regular object (no need of cloning)
if (this.hasOwnProperty(params) && this[params] == "function")
return typeof exportFunction == "function"
? exportFunction(this[params], unsafeWindow) // return exported function
: this[params]; // regular function (no need of exporting)
} catch(err) {
error("Exporting failure: " + err, "OPTIONS");
}
}
};
// <-- End of options object
// --> Injection object
var inject = {
// Constants required by the page
constants: function () {
// Safe string
unsafeWindow.phraseText.shop_filter_extender = "Extender";
// EXTENDER :: Modification - add custom filter
if (unsafeWindow.shopFilters.indexOf("extender") == -1) {
log("Injecting extender filter...");
unsafeWindow.shopFilters.push("extender");
}
unsafeWindow.extender.options = options.export();
//Inject structured clone (for Mozilla)
if (typeof (cloneInto) == "function") {
// unsafeWindow.extender_queueDelay = cloneInto(options.queueDelay, unsafeWindow);
// unsafeWindow.extender_confirmSuperiorMaterials = cloneInto(options.superiorMaterials, unsafeWindow);
// unsafeWindow.extender_bruteWounds = cloneInto(options.bruteWounds, unsafeWindow);
// unsafeWindow.extender_bruteSwitchOff = cloneInto(options.bruteSwitchOff, unsafeWindow);
// unsafeWindow.extender_debugMode = cloneInto(options.debugMode, unsafeWindow);
// unsafeWindow.extender_baseDelay = cloneInto(options.baseDelay, unsafeWindow);
// unsafeWindow.extender_neverSpendGold = cloneInto(options.neverSpendGold, unsafeWindow);
//
// unsafeWindow.extender_boonsSortBy = cloneInto(options.boonsSortBy, unsafeWindow);
// unsafeWindow.extender_boonsSortBy2 = cloneInto(options.boonsSortBy2, unsafeWindow);
// unsafeWindow.extender_shopSortBy = cloneInto(options.shopSortBy, unsafeWindow);
// unsafeWindow.extender_shopSortBy2 = cloneInto(options.shopSortBy2, unsafeWindow);
//
// unsafeWindow.extender_sendAllAction = cloneInto(options.sendAllAction, unsafeWindow);
// //unsafeWindow.extender_autoBossChallenge = cloneInto(options.autoBossChallenge, unsafeWindow);
//
unsafeWindow.userContext.tooltipsEnabled = cloneInto(options.doTooltips, unsafeWindow);
//
} else {
// //unsafeWindow.extender_queueDelay = options.queueDelay;
// //unsafeWindow.extender_confirmSuperiorMaterials = options.superiorMaterials;
// unsafeWindow.extender_bruteWounds = options.bruteWounds;
// unsafeWindow.extender_bruteSwitchOff = options.bruteSwitchOff;
// unsafeWindow.extender_debugMode = options.debugMode;
// unsafeWindow.extender_baseDelay = options.baseDelay;
// unsafeWindow.extender_neverSpendGold = options.neverSpendGold;
//
// unsafeWindow.extender_boonsSortBy = options.boonsSortBy;
// unsafeWindow.extender_boonsSortBy2 = options.boonsSortBy2;
// unsafeWindow.extender_shopSortBy = options.shopSortBy;
// unsafeWindow.extender_shopSortBy2 = options.shopSortBy2;
//
// unsafeWindow.extender_sendAllAction = options.sendAllAction;
// //unsafeWindow.extender_autoBossChallenge = options.autoBossChallenge;
//
unsafeWindow.userContext.tooltipsEnabled = options.doTooltips;
}
log("Constants injected successfully.", "INJECTOR");
},
// Inject code
code: function (code) {
var script = document.createElement('script');
script.type = "text/javascript";
script.innerHTML = code;
document.head.appendChild(script);
log("Code injected successfully.", "INJECTOR");
},
outSource: function (src, delay) {
var script = document.createElement('script');
script.type = "text/javascript";
script.src = src;
delay ? setTimeout(function () {
document.head.appendChild(script);
}, (options.baseDelay / 4) * 1000) : document.head.appendChild(script);
log("Script from outer source injected.", "INJECTOR");
},
// Injects a DOM object and starts observing it
observable: function () {
$("div#outerwrap div.footer").prepend(templates.observable);
signalObserver.observe(document.getElementById("observable"), {
// childList: true,
attributes: true,
// characterData: true,
// subtree: true,
attributeOldValue: true
// if attributes
// characterDataOldValue: true, // if characterData
// attributeFilter: ["id", "dir"], // if attributes
});
log("Observable injected successfully.", "INJECTOR");
},
// Inject console and alert handling separately once
console: function () {
if (typeof exportFunction == "function") {
exportFunction(log, unsafeWindow, {defineAs: "log"});
exportFunction(warn, unsafeWindow, {defineAs: "warn"});
exportFunction(error, unsafeWindow, {defineAs: "error"});
exportFunction(clientLog, unsafeWindow, {defineAs: "clientLog"});
exportFunction(inform, unsafeWindow, {defineAs: "inform"});
//exportFunction(progress, unsafeWindow, {defineAs: "progress"});
} else {
unsafeWindow.log = log;
unsafeWindow.warn = warn;
unsafeWindow.error = error;
unsafeWindow.clientLog = clientLog;
unsafeWindow.inform = inform;
//unsafeWindow.progress = progress;
}
log("Messaging system injected successfully.", "INJECTOR");
}
};
// <-- End of injection object
// --> Message handling & log
function log(message, type) {
if (typeof message == "object") {
clientLog(message, type);
return;
}
if (options && options.debugMode && console && console.log
&& typeof (console.log) == "function") {
if (!type)
type = "extender";
var prefix = type.toString().toUpperCase() + " <" + new Date().toLocaleTimeString() + "> ";
console.log(prefix + message);
}
}
function error(message, type) {
if (console && console.error && typeof (console.error) == "function") {
if (!type)
type = "extender";
var prefix = type.toString().toUpperCase() + " - ERROR <" + new Date().toLocaleTimeString() + "> ";
console.error(prefix + message);
}
}
function warn(message, type) {
if (console && console.warn && typeof (console.warn) == "function") {
if (!type)
type = "extender";
var prefix = type.toString().toUpperCase() + " - WARNING <" + new Date().toLocaleTimeString() + "> ";
console.warn(prefix + message);
}
}
function inform(msg, progress, info) {
if (unsafeWindow && typeof unsafeWindow.doAlert == "function") {
var exalert = $("div#exalert.exrow:visible");
var expinfo = $("div#expinfo.exrow:visible");
var exprogress = $("div#exprogress.progstretch-inner:visible");
if(exalert.length) { // alert shown
msg &&
exalert.html(msg);
info && expinfo &&
expinfo.html(info);
progress && exprogress &&
exprogress.css("width", progress + "%");
return;
}
// Construct alert
unsafeWindow.doAlert("EXTENDER", templates.formatAlert(msg, progress, info))
} else if (alert && typeof alert == "function")
alert("Progress: " + progress + " : " + info + "\n\n" + msg);
}
function clientLog(data, type) {
//console.debug("Debugging arguments: ", arguments);
if (options.logLevel.indexOf(type) > -1) {
//console.debug("Debugging data: ", data);
var clientEntries = sessionStorage.get("clientEntries", []);
if(data.message != void 0){
var msg = {
message: data.message,
type: type,
timestamp: moment().format()
};
clientEntries.push(msg);
} else {
var stored = clientEntries.filter(function (item) {
return item.symbol === data.symbol;
})[0]; // check if it the logged item is in the array
if (stored != void 0) { // already in storage
stored.quantity += data.quantity;
stored.type = "";
stored.timestamp = "";
} else { // new entry
var entry = {
symbol: data.symbol,
type: type,
quantity: data.quantity,
timestamp: moment().format()
};
clientEntries.push(entry);
}
}
sessionStorage.set("clientEntries", clientEntries);
}
}
// <-- Message handling
// --> Loops handling
function toggleAll() {
toggleAutoCollect();
toggleQueueTimer();
toggleReloadWindow();
}
var autoCollectLoop;
function toggleAutoCollect() {
if (options.autoCollectInterval > 0) {
autoCollectLoop = setInterval(collectTax, options.autoCollectInterval * 60 * 1000);
log("Auto collect loop set to: " + options.autoCollectInterval + "min.");
log("Immediate collect attempt.", "EXTENDER");
collectTax();
} else {
autoCollectLoop = clearInterval(autoCollectLoop);
log("Auto collect loop disabled.");
}
}
var queueTimer;
function toggleQueueTimer() {
if (options.queueTimerInterval > 0) {
queueTimer = setInterval(unsafeWindow.production.attempt, options.queueTimerInterval * 60 * 1000);
log("Queue timer interval set to: " + options.queueTimerInterval + "min.");
log("Immediate production attempt.", "EXTENDER");
unsafeWindow.production.attempt();
} else {
queueTimer = clearInterval(queueTimer);
log("Queue timer disabled.");
}
}
var reloadWindowTimeout;
function toggleReloadWindow() {
if (options.autoReloadInterval > 0) {
setTimeout(function () {
//saveProductionQueue();
window.location.reload(true);
}, options.autoReloadInterval * 60 * 60 * 1000);
log("Auto reload interval set to: " + options.autoReloadInterval + "h.");
} else {
reloadWindowTimeout = clearTimeout(reloadWindowTimeout);
log("Auto reloading cancelled.");
}
}
function acceptAllFavors() {
ajax({
url: "/play/accept_favor",
success: function (r) {
//console.debug(r, r.accepted);
r.silver_reward && log({
symbol: "silver_coins",
quantity: r.silver_reward
}, "FAVOR");
if(!$.isEmptyObject(r.accepted)){
for(var item in r.accepted){
if(!r.accepted.hasOwnProperty(item))
continue;
var value = r.accepted[item];
r.silver_reward && log({
symbol: item,
quantity: value
}, "FAVOR");
//log("Accepted: " + value + " x " + item, "FAVOR", true);
}
} else {
log("All favors have been claimed.");
}
}
});
}
function quarterMasterDo(status) {
if (!status) {
ajax({
url: "/play/quartermaster_status",
success: function (response) {
quarterMasterDo(response);
}
});
return;
}
if (options.autoQMaster && status.total_keys) {
openBox();
return;
}
if (status.available_daily_key) {
claimDailyQuarterMaster();
return;
}
if (status.available_bonus_key) {
claimBonusQuarterMaster();
return;
}
log("All quartermaster rewards have been taken.");
unsafeWindow.claimDaily();
log("Daily reward claimed.")
}
function claimDailyQuarterMaster() {
ajax({
url: "/play/quartermaster_claim_daily",
success: function (r) {
quarterMasterDo(r.status);
}
});
}
function claimBonusQuarterMaster() {
ajax({
url: "/play/quartermaster_claim_bonus",
success: function (r) {
quarterMasterDo(r.status);
}
});
}
function openBox() {
if(!options.autoQMaster){
log("Feature has been disabled.", "QUARTERMASTER");
return;
}
ajax({
url: "/play/quartermaster_open_chest/?bribes=0&nonce=" + unsafeWindow.userContext.purchase_nonce,
success: function (r) {
if(!r.purchase_nonce) {
error("Could not retrieve a purchase nonce. Process terminated...");
return;
}
unsafeWindow.userContext.purchase_nonce = r.purchase_nonce;
if(!r.rewards) {
error("No rewards retrieved. Process terminated...");
console.debug("Server responded: ", r);
return;
}
//console.debug(r.rewards);
for(var i = 0; i < r.rewards.length; i++){
var reward = r.rewards[i];
//var clientEntry = "Reward claimed: " + reward.item_symbol + ', ' +
// 'quantity: ' + reward.quantity;
log({
symbol: reward.item_symbol,
quantity: reward.quantity
}, "QMASTER");
//log(clientEntry, "QUARTERMASTER", true);
}
quarterMasterDo();
}
});
}
function sendGifts(){
ajax({
url: "/play/gifts",
success: function (r) {
var bestGift = r.favors.sort(function(a, b){
return a.description < b.description;
})[0].symbol;
}
});
}
function collectTax() {
try {
var itemId = unsafeWindow.buildingBySymbol('counting_house').item_id;
unsafeWindow.doCollect(itemId);
log("Silver collected.");
} catch (err) {
error(err);
}
}
// <-- Loops handling
// --> Settings handling
$("#main_toolbar_buttons").on('click', "#extender-menu", showSettings);
function showSettings(e) {
e.preventDefault();
try {
// Clear loading screen if any
$("#loadingbg:visible").hide();
// Construct header and place a container for the content
$("#credits_page").empty().append(templates.optionsHeader).append(templates.tabContent);
// Construct tabs
$("#extenderTabMenu").find(".charactertabs")
.append(templates.optionsTab("logTab", "LOG"))
.append(templates.optionsTab("mainTab", "MAIN"))
.append(templates.optionsTab("queueTab", "QUEUE"))
.append(templates.optionsTab("bruteTab", "BRUTING"))
.append(options.featureTesting && templates.optionsTab("weTab", "WE"));
$("#mainTab").trigger('click');
optionsBottom(); // Construct the bottom of the options window
$("#credits_roll").show();
} catch (err) {
error(err, "show_settings");
}
}
function optionsBottom() {
var saveBtn = $("#saveOptions");
var container = $("#creditsclose");
if (saveBtn.length == 0 && container.length > 0) {
container.before(templates.saveOptionsBtn);
}
container.attr('onclick', '(function(){ $("#credits_page").empty(); $("#credits_roll").hide(); })()');
var resetBtn = $("#resetOptions");
if (resetBtn.length == 0 && container.length > 0) {
container.after(templates.resetOptionsBtn);
}
}
$("#credits_roll").on("click", ".inventorytabwrap", tab_onchange);
function tab_onchange(e) {
e.preventDefault();
$(".inventorytab.active").removeClass("active");
$(this).find(".inventorytab").addClass("active");
var tabContent = $("#extenderTabContent");
if(!tabContent.length)
{
error("Cannot locate tab content!", "tab_onchange")
return;
}
switch (this.id) {
case "logTab":
tabContent.html(templates.logTab(options));
break;
case "mainTab":
tabContent.html(templates.mainTab(options));
break;
case "queueTab":
tabContent.html(templates.queueTab(options));
unsafeWindow.production.render();
break;
case "bruteTab":
getSwornSwords();
tabContent.html(templates.bruteTab(options));
break;
case "weTab":
tabContent.html(templates.weTab(options));
break;
default:
warn("Not a known tab or in development.");
break;
}
}
$("#credits_roll").on('click', "#saveOptions", saveOptions_click);
function saveOptions_click(e) {
e.preventDefault();
try {
if ($("#credits_roll").is(":hidden")) {
return;
}
var tab = $(".inventorytab.active:visible").parents(".inventorytabwrap").attr("id");
switch (tab) {
case "mainTab":
saveMainTab();
break;
case "queueTab":
saveQueueTab();
break;
case "bruteTab":
saveBruteTab();
break;
case "weTab":
saveWeTab();
break;
case "logTab":
saveLogTab();
break;
default:
warn("Not a known tab or in development.");
return;
}
//options.set();
//inject.constants();
//unsafeWindow.sort();
//toggleAll();
$("#credits_page").empty();
$("#credits_roll").hide();
inform("Settings saved.");
} catch (e) {
inform(e);
}
}
function saveLogTab(){
var $logLevelTimestamp = $("#logLevelTimestamp");
if($logLevelTimestamp.length){
options.logLevelTimestamp = $logLevelTimestamp.val();
options.outputLogAsText = $("#outputLogAsText").hasClass("checked");
var index = -1;
if($("#logAdventures").hasClass("checked")){
if(options.logLevel.indexOf("ADVENTURE") == -1)
options.logLevel.push("ADVENTURE");
} else {
index = options.logLevel.indexOf("ADVENTURE");
index && options.logLevel.splice(index, 1);
}
if($("#logQMaster").hasClass("checked")){
if(options.logLevel.indexOf("QMASTER") == -1)
options.logLevel.logLevel.push("QMASTER");
} else {
index = options.logLevel.indexOf("QMASTER");
index && options.logLevel.splice(index, 1);
}
if($("#logDaily").hasClass("checked")){
if(options.logLevel.indexOf("DAILY") == -1)
options.logLevel.push("DAILY");
} else {
index = options.logLevel.indexOf("DAILY");
index && options.logLevel.splice(index, 1);
}
if($("#logFavors").hasClass("checked")){
if(options.logLevel.indexOf("FAVOR") == -1)
options.logLevel.push("FAVOR");
} else {
index = options.logLevel.indexOf("FAVOR");
index && options.logLevel.splice(index, 1);
}
options.set();
}
}
function saveWeTab(){
var wed = parseInt($("#worldEventDelay").text());
if (!isNaN(wed) && options.worldEventDelay != wed) {
options.worldEventDelay = wed;
}
options.weManagerEnabled = $("#weManagerEnabled").hasClass("checked");
unsafeWindow.worldEvent.config(options.export(["weManagerEnabled", "worldEventDelay"]));
unsafeWindow.worldEvent.dispatch();
options.set();
}
function saveMainTab() {
var bd = parseInt($("#baseDelay").text());
if (!isNaN(bd) && options.baseDelay != bd) {
options.baseDelay = bd;
}
options.hideLockedBuildings = $("#toggleLockedBuildings").hasClass("checked");
//options.useLocalDbOnly = $("#toggleLocalDbOnly").hasClass("checked");
options.debugMode = $("#toggleDebugModes").hasClass("checked");
options.doTooltips = $("#toggleTooltips").hasClass("checked");
options.appendLastSeen = $("#toggleLastSeen").hasClass("checked");
options.neverSpendGold = $("#neverSpendGold").hasClass("checked");
options.autoBossChallenge = $("#autoBossChallenge").hasClass("checked");
options.autoQMaster = $("#autoQMaster").hasClass("checked");
unsafeWindow.bossChallenger.config(options.export(["autoBossChallenge"]));
var ari = parseInt($("#autoReloadInterval").val());
if (!isNaN(ari) && options.autoReloadInterval !== ari) {
options.autoReloadInterval = ari;
toggleReloadWindow();
}
var aci = parseInt($("#autoCollectInterval").val());
if (!isNaN(aci) && options.autoCollectInterval !== aci) {
options.autoCollectInterval = aci;
toggleAutoCollect();
}
options.avaSendSubcamps = $("#avaSendSubcamps").hasClass("checked");
options.boonsSortBy = $("#boonsSortBy").val();
options.boonsSortBy2 = $("#boonsSortBy2").val();
options.shopSortBy = $("#shopSortBy").val();
options.shopSortBy2 = $("#shopSortBy2").val();
options.sendAllAction = $("#sendAllAction").val();
options.defaultBattle = $("#default_battle").val();
options.defaultTrade = $("#default_trade").val();
options.defaultIntrigue = $("#default_intrigue").val();
options.set();
inject.constants();
unsafeWindow.sort();
}
function saveQueueTab() {
if ($("#credits_roll").is(":hidden")) {
return;
}
options.superiorMaterials = $("#toggleSuperiorMaterials").hasClass("checked");
options.doSpeedUp = $("#toggleDoSpeedUp").hasClass("checked");
var qd = parseInt($("#queueDelay").text());
if (!isNaN(qd) && options.queueDelay !== qd) {
options.queueDelay = qd;
}
var qti = parseInt($("#queueTimerInterval").val());
if (!isNaN(qti) && options.queueTimerInterval !== qti) {
options.queueTimerInterval = qti;
toggleQueueTimer();
}
unsafeWindow.production.config(options.export(["queueDelay", "superiorMaterials", "doSpeedUp"]));
options.set();
inject.constants();
}
function saveBruteTab() {
if ($("#credits_roll").is(":hidden")) {
return;
}
var bWounds = parseInt($("#bruteWounds").text());
if (!isNaN(bWounds)) {
options.bruteWounds = bWounds;
}
var bSwitch = $("#bruteSwitchOff").find("a.btngold");
options.bruteSwitchOff = bSwitch.text() == "switch off";
var attack = $("#selectedAction").val();
if(attack) options.selectedAction = attack == "none" ? null : attack;
options.set();
inject.constants();
//unsafeWindow.sort();
}
$("#credits_roll").on('click', "#infoBtn", info_onclick);
function info_onclick() {
getSwornSwords();
$("#extenderTabContent").html(templates.ssInfo(options.swornSwords));
}
$("#credits_roll").on('click', "#configLogBtn", config_onclick);
function config_onclick() {
log("Configure log level.");
$("#logContent").html(templates.configLog(options));
}
$("#credits_roll").on('click', "#resetOptions", resetOptions_click);
function resetOptions_click(e) {
e.preventDefault();
options.reset();
inject.constants();
unsafeWindow.sort();
toggleAll();
$("#credits_page").empty();
$("#credits_roll").hide();
inform("Options reset.");
}
// <-- Settings handling
//--> Brute force adventure
$("#modal_dialogs_top").on("click", "#speedupbtn", viewAdventure_onclick);
function viewAdventure_onclick() {
log("View adventure details.");
var vBtn = $(this).find("a.btngold");
if (!vBtn || vBtn.text() != "View Results!") {
return;
}
setTimeout(function () {
var btn = $("#bruteBtn");
var container = $(".challengerewards .challengerewarditems:first");
if (container.length > 0 && btn.length == 0) {
container.after(templates.bruteBtn);
}
}, (options.baseDelay / 2) * 1000);
}
$("#quests_container").on("click", "span#bruteBtn.btnwrap.btnmed", brute_onclick);
$("#credits_roll").on("click", "span#bruteBtn.btnwrap.btnmed", brute_onclick);
$("#credits_roll").on("click", "span#bruteAllBtn.btnwrap.btnmed", brute_onclick);
function brute_onclick() {
// log("Brute!");
// Save settings first
saveBruteTab();
// Find button text
var b = $(this).find("a.btngold");
if (!b || b.length == 0) {
warn("Cannot find brute button!");
}
unsafeWindow.brutingImmediateTermination = false;
b.text("Bruting...");
if (this.id == "bruteAllBtn") {
// Brute all sworn swords adventure...
unsafeWindow.bruteSendAll();
} else {
// Else, brute adventure...
unsafeWindow.bruteForce(true);
}
}
function getSwornSwords() {
try {
var ss = [];
var pi = unsafeWindow.playerInventory;
for (var i = 0; i < pi.length; i++) {
var s = pi[i];
if (s.slot == "Sworn Sword") {
ss.push(s);
}
}
if (ss.length > 0) {
options.swornSwords = ss;
options.set("swornSwords");
}
} catch(err) {
error('Sworn swords retrieval failed: ' + err);
}
}
// <-- Brute force adventure
// Do adventures anytime <DEPRECATED>
//$("#modal_dialogs_top").on("click", ".adventurebox .adventuremenu .adventurescroll .adventureitem.locked", lockedAdventure_onclick);
//function lockedAdventure_onclick(e) {
// log("Trying to unlock adventure.");
//
// try {
// e.preventDefault();
// e.stopPropagation();
//
// var id = this.id;
// var aid = id.replace("adventure_", "");
//
// // console.debug(id, aid);
//
// unsafeWindow.chooseAdventure(aid);
// } catch (e) {
// error(e);
// }
//
//}
$("#modal_dialogs_top").on('click', ".inventorytabwrap", building_tab_onclick);
function building_tab_onclick(){
//$("#buildingQueueTab_inner").addClass("active");
if(this.id == "buildingQueueTab"){
$("#building_tab_main").hide();
$("#upgradetab_inner").removeClass("active");
$("#building_tab_prod").hide();
$("#productiontab_inner").removeClass("active");
$("#building_tab_queue").show();
$("#buildingQueueTab_inner").addClass("active");
unsafeWindow.production.render(unsafeWindow.userContext.activeBuildingPanel);
} else if ($("#building_tab_queue").is(":visible")){
$("#building_tab_queue").hide();
$("#buildingQueueTab_inner").removeClass("active");
}
}
$("#building_items").on('click', ".unlocked", upgradetab_changed);
$("#modal_dialogs_top").on('click', ".buildingupgradetree .upgradeicon", upgradetab_changed);
function upgradetab_changed() {
// log('Upgrade description changed.');
if(this.id == "bc_619")
return;
var btn = $("#upgradeQueue");
var container = $("#selected_upgrade");
if (container.length > 0 && btn.length == 0) {
container.append(templates.queueUpgradeBtn);
//if(!$("#exUpgradeContainer").length) {
// var html = $(".upgradeinfobg").html();
// html = '<div id="exUpgradeContainer" style="height: 250px; overflow-y: scroll;">' + html + '</div>';
// $(".upgradeinfobg").html(html);
//}
}
var tab = $("#buildingQueueTab");
container = $("div#chartabmenu div.charactertabs");
if (container.length > 0 && tab.length == 0) {
container.append(templates.buildingQueueTabBtn);
$("#building_tab_prod").after(templates.buildingTabQueue());
}
}
$("#modal_dialogs_top").on('click', ".production .productionrow", productiontab_onchange);
function productiontab_onchange() {
// log('Production view changed.');
var btns = $(".production .craftbox .statviewbtm:visible .btnwrap.btnmed.equipbtn.queue:visible");
var container = $(".production .craftbox .statviewbtm:visible");
if (container.length > 0 && btns.length == 0) {
container.prepend(templates.queue5Btn);
container.prepend(templates.queueBtn);
}
}
//$("#modals_container").on("click", "#hudchatbtn", warmap_onclick);
$("#modals_container").on("click", ".messagetab", warmap_onclick);
//$("#modals_container").on("click", "div.avaregions a.avaregion", warmap_onclick);
function warmap_onclick(e) {
e.preventDefault();
e.stopPropagation();
if (this.id !== "messagetab-wars") {
$("#ex_search_row").remove();
return;
}
setTimeout(function () {
var row = $("#ex_search_row");
var container = $("div#alliance_main_content");
if (container.length > 0 && row.length == 0) {
container.after(templates.searchAllianceBtn);
}
}, (options.baseDelay / 2) * 1000);
}
$("#modal_dialogs_top").on('click', "[onclick*='pvpIncomingAttacks']", inspectIncoming);
function inspectIncoming(e) {
e.preventDefault();
ajax({
method: "GET",
url: "/play/incoming_attacks",
success: function (a) {
try {
// console.debug(a);
$('div.perkscroll div.achiev-content').each(function () {
var id = /[0-9]+/.exec($(this).find('div.increspond').attr('onclick'));
var attack = a.attacks.filter(function (e) {
return e.camp_attack_id === null ? e.pvp_id == id : e.camp_attack_id == id;
})[0];
if (!attack)
return;
$(this).find("span.charname").attr("onclick", "return characterMainModal(" + attack.attacker.user_id + ")");
$(this).find("span.charportrait").attr("onclick", "return characterMainModal(" + attack.attacker.user_id + ")");
//$(this).find("span.targetalliancename").attr("onclick", "return allianceInfo(" + attack.alliance_id + ")");
if(!options.appendLastSeen)
return;
var text = 'Last seen: ' + moment(attack.attacker.updated_at,"YYYY-MM-DD HH:mm:ss Z").local().format('MMMM Do YYYY, h:mm:ss a');
$(this).append('<div class="ex_attack_timestamp">' + text + '</div>');
});
unsafeWindow.$(".scroll-pane:visible").jScrollPane();
} catch (e) {
error(e);
}
}
});
}
$("#modal_dialogs_top").on('click', "[onclick*='pvpOutgoingAttacks']", inspectOutgoing);
function inspectOutgoing(e) {
e.preventDefault();
ajax({
method: "GET",
url: "/play/outgoing_attacks",
success: function (a) {
try {
// console.debug(a);
$('div.perkscroll div.achiev-content:visible').each(function () {
var id = /[0-9]+/.exec($(this).find('div.increspond').attr('onclick'));
var attack = a.attacks.filter(function (e) {
return e.camp_attack_id === null ? e.pvp_id == id : e.camp_attack_id == id;
})[0];
if (!attack || !attack.defender)
return;
$(this).find("span.charname").attr("onclick", "return characterMainModal(" + attack.defender.user_id + ")");
$(this).find("span.charportrait").attr("onclick", "return characterMainModal(" + attack.defender.user_id + ")");
//$(this).find("span.targetalliancename").attr("onclick", "return allianceInfo(" + attack.alliance_id + ")");
if(!options.appendLastSeen)
return;
var text = 'Last seen: ' + moment(attack.defender.updated_at,"YYYY-MM-DD HH:mm:ss Z").local().format('MMMM Do YYYY, h:mm:ss a');
$(this).append('<div class="ex_attack_timestamp">' + text + '</div>');
});
unsafeWindow.$(".scroll-pane:visible").jScrollPane();
} catch (e) {
error(e);
}
}
});
}
$("#modal_dialogs_top").on('click', "[onclick*='pvpStartWithTarget']", inspectTarget);
$("#modal_dialogs_top").on('click', "[onclick*='pvpTargetSelected']", inspectTarget);
function inspectTarget(e) {
e.preventDefault();
//console.debug(e, this, $(this));
var func = $(this).attr("onclick");
var id = func.indexOf("pvpTargetSelected") > -1
? func.substring(func.indexOf(",") + 1, func.indexOf(")"))
: func.substring(func.indexOf("(") + 1, func.indexOf(")"));
if(!id){
warn("Could not retrieve player id. Exiting...");
return;
}
ajax({
method: "GET",
url: "/play/character_pvp/" + id,
success: function (a) {
try {
// console.debug(a);
var lastUpdated =
a.defender.armor ? a.defender.armor.updated_at
: a.defender.weapon ? a.defender.weapon.updated_at
: a.defender.companion ? a.defender.companion.updated_at
: null;
if (!lastUpdated) {
warn("Could not establish when was the user last seen.");
return;
}
var $h2 = $(".infobar:visible:first").find("h2");
if($h2.length){
$h2.css("padding-left", "140px");
$h2.html('Last seen: ' + moment(lastUpdated, "YYYY-MM-DD HH:mm:ss Z").local().format('MMMM Do YYYY, h:mm:ss a'));
}
} catch (e) {
error(e);
}
}
});
}
$("#modals_container").on("click", "[onclick*='campActivity']", campactivity_onclick);
function campactivity_onclick(){
log("Camp activity requested.");
var oncl = $(this).attr("onclick");
var startIdx = oncl.indexOf('campActivity(') + 13;
var endIdx = oncl.lastIndexOf(');');
var params = oncl.substring(startIdx, endIdx).split(',');
var campId = params[0];
var category = params[1]; // 1 - provisions, // 2 - action, // 3 - garrison
if(!campId || !category){
error("Failed resolving camp id and category.", "CAMP");
return;
}
//console.debug("Parameters resolved, camp id: ", campId, " category: ", category);
switch(category){
case '2':
analyzeActions(campId);
break;
case '1':
case '3':
default:
log("No actions implemented for this category.");
return;
}
}
function analyzeActions(camp){
ajax({
url: "/play/camp_messages/" + camp + "?category=2",
success: function(a) {
var contents = $(".achiev-box.action-battle .achiev-content:visible");
if(contents.length !== a.length){
warn("Wrong response format.", "CAMP");
return;
}
var i = 0;
contents.each(function(){
var initiator = $(this).find(".activityinitiator h3 span");
var target = $(this).find(".activitytarget h3 span");
if(initiator.length){
initiator.attr("onclick", "return allianceInfo(" + a[i].camp_attack.alliance_id + ")");
initiator.before('<span onclick="return characterMainModal(' + a[i].user_id + ')">' + a[i].name + '</span>');
// Assign dirrect assault link to their camp
$(this).find(".activityinitiatorcamp h3 span").attr("onclick", "campChoseTarget(" + a[i].camp_attack.region + ", " + a[i].camp_attack.subregion + ", " + a[i].camp_attack.alliance_id + ")" );
} else if (target.length) {
target.attr("onclick", "return allianceInfo(" + a[i].camp_attack.target_alliance_id + ")");
//target.before('<span onclick="return characterMainModal(' + a[i].user_id + ')">' + a[i].name + '</span>');
// Assign dirrect assault link to their camp
$(this).find(".activitytargetcamp h3 span").attr("onclick", "campChoseTarget(" + a[i].camp_attack.region + ", " + a[i].camp_attack.subregion + ", " + a[i].camp_attack.target_alliance_id + ")" );
}
i++;
});
}
})
}
$("#modals_container").on("click", "#ex_alliance_search", searchAlliance_onclick);
function searchAlliance_onclick(e) {
e.preventDefault();
unsafeWindow.showSpinner();
window.setTimeout(function () {
var keys = $("#ex_alliance_search_input").val();
if (!keys || keys.length == 0) {
return;
}
var keysArray = keys.split(" ");
var c = keysArray[0];
for (var i = 1; i < keysArray.length; i++) {
c += "+" +
keysArray[i];
}
//console.debug("Sending data: ", c);
GM_xmlhttpRequest({
method: "GET",
url: "/play/alliance_search/?tags=0&name=" + c,
onload: function (a) {
unsafeWindow.hideSpinner();
if (a.error) {
var e = "Something went awry with your search. Please try again.";
"query-error" == e.error && (e = "Alliance Search by name requires more than 3 characters.");
unsafeWindow.doAlert("Alliance Search Error!", e);
} else {
//console.debug("Raw response: ", a);
var response = JSON.parse(a.responseText);
//console.debug("Response text parsed: ", response);
displayResults(response.alliances);
}
}
});
}, (options.baseDelay / 2) * 1000);
}
function displayResults(a) {
console.debug("Alliances to be displayed: ", a);
$("#ex_alliance_search_input").val("");
if (!(a instanceof Array) || a.length == 0) {
$("#ex_alliance_search_input").attr("placeholder", "No alliances found");
return;
}
// Clean table
$(".avaranking:visible:first tr:not(:first)").empty();
// Fill table
var l = a.length > 4 ? 4 : a.length;
for (var i = 0; i < l; i++) {
$(".avaranking:visible:first tr:first").after(templates.allianceRow(a[i], unsafeWindow.userContext.activeRegion));
}
}
$("#modal_dialogs_top").on('click', "[onclick*='chooseAdventure']", adventureItem_onclick);
function adventureItem_onclick() {
//log("Adventures display.");
setTimeout(function () {
var btn = $("#adventureSendAll");
var container = $("div.infobar span#backbtn.btnwrap.btnsm:visible");
if (container.length > 0 && btn.length == 0) {
container.after(templates.sendAllBtn);
}
}, (options.baseDelay / 2) * 1000);
}
$("#modals_container").on('click', "[onclick*='pvpTargetSelected']", pvpStart_onclick);
$("#modals_container").on('click', "[onclick*='pvpStartWithTarget']", pvpStart_onclick);
function pvpStart_onclick() {
//log('Displaying pvp dialog with a target specified.');
setTimeout(function () {
var btn = $("#pvpSendAll");
var container = $("div.infobar span#backbtn.btnwrap.btnsm:visible");
if (container.length > 0 && btn.length == 0) {
container.after(templates.pvpSendAllBtn);
}
}, (options.baseDelay / 2) * 1000);
}
$(document).on('click', "[onclick*='campChoseTarget']", avaStart_onclick);
function avaStart_onclick() {
log('Displaying ava dialog with a target specified.');
setTimeout(function () {
var btn = $("#avaSendAll");
var container = $("div.infobar span#backbtn.btnwrap.btnsm:visible");
if (container.length > 0 && btn.length == 0) {
container.after(templates.avaSendAllBtn);
}
}, (options.baseDelay / 2) * 1000);
}
$('#modal_dialogs').on('click', '#shop_offer_btn', function(e){
log('Displaying offer code dialog.');
console.debug(options.lastIdChecked)
setTimeout(function () {
var btn = $("#find_gifts");
var container = $("div#modals_container_alerts div.alertcontents div.alertbox div.alertboxinner div.alertinput");
if (container.length > 0 && btn.length == 0) {
container.after(templates.findGifts(options.lastIdChecked, 100));
}
}, (options.baseDelay / 2) * 1000);
});
function checkSource() {
console.log("-------------------------------------\\");
console.log("Script scheduled for update check.");
console.log("-------------------------------------/");
var lastUpdateCheck = GM_SuperValue.get("lastUpdateCheck", "never");
console.log("Function definitions updated: " + lastUpdateCheck);
console.log("Source control check for integrity initiated...");
var updateRequired = false;
eval(GM_getResourceText("original"));
if (typeof original == "undefined") {
error("Cannot find original function data.");
return;
}
try {
for (var fn in original) {
console.log("Current function: " + fn);
if (!original.hasOwnProperty(fn)) {
console.error("Function does not have a stored value!");
continue;
}
console.log("Retrieving page function...");
if (!unsafeWindow[fn]) {
console.error("No such function on page!");
continue;
}
var pageFn = unsafeWindow[fn].toString();
console.log("Function retrieved. Comparing...");
if (pageFn !== original[fn]) {
console.warn("Changes detected! Please revise: " + fn);
updateRequired = true;
continue;
}
console.log("No changes were detected. Continuing...");
}
} catch (e) {
alert("Source control encountered an error: " + e);
return;
}
console.log("-------------------------------------|");
console.log("-------------------------------------| > End of script update check");
if (!updateRequired) {
GM_SuperValue.set("lastUpdateCheck", new Date());
}
alert("Source control resolved that " +
(updateRequired ? "an update is required." : "no changes are necessary.") +
"\nSee the console log for details.\nPress OK to reload again.");
}
// jQuery ajax
function ajax(params) {
if (typeof params != "object") {
error("The request requires object with parameters.");
return;
}
// Required
if (!params.url) {
error("Request url was not passed.");
return;
}
// Required
if (!params.onload && !params.success) {
error("Callback handler missing. Cannot execute.");
return;
}
if (!params.type) {
params.type = "GET";
}
if (!params.timeout) {
params.timeout = 3E4;
}
if (!params.onerror) {
params.onerror = function (gme) {
error("Error occurred while running the request. Details:");
console.debug("Original ajax request parameters: ", params);
console.debug("GM_XmlHttpRequest error response: ", gme);
}
}
if (!params.onload) {
params.onload = function (gmr) {
var response;
if (!gmr.response) {
params.error ? params.error(gmr) : params.onerror(gmr);
} else {
//var headerString = gmr.responseHeaders;
//var headers = headerString.split('\n');
//console.debug("Debugging response headers: ", headers);
if (gmr.responseHeaders.indexOf("Content-Type: application/json;") > -1) {
response = JSON.parse(gmr.responseText);
params.success(response);
} else {
params.success(gmr.responseText);
}
}
if (params.complete)
params.complete(response);
};
}
if (!params.ontimeout) {
params.ontimeout = function (gmt) {
warn("The request timed out. Details:");
console.debug("Original ajax request parameters: ", params);
console.debug("Grease monkey error response: ", gmt);
};
}
window.setTimeout(function () {
GM_xmlhttpRequest({
//binary: false,
//context: {},
//data: "",
//headers: {},
method: params.type,
//onabort: params.onabort,
onerror: params.onerror,
onload: params.onload,
//onprogress: params.onprogress,
//onreadystatechange: params.onreadystatechange,
ontimeout: params.ontimeout,
//overrideMimeType: "",
//password: "",
//synchronous: false,
timeout: params.timeout,
//upload: {},
url: params.url
//user: ""
});
}, 1E3);
}
$("div#page-wrap").on('click', 'a#navlink-buildings', function(){
log("Navigated to buildings sub-menu.");
if(options.hideLockedBuildings){
$(".locked").hide();
} else {
$(".locked:hidden").show();
}
});