// ==UserScript==
// @name FastRecall
// @namespace FastRecallNamespace
// @author [TSN]Kanly
// @include *.ogame.gameforge.com/game/*
// @description FastRecall for Ogame: Allows you to recall fleets from the events list drop down bar
// @version 1.4
// @downloadURL none
// ==/UserScript==
var scriptFunc = (function() {
var Recall = {
getMovement: true,
getEvents: true,
pendingMovement: false,
pendingEvents: false,
availableMovements: [],
availableEvents: {},
currentPage: "",
universeFull: "",
missionType: {deploy:4, acsAttack:2, attack:1},
init: function() {
var observer = new MutationObserver(Recall.initAppendRecall);
var target = document.getElementById('eventboxContent');
Recall.universeFull = document.getElementsByName("ogame-universe")[0].content;
Recall.currentPage = (window.location+"").match(/page=[^&]+((?=&)|(?=#)|)/g)[0].replace("page=", "");
/* Disable FastRecall on fleet1/2/3 and movement pages */
if (Recall.currentPage !== "movement" &&
Recall.currentPage !== "fleet1" &&
Recall.currentPage !== "fleet2" &&
Recall.currentPage !== "fleet3") {
observer.observe(target, {childList: true});
/* If events are not hidden (Options->Display->Always show events */
if ($('table#eventContent').exists()) {
Recall.initAppendRecall();
}
}
},
initAppendRecall: function(mutations) {
if ($('table#eventContent').exists()) {
/* Get the "fleet movement" page information only once - when the fleets eventbox is showen for the first time */
if (Recall.getMovement === true && Recall.pendingMovement === false) {
Recall.pendingMovement = true;
Recall.getFleetMovement();
}
/* Get a clean eventlist content only once.
This is done because AGO or other tools might alter the original information (eg. change clocks values to local time)
*/
if (Recall.getEvents === true && Recall.pendingEvents === false) {
Recall.pendingEvents = true;
Recall.getEventsList();
}
if (Recall.getEvents === false && Recall.getMovement === false) {
Recall.doAppendRecall();
}
}
},
doAppendRecall: function() {
if ($('table#eventContent').exists()) {
Recall.appendEventlistReload();
$('table#eventContent tr[data-return-flight="false"]').each(function() {
var row = $(this);
var isAllianceAttack = row.hasClass('allianceAttack');
if (isAllianceAttack === false) {
var missionType = parseInt(row.attr('data-mission-type'));
var eventRowId;
if (missionType !== Recall.missionType.acsAttack)
eventRowId = parseInt(row.attr('id').match(/\d+/)[0]);
else
eventRowId = parseInt(row.find('td.icon_movement span.tooltip').attr('data-federation-user-id').match(/\d+/)[0]);
if (Recall.availableEvents[eventRowId]) {
var returnId = Recall.matchEventWithMovement(Recall.availableEvents[eventRowId]);
if (returnId !== "" && returnId !== "multipleMatch")
row.append('
| ');
}
}
});
$('.oaf_recall_icon').click(function(){
var recallId = $(this).attr('oaf_recall_id');
var url = 'http://'+Recall.universeFull+'/game/index.php?page=movement&return='+recallId;
$.get(url, function(response) {$('#eventHeader .icon_reload').click();});
});
}
},
appendEventlistReload: function() {
if (!window.AGO && $('#eventHeader .icon_reload.recall_eventlist_reload').exists() === false) {
$('#eventHeader').prepend('').click(function(){
$.get("/game/index.php?page=eventList&ajax=1", function (a) { $("#eventboxContent").html(a);});
});
}
},
getFleetMovement: function() {
/* Get the "fleet movement" page information; should be called only once */
var url = 'http://'+Recall.universeFull+'/game/index.php?page=movement';
$.get(url, Recall.parseFleetMovement);
},
parseFleetMovement: function(html) {
/* get own fleet flights except returning ones */
var page = $(html);
Recall.availableMovements = [];
page.find('.fleetDetails[data-return-flight="false"]').each(function() {
var item = $(this);
var info = {};
info.arrivalTime = item.attr('data-arrival-time');
info.originPosStr = item.find('.originCoords').text();
info.destinationPosStr = item.find('.destinationCoords').text();
info.returnId = item.attr('id').match(/\d+/g)[0];
info.missionType = parseInt(item.attr('data-mission-type'));
var retTime = item.find('span.nextabsTime');
if (retTime.exists())
info.retClock = retTime.text().trim();
else
info.retClock = "none";
/* console.log("New movement: " + JSON.stringify(info)); */
Recall.availableMovements.push(info);
});
Recall.pendingMovement = false;
Recall.getMovement = false;
/* On galaxy view: the miniFleetToken is invalidated after getting the fleetMovement page.
As a result, the first spy attempt will fail ('an error has occured'). We get a valid token
by sending an invalid spy request and using the newToken from the response.
*/
if (Recall.currentPage === "galaxy") {
var url = 'http://'+Recall.universeFull+'/game/index.php?page=minifleet&ajax=1';
var data = 'mission=6&token=none&speed=10';
$.post(url, data, function(resp){
try {
window.miniFleetToken = JSON.parse(resp).newToken;
} catch(e) {}
});
}
Recall.doAppendRecall();
},
getEventsList: function() {
/* get eventlist content; should be called only once */
$.get("/game/index.php?page=eventList&ajax=1", function (a) {
var item = $(''+a+'
');
Recall.availableEvents = {};
item.find('table#eventContent tr[data-return-flight="false"]').each(function() {
var row = $(this);
var isFriendly = row.find('.countDown.friendly').exists();
var isAllianceAttack = row.hasClass('allianceAttack');
if (isFriendly === true && isAllianceAttack === false) {
var info = {};
info.arrivalTime = row.attr('data-arrival-time');
info.originPosStr = row.find('.coordsOrigin').text().trim();
info.destinationPosStr = row.find('.destCoords').text().trim();
info.missionType = parseInt(row.attr('data-mission-type'));
var eventRowId;
if (info.missionType !== Recall.missionType.acsAttack) {
eventRowId = parseInt(row.attr('id').match(/\d+/)[0]);
}
else {
eventRowId = parseInt(row.find('td.icon_movement span.tooltip').attr('data-federation-user-id').match(/\d+/)[0]);
var unionName = row.attr('class').match(/union\d+/)[0];
/* console.log(unionName + " " + eventRowId + " " + item.find('tr.partnerInfo.' + unionName).length); */
if (unionName.indexOf("" + eventRowId) !== -1 && item.find('tr.partnerInfo.' + unionName).length === 1)
info.missionType = Recall.missionType.attack;
}
var retRow = item.find('#eventRow-'+(eventRowId+1)+'[data-return-flight="true"]');
if (retRow.exists()) {
var retTime = retRow.attr('data-arrival-time');
var origPosRet = retRow.find('.coordsOrigin').text().trim();
var destPosRet = retRow.find('.destCoords').text().trim();
if (origPosRet === info.originPosStr && destPosRet === info.destinationPosStr) {
info.retClock = retRow.find('td.arrivalTime').text().trim();
}
else {
info.retClock = "none";
}
}
else {
info.retClock = "none";
}
/* console.log("New event row: " + JSON.stringify(info)); */
Recall.availableEvents[eventRowId] = info;
}
});
$("#eventboxContent").html(a);
Recall.getEvents = false;
Recall.pendingEvents = false;
});
},
matchEventWithMovement: function(evInfo) {
var retVal = "";
for (var m in Recall.availableMovements) {
if (Recall.availableMovements.hasOwnProperty(m) === false)
continue;
var mvInfo = Recall.availableMovements[m];
if (mvInfo.arrivalTime === evInfo.arrivalTime &&
mvInfo.originPosStr === evInfo.originPosStr &&
mvInfo.destinationCoords === evInfo.destinationCoords &&
mvInfo.missionType === evInfo.missionType) {
if (mvInfo.missionType === Recall.missionType.deploy ||
(mvInfo.retClock === evInfo.retClock && mvInfo.retClock !== "none")) {
if (retVal === "")
retVal = mvInfo.returnId;
else
retVal = "multipleMatch";
}
}
}
return retVal;
}
};
$.fn.exists = function () {
return this.length !== 0;
};
Recall.init();
}).toString();
function injectScript (myFunc) {
var script = document.createElement ("script");
script.setAttribute ("type", "application/javascript");
script.textContent = "(" + myFunc + ") ();";
document.body.appendChild (script);
}
function injectCss() {
var recallImage = "data:image/gif;base64,R0lGODlhEAAQAKIAAISbrAAAAP///2+JnVx2iwAAAAAAAAAAACH5BAAAAAAALAAAAAAQABAAAAMqGLTcrS7KSautIut9mejLtwwkKZTliQ5Atg4qus1x2dbviud875eBHzABADs=";
var recallCss = '.oaf_recall_icon {background-image: url('+recallImage+'); background-repeat: no-repeat !important;} #eventHeader .recall_eventlist_reload {position: absolute; left: 14px; margin: 4px 0;}';
var eventlistReloadCss = '#eventHeader .recall_eventlist_reload {position: absolute; left: 14px; margin: 4px 0;}';
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = recallCss;
document.getElementsByTagName("head")[0].appendChild(style);
}
if (document.body) {
injectScript(scriptFunc);
injectCss();
}