// ==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://greasyforks.org/scripts/5279-greasemonkey-SuperValues/code/GreaseMonkey_SuperValues.js?version=20819
// @require https://greasyforks.org/scripts/7573-storage-prototype-extension/code/StoragePrototype_extension.js?version=32814
// @require https://greasyforks.org/scripts/5427-gota-extender-constants/code/GOTA_Extender_Constants.js?version=33067
// @resource custom https://greasyforks.org/scripts/5426-gota-extender-custom/code/GOTA_Extender_Custom.js?version=33233
// @resource auxiliary https://greasyforks.org/scripts/5618-gota-extender-auxiliary/code/GOTA_Extender_Auxiliary.js?version=33234
// @resource original https://greasyforks.org/scripts/6702-gota-extender-original/code/GOTA_Extender_Original.js?version=31299
// @resource production https://greasyforks.org/scripts/7611-gota-extender-production/code/GOTA_Extender_Production.js?version=33066
// @version 6.6.6
// @grant unsafeWindow
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_openInTab
// @grant GM_xmlhttpRequest
// @grant GM_getResourceText
// @grant GM_getResourceURL
// @grant GM_registerMenuCommand
// ==/UserScript==
// --> Register menu commands
(function(){
GM_registerMenuCommand("HOME", openHome);
function openHome() {
GM_openInTab("https://greasyforks.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);
}
}());
// <-- End of menu commands
// --> Initialization
// Resolves conflicts of different jQuery versions
$ = this.$ = this.jQuery = jQuery.noConflict(true);
// Observes DOM object mutations
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
$(window).bind("load", function () {
setTimeout(function () {
initialize();
}, ((options ? options.baseDelay : 4E3) / 2) * 1000);
});
function initialize() {
try {
// Add global styles
styles.addAllStyles();
// Get all GM values
options.get();
// Check script if scheduled
if (options.checkScript) {
checkSource();
options.checkScript = false;
options.set("checkScript");
window.location.reload(true);
return;
}
// Clean up GOTA shit...
console.clear();
// Inject Storage extension functions (for use in the page)
inject.outSource("https://greasyforks.org/scripts/7573-storage-prototype-extension/code/StoragePrototype_extension.js?version=32814");
// Try an injection sequence
inject.observable();
inject.constants();
inject.console();
// Inject auxiliary code
inject.code(GM_getResourceText("custom"));
inject.code(GM_getResourceText("auxiliary"));
inject.code(GM_getResourceText("production"));
// Initialize modules
setTimeout(function() {
unsafeWindow.production.init(options.export(["queueDelay", "superiorMaterials"]));
unsafeWindow.bossChallenger.init();
}, 2E3);
} catch (e) {
error("Fatal error, injection failed: " + e);
inform("Fatal error, injection failed: " + e);
return;
}
try {
// Toggle
toggleAll();
// Claim
quarterMasterDo();
// Claim favours
acceptAllFavors();
// Try to load the queue
//if (options.productionQueue != void 0 && options.productionQueue.length > 0) {
// loadComponent("productionQueue");
//
// // When done attempt production
// if (typeof unsafeWindow.attemptProduction == "function") {
// unsafeWindow.attemptProduction();
// }
//}
//
//// Try to load the boss challenges
//if (options.bossChallenges != void 0 && options.bossChallenges.length > 0) {
// loadComponent("bossChallenges");
//
// // When done attempt production
// for(var i = 0; i < options.bossChallenges.length; i++){
// var c = options.bossChallenges[i];
// unsafeWindow.questSubmit(c.symbol, c.stage, s.attack, c.chosen, null, null, c.questId);
// }
//}
// Store all sworn swords
getSwornSwords();
// Sort player inventory
unsafeWindow.sort();
log('Initialized. Happy hacking.');
inform("Initialized.");
} catch (e) {
error("Fatal error, initialization failed: " + e);
inform("Fatal error, initialization failed: " + e);
}
}
// <-- 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 commandObj = JSON.parse(observable.attr("command"));
if (!commandObj || typeof commandObj != "object") {
var msg = "Error: Cannot parse the command object given.";
var prefix = "COMMAND ACKNOWLEDGED" + " | " + new Date().toLocaleTimeString() + " | ";
observable.val(prefix + msg);
error(msg);
return;
}
if (typeof commandObj.name !== "string") {
var msg = "Error: Command does not have a name specified.";
var prefix = "COMMAND ACKNOWLEDGED" + " | " + new Date().toLocaleTimeString() + " | ";
observable.val(prefix + msg);
error(msg);
return;
}
var args = commandObj.args;
// Parse command
switch (commandObj.name) {
//case "save":
// saveComponent(args[0]);
//
// var prefix = "COMMAND ACKNOWLEDGED" + " | " + new Date().toLocaleTimeString() + " | ";
// observable.val(prefix + args[0] + " set for persistence.");
//
// break;
case "option":
//log("argument 1 = " + args[0] + ", " +
// "has own prop? " + (options.hasOwnProperty(args[0])) + ", " +
// "argument 2 = " + args[1], "DEBUG");
// 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]);
var prefix = "COMMAND ACKNOWLEDGED" + " | " + new Date().toLocaleTimeString() + " | ";
observable.val(prefix + "Option set.");
return;
}
if (options.hasOwnProperty(args[0])) {
if (typeof options[args[0]] == "object") {
log(args[0] + " is a composite object:");
console.log(typeof cloneInto == "function" ? cloneInto(options[args[0]], unsafeWindow) : options[args[0]]);
} else {
log(args[0] + ": " + options[args[0]]);
}
var prefix = "COMMAND ACKNOWLEDGED" + " | " + new Date().toLocaleTimeString() + " | ";
observable.val(prefix + "See console for requested option.");
return;
}
var msg = "Warning: Lack of or incorrect parameters passed to command.";
var prefix = "COMMAND ACKNOWLEDGED" + " | " + new Date().toLocaleTimeString() + " | ";
observable.val(prefix + msg);
warn(msg);
break;
default:
var msg = "Error: Unknown command.";
var prefix = "COMMAND ACKNOWLEDGED" + " | " + new Date().toLocaleTimeString() + " | ";
observable.val(prefix + msg);
error(msg);
break;
}
}
// <-- Page command handling
// --> Options object
var options = {
swornSwords: [],
default_swornSwords: [],
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,
allowBruting: true,
default_allowBruting: true,
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: "friendly",
default_sendAllAction: "friendly",
autoBossChallenge: false,
default_autoBossChallenge: false,
get: function () {
var prefix = "";
// Separate variable retrieval for both hosts
if (unsafeWindow.location.host === "gota-www.disruptorbeam.com") {
prefix = "gota-";
}
for (var property in this) {
if (this.hasOwnProperty(property) && property.indexOf("default_") == -1 && typeof this[property] != "function") {
// console.debug("Retirevieng " + prefix + property + " with default value of " + this["default_" + property]);
this[property] = GM_SuperValue.get(prefix + property, this["default_" + property]);
// console.debug("Property " + property + " has a value of " + this[property]);
}
}
},
set: function (opt) {
var prefix = "";
// Separate variable set for both hosts
if (unsafeWindow.location.host === "gota-www.disruptorbeam.com") {
prefix = "gota-";
}
if (opt && this.hasOwnProperty(opt)) {
GM_SuperValue.set(prefix + opt, this[opt]);
return;
}
//var newValues = [];
// Store all properties
for (var prop in this) {
if (prop.indexOf("default_") > -1)
continue;
if (this.hasOwnProperty(prop) && typeof this[prop] != "function") {
GM_SuperValue.set(prefix + 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();
},
export: function(params){
if(params == void 0) {
return typeof cloneInto == "function"
? cloneInto(this, unsafeWindow) // return structured clone
: this; // regular object (no need of cloning)
}
if(typeof params == "object" && params instanceof Array) {
var exportObject = {};
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)
}
};
// <-- 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");
}
// 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.");
},
// 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.");
},
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);
},
// 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.");
},
// 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(inform, unsafeWindow, {defineAs: "inform"});
} else {
unsafeWindow.log = log;
unsafeWindow.warn = warn;
unsafeWindow.error = error;
unsafeWindow.inform = inform;
}
var clientEntries = sessionStorage.get("clientEntries", []);
clientEntries.push([new Date().toLocaleTimeString() + " | Extender initialized successfully."]);
sessionStorage.set("clientEntries", clientEntries);
//typeof (cloneInto) == "function"
// ? unsafeWindow.clientEntries = cloneInto(clientEntriesArray, unsafeWindow)
// : unsafeWindow.clientEntries = clientEntriesArray;
log("Messaging system injected successfully.");
}
};
// <-- End of injection object
// --> Message handling
(function(){
window.log = function log(message, type, clientEntry) {
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);
}
if(clientEntry != void 0){
var clientEntries = sessionStorage.get("clientEntries", []);
clientEntries.push(new Date().toLocaleTimeString() + " | " + message);
sessionStorage.set("clientEntries", clientEntries);
}
};
window.error = 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);
}
}
window.warn = 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);
}
}
window.inform = function inform(msg) {
if (unsafeWindow && typeof unsafeWindow.doAlert == "function") {
unsafeWindow.doAlert("EXTENDER", templates.formatMessage(msg));
//$("div#modals_container_high div#modalwrap div#exalert")
// .parents("div.alertboxinner").css("min-height", "0")
// .parent("div.alertbox").css("min-height", "0")
// .parent("div.alertcontents").css("min-height", "0");
} else if (alert && typeof alert == "function")
alert(msg);
}
}());
// <-- 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.");
} 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.");
} 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("Favors claimed: silver reward: " + r.silver_reward, "FAVOR", true);
if(!$.isEmptyObject(r.accepted)){
for(var item in r.accepted){
var value = r.accepted[item];
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 (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() {
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(clientEntry, "QUARTERMASTER", true);
}
quarterMasterDo();
}
});
}
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 {
$("#credits_page").empty();
$("#credits_page").append(templates.optionsHeader);
$("#extenderTabMenu .charactertabs").append(templates.optionsTab("logTab", "LOG"));
$("#extenderTabMenu .charactertabs").append(templates.optionsTab("mainTab", "MAIN"));
$("#extenderTabMenu .charactertabs").append(templates.optionsTab("queueTab", "QUEUE"));
if (options.allowBruting) {
$("#extenderTabMenu .charactertabs").append(templates.optionsTab("bruteTab", "BRUTING"));
}
$("#credits_page").append(templates.tabContent);
$("#mainTab").trigger('click');
optionsBottom();
$("#credits_roll").show();
} catch (err) {
error(err);
return;
}
}
function optionsBottom() {
var saveBtn = $("#saveOptions");
var container = $("#creditsclose");
if (saveBtn.length == 0 && container.length > 0) {
container.before(templates.saveOptionsBtn);
}
$("#creditsclose").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");
switch (this.id) {
case "logTab":
$("#extenderTabContent").html(templates.logTab());
break;
case "mainTab":
$("#extenderTabContent").html(templates.mainTab(options));
break;
case "queueTab":
$("#extenderTabContent").html(templates.queueTab(options));
unsafeWindow.production.render();
break;
case "bruteTab":
getSwornSwords();
$("#extenderTabContent").html(templates.bruteTab(options));
break;
default:
break;
}
}
$("#credits_roll").on('click', "#saveOptions", saveOptions_click);
function saveOptions_click(e) {
e.preventDefault();
try {
var tab = $(".inventorytab.active:visible").parents(".inventorytabwrap").attr("id");
switch (tab) {
case "mainTab":
saveMainTab();
break;
case "queueTab":
saveQueueTab();
break;
case "bruteTab":
saveBruteTab();
break;
default:
return;
}
//options.set();
//inject.constants();
//unsafeWindow.sort();
//toggleAll();
$("#credits_page").empty();
$("#credits_roll").hide();
inform("Settings saved.");
} catch (e) {
inform(e);
}
}
function saveMainTab() {
if ($("#credits_roll").is(":hidden")) {
return;
}
var bd = parseInt($("#baseDelay").text());
if (!isNaN(bd) && options.baseDelay != bd) {
options.baseDelay = bd;
}
options.debugMode = $("#toggleDebugModes").hasClass("checked");
options.doTooltips = $("#toggleTooltips").hasClass("checked");
options.neverSpendGold = $("#neverSpendGold").hasClass("checked");
options.autoBossChallenge = $("#autoBossChallenge").hasClass("checked");
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.boonsSortBy = $("#boonsSortBy").val();
options.boonsSortBy2 = $("#boonsSortBy2").val();
options.shopSortBy = $("#shopSortBy").val();
options.shopSortBy2 = $("#shopSortBy2").val();
options.sendAllAction = $("#sendAllAction").val();
options.set();
inject.constants();
unsafeWindow.sort();
}
function saveQueueTab() {
if ($("#credits_roll").is(":hidden")) {
return;
}
options.superiorMaterials = $("#toggleSuperiorMaterials").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();
}
//saveComponent("productionQueue");
options.set();
inject.constants();
//unsafeWindow.sort();
}
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";
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', "#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!" || !options.allowBruting) {
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!");
}
if (!options.allowBruting) {
error("Bruting is not allowed.");
return;
}
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() {
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();
}
}
// <-- 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);
// }
//
//}
$("#building_items").on('click', ".unlocked", upgradetab_changed);
$("#modal_dialogs_top").on('click', ".buildingupgradetree .upgradeicon", upgradetab_changed);
function upgradetab_changed() {
// log('Upgrade description changed.');
var btn = $("#upgradeQueue");
var container = $("#selected_upgrade");
if (container.length > 0 && btn.length == 0) {
container.append(templates.queueUpgradeBtn);
}
}
$("#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);
}
}
//$("#modal_dialogs_top").on('click', '#upgradeQueue', queue_clicked);
//$("#modal_dialogs_top").on('click', 'span.btnwrap.btnmed.equipbtn.queue', queue_clicked);
//function queue_clicked(e) {
// e.preventDefault();
//
// try {
// var queueingUpgrade = $(this).hasClass('upgradeQueue');
// log("Queing " + (queueingUpgrade ? "upgrade." : "item(s)."));
//
// if (queueingUpgrade) {
//
// var container = $(this).parents('div#selected_upgrade');
// var name = $(container).find('h5:first').text();
//
// var infoBtm = $(this).parents('div.buildinginfobtm');
// var func = $(infoBtm).find('.upgradeicon.active').attr('onclick');
// var upgradeImg = $(infoBtm).find('.upgradeicon.active .upgradeiconart img').attr('src');
//
// if (func.indexOf("clickSelectUpgrade") == -1) {
// error("Cannot resolve upgrade id.");
// return;
// }
//
// // TODO: Improve...
// // "return clickSelectUpgrade('7', 'balcony');"
// var symbol = func.split("'")[3];
// log("Selected " + symbol + " upgrade. Retrieve successfull.");
//
// var upgradeId;
//
// var buildingUpgrades = unsafeWindow.buildingUpgrades[unsafeWindow.userContext.activeBuildingPanel];
// for (var j = 0; j < buildingUpgrades.length; j++) {
// if (buildingUpgrades[j].symbol == symbol) {
// upgradeId = buildingUpgrades[j].id;
// break;
// }
// }
//
// if (!upgradeId) {
// error("Fatal error, cannot resolve upgrade id.");
// return;
// }
//
// log("Upgrade id resolved: " + upgradeId);
//
// var upgrade = {
// "name": name,
// "upgradeId": upgradeId,
// "type": "upgrade",
// "symbol": symbol,
// "img": upgradeImg,
// "activeBuildingPanel": unsafeWindow.userContext.activeBuildingPanel
// };
//
// // Insert the element into the queueArray (cloneInto for Mozilla)
// if (typeof cloneInto == "function") {
// var upgradeClone = cloneInto(upgrade, unsafeWindow);
// unsafeWindow.productionQueue.push(upgradeClone);
// } else {
// unsafeWindow.productionQueue.push(upgrade);
// }
//
// options.productionQueue = unsafeWindow.productionQueue;
// options.set("productionQueue");
//
// log("Pushed upgrade to queue.");
//
// } else {
//
// // Extract and construct object
// var statview = $(this).parents(".statview");
// var imgSrc = $(statview).find("div.statviewimg img").attr('src');
//
// if (typeof (imgSrc) == "undefined") {
// imgSrc = $(statview).find("span.iconview img").attr('src');
// }
//
// var statViewName = $(statview).find(".statviewname h3").text();
// var quantity = $(this).attr("data-quantity");
//
// // Extract variables needed
// var recipeName;
//
// var source = unsafeWindow.userContext.productionItemsClick[unsafeWindow.userContext.currentProductionItem];
//
// if (!source) {
// error('Failed to extract source production item.');
// return;
// }
//
// for (var i = 0; i < unsafeWindow.userContext.recipeData.length; i++) {
// var r = unsafeWindow.userContext.recipeData[i];
// if (r.output == source.outputSymbol) {
// recipeName = r.symbol;
// break;
// }
//
// if (r.success_loot_table && r.success_loot_table == source.outputSymbol) {
// recipeName = r.symbol;
// break;
// }
//
// if (r.success_loot_item && r.success_loot_item == source.outputSymbol) {
// recipeName = r.symbol;
// break;
// }
// }
//
// // Last attempt, these here are expensive operations
// if (!recipeName) {
// for (var i = 0; i < unsafeWindow.userContext.recipeData.length; i++) {
// var r = unsafeWindow.userContext.recipeData[i];
// var recipeInputs = JSON.stringify(r.input.split(","));
// if (JSON.stringify(source.recipeInputs) === recipeInputs) {
// recipeName = r.symbol;
// break;
// }
// }
// }
// if (!recipeName) {
// error('Failed to extract recipeName.');
// return;
// }
//
// log('All needed variables were extracted.');
//
// do {
//
// // Construct production element
// var element = {
// "recipeName": recipeName,
// "name": statViewName,
// "img": imgSrc,
// "type": "item",
// "outputSymbol": source.outputSymbol,
// "recipeCategory": source.recipeCategory,
// "recipeData": unsafeWindow.userContext.recipeData,
// "activeBuildingPanel": unsafeWindow.userContext.activeBuildingPanel
// };
//
// // Insert the element into the queueArray (cloneInto for Mozilla)
// if (typeof (cloneInto) == "function") {
// var elementClone = cloneInto(element, unsafeWindow);
// unsafeWindow.productionQueue.push(elementClone);
// } else {
// unsafeWindow.productionQueue.push(element);
// }
//
// options.productionQueue = unsafeWindow.productionQueue;
// options.set("productionQueue");
//
// quantity--;
//
// log('Pushed element to queue.');
//
// } while (quantity > 0);
// }
//
// log('Attempting immediate production...');
// unsafeWindow.attemptProduction(unsafeWindow.userContext.activeBuildingPanel);
// inform('Enqueued.');
//
// } catch (err) {
// error(err);
// }
//}
//function saveProductionQueue() {
//
// var p = unsafeWindow.productionQueue;
// if (p && p.length > 0) {
// options.productionQueue = p;
// options.set("productionQueue");
// }
//}
//function saveComponent(component) {
// console.debug("Saving component " + component);
//
// if (component == void 0) {
// error("Cannot save " + component + ". Exiting...")
// return;
// }
//
// var p = unsafeWindow[component];
// if (p == void 0) {
// error("Could not find " + component + " on page. Exiting...")
// return;
// }
//
// options.productionQueue = p;
// options.set("productionQueue");
//
//}
//function loadComponent(component) {
//
// if (component == void 0) {
// error("Cannot load " + component + ". Exiting...")
// return;
// }
//
// // console.debug("Conditions: ", !options.productionQueue, options.productionQueue.length == 0);
// if (options[component] == void 0) {
// warn("No stored " + component + " was found in options.");
// return;
// }
//
// // console.debug("Conditions: ", !unsafeWindow.productionQueue);
// if (unsafeWindow[component] == void 0) {
// warn("The " + component + " was not found in page. Extender will create it.");
// }
//
// if (typeof cloneInto == "function") { // Mozilla
// unsafeWindow[component] = cloneInto(options[component], unsafeWindow);
// } else { // Chrome
// unsafeWindow[component] = options[component];
// }
//
// // Clear this from options
// options[component] = null;
// options.set(component);
//}
//function loadProductionQueue() {
//
// // console.debug("Conditions: ", !options.productionQueue, options.productionQueue.length == 0);
// if (!options.productionQueue || options.productionQueue.length == 0) {
// warn("No stored queue was found in options.");
// return;
// }
//
// // console.debug("Conditions: ", !unsafeWindow.productionQueue);
// if (!unsafeWindow.productionQueue) {
// warn("No queue was found on page to fill.");
// return;
// }
//
// if (typeof cloneInto == "function") {
// unsafeWindow.productionQueue = cloneInto(options.productionQueue, unsafeWindow);
// } else {
// unsafeWindow.productionQueue = options.productionQueue;
// }
//
// // Clear this from options
// options.productionQueue = null;
// options.set("productionQueue");
//
//
// // When done attempt production
// if (typeof unsafeWindow.attemptProduction == "function") {
// unsafeWindow.attemptProduction();
// }
//
//}
//$("#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', '#incomingtab', wireEvents);
function wireEvents(e) {
e.preventDefault();
ajax({
method: "GET",
url: "/play/incoming_attacks",
success: function (a) {
try {
// console.debug(response, 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 + ")");
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');
});
} catch (e) {
error(e);
}
}
});
//window.setTimeout(function () {
// GM_xmlhttpRequest({
// method: "GET",
// url: "/play/incoming_attacks",
// onload: function (response) {
// try {
// var a = JSON.parse(response.responseText);
// // console.debug(response, 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 + ")");
// });
// } catch (e) {
// error(e);
// }
// }
// });
//}, (options.baseDelay / 2) * 1000);
}
function saveBossChallenges() {
var p = unsafeWindow.bossChallenges;
if (p && p.length > 0) {
options.bossChallenges = p;
options.set("bossChallenges");
}
}
function loadBossChallenges() {
var p = unsafeWindow.bossChallenges;
if (p && p.length > 0) {
options.bossChallenges = p;
options.set("bossChallenges");
}
}
$("#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);
}
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);
}