Game of Thrones Ascent Extender
当前为
// ==UserScript==
// @name GOTA Extender
// @namespace gota_extender
// @description Game of Thrones Ascent Extender
// @include http://gota.disruptorbeam.com/*
// @include http://gota-www.disruptorbeam.com/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @version 1.8
// @grant unsafeWindow
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
this.$ = this.jQuery = jQuery.noConflict(true);
// Thanks to Nolana (https://greasyfork.org/scripts/1271-gota-improvements)
$(window).bind("load", function () {
setTimeout(function () {
initialize();
}, 2000);
});
// ------------------------------------------------------------------------------------------------------------------------------------> Configurable variables
var userAlert = GM_getValue('userAlert', true);
var debugAlert = GM_getValue('debugAlert', false);
var autoCollect = GM_getValue('autoCollect', true);
var queueDelay = GM_getValue('queueDelay', 4); // seconds
var autoCollectInterval = GM_getValue('autoCollectInterval', 60); // minutes
// <------------------------------------------------------------------------------------------------------------------------------------ End of configurable variables
function initialize() {
try {
// Replace buildTimerUpdate
injectConst(customBuildTimerUpdate);
// Toggle auto collect
toggleAutoCollect();
// Reload window on 22h
setInterval(function () {
claimDaily();
window.location.reload(true);
}, 22 * 60 * 60 * 1000);
if (debugAlert) {
alert('Initialized.');
}
} catch (err) {
if (debugAlert) {
alert(err);
}
}
}
function injectConst(constant) {
var script = document.createElement('script');
script.type = "text/javascript";
script.innerHTML = constant;
document.head.appendChild(script);
}
var autoCollectLoop;
function toggleAutoCollect() {
if (autoCollect) {
autoCollectLoop = setInterval(collectTax, autoCollectInterval * 60 * 1000);
} else {
autoCollectLoop = clearInterval(autoCollectLoop);
}
}
// ------------------------------------------------------------------------------------------------------------------------------------> Constants (generated)
var customBuildTimerUpdate = '\
buildTimerUpdate = function(c, a, b) {\
$("#timer-" + c).html(renderBuildTime(a));\
$("#timer-panel-" + c).html(renderBuildTime(a));\
\
percent = 100 - 100 * (a / b);\
$("#progress-" + c).html(\'<span style="width:\' + percent + \'%;"></span>\');\
\
var d = buildingById(c);\
d.build_remaining = a;\
markup = renderBuildPanelAction(d);\
\
$("#speed_button_" + c).show();\
$("#build_panel_action_" + c).html(markup);\
$("#production_timer_" + c).html(renderBuildTime(d.build_remaining, true));\
$("#production_timer_upper_" +\
c).html(renderBuildTime(d.build_remaining));\
$("#production_progress_" + c).css({ width: percent + "%" });\
$("#duration_long_" + c).html(durationLong(buildTimerDescription(d), a, b));\
a--;\
userContext.doBuildId == c && (300 >= a ?\
($("#speed_up_skip_block").hide(),\
$("#speed_up_skip_use").show()) :\
($("#speed_up_skip_use").hide(),\
$("#speed_up_skip_block").show()),\
$(".speed_building_" + c).html() != renderSpeedUpButton(c) && $(".speed_building_" + c).html(renderSpeedUpButton(c)));\
\
d.cooldown = a;\
d.original_cooldown_seconds = b;\
displayBuildingCooldown(d);\
0 < a || (closeSpeedUp(), finalizeBuildingConstruction(d), clearBuildingTimer(d.symbol));\
\
if(a < 300){\
doInstantSpeedUp(c);\
var building = buildingById(c);\
doFinishProduction(building.item_id);\
setTimeout(function(){\
closeModalLarge(building.symbol);\
console.log("EXTENDER :: Injected buildTimerUpdate tries to close modal dialog.");\
}, 2000);\
}\
};\
doLog = function(a, b, c){ };';
var extenderButton = '<a id="extender-menu" class="navlink" data-menu="manager">\
<span class="navlinkbox">\
<span class="navlinkicon"></span>\
<span class="vertcenter">\
<span>Extender</span>\
</span>\
</span>\
</a>';
var extenderButtonStyle = '<style>\
#extender-menu .navlinkicon { \
background-image: url("http://disruptorbeamcdn-01.insnw.net/images/icons/newnav-menu.png?t=386c1688da2a"); \
}</style>';
var extenderQueueButton = '<span class="btnwrap btnmed equipbtn queue"><span class="btnedge"><a class="btngold">Queue</a></span></span>';
var saveOptionsButton = '<span id="saveOptions" class="btnwrap btnlg"><span class="btnedge"><a class="btngold">Save</a></span></span>';
var saveOptionsButtonStyle = '<style>\
#saveOptions {\
bottom: 15px;\
left: 34%;\
margin-left: -40px;\
padding: 0;\
position: absolute;\
width: 80px;\
}</style>';
var resetOptionsButton = '<span id="resetOptions" class="btnwrap btnlg"><span class="btnedge"><a class="btngold">Reset</a></span></span>';
var resetOptionsButtonStyle = '<style>\
#resetOptions {\
bottom: 15px;\
left: 66%;\
margin-left: -40px;\
padding: 0;\
position: absolute;\
width: 80px;\
}</style>';
// ------------------------------------------------------------------------------------------------------------------------------------> Mutation observers and associated logic
// Observes DOM object mutations
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
// Observers construction
var mainToolbarObserver = new MutationObserver(main_toolbar_buttons_changed);
var modalsObserver = new MutationObserver(modal_dialog_changed);
var productionObserver = new MutationObserver(production_statview_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
});
modalsObserver.observe(document.getElementById("modal_dialogs_top"), {
childList: true,
});
// Event handlers; FIRED by observed mutations
function modal_dialog_changed(mutations, target){
if(debugAlert){
console.log('EXTENDER :: Modal dialogs tree changed.');
}
productionObserver.observe(document.getElementById("production_statview"), {
childList: true,
});
}
function main_toolbar_buttons_changed(mutations, target) {
if(debugAlert){
console.log('EXTENDER :: Mutation on main toolbar buttons.');
console.log(mutations);
}
var extender = $("#extender-menu");
if (extender.length == 0) {
$("#navmenubox").append(extenderButton);
$("#navmenubox").append(extenderButtonStyle);
$("#extender-menu").on('click', extenderButton_clicked);
}
// Attempt production here
executeProductionElement();
}
function executeProductionElement(){
if(!productionQueue || productionQueue.length == 0){
return;
}
var busyBuildings = [];
for(var i = 0; i < productionQueue.length; i++){
var element = productionQueue[i];
// Building found in busy buildings array
if(busyBuildings.indexOf(element.building.symbol) > -1){
continue;
}
// If produce successful, add building to busy array
if(produce(element)){
busyBuildings.push(element.building.symbol);
};
}
}
function production_statview_changed(){
if(debugAlert) {
alert('Production view constructed!');
}
var btn = '<span class="btnwrap btnmed equipbtn queue" data-quantity="1"><span class="btnedge"><a class="btngold">Queue</a></span></span>';
var btnx5 = '<span class="btnwrap btnmed equipbtn queue" data-quantity="5"><span class="btnedge"><a class="btngold">Queue x5</a></span></span>';
$(".statviewbtm").prepend(btnx5);
$(".statviewbtm").prepend(btn);
// Attach event handler
$("span.btnwrap.btnmed.equipbtn.queue").on('click', queue_clicked);
}
// Keeps queued elements
var productionQueue = [];
function queue_clicked(){
try {
// Extract and construct eye-candy stuff
var divUrl = $("div.statviewimg img").attr('src');
var statViewName = $(".statviewname h3").text();
var queueId = 'productionQueueElement_' + productionQueue.length;
var elementStyle = 'background-image: url("' + divUrl + '"); background-position: 0 center !important; background-size: 100% auto !important;';
var elementHtml = '<a class="navlink active" id="' + queueId + '">\
<span class="navlinkbox">\
<span class="navlinkicon"></span>\
<span class="vertcenter">\
<span>' + statViewName + '</span>\
</span>\
</span>\
</a>';
// Extract variables needed
var building;
var recipeName;
var sourceEl = unsafeWindow.userContext.productionItemsClick[unsafeWindow.userContext.currentProductionItem];
for (var i = 0; i < unsafeWindow.userContext.recipeData.length; i++) {
if (unsafeWindow.userContext.recipeData[i].output == sourceEl.outputSymbol) {
recipeName = unsafeWindow.userContext.recipeData[i].symbol;
break;
}
}
for (var i = 0; i < unsafeWindow.userContext.buildingsData.length; i++) {
var currentBuilding = unsafeWindow.userContext.buildingsData[i];
if (currentBuilding.symbol == unsafeWindow.userContext.activeBuildingPanel) {
building = currentBuilding;
break;
}
}
// Construct production element
var productionEl = {
id: queueId,
name: statViewName,
HTML: elementHtml,
css: elementStyle,
source: sourceEl,
building: building,
recipeName: recipeName,
recipeData: unsafeWindow.userContext.recipeData,
};
var quantity = $(this).attr("data-quantity");
if (debugAlert) {
console.log("EXTENDER :: Queued " + quantity + " " + productionEl.name);
}
do {
// Insert the element into the queueArray
productionQueue.push(productionEl);
quantity--;
} while (quantity > 0)
// var autoQueueBtn = $("#auto-queue");
// if(!autoQueueBtn || autoQueueBtn.length == 0){
// constructPanel();
// }
//
// $(autoQueueBtn).after(productionEl.HTML);
// $("#" + productionEl.id + " span.navlinkicon").attr('style', productionEl.css);
var productionBuilding = unsafeWindow.buildingBySymbol(productionEl.building.symbol);
if (productionBuilding.build_remaining && productionBuilding.build_remaining > 0) {
if (userAlert) {
alert('Enqueued.');
}
} else {
unsafeWindow.doProduction(productionEl.source.outputSymbol, productionEl.source.recipeCategory, null, null, productionEl.recipeName);
}
} catch (err) {
if (debugAlert) {
alert(err);
}
}
}
function produce(element){
// Check if the building is producing
var productionBuilding = unsafeWindow.buildingBySymbol(element.building.symbol);
if(productionBuilding.build_remaining && productionBuilding.build_remaining > 0){
if(debugAlert){
console.log('EXTENDER :: Attempted production for building ' + element.building.symbol + ', but building was busy.');
}
return false;
}
if(debugAlert){
console.log('EXTENDER :: Productiion of '+ element.name +
' id: '+ element.id +
' building: '+ element.building.symbol +
' recipe: '+ element.recipeName);
}
// Load data needed for production
unsafeWindow.userContext.recipeData = element.recipeData;
unsafeWindow.userContext.activeBuildingPanel = element.building.symbol;
// Attempt production
setTimeout(function () {
try {
if (debugAlert) {
console.log("EXTENDER :: Do production, do production!!!!! Now: " + element.name);
}
unsafeWindow.doProduction(element.source.outputSymbol, element.source.recipeCategory, null, null, element.recipeName);
} catch (err) {
if (debugAlert) {
alert(err);
}
}
}, queueDelay * 1000);
// Remove element from the production array
var elementPosition = productionQueue.indexOf(element);
if(elementPosition > -1){
productionQueue.splice(elementPosition, 1);
}else{
if(debugAlert){
alert('Element missing from production queue!');
}
return false;
}
if (debugAlert) {
console.log("EXTENDER :: Production finished. Element popped. Exiting...");
}
return true;
}
function collectTax(){
if(debugAlert){
alert('Collect attempt.');
}
// Can't use doCollect because of some stupid offset
// in the animation. needs to have the activePanel set
unsafeWindow.clickBuildingUpgradePanel('counting_house');
unsafeWindow.$("#collectbtn").click();
setTimeout(function() {
unsafeWindow.closeModalLarge('modal_dialogs_top');
if (debugAlert) {
console.log("EXTENDER :: Attempt to close the modal dialog.");
}
}, 2000);
}
function setGMValues() {
GM_setValue("userAlert", userAlert);
GM_setValue("debugAlert", debugAlert);
GM_setValue("autoCollect", autoCollect);
GM_setValue("autoCollectInterval", autoCollectInterval);
}
function showSettings() {
// Fill in data...
var extenderHtml =
'<h1 style="font-family:GoudyTrajan-Bold,Trajan,\'Trajan Pro\',Trajanbold;">Extender options</h1><hr />'+
'<a style="color:white;padding-right:4px;padding-left:32px!important;" href="#" id="toggleUserAlerts" class="extender-option checkbox ' + (userAlert ? 'checked' : '') + '">Show user alerts</a>'+
'<a style="color:white;padding-right:4px;padding-left:32px!important;" href="#" id="toggleDebugAlerts" class="extender-option checkbox ' + (debugAlert ? 'checked' : '') + '">Show debug alerts</a>'+
'<a style="color:white;padding-right:4px;padding-left:32px!important;" href="#" id="toggleAutoCollect" class="extender-option checkbox ' + (autoCollect ? 'checked' : '') + '">Enable auto-collecting</a>' +
'<br />' +
'<label for="autoCollectInteval">Auto collect in (minutes): </label>' +
'<input type="number" maxlength="3" style="width:38px" id="autoCollectInterval" value="' + autoCollectInterval + '">' +
'<div class="tablewrap">' +
'<table id="queueTable" class="powertable">' +
'<tbody>' +
'<tr id="headerRow">' +
'<th id="col1"><span class="colsort">Building</span></th>' +
'<th id="col2"><span class="colsort">Name</span></th>' +
'<th id="col3"><span class="colsort">Icon</span></th>' +
'<th id="col4"><span class="colsort">QueueID</span></th>' +
'</tr>' +
'</tbody>' +
'</table>' +
'</div>'
;
$("#credits_page").html(extenderHtml);
renderProductionItems();
if ($("#saveOptions").length == 0) {
$("#creditsclose").before(saveOptionsButton);
$("#creditsclose").before(saveOptionsButtonStyle);
$("#saveOptions").on('click', saveOptions_click);
}
$("#creditsclose").attr('onclick', '(function(){ $("#credits_roll").hide(); })()');
if ($("#resetOptions").length == 0) {
$("#creditsclose").after(resetOptionsButton);
$("#creditsclose").after(resetOptionsButtonStyle);
$("#resetOptions").on('click', resetOptions_click);
}
$("#credits_roll").show();
//$("#modalbg_dark").show();
}
function extenderButton_clicked(e) {
e.preventDefault();
if (debugAlert) {
alert('Extender menu access.');
}
showSettings();
}
function saveOptions_click(e) {
e.preventDefault();
userAlert = $("#toggleUserAlerts").hasClass("checked");
debugAlert = $("#toggleDebugAlerts").hasClass("checked");
autoCollect = $("#toggleAutoCollect").hasClass("checked");
var newInterval = parseInt($("#autoCollectInterval").val());
if (autoCollectInterval != newInterval) {
autoCollectInterval = newInterval;
autoCollectLoop = null;
toggleAutoCollect();
}
setGMValues();
$("#credits_roll").hide();
if (userAlert) {
alert('Settings saved.');
}
}
function resetOptions_click(e) {
e.preventDefault();
userAlert = true;
debugAlert = false;
autoCollect = true;
autoCollectInterval = 60;
autoCollectLoop = null;
toggleAutoCollect();
setGMValues();
$("#credits_roll").hide();
if (userAlert) {
alert('Options reset.');
}
}
$("#credits_roll").on('click', '.extender-option.checkbox', function (e) {
e.preventDefault();
if (debugAlert) {
alert('Option changed.');
}
$(this).toggleClass('checked');
});
function renderProductionItems() {
for (var i = 0; i < productionQueue.length; i++) {
var pEl = productionQueue[i];
var tableRow = '<tr class="" style="cursor: pointer" onclick="alert(\'Implement me!\');">'+
'<td><span class="name colsort">' + pEl.building.symbol + '</span></td>' +
'<td><span class="name colsort">' + pEl.name + '</span></td>' +
'<td><span class="avatarimg" id="'+ pEl.id +'"></span></td>' +
'<td><span class="ranklist colsort">' + i + '</span></td>' +
'</tr>';
$("#headerRow").after(tableRow);
$("#" + pEl.id).attr("style", pEl.css);
}
}