// ==UserScript==
// @name KOCAttack - Extra Features!
// @version 0.9.7.4
// @namespace KOCAttack-Extra
// @homepage http://userscripts.org/scripts/show/89473
// @description Same as the original Kingdoms of Camelot Attack script, but with extra features.
// @include *apps.facebook.com/kingdomsofcamelot*
// @include *kingdomsofcamelot.com/*main_src.php*
// @include *kingdomsofcamelot.com/*newgame_src.php*
// @include *facebook.com/connect/uiserver.php*
// @include *kingdomsofcamelot.com/*standAlone.php*
// ==/UserScript==
var KOCAversion = '0.9.7.4';
// Override the default alert functionality of the web browser (which causes the script to pause)
// Instead of displaying alert popups, messages will be displayed in the firefox console
unsafeWindow.alert = function(message) {
console.info("Javascript Alert: "+message);
if(typeof(GM_log)=="function"){
GM_log("Javascript Alert: "+message);
}
}
alert = unsafeWindow.alert;
// String prototypes
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }
String.prototype.StripQuotes = function() {
return this.replace(/"/g,'');
};
// Quick is_int function for javascript
function is_int(value){
if((parseFloat(value) == parseInt(value)) && !isNaN(value)){
return true;
} else {
return false;
}
}
/*
// Array remove function (found at http://ejohn.org/blog/javascript-array-remove/)
Examples:
Remove the second item from the array:
ArrayRemoveItem(array, 1);
Remove the second-to-last item from the array:
ArrayRemoveItem(array, -2);
Remove the second and third items from the array:
ArrayRemoveItem(array, 1,2);
Remove the last and second-to-last items from the array:
ArrayRemoveItem(array, -2,-1);
*/
ArrayRemoveItem = function(array, from, to) {
var rest = array.slice((to || from) + 1 || array.length);
array.length = from < 0 ? array.length + from : from;
return array.push.apply(array, rest);
};
if(!this.JSON2){JSON2={};}
(function(){function f(n){return n<10?'0'+n:n;}
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z';};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
if(typeof rep==='function'){value=rep.call(holder,key,value);}
switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
v=partial.length===0?'[]':gap?'[\n'+gap+
partial.join(',\n'+gap)+'\n'+
mind+']':'['+partial.join(',')+']';gap=mind;return v;}
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+
mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
if(typeof JSON2.stringify!=='function'){JSON2.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
return str('',{'':value});};}
if(typeof JSON2.parse!=='function'){JSON2.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
return reviver.call(holder,key,value);}
cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
throw new SyntaxError('JSON.parse');};}})();
if(!this.GM_log) {
GM_log=function(m) {
console.log(m);
}
GM_registerMenuCommand=function(text,f) {
}
}
if(!this.unsafeWindow) {
//~~~ need helper to return values?
unsafeWindow={};
}
function inspect(obj, maxLevels, level){
var str = '', type, msg;
// Start Input Validations
// Don't touch, we start iterating at level zero
if(level == null) level = 0;
// At least you want to show the first level
if(maxLevels == null) maxLevels = 1;
if(maxLevels < 1)
return '<font color="red">Error: Levels number must be > 0</font>';
// We start with a non null object
if(obj == null)
return '<font color="red">Error: Object <b>NULL</b></font>';
// End Input Validations
// Each Iteration must be indented
str += '<ul>';
// Start iterations for all objects in obj
for(property in obj)
{
try
{
// Show "property" and "type property"
type = typeof(obj[property]);
str += '<li>(' + type + ') ' + property +
( (obj[property]==null)?(': <b>null</b>'):(': '+obj[property])) + '</li>';
// We keep iterating if this property is an Object, non null
// and we are inside the required number of levels
if((type == 'object') && (obj[property] != null) && (level+1 < maxLevels))
str += inspect(obj[property], maxLevels, level+1);
}
catch(err)
{
// Is there some properties in obj we can't access? Print it red.
if(typeof(err) == 'string') msg = err;
else if(err.message) msg = err.message;
else if(err.description) msg = err.description;
else msg = 'Unknown';
str += '<li><font color="red">(Error) ' + property + ': ' + msg +'</font></li>';
}
}
// Close indent
str += '</ul>';
return str;
}
function MinDigits(num,digits) {
while((""+num).length<digits) {
num="0"+num;
}
return num;
};
function SecsToStr(secs) {
secs=Math.floor(secs);
return Math.floor(secs/60/60/24%60)+
":"+MinDigits(Math.floor(secs/60/60%60),2)+
":"+MinDigits(Math.floor(secs/60%60),2);
// ":"+MinDigits(Math.floor(secs%60),2);
};
var nHtml={
FindByXPath:function(obj,xpath,nodetype) {
if(!nodetype){
nodetype = XPathResult.FIRST_ORDERED_NODE_TYPE;
}
try {
var q=document.evaluate(xpath,obj,null,nodetype,null);
} catch(e) {
GM_log('bad xpath:'+xpath);
}
if(nodetype == XPathResult.FIRST_ORDERED_NODE_TYPE){
if(q && q.singleNodeValue) { return q.singleNodeValue; }
}else{
if(q){
return q;
}
}
return null;
},
ClickWin:function(win,obj,evtName) {
var evt = win.document.createEvent("MouseEvents");
evt.initMouseEvent(evtName, true, true, win,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
return !obj.dispatchEvent(evt);
},
Click:function(obj) {
return this.ClickWin(window,obj,'click');
},
ClickTimeout:function(obj,millisec) {
window.setTimeout(function() {
return nHtml.ClickWin(window,obj,'click');
},millisec+Math.floor(Math.random()*500));
},
SetSelect:function(obj,v) {
for(var o=0; o<obj.options.length; o++) {
if(v==obj.options[o].value) { obj.options[o].selected=true; return true; }
}
return false;
}
};
function ById(id) {
return document.getElementById(id);
}
function ByName(name) {
return document.getElementsByName(name);
}
function AddText(box1,txt) {
var txtObj;
box1.appendChild(txtObj=document.createTextNode(txt));
return txtObj;
}
function AddHtml(box1,txt) {
var txtObj;
var sp=document.createElement('span');
sp.innerHTML=txt;
box1.appendChild(sp);
return txtObj;
}
function getAttackTypeSelected (){
if (document.getElementById('modal_attack_tab_4').className == 'selected') // attack
return 0;
if (document.getElementById('modal_attack_tab_1').className == 'selected') // transport
return 1;
if (document.getElementById('modal_attack_tab_3').className == 'selected') // scout
return 2;
if (document.getElementById('modal_attack_tab_2').className == 'selected') // reinforce
return 3;
if (document.getElementById('modal_attack_tab_5').className == 'selected') // reassign
return 4;
return null;
}
var KOCAttack={
startListenTime:null,
prevAttack:{'x':"350",'y':'350'},
options:null,
iframeCommunicator:{},
isChrome:navigator.userAgent.toLowerCase().indexOf('chrome') > -1,
valuesCache:{},
seed:{},
currentPage:null,
DoUnsafeWindow:function(func, execute_by_embed) {
if(this.isChrome || execute_by_embed) {
var scr=document.createElement('script');
scr.innerHTML=func;
document.body.appendChild(scr);
} else {
try {
eval("unsafeWindow."+func);
} catch (error) {
this.Log("A javascript error has occurred when executing a function via DoUnsafeWindow. Error description: "+error.description);
}
}
},
GetSeed:function() {
return unsafeWindow.seed;
},
ShowImportExportBox:function() {
var div=ById('ImportExportBoxDiv');
if(!div) {
div=document.createElement('div');
div.id='KOCAttackViewAttacks';
div.style.zIndex=100000;
div.style.position='absolute';
div.style.left='8px';
div.style.top='8px';
div.style.backgroundColor='#fff';
div.style.border='3px solid #888';
div.style.padding='10px';
document.body.appendChild(div);
}
div.innerHTML = '';
var m = '<a id="ImportBoxCancel" class="button20"><span>Close</span></a>';
m += '<a id="ImportData" class="button20"><span>Import</span></a>';
m += '<a id="ExportData" class="button20"><span>Export</span></a> ';
var cities=this.GetSeed().cities;
//WinLog.write(inspect(cities));
var citysel ='<select id=srcCity>';
//citysel += '<option value=All>All Cities</option>';
for(var c=0; c<cities.length; c++) {
citysel += '<option value="'+cities[c][0]+'">'+cities[c][1]+'</option>';
}
citysel += '<option value=options>Options</option>';
citysel += '</select>';
m += citysel;
m += '<br><textarea id="ImportExportArea" rows=25 cols=60></textarea>';
div.innerHTML = m;
ById('ImportBoxCancel').addEventListener('click',function() {
div.innerHTML = '';
div.style.display='none';
},false);
ById('ImportData').addEventListener('click',function() {
},false);
ById('ExportData').addEventListener('click',function() {
var x;
var names=KOCAttack.browser_listValues();
var obj={};
var serverId=KOCAttack.GetServerId();
for(var n=0; n<names.length; n++) {
var name=names[n];
var a = name.substring(0,11);
var b = 'attack_'+serverId+'_';
if (a==b ) {
var sid=KOCAttack.GetServerIdFromName(name);
if(sid!=serverId) continue;
var v=KOCAttack.browser_getValue(name,null);
if(v!=null && v!=undefined && v!=""){
x = JSON2.parse(v);
if (x.fromCity == ById('srcCity').value) {
obj[name]=v;
}
}
}
else if (ById('srcCity').value == 'options') {
var sid=KOCAttack.GetServerIdFromName(name);
if(sid!=serverId) continue;
var v=KOCAttack.browser_getValue(name,null);
if(v!=null && v!=undefined && v!=""){
obj[name]=v;
}
}
}
ById('ImportExportArea').value = JSON2.stringify(obj);
},false);
},
ShowViewAttacksDialog:function() {
var t=this;
t.attacks=[];
var div=ById('KOCAttackViewAttacks');
if(!div) {
div=document.createElement('div');
div.id='KOCAttackViewAttacks';
div.style.zIndex=100000;
div.style.position='absolute';
div.style.left='8px';
div.style.top='8px';
div.style.backgroundColor='#fff';
div.style.border='3px solid #888';
div.style.padding='10px';
document.body.appendChild(div);
}
var cities=this.GetSeed().cities;
//WinLog.write(inspect(cities));
var citysel ='<select id=srcCity>';
citysel += '<option value=All>All Cities</option>';
for(var c=0; c<cities.length; c++) {
citysel += '<option value="'+cities[c][1]+'">'+cities[c][1]+'</option>';
}
citysel += '</select>';
var levelsel ='<select id=srcLevel>';
levelsel += '<option value="All">All Levels</option>';
for(var c=1; c<=11; c++) {
levelsel += '<option value="'+c+'">Level '+c+'</option>';
}
levelsel += '</select>';
var typesel ='<select id=srcAttackType>';
typesel += '<option value="All">All</option>';
typesel += '<option value="normal">Attacks</option>';
typesel += '<option value="transport">Transports</option>';
typesel += '<option value="bulkadded">Bulk Adds</option>';
typesel += '</select>';
div.style.display='block';
div.innerHTML='';
var m = '<DIV id="srcAttackOpts" style="height:30px">\
<TABLE><TR valign=bottom><TD class=xtab width=100 align=center>Search for: </td><TD align=left>\
<SELECT id=srcAttack>\
<OPTION value=All>All</option>\
<OPTION value=Camp>Barb Camp</option>\
<OPTION value=Wilderness>Wilderness</option>\
<OPTION value=Grassland>Grassland</option>\
<OPTION value=Lake>Lake</option>\
<OPTION value=Mountains>Mountains</option>\
<OPTION value=Forest>Woods</option>\
<OPTION value=Hills>Hills</option>\
<OPTION value=Plain>Plains</option>\
<OPTION value=City>City</option>\
<OPTION value=Transport>Transport</option>\
<OPTION value=Unknown>Unknown</option>\
</select></td>\
<td class=xtab width=100 align=center>Select City: </td>\
<td align=left><span id=ptattackcity></span></td>\
<td class=xtab width=100 align=center>Select Level: </td>\
<td align=left><span id=ptattacklevel></span></td>\
<td class=xtab width=100 align=center>Select Type: </td>\
<td align=left><span id=ptattacktype></span></td></tr>\
</table></div>\
<a id="KOCAttackViewAttacksCancel" class="button20"><span>Close</span></a>\
<a id="KOCAttackViewAttacksList" class="button20"><span>List Attacks</span></a>\
<a id="KOCAttackViewAttacksClearList" class="button20"><span>Clear List</span></a>\
<a id="KOCAttackViewAttacksDelete" class="button20"><span>Delete Selected</span></a>\
<br><br><DIV id="srcAttackResults" style="height:470px; max-height:470px; overflow-y:auto;"></div>\
';
//<a id="KOCAttackViewAttacksImportExport" class="button20"><span>Import / Export</span></a>\
var srcAttackResults = ById("srcAttackResults");
if (srcAttackResults != null){
ById('KOCAttackViewAttacksClearList').click();
}
div.innerHTML = m;
ById('ptattackcity').innerHTML = citysel;
ById('ptattacklevel').innerHTML = levelsel;
ById('ptattacktype').innerHTML = typesel;
ById('KOCAttackViewAttacksClearList').addEventListener('click',function() {
ById('srcAttackResults').innerHTML='';
},false);
ById('KOCAttackViewAttacksCancel').addEventListener('click',function() {
div.style.display='none';
},false);
//ById('KOCAttackViewAttacksImportExport').addEventListener('click',function() {
// t.ShowImportExportBox();
//},false);
ById('KOCAttackViewAttacksList').addEventListener('click',function() {
t.attacks=[];
t.DetailAttacks();
//WinLog.write(inspect(t.attacks,10));
var typeQuery = ById('srcAttackType').value;
var cityQuery = ById('srcCity').value;
var levelQuery = ById('srcLevel').value;
var attackQuery = ById('srcAttack').value;
var h = '<table>';
h += '<tr><td><input type=checkbox id=selAllAttacks></td><td> </td><td>City</td><td>Coords</td><td nowrap>What</td>';
h += '<td>Type</td><td>Attack Troops</td><td>Suicide Troops/Resources</td><td>Dist</td><td>Time</td><td>Ignore</td></tr>';
var tableRows= '';
var count = 1
for(var a=0; a<t.attacks.length; a++) {
var levelInfo=t.GetLevelInfo(t.attacks[a]);
if (levelInfo==undefined) levelInfo='';
var type;
if (levelInfo.type){
type = levelInfo.type;
} else {
type = 'Unknown';
}
var displayRow = '';
if (cityQuery != 'All'){
if (t.GetCityName(t.attacks[a]['fromCity']) != cityQuery){
continue;
}
}
if (levelQuery != 'All'){
if (levelInfo.level != levelQuery){
continue;
}
}
if (typeQuery != 'All'){
if (t.attacks[a].currenttattackwavetype != typeQuery){
continue;
}
}
if (attackQuery != 'All'){
if (type != attackQuery){
continue;
}
}
tableRows += '<tr id=row'+count+' style="display: '+displayRow+';">';
tableRows += '<td><input type=checkbox id=aasel'+count+'>';
tableRows += '<td>'+count+'</td><td>'+t.GetCityName(t.attacks[a]['fromCity'])+'</td>';
tableRows += '<td id=aacoords'+count+' onclick="aaGotoMapHide('+t.attacks[a].xy[0]+','+t.attacks[a].xy[1]+')">'+t.attacks[a].xy[0]+','+t.attacks[a].xy[1]+'</td>';
tableRows += '<td nowrap>'+type+' Level '+levelInfo.level+'</td>';
tableRows += '<td>'+t.attacks[a].currenttattackwavetype+'</td>';
tableRows += '<td>';
if(typeof(t.attacks[a].troops)=="object") {
var troops='';
for(var i=1; i<t.attacks[a].troops.length; i++) {
troops += t.attacks[a].troops[i]+',';
}
troops = troops.substring(0, troops.length - 1);
tableRows += troops;
}
else{
tableRows += ' ';
}
tableRows += '</td>';
tableRows += '<td>';
if(typeof(t.attacks[a].suicidewave)=="object") {
var suicide='';
for(var i=1; i<t.attacks[a].suicidewave.length; i++) {
suicide += t.attacks[a].suicidewave[i]+',';
}
suicide = suicide.substring(0, suicide.length - 1);
tableRows += suicide;
}
else if (typeof(t.attacks[a].resources)=="object"){
var resources='';
for(var i=1; i<t.attacks[a].resources.length; i++) {
resources += t.attacks[a].resources[i]+',';
}
resources = resources.substring(0, resources.length - 1);
tableRows += resources;
}
else {
tableRows += ' ';
}
tableRows += '</td>';
var distance=t.CalcXYDist({'x':t.attacks[a].xy[0],'y':t.attacks[a].xy[0]},{'x':t.GetCityCoordsX(t.attacks[a]['fromCity']),'y':t.GetCityCoordsX(t.attacks[a]['fromCity'])});
tableRows += '<td>'+parseInt(distance)+'</td>';
var nowSecs=new Date().getTime()/1000;
tableRows += '<td>'+SecsToStr(nowSecs-t.attacks[a].time)+'</td>';
var ignChecked = '';
if (t.attacks[a].ignore == null || t.attacks[a].ignore==undefined){
ignChecked = '';
}else{
ignChecked = 'CHECKED';
}
tableRows += '<td><input type=checkbox name=chkIgnore id='+count+' '+ignChecked+'></td>';
tableRows += '</tr>';
count++;
}
h += tableRows + '</table>';
ById('srcAttackResults').innerHTML = h;
ById('KOCAttackViewAttacksDelete').addEventListener('click',function() {
var deletes = 0;
for (var i=1; i<count; i++){
var row = 'aasel'+i;
if (ById(row) == undefined) continue;
if (ById(row).checked == true){
//ById(row).checked == false;
var c = ById('aacoords'+i).innerHTML;
var xy = c.split(",");
GM_log('Coords '+xy[0]+' '+xy[1]);
t.DeleteAttack(xy[0],xy[1]);
deletes++;
}
}
window.alert(deletes+' of coords deleted');
// var listBtn=ById('KOCAttackViewAttacksList');
// nHtml.Click(listBtn);
},false);
for (var i=1; i<count; i++){
var ignore = i;
t.addEvent(ById(ignore), "click", t.ChangeIgnore);
}
ById('selAllAttacks').addEventListener('click',function() {
var myChecked = true;
if (ById('selAllAttacks').checked == false){
myChecked = false;
}
for (var i=1; i<count; i++){
var row = 'aasel'+i;
ById(row).checked=myChecked;
}
},false);
},false);
},
addEvent:function(obj, type, fn){
if (obj.attachEvent) {
obj['e' + type + fn] = fn;
obj[type + fn] = function(){obj['e' + type + fn](window.event);}
obj.attachEvent('on' + type, obj[type + fn]);
}
else{
obj.addEventListener(type, fn, false);
}
},
ChangeIgnore:function(e){
var c = ById('aacoords'+e.target.id).innerHTML;
var xy = c.split(",");
var serverID = KOCAttack.GetServerId();
var attackname = 'attack_'+serverID+'_'+xy[0]+','+xy[1];
var str = GM_getValue(attackname,'')
if(!str) return null;
attack= JSON2.parse(str);
attack.ignore=e.target.checked?true:undefined;
//WinLog.write (inspect(attack,10));
GM_setValue(attackname,JSON2.stringify(attack));
},
GetAttack:function(x,y) {
var str=this.browser_getValue(this.GetAttackName(x,y),'');
if(!str) return null;
return JSON2.parse(str);
},
GetCityName:function(cityid) {
var cityName;
for(var a=0; a<unsafeWindow.seed.cities.length; a++) {
if(unsafeWindow.seed.cities[a][0] == cityid){
var cityName = unsafeWindow.seed.cities[a][1];
}
}
return cityName;
},
GetCityCoordsX:function(cityid) {
var cityName;
for(var a=0; a<unsafeWindow.seed.cities.length; a++) {
if(unsafeWindow.seed.cities[a][0] == cityid){
var x = unsafeWindow.seed.cities[a][2];
}
}
return x;
},
GetCityCoordsY:function(cityid) {
var cityName;
for(var a=0; a<unsafeWindow.seed.cities.length; a++) {
if(unsafeWindow.seed.cities[a][0] == cityid){
var y = unsafeWindow.seed.cities[a][3];
}
}
return y;
},
ReloadWindow:function() {
var m=/^[a-zA-Z]+([0-9]+)\./.exec(document.location.hostname);
if (!m){
//window.location.reload(true);
history.go(0);
return;
}
var goto = window.location.protocol+'//apps.facebook.com/kingdomsofcamelot/?s='+m[1];
var t = '<FORM target="_top" action="'+ goto +'" method=post><INPUT id=xxButReload type=submit value=RELOAD><input type=hidden name=s value="'+ m[1] +'"</form>';
var e = document.createElement ('div');
e.innerHTML = t;
document.body.appendChild (e);
setTimeout (function (){document.getElementById('xxButReload').click();}, 0);
},
ShowOptionsDialog:function() {
var div=ById('KOCAttackOptions');
if(!div) {
div=document.createElement('div');
div.id='KOCAttackOptions';
div.style.zIndex=100000;
div.style.position='absolute';
div.style.left='8px';
div.style.top='8px';
div.style.backgroundColor='#fff';
div.style.border='3px solid #888';
div.style.padding='10px';
div.style.maxWidth='700px';
document.body.appendChild(div);
}
var okCitiesHtml="<span onmousedown='return false; '>";
for(var c=1; c<=8; c++) {
okCitiesHtml+=
"<a style='font-size: 11px; padding: 2px; cursor: pointer; text-decoration: none' id='KOCAttackOkCities_"+c+"'>"+c+"</a> ";
}
okCitiesHtml+='</span>';
var attackfirst = '';
var arrData = [["Camp", "Camps"],["City", "City"],["Transport", "Transport"],["Wilderness", "Wildernesses"],["None", "None"]];
for (var i=0; i < arrData.length; i++){
attackfirst += "<input type=radio name=KOCAttackPriority id='KOCAttackPriority_"+arrData[i][0]+"' value="+arrData[i][0]+" "+(arrData[i][0]==this.options.attackpriority?'checked':'')+"/>";
attackfirst += "<label for='KOCAttackPriority_"+arrData[i][0]+"'>"+arrData[i][1]+"</label>";
};
div.style.display='block';
div.innerHTML='';
this.options=this.GetOptions();
div.innerHTML="<form><table>"+
"<tr><td valign='top' align='center'><img src='img/units/unit_6_50.jpg' /></td><td valign='top'>"+
"Attack Order: <select id='KOCAttackOrder'><option value='mostTroops'>Use most troops first</option><option value='closest'>Closest targets first</option></select><br />"+
"Attack Type: <input type='checkbox' "+(this.options.attackTypeCamp?'checked':'')+" id='KOCAttackTypeCamp'>Camp "+
"<input type='checkbox' "+(this.options.attackTypeWild?'checked':'')+" id='KOCAttackTypeWild'>Wilderness "+
"<input type='checkbox' "+(this.options.attackTypeCity?'checked':'')+" id='KOCAttackTypeCity'>City "+
"<input type='checkbox' "+(this.options.attackTypeTransport?'checked':'')+" id='KOCAttackTypeTransport'>Transport<br> "+
"Prioritise attacks for : "+attackfirst+
"<br><br />"+
"<input id='KOCAttackDelay' value='"+this.options.attackDelay+"' size='3' /> seconds inbetween sending each attack<br />"+
"Time inbetween sending to the <u>same target</u>...<br />"+
"<div style='margin-left: 40px'>"+
"Attacking camp:<input id='KOCAttackHoursSinceLastCamp' value='"+(this.options.attackSecsSinceLastCamp/(60*60))+"' size='3' />hrs<br />"+
"Attacking wilderness:<input id='KOCAttackHoursSinceLastWild' value='"+(this.options.attackSecsSinceLastWild/(60*60))+"' size='3' />hrs<br />"+
" Attacking city:<input id='KOCAttackHoursSinceLastCity' value='"+(this.options.attackSecsSinceLastCity/(60*60))+"' size='3' />hrs<br />"+
" Transporting:<input id='KOCAttackMinsSinceLastTransport' value='"+(this.options.attackSecsSinceLastTransport/(60))+"' size='3' />mins<br />"+
" If transporting, try to keep at least <input id='KOCAttackTransportReserveAmount' value='"+this.options.transportResourcesReserveAmount+"' size='10' /> of each resource in each city <font color=#FF0000>(NEW)</font>"+
"</div>"+
"<input id='KOCAttackRandom' value='"+this.options.randomPercent+"' size='3' />% random adjustment for all delays (to look more human).<br />"+
"<input id='KOCAttackRally' value='"+this.options.rallyKeep+"' size='3' /> of rally point slots to keep<br />"+
"<br />"+
"<input id='KOCAttackMaxDistance' value='"+(this.options.attackMaxDistance)+"' size='3' /> max distance away from city to attack/transport.<br />"+
"<input id='KOCAttackLockAttackFromCity' type='checkbox' "+(this.options.lockAttackFromCity?'checked':'')+" /> Only launch attacks from city they were first launched from.<br />"+
"<input id='KOCAttackUnselectKnight' type='checkbox' "+(this.options.knightreset?'checked':'')+" /> Deselect knight when not in attack mode.<br />"+
"<input id='KOCAttackRetryMarch' type='checkbox' "+(this.options.retryMarch?'checked':'')+" /> Retry march if it has unknown/excess traffic error (press reload after changing this option).<br />"+
"<input id='KOCAttackImpendingStopAttack' type='checkbox' "+(this.options.impendingStopAttack?'checked':'')+" /> Stop auto attack on impeding alert.<span style='color:red'> (Will not restart auto after the attack. Use at your own risk)</span><br />"+
"Open up this URL (such as a link to a sound/video file) in a tab when we're under attack:<br /><input id='KOCAttackImpendingAttackUrl' size='60' value='"+(this.options.impendingAttackUrl)+"' /><br />"+
"</td></tr>"+
"<tr><td valign='top' align='center'><img src='img/chrome_message_up.png' /></td><td valign='top'>"+
"<input id='KOCAttackRemoveReports' type='checkbox' "+(this.options.autoRemoveReports?'checked':'')+" /> Auto remove barbarian/wilderness attack reports.<br />"+
"<input id='KOCAttackRemoveFarmReports' type='checkbox' "+(this.options.autoRemoveFarmReports?'checked':'')+" /> Auto remove farm attack reports.<br />"+
"<input id='KOCAttackKeepReports' value='"+this.options.keepReports+"' size='3' /> attack reports to keep maximum in the attack dialog.<br />"+
"<input id='KOCAttackNoViewReports' type='checkbox' "+(this.options.noViewReports?'checked':'')+" /> Disable viewing of reports, this will also disable collecting of reports for the attack page.<br />"+
"</td></tr>"+
"<tr><td valign='top' align='center'><img src='img/chome_alliance_up.png' /></td><td valign='top'>"+
"<input id='KOCAttackPercentOfPopToTrain' value='"+this.options.percentOfPopToTrain+"' size='3' />% of idle population available before we auto train <input id='KOCAttackPercentToTrainOfMax' value='"+this.options.percentToTrainOfMax+"' size='3' />% of max available.<br />"+
"<span style=\"font-size:10px; color:#555; line-height:18px; \">To enable auto training, toggle the auto train button under a troop type in the barracks.</span><br />"+
"<span style=\"font-size:10px; color:#555; line-height:18px; \">Note: If you auto train 100% of max population, you might sometimes encounter resource errors due to game caching.</span><br />"+
"</td></tr>"+
"<tr><td valign='top' align='center'><img src='img/gold_30.png' /></td><td valign='top'>"+
"<input id='KOCAttackAutoGoldHappiness' value='"+this.options.autoGoldHappiness+"' size='3' />% happiness before we click auto gold.<br />"+
"<span style=\"font-size:10px; color:#555; line-height:18px; \">To enable auto gold, toggle the auto gold button from inside your castle overview window.</span><br />"+
"</td></tr>"+
"<tr><td valign='top' align='center'><img src='img/gems.png' /></td><td valign='top'>"+
"<input id='KOCAttackDisableMapDraw' type='checkbox' "+(this.options.disableDrawMapIcons?'checked':'')+" /> Disable drawing of map icons.<br />"+
"<input id='KOCAttackDisableInviteFriends' type='checkbox' "+(this.options.disableInviteFriends?'checked':'')+" /> Disable the annoying \"Invite Friends\" popup dialog in-game.<br />"+
"<input id='KOCAttackAutoHelpAlliance' type='checkbox' "+(this.options.autoHelpAlliance?'checked':'')+" /> Automatically help alliance members with building/researching.<br />"+
"<input id='KOCAttackHideAllianceHelpRequests' type='checkbox' "+(this.options.hideAllianceHelpRequests?'checked':'')+" /> Hide alliance help requests/reports in chat (if above is checked, then after helping).<br />"+
"<input id='KOCAttackAutoPublishGamePopups' type='checkbox' "+(this.options.autoPublishGamePopups?'checked':'')+" /> Automatically publish game popups (such as help requests) to facebook wall.<br />"+
"If above is checked, what privacy setting should we use? <select id='KOCAttackAutoPublishPrivacy'><option value='80'>Everyone</option><option value='50'>Friends of Friends</option><option value='40'>Friends Only</option><option value='10'>Only Me</option></select><br />"+
"<input id='KOCAttackAutoLogBackIn' type='checkbox' "+(this.options.autoLogBackIn?'checked':'')+" /> Automatically log back into domain if disconnected due to maintenance or server down-time.<br />"+
"<input id='KOCAttackEnableLogging' type='checkbox' "+(this.options.enableLogging?'checked':'')+" /> Enable diagnostic logging in the Firefox error console messages window (useful if trying to debug a problem or if you are submitting details along with a bug report).<br />"+
"</td></tr>"+
"<tr><td valign='top' align='center'><img src='img/buildings/castle_lvl10.png' /></td><td valign='top'>"+
"<input id='KOCAttackChangeCitySecs' value='"+(this.options.changeCitySecs)+"' size='3' /> seconds inbetween changing cities.<br />"+
"Cycle thru all the cities <input id='KOCAttackCitiesDoneMax' value='"+(this.options.autoAttackCitiesDoneMax)+"' size='3' /> times and then wait "+
"<input id='KOCAttackCitiesDelay' value='"+this.options.waitAfterCitiesDone+"' size='3' />secs before refreshing.<br />"+
"Cities to attack from: "+okCitiesHtml+'<br />'+
"<tr><td valign='top' align='center'></td><td valign='top'>"+
"Import/Export: Paste or copy the settings here...<br /><textarea id='KOCAttackImport'></textarea>"+
"<a class='button20' id='KOCAttackImportButton'><span>Import</span></a> <a class='button20' id='KOCAttackExportButton'><span>Export</span></a><br />"+
"</td></tr>"+
"</table>"+
"<TABLE width=100%><TR><TD>"+
"<a id='KOCAttackOptionsSave' class='button20'><span>Save</span></a> <a id='KOCAttackOptionsCancel' class='button20'><span>Cancel</span></a> <a id='KOCAttackOptionsReset' class='button20'><span>Reset options</span></a> <a id='KOCAttackOptionsResetAll' class='button20'><span>Reset all!</span></a>"+
"<a id='KOCAttackDeleteAllStoredAttacks' class='button20'><span>Delete all stored attacks</span></a>"+
"<a id='KOCAttackDeleteTransports' class='button20'><span>Delete transports</span></a>"+
//"<a id='KOCAttackListAttacks' class='button20'><span>List attacks</span></a><a id='KOCAttackListTransports' class='button20'><span>List transports</span></a>"+
"</td><TD align=right>"+ KOCAversion +"</td></tr></form>";
var t=this;
var importText=ById('KOCAttackImport');
importText.addEventListener('focus',function() {
importText.select();
},false);
ById('KOCAttackImportButton').addEventListener('click',function() {
if(importText.value=="") return;
t.ImportAllFromJSON(importText.value);
},false);
ById('KOCAttackExportButton').addEventListener('click',function() {
importText.value=t.ExportAllToJSON();
},false);
nHtml.SetSelect(ById('KOCAttackOrder'),this.options.attackOrder);
ById('KOCAttackOptionsCancel').addEventListener('click',function() {
div.style.display='none';
},false);
ById('KOCAttackOptionsReset').addEventListener('click',function() {
t.ClearOptions();
this.options=t.GetOptions();
div.style.display='none';
},false);
ById('KOCAttackOptionsResetAll').addEventListener('click',function() {
t.FactoryReset();
//window.location.reload(true);
t.ReloadWindow();
},false);
ById('KOCAttackDeleteAllStoredAttacks').addEventListener('click',function() {
t.DeleteAllStoredAttacks();
//window.location.reload(true);
t.ReloadWindow();
},false);
ById('KOCAttackDeleteTransports').addEventListener('click',function() {
t.DeleteTransports();
//window.location.reload(true);
t.ReloadWindow();
},false);
//ById('KOCAttackListTransports').addEventListener('click',function() {
//t.ListTransports();
//window.location.reload(true);
//},false);
//ById('KOCAttackListAttacks').addEventListener('click',function() {
//t.ListAttacks();
//window.location.reload(true);
//},false);
nHtml.SetSelect(ById('KOCAttackAutoPublishPrivacy'),this.options.autoPublishPrivacySetting);
for(var c=1; c<=8; c++) {
var sp=ById('KOCAttackOkCities_'+c);
var SetCity=function(target,set) {
target.style.border=set?'2px solid #080':'';
target.style.margin=set?'2px':'4px';
};
sp.addEventListener('click',function(evt) { SetCity(evt.target,evt.target.style.border==''?true:false); },false);
//sp.onmousedown=function() { return false; }
SetCity(sp,t.options.okCities[c]);
}
ById('KOCAttackOptionsSave').addEventListener('click',function() {
t.options.attackTypeCamp=ById('KOCAttackTypeCamp').checked;
t.options.attackTypeCity=ById('KOCAttackTypeCity').checked;
t.options.attackTypeWild=ById('KOCAttackTypeWild').checked;
t.options.attackTypeTransport=ById('KOCAttackTypeTransport').checked;
var attackpriority = ByName('KOCAttackPriority');
if(attackpriority){
for(var i = 0; i < attackpriority.length; i++) {
if(attackpriority[i].checked) {
t.options.attackpriority = attackpriority[i].value;
break;
}
}
}
t.options.attackDelay=parseInt(ById('KOCAttackDelay').value);
t.options.waitAfterCitiesDone=parseInt(ById('KOCAttackCitiesDelay').value);
t.options.keepReports=parseInt(ById('KOCAttackKeepReports').value);
t.options.changeCitySecs=parseInt(ById('KOCAttackChangeCitySecs').value);
t.options.autoGoldHappiness=parseInt(ById('KOCAttackAutoGoldHappiness').value);
t.options.percentOfPopToTrain=parseFloat(ById('KOCAttackPercentOfPopToTrain').value);
t.options.percentToTrainOfMax=parseFloat(ById('KOCAttackPercentToTrainOfMax').value);
var prev_disableInviteFriends = t.options.disableInviteFriends;
t.options.disableInviteFriends=ById('KOCAttackDisableInviteFriends').checked;
t.options.disableDrawMapIcons=ById('KOCAttackDisableMapDraw').checked;
if(prev_disableInviteFriends != t.options.disableInviteFriends){
alert("You changed the option for disabling/enabling the \"Invite Friends\" feature.\nPlease note: You will need to refresh the entire game window for the new setting to take effect!");
}
t.options.autoHelpAlliance=ById('KOCAttackAutoHelpAlliance').checked;
t.options.hideAllianceHelpRequests=ById('KOCAttackHideAllianceHelpRequests').checked;
t.options.autoPublishGamePopups=ById('KOCAttackAutoPublishGamePopups').checked;
t.options.autoPublishPrivacySetting=ById('KOCAttackAutoPublishPrivacy').value;
t.options.autoLogBackIn=ById('KOCAttackAutoLogBackIn').checked;
t.options.enableLogging=ById('KOCAttackEnableLogging').checked;
t.options.attackSecsSinceLastCamp=parseFloat(ById('KOCAttackHoursSinceLastCamp').value)*60*60;
t.options.attackSecsSinceLastWild=parseFloat(ById('KOCAttackHoursSinceLastWild').value)*60*60;
t.options.attackSecsSinceLastCity=parseFloat(ById('KOCAttackHoursSinceLastCity').value)*60*60;
t.options.attackSecsSinceLastTransport=parseFloat(ById('KOCAttackMinsSinceLastTransport').value)*60;
t.options.transportResourcesReserveAmount=parseInt(ById('KOCAttackTransportReserveAmount').value);
t.options.randomPercent=parseFloat(ById('KOCAttackRandom').value);
t.options.rallyKeep=parseInt(ById('KOCAttackRally').value);
t.options.attackMaxDistance=parseFloat(ById('KOCAttackMaxDistance').value);
t.options.autoAttackCitiesDoneMax=parseInt(ById('KOCAttackCitiesDoneMax').value);
t.options.attackOrder=ById('KOCAttackOrder').value;
t.options.lockAttackFromCity=ById('KOCAttackLockAttackFromCity').checked;
t.options.knightreset=ById('KOCAttackUnselectKnight').checked;
t.options.autoRemoveReports=ById('KOCAttackRemoveReports').checked;
t.options.autoRemoveFarmReports=ById('KOCAttackRemoveFarmReports').checked;
t.options.retryMarch=ById('KOCAttackRetryMarch').checked;
t.options.impendingAttackUrl=ById('KOCAttackImpendingAttackUrl').value;
t.options.impendingStopAttack=ById('KOCAttackImpendingStopAttack').checked;
t.options.noViewReports=ById('KOCAttackNoViewReports').checked;
for(var c=1; c<=8; c++) {
var okcity=ById('KOCAttackOkCities_'+c);
t.options.okCities[c]=okcity.style.border!=""?true:false;
}
t.SetOptions(t.options);
div.style.display='none';
},false);
},
AddOptionsLink:function() {
var t=this;
var a=ById('KOCAttackOptionsLink');
if(a) return;
a=this.AddTabLink('Options');
if(!a) {
window.setTimeout(function() {
t.AddOptionsLink();
},t.GetRandTime(250));
return;
}
a.id='KOCAttackOptionsLink';
a.addEventListener('click',function() {
t.ShowOptionsDialog();
},false);
},
AddViewAttacksLink:function() {
var t=this;
var a=ById('KOCAttackViewAttacksLink');
if(a) return;
a=this.AddTabLink('View Attacks');
if(!a) {
window.setTimeout(function() {
t.AddViewAttacksLink();
},t.GetRandTime(250));
return;
}
a.id='KOCAttackViewAttacksLink';
a.addEventListener('click',function() {
t.ShowViewAttacksDialog();
},false);
},
/*
AddImportExportLink:function() {
var t=this;
var a=ById('KOCImportExportLink');
if(a) return;
a=this.AddTabLink('Imp Exp');
if(!a) {
window.setTimeout(function() {
t.AddImportExportLink();
},t.GetRandTime(250));
return;
}
a.id='KOCImportExportLink';
a.addEventListener('click',function() {
t.ShowImportExportBox();
},false);
},
*/
AddTabLink:function(html) {
// Resize main tab bar container
var tab_container = ById("main_engagement_tabs");
tab_container.style.width = "715px";
// Create new tab
var a=document.createElement('a');
a.className='navTab';
a.innerHTML='<span>'+html+'</span>';
var tabs=ById('KOCAttackTabs');
if(!tabs) {
var ptabs=ById('main_engagement_tabs');
if(!ptabs) {
ptabs=ById('topnav_msg');
if(ptabs)ptabs=ptabs.parentNode;
}
if(!ptabs) {
ptabs=document.body;
}
tabs=document.createElement('span');
tabs.id='KOCAttackTabs';
ptabs.insertBefore(tabs,ptabs.childNodes[0]);
}
if(tabs) {
tabs.style.whiteSpace='nowrap';
tabs.style.width='1600px';
tabs.appendChild(a);
return a;
}
return null;
},
ToggleAutoAttack:function() {
var t=this;
var a=t.GetAutoAttack();
if(!a) {
t.Log("Enabling Auto Attack");
t.SetAutoAttack({'barbarian':true,'cities':{}});
window.setTimeout(function() {
t.SetAttackStatusMessage();
},t.GetRandTime(250));
t.RestartAutoAttack();
} else {
t.Log("Disabling Auto Attack");
t.ClearAutoAttackTimeout();
t.SetAutoAttack(null);
window.setTimeout(function() {
t.SetAttackStatusMessage();
},t.GetRandTime(250));
}
/*
// toggle for this city,
if(!a.cities) a.cities={};
var city=t.GetCurrentCityId();
a.cities[city]=a.cities[city]?undefined:true;
var attackCities=0;
for(city in a.cities) {
attackCities++;
}
if(attackCities==0) {
t.ClearAutoAttackTimeout();
t.SetAutoAttack(null);
}
*/
},
SetAttackStatusMessage:function() {
//var mess=this.GetStatusMessage();
var toggle=ById('KOCAttackToggle');
if(!toggle) {
var t=this;
toggle=this.AddTabLink('Auto Attack');
if(!toggle) {
window.setTimeout(function() {
t.SetAttackStatusMessage();
},t.GetRandTime(250));
return;
}
toggle.id='KOCAttackToggle';
toggle.addEventListener('click',function() {
t.ToggleAutoAttack();
},false);
}
var autoAttack=this.GetAutoAttack();
//if(autoAttack && autoAttack.cities && autoAttack.cities[t.GetCurrentCityId()]) {
if(autoAttack) {
toggle.innerHTML='<span>Auto Attack - On</span>';
} else {
toggle.innerHTML='<span>Auto Attack - Off</span>';
}
},
SetStatusMessage:function(str) {
var mess=this.GetStatusMessage();
var txt=ById('KOCAttackMessage');
if(!txt) {
txt=document.createElement('span');
mess.appendChild(txt);
}
txt.innerHTML=str;
},
GetStatusMessage:function() {
var mess=ById('KOCAttackStatus');
if(!mess) {
var timeHead=ById('kochead_time');
mess=document.createElement('span');
mess.id='KOCAttackStatus';
timeHead.parentNode.appendChild(mess);
}
return mess;
},
Log:function(str) {
if(!this.options || !this.options.enableLogging){
// disable logging
return;
}
str=this.GetServerId()+":"+str;
GM_log(str);
},
currentServerId:-1,
GetServerId:function() {
var m=/^[a-zA-Z]+([0-9]+)\./.exec(document.location.hostname);
if(m) {
this.currentServerId = m[1];
}
// Attempt to pull current server id from greasemonkey cache for cross-domain calls
if(this.currentServerId<0){
this.currentServerId = GM_getValue("KOCAttackLastKnownServerID",-1);
}
return this.currentServerId;
},
GetValue:function(prefix,def) {
var n=prefix+'_'+this.GetServerId();
return this.browser_getValue(n,def);
},
SetValue:function(prefix,val) {
var n=prefix+'_'+this.GetServerId();
this.browser_setValue(n,val);
},
GetValuesCache:function(doneFunc) {
if(!this.isChrome) {
if(doneFunc) {
doneFunc.call(this);
}
return;
}
/*
var t=this;
chrome.extension.sendRequest({func:"get","n":'KOCAttack'},
function(response) {
//~~~
this.valuesCache=JSON2.parse(unescape(response.v));
if(doneFunc) {
doneFunc.call(t);
}
});
return def;
*/
var idx=0;
var cookie='kocattack';
var doccookie=document.cookie;
while(true) {
var i=doccookie.indexOf(cookie+'=',idx);
if(i<0) { this.valuesCache={}; return; }
idx=i+cookie.length+1;
var ch=doccookie.substring(i-1,i);
if(i==0 || ch==';' || ch==' ' || ch=='=') {
break;
}
}
var idxEnd=doccookie.indexOf(";",idx);
if(idxEnd<0) { idxEnd=doccookie.length; }
var cookieVal=doccookie.substring(idx,idxEnd);
this.valuesCache=JSON2.parse(unescape(cookieVal));
},
SetValuesCache:function() {
if(!this.isChrome) return;
document.cookie='kocattack='+escape(JSON2.stringify(this.valuesCache))+'; expires='+
(new Date(new Date().getTime()+(60*60*24*365*5)).toGMTString() );
},
browser_listValues:function() {
if(this.isChrome) {
var ns=[];
for(var n in this.valuesCache) {
ns.push(n);
}
return ns;
}
return GM_listValues();
},
browser_getValue:function(n,def) {
if(this.isChrome) {
if(this.valuesCache==null) {
this.GetValuesCache();
}
if(this.valuesCache[n]==undefined) {
return def;
}
return this.valuesCache[n];
}
return GM_getValue(n,def);
},
browser_setValue:function(n,val) {
if(this.isChrome) {
this.valuesCache[n]=val;
return;
}
if(val==null || val==undefined) {
GM_deleteValue(n);
} else {
GM_setValue(n,val);
}
},
GetMinHours:function() {
var m=this.GetValue('MinHours',1);
if(m=="" || m==undefined) m=1;
return m;
},
SetMinHours:function(val) {
this.SetValue('MinHours',val);
},
ClearOptions:function() {
this.SetValue('Options',JSON.stringify({}));
},
GetOptions:function() {
var json=this.GetValue('Options','{}');
if(json=='') json='{}';
var options=JSON2.parse(json);
var defOptions={"attackDelay":15,
"attackTypeCamp":true,
"attackOrder":"closest",
"attackpriority":"None",
"autoRemoveReports":true,
"rallyKeep":0,
"disableDrawMapIcons":false,
"attackSecsSinceLastCity":60*60*12,
"attackSecsSinceLastCamp":3600,
"attackSecsSinceLastWild":3600,
"attackSecsSinceLastTransport":60,
"transportResourcesReserveAmount":1000000,
"randomPercent":10,
"keepReports":10,
"attackMaxDistance":60,
"lockAttackFromCity":true,
"knightreset":true,
"waitAfterCitiesDone":20,
"autoAttackCitiesDoneMax":2,
"changeCitySecs":20,
"retryMarch":true,
"noViewReports":false,
"chromeKeepReports":2,
"percentOfPopToTrain":75,
"percentToTrainOfMax":95,
"autoGoldHappiness":99,
"disableInviteFriends":true,
"autoHelpAlliance":true,
"hideAllianceHelpRequests":false,
"autoPublishGamePopups":false,
"autoPublishPrivacySetting":"80",
"autoLogBackIn":true,
"enableLogging":false,
"okCities":[1,1,1,1,1,1,1,1,1,1],
'impendingAttackUrl':''};
for(var n in defOptions) {
if(options[n]!=undefined) { continue; }
options[n]=defOptions[n];
}
return options;
},
SetOptions:function(v) {
this.SetValue('Options',JSON2.stringify(v));
},
ClearCrossIframeCommands:function() {
this.SetValue('CrossIframeCommands',JSON.stringify({}));
},
GetCrossIframeCommands:function() {
var json=this.GetValue('CrossIframeCommands','{}');
if(json=='') json='{}';
var commands=JSON2.parse(json);
if(!commands.queue || commands.queue instanceof Array !== true){
commands.queue = new Array();
}
return commands;
},
SetCrossIframeCommands:function(v) {
this.SetValue('CrossIframeCommands',JSON2.stringify(v));
},
AddCrossIframeCommand:function(pageName, functionCall, functionParameters) {
var command = {};
command.pageName = pageName;
command.functionCall = functionCall;
var commands = this.GetCrossIframeCommands();
commands.queue.push(command);
this.SetCrossIframeCommands(commands);
},
GetAttackName:function(x,y) {
return 'attack_'+this.GetServerId()+'_'+x+','+y;
},
SetAttack:function(x,y,attack) {
this.browser_setValue(this.GetAttackName(x,y), JSON2.stringify(attack));
},
GetAttack:function(x,y) {
var str=this.browser_getValue(this.GetAttackName(x,y),'');
if(!str) return null;
return JSON2.parse(str);
},
DeleteAttack:function(x,y) {
var str=this.browser_getValue(this.GetAttackName(x,y),'');
if(!str) return;
GM_deleteValue(this.GetAttackName(x,y));
},
isSuicideAttackDefinedAtLocation:function(x,y) {
var attack=this.GetAttack(x,y);
if(!attack){ return false; }
if(attack.suicidewave) { return true; }
if(attack.a && attack.a.suicidewave){ return true; }
return false;
},
IsFirstAttackAtLocation:function(x,y) {
var attack=this.GetAttack(x,y);
if(!attack){
this.Log("Attack not defined in system. This is first attack!");
return true;
}
if(attack.a) { attack = attack.a; }
// Check the current marches to see if there's an existing attack underway from this city
var current_marches=this.GetSeed().queue_atkp["city" + this.GetCurrentCityId()];
for (var march in current_marches) {
if(current_marches[march]['toXCoord'] == x && current_marches[march]['toYCoord'] == y){
this.Log("Troops are already marching to ("+x+","+y+") in the troop activity.");
/*
this.Log("Suicide wave time: "+attack.suicidewavetime+". Attack time: "+attack.time+".");
if(!attack.suicidewavetime || !attack.time){
this.Log("Suicide wave time: "+attack.suicidewavetime+". Attack time: "+attack.time+". This is first attack!");
return true;
}
*/
if(attack.suicidewavetime && attack.suicidewave){
var nowSecs=new Date().getTime()/1000;
var elapsedTime=nowSecs-attack.suicidewavetime;
if(elapsedTime > 30 && attack.time < attack.suicidewavetime){
this.Log("Suicide wave attack was sent more than 30 seconds ago and normal wave has not been sent yet. Suicide wave should be re-sent! This is the first attack sent to ("+x+","+y+")!");
return true;
}
}
this.Log("This is not the first attack sent to ("+x+","+y+").");
return false;
break;
}
}
/*
if(this.prevAttack.x && this.prevAttack.y){
if(this.prevAttack.x==x && this.prevAttack.y==y) {
this.Log("Previous attack matches current attack. This is not first attack!");
return false;
}
}
*/
this.Log("Troops are not currently marching to ("+x+","+y+") in the troop activity. This is the first attack.");
return true;
},
GetCommandHistory:function(history_log_name) {
if(!history_log_name){
var history_log_name = "default";
}
var json=this.GetValue('PreviousCommandHistory_'+history_log_name,'{}');
if(json=='') json='{}';
var json_object=JSON2.parse(json);
if(!json_object['items']){
json_object['items'] = Array();
}
return json_object;
},
AddToCommandHistory:function(command_string, history_log_name, log_length_limit) {
if(!command_string){ return false; }
if(!history_log_name){ var history_log_name = "default"; }
// Default to a history length of 20 commands
if(!log_length_limit){ var log_length_limit = 20; }
// Get the previous history of commands
var previous_commands = this.GetCommandHistory(history_log_name);
var items = previous_commands['items'];
// Add the new command
items.push(command_string);
// Limit the history length
if(items.length>log_length_limit){
items = items.slice(items.length-log_length_limit);
}
previous_commands['items'] = items;
this.SetValue('PreviousCommandHistory_'+history_log_name,JSON2.stringify(previous_commands));
},
FindInCommandHistory:function(command_string, history_log_name) {
if(!command_string){ return false; }
if(!history_log_name){ var history_log_name = "default"; }
// Get the previous history of commands
var previous_commands = this.GetCommandHistory(history_log_name);
var items = previous_commands['items'];
for(var i=0; i<items.length; i++){
if(items[i] == command_string){
return true;
}
}
return false;
},
GetGuiCoords:function() {
var x=ById('modal_attack_target_coords_x');
var y=ById('modal_attack_target_coords_y');
if(!x || !y) {
this.Log("Cannot find gui coords");
return null;
}
if(x.value.length<1 || y.value.length<1){
this.Log("One or both coordinates are missing!");
return null;
}
return [x.value,y.value];
},
SetAttackFromGui:function(box, resetTime) {
var xy=this.GetGuiCoords();
if(!xy) return null;
if(!resetTime){resetTime=false;}
return this.SetAttackFromGuiXY(xy[0],xy[1],box, null, null, resetTime);
},
AttackLastSentTime:0,
UpdateAttackLastSentTime:function(){
this.AttackLastSentTime = new Date().getTime()/1000;
this.SetValue('AttackLastSentTime',parseInt(this.AttackLastSentTime));
},
SendingMultipleWaves:false,
IsCurrentlySendingMultipleWaves:function() {
if(this.AttackLastSentTime == 0){
this.AttackLastSentTime = this.GetValue('AttackLastSentTime',0);
}
var nowSecs = new Date().getTime()/1000;
var waveTimerDelay = this.options.attackDelay*2;
var timeDifference = nowSecs-this.AttackLastSentTime;
//this.Log("nowSecs: "+nowSecs+" waveTimerDelay: "+waveTimerDelay+" timeDifference: "+timeDifference+" SendingMultipleWaves: "+this.SendingMultipleWaves);
// If the last attack was sent at a time ago that is more than twice the attack delay,
// then we assume something failed and we reset the multiple wave tracker so everything can continue.
if(timeDifference > waveTimerDelay && this.SendingMultipleWaves==true){
this.SendingMultipleWaves=false;
this.Log("Multiple wave timer \("+waveTimerDelay+"\ seconds) has expired. Last known attack was sent "+timeDifference+" seconds ago. Resetting timer and continuing...");
}
return this.SendingMultipleWaves;
},
SetAttackFromGuiXY:function(x,y,box,isSuicideWave,locationType,resetTime) {
if(resetTime==true){
this.Log("Resetting start times for attack ("+x+","+y+")");
}
// Determine location type
if(!locationType){ var locationType = ""; }
var locationTypeRadioBoxes = ByName('KOCAttackLocationType');
if(locationTypeRadioBoxes){
for(var i = 0; i < locationTypeRadioBoxes.length; i++) {
if(locationTypeRadioBoxes[i].checked) {
locationType = locationTypeRadioBoxes[i].value;
break;
}
}
}
// Determine attack wave type
if(!isSuicideWave){
var isSuicideWave = false;
var bulkAddSuicideWaveCheckbox = ById("KOCAttackBulkAddSuicideWave");
if(bulkAddSuicideWaveCheckbox){isSuicideWave = bulkAddSuicideWaveCheckbox.checked;}
var otherIsSuicideWaveCheckbox = ById("KOCAttackSuicideWaveCheckbox");
if(otherIsSuicideWaveCheckbox){ if(otherIsSuicideWaveCheckbox.checked){isSuicideWave=true;} }
}
var troops=[];
var totalTroops=0;
for(var tr=0; tr<20; tr++) {
var troop=ById('modal_attack_unit_ipt'+tr);
if(!troop) continue;
try {
var v=parseInt(troop.value);
troops[tr]=v;
totalTroops+=v;
} catch(e) {
continue;
}
}
var comment=ById('KocAttackComment');
var marchType = getAttackTypeSelected();
if(marchType==null) {
throw("Cannot find attack type");
}
if(totalTroops<=0) {
this.Log("No troops, not saving attack");
return null;
}
var nowSecs=new Date().getTime()/1000;
var monthAgo=nowSecs-(60*60*24*31);
// ignore anything other than attack
if(marchType==0 && locationType!="Transport") {
var attack=this.GetAttack(x,y);
if(!attack) attack={};
attack.type=marchType;
if(comment){ attack.comment=comment.value; }
var SuicideAttackDefined=this.isSuicideAttackDefinedAtLocation(x,y);
var firstAttack=this.IsFirstAttackAtLocation(x,y);
this.Log("First attack?: "+firstAttack);
this.Log("Suicide attack defined? : "+SuicideAttackDefined);
if(isSuicideWave) {
this.Log("Suicide attack determined by checkbox");
this.Log("Suicide wave :"+troops);
attack.suicidewave=troops;
attack.currenttattackwavetype = "suicide";
attack.suicidewavetime = nowSecs;
if(resetTime==true){ attack.suicidewavetime=monthAgo; }
this.SendingMultipleWaves = true;
} else {
this.Log("Normal wave :"+troops);
attack.time=nowSecs;
if(resetTime==true){ attack.time=monthAgo; }
if(!SuicideAttackDefined && firstAttack){
attack.suicidewave=undefined;
}
attack.currenttattackwavetype = "normal";
attack.troops=troops;
this.SendingMultipleWaves = false;
}
//if (this.options.lockAttackFromCity) {
attack.fromCity=this.GetCurrentCityId();
//}
//Check if level is undefined
if(!attack.levelInfo){attack.levelInfo={'type':locationType,'level':0};}
if(locationType==""){
if(attack.levelInfo.type!=""){
// a pre-defined location type was already entered before for this attack.
locationType = attack.levelInfo.type;
}else{
// Default to camp if attack location type was absolutely not specified in any way
locationType = "Camp";
}
}
attack.levelInfo.type = locationType;
//attack.ignore=undefined;
this.prevAttack={'x':x,'y':y};
this.SetAttack(x,y,attack);
return attack;
} else if(marchType==1 || locationType=="Transport") {
// try to parse transports
var attack=this.GetAttack(x,y);
if(!attack) attack={};
attack.type=1; //If we got here presume to be transport mode
//attack.ignore=true; // We set this to ignore for now until I can get the auto attack working
if(comment){
attack.comment=comment.value;
}
var SuicideAttackDefined=this.isSuicideAttackDefinedAtLocation(x,y);
attack.time=nowSecs;
if(resetTime==true){ attack.time=monthAgo; }
attack.troops=troops;
var resources=[];
var resourceTypes = new Array(
'gold',
'rec1',
'rec2',
'rec3',
'rec4'
);
for(var res=0; res<resourceTypes.length; res++) {
var resource=ById('modal_attack_'+resourceTypes[res]);
if(!resource) continue;
try {
var v=parseInt(resource.value);
resources[res]=v;
totalResources+=v;
} catch(e) {
continue;
}
}
attack.resources=resources;
//if (this.options.lockAttackFromCity) {
attack.fromCity=this.GetCurrentCityId();
//}
//attack.ignore=undefined;
//locationType = "Transport"; Redundant code
//Check if level is undefined
if(!attack.levelInfo){attack.levelInfo={'type':locationType,'level':0};}
// Set the location type
//attack.levelInfo.type = locationType;
attack.currenttattackwavetype = "transport";
this.prevAttack={'x':x,'y':y};
this.SetAttack(x,y,attack);
return attack;
} else {
// Reset it
this.prevAttack={'x':"350",'y':'350'};
}
return null;
},
ToggleCurrenttAttackWaveType:function(x,y,manual_setting) {
var original_attack = this.GetAttack(x,y);
if(original_attack) {
var attack = original_attack;
if(original_attack.a){
attack = original_attack.a;
}
var previousattackwavetype = 'undefined';
if(attack){
//this.Log("Inspecting attack: "+inspect(attack,10));
if(attack.currenttattackwavetype){
previousattackwavetype = attack.currenttattackwavetype;
}
if(manual_setting){
attack.currenttattackwavetype = manual_setting;
}else if(attack.suicidewave && attack.currenttattackwavetype == "bulkadded"){
attack.currenttattackwavetype = "suicide";
}else{
// Toggle back and forth
if(attack.suicidewave && attack.currenttattackwavetype == "normal"){
attack.currenttattackwavetype = "suicide";
}else{
attack.currenttattackwavetype = "normal";
}
}
this.Log("Toggling attack for ("+x+", "+y+") from "+previousattackwavetype+" to "+attack.currenttattackwavetype);
if(original_attack.a){
original_attack.a = attack;
attack = original_attack;
}
this.SetAttack(x,y,attack);
return attack.currenttattackwavetype;
}else{
return false;
}
}else{
return false;
}
},
BulkAddCoords:function(box,coordsText,force,locationType,isSuicideWave) {
if(!locationType){
var locationType = "Camp"; //Default to camp
}
if(!isSuicideWave){
var isSuicideWave = false;
}
var coordRows=coordsText.split("\n");
var added=0;
for(var r=0; r<coordRows.length; r++) {
var row=coordRows[r];
var m=/^\s*([0-9]+)\s*,\s*([0-9]+)/.exec(row);
if(!m) {
m=/^\s*([0-9]+)\s+([0-9]+)/.exec(row);
if(!m) continue;
}
var x=m[1];
var y=m[2];
var attack=this.GetAttack(x,y);
var currenttattackwavetype = "bulkadded";
if(locationType=="Transport"){
currenttattackwavetype = "transport";
}
var SuicideAttackDefined=this.isSuicideAttackDefinedAtLocation(x,y);
var previous_suicidewave = undefined;
if(attack && (SuicideAttackDefined || isSuicideWave)){
previous_suicidewave = attack.suicidewave;
}
if(attack && !force) {
if(SuicideAttackDefined && isSuicideWave==true){
this.Log('Suicide wave for '+x+','+y+' has already been added. Try over-writing it.');
continue;
}else if(attack.troops){
this.Log('Attack wave for '+x+','+y+' has already been added. Try over-writing it.');
continue;
}
}
var attack=this.SetAttackFromGuiXY(x,y,box,isSuicideWave,locationType);
if(attack) {
attack.levelInfo={'type':locationType,'level':0};
attack.fromCity=this.GetCurrentCityId();
var nowSecs=new Date().getTime()/1000;
var monthAgo=nowSecs-(60*60*24*31);
attack.time=monthAgo;
if(SuicideAttackDefined || isSuicideWave || previous_suicidewave){
// set up suicide wave before attack time, according to "seconds in between sending each attack"
attack.suicidewavetime = attack.time - this.options.attackDelay;
if(previous_suicidewave && (!SuicideAttackDefined || !isSuicideWave)){
this.Log("Previous suicide wave for this attack was over-written by new attack. Merging and restoring...");
attack.suicidewave = previous_suicidewave;
}
}
attack.ignore=undefined;
attack.currenttattackwavetype=currenttattackwavetype;
this.SetAttack(x,y,attack);
this.Log(x+','+y+' attack added: '+inspect(attack));
this.Log("current attack wave type: "+attack.currenttattackwavetype);
added++;
}
}
// Redraw attacks on map listing
this.DrawClosestFarms();
// done
return added;
},
BulkAddAttackLink:function(box) {
var div=ById('BulkAddAttackDiv');
var t=this;
if(!div) {
div=document.createElement('div');
div.id='BulkAddAttackDiv';
div.style.display='inline';
}
div.innerHTML='';
var bulkAddTable=document.createElement('table');
bulkAddTable.style.background='transparent';
var bulkAddDiv=document.createElement('div');
bulkAddTable.insertRow(-1).insertCell(-1).appendChild(bulkAddDiv);
bulkAddDiv.style.display='none';
//AddHtml(bulkAddDiv,"<hr />");
AddHtml(bulkAddDiv,"Copy and paste coords here (ie. 343,434) one on each line...<br />Note: it will only add the target using the current number of troops on this screen.<br /><input id='KOCAttackBulkAddForce' type='checkbox' /> <label for=\"KOCAttackBulkAddForce\">Overwrite existing attack if one already exists</label><br />");
// radio boxes for defining bulk coordinate type
AddHtml(bulkAddDiv,"<hr />");
AddHtml(bulkAddDiv,"Type of Locations (All coordinates must match this type):<br />");
var arrData = [["Camp", "Camps"],["City", "City"],["Transport", "Transport"],["Wilderness", "Wildernesses"]];
for (var i=0; i < arrData.length; i++){
var objRadItem = document.createElement("input");
objRadItem.type = "radio";
objRadItem.name = "KOCAttackBulkAddLocationType";
objRadItem.id = "KOCAttackBulkAddLocationType_" + arrData[i][0];
objRadItem.value = arrData[i][0];
if(i == 0) {objRadItem.defaultChecked = true; objRadItem.checked = true; };
var objTextNode = document.createTextNode(" " + arrData[i][1]);
var objLabel = document.createElement("label");
objLabel.htmlFor = objRadItem.id;
objLabel.appendChild(objRadItem);
objLabel.appendChild(objTextNode);
bulkAddDiv.appendChild(objLabel);
objRadItem.addEventListener('change',function() {
var locationType = "Camp"; // Set default value to camp
var bulkLocationTypeRadioBoxes = ByName('KOCAttackBulkAddLocationType');
if(bulkLocationTypeRadioBoxes){
for(var i = 0; i < bulkLocationTypeRadioBoxes.length; i++) {
if(bulkLocationTypeRadioBoxes[i].checked) {
locationType = bulkLocationTypeRadioBoxes[i].value;
break;
}
}
}
// Select the same radio box in the normal add area
var locationTypeRadioBoxes = ByName('KOCAttackLocationType');
if(locationTypeRadioBoxes){
for(var i = 0; i < locationTypeRadioBoxes.length; i++) {
if(locationTypeRadioBoxes[i].value == locationType) {
locationTypeRadioBoxes[i].checked = true;
break;
}
}
}
},false);
AddHtml(bulkAddDiv," ");
};
AddHtml(bulkAddDiv,"<hr />");
//AddHtml(bulkAddDiv,"<input id='KOCAttackBulkAddSuicideWave' type='checkbox' /> This is an initial suicide wave to wipe out traps on a wilderness.<br />");
var bulkAddSuicideSpan=document.createElement('span');
var bulkAddSuicideCheckbox=document.createElement('input');
bulkAddSuicideCheckbox.id = "KOCAttackBulkAddSuicideWave";
bulkAddSuicideCheckbox.name = bulkAddSuicideCheckbox.id;
bulkAddSuicideCheckbox.type='checkbox';
bulkAddSuicideSpan.appendChild(bulkAddSuicideCheckbox);
AddHtml(bulkAddSuicideSpan,'<label for="KOCAttackBulkAddSuicideWave">This is an initial suicide wave to wipe out traps on a wilderness.</label>');
bulkAddDiv.appendChild(bulkAddSuicideSpan);
bulkAddSuicideCheckbox.addEventListener('click',function() {
var bulkAddSuicideWaveCheckbox = ById("KOCAttackBulkAddSuicideWave");
var suicideWaveCheckbox = ById("KOCAttackSuicideWaveCheckbox");
var locationType_Wilderness = ById("KOCAttackLocationType_Wilderness");
var bulkAddLocationType_Wilderness = ById("KOCAttackBulkAddLocationType_Wilderness");
if(bulkAddSuicideWaveCheckbox && suicideWaveCheckbox && locationType_Wilderness && bulkAddLocationType_Wilderness){
if(bulkAddSuicideCheckbox.checked){
suicideWaveCheckbox.checked = true;
locationType_Wilderness.checked = true;
bulkAddLocationType_Wilderness.checked = true;
}else{
suicideWaveCheckbox.checked = false;
}
}
},false);
AddHtml(bulkAddDiv,"<hr />");
var coords=document.createElement('textarea');
coords.wrap='off';
coords.style.whiteSpace='nowrap';
coords.cols=10;
coords.rows=8;
bulkAddDiv.appendChild(coords);
AddHtml(bulkAddDiv,"<br />");
var bulkAdd=document.createElement('a');
bulkAdd.className='buttonDown20';
bulkAdd.innerHTML='<span>Bulk Add</span>';
bulkAddDiv.appendChild(bulkAdd);
bulkAdd.addEventListener('click',function() {
// Determine location type
var locationType = "Camp"; // Set default value to camp
var locationTypeRadioBoxes = ByName('KOCAttackBulkAddLocationType');
if(locationTypeRadioBoxes){
for(var i = 0; i < locationTypeRadioBoxes.length; i++) {
if(locationTypeRadioBoxes[i].checked) {
locationType = locationTypeRadioBoxes[i].value;
break;
}
}
}
// Determine attack wave type
var isSuicideWave = false;
var bulkAddSuicideWaveCheckbox = ById("KOCAttackBulkAddSuicideWave");
if(bulkAddSuicideWaveCheckbox){isSuicideWave = bulkAddSuicideWaveCheckbox.checked;}
var otherIsSuicideWaveCheckbox = ById("KOCAttackSuicideWaveCheckbox");
if(otherIsSuicideWaveCheckbox){ if(otherIsSuicideWaveCheckbox.checked){isSuicideWave=true;} }
// Add the coordinates
var added=t.BulkAddCoords(box,coords.value,ById('KOCAttackBulkAddForce').checked,locationType,isSuicideWave);
bulkAddDiv.style.display='none';
bulkAddAttackLink.style.display='inline';
window.alert('Bulk added '+added+' coords');
},false);
AddHtml(bulkAddDiv,"<br />");
var bulkAddAttackLink=document.createElement('a');
bulkAddAttackLink.className='buttonDown20';
bulkAddAttackLink.innerHTML='<span>Bulk add coords</span>';
bulkAddAttackLink.addEventListener('click',function() {
if(bulkAddDiv.style.display=='inline'){
bulkAddDiv.style.display='none';
}else{
bulkAddDiv.style.display='inline';
}
},false);
div.appendChild(bulkAddAttackLink);
div.appendChild(bulkAddTable);
return div;
},
hideAttackEffortsState : true,
HideAttackEfforts: function () {
var t = KOCAttack;
if (!ById('modal_attack_march_boost')) { return; }
var span = document.createElement('span');
var a = document.createElement('a');
//var txt = document.createElement('text');
a.innerHTML = 'Hide Attack/Speed Boosts';
//inp.type='checkbox';
span.appendChild(a);
//span.appendChild (txt);
if (t.hideAttackEffortsState) {
hideshow('none');
}
a.addEventListener('click', function (evt) {
t.hideAttackEffortsState = !t.hideAttackEffortsState;
hideshow();
}, false);
for (var i = 1; i < 5; i++) {
document.getElementById('modal_attack_tab_' + i).addEventListener('click', hideshow, false);
document.getElementById('modal_attack_tab_' + i).addEventListener('click', setLocationType, false);
}
return span;
function setLocationType() {
var attackTypeSelected = getAttackTypeSelected();
if(attackTypeSelected==1){
// Transport
var KOCAttackLocationType_Transport = ById("KOCAttackLocationType_Transport");
if(KOCAttackLocationType_Transport) { KOCAttackLocationType_Transport.checked = true; }
var KOCAttackBulkAddLocationType_Transport = ById("KOCAttackBulkAddLocationType_Transport");
if(KOCAttackBulkAddLocationType_Transport) { KOCAttackBulkAddLocationType_Transport.checked = true; }
}else{
// Default back to Camp
var KOCAttackLocationType_Camp = ById("KOCAttackLocationType_Camp");
if(KOCAttackLocationType_Camp) { KOCAttackLocationType_Camp.checked = true; }
var KOCAttackBulkAddLocationType_Camp = ById("KOCAttackBulkAddLocationType_Camp");
if(KOCAttackBulkAddLocationType_Camp) { KOCAttackBulkAddLocationType_Camp.checked = true; }
}
}
function hideshow() {
if (t.options.knightreset) {
var attackTypeSelected = getAttackTypeSelected();
var knightSelect = ById('modal_attack_knight');
if (attackTypeSelected != 0) { knightSelect.selectedIndex = 0; }
}
if (t.hideAttackEffortsState) {
disp = 'none';
}else{
disp = 'block';
}
ById('modal_attack_march_boost').style.display = disp;
ById('modal_attack_attack_boost').style.display = disp;
ById('modal_attack_defense_boost').style.display = disp;
var div = ById('modal_attack_speed_boost');
for (var i = 0; i < i < div.childNodes.length; i++) {
if (div.childNodes[i].className == 'section_title'){
div.childNodes[i].style.display = disp;
}
if (div.childNodes[i].className == 'section_content') {
div = div.childNodes[i];
for (i = 0; i < div.childNodes.length; i++) {
if (div.childNodes[i].style != undefined && div.childNodes[i].className != 'estimated') {
div.childNodes[i].style.display = disp;
}
}
break;
}
}
}
},
SetResourceInput:function(num,resourceCount) {
var resource=ById('modal_attack_'+num);
if(!resource) return null;
resource.value=resourceCount;
resource.style.backgroundColor='';
// send a shift key so that it recalculates
var evt = document.createEvent("KeyboardEvent");
if(evt.initKeyboardEvent) {
evt.initKeyboardEvent("keyup",true,true,null,false,false,false,false,0x10,0);
} else {
evt.initKeyEvent("keyup",true,true,null,false,false,false,false,0x10,0);
}
resource.dispatchEvent(evt);
if(parseInt(resourceCount)>0) {
if(resource.value!=resourceCount) {
this.Log('Not able to set resource count:'+num+',wanted:'+resourceCount+', count:'+resource.value);
resource.style.backgroundColor='#f88';
return 'notfull';
} else {
resource.style.backgroundColor='#ff8';
return 'full';
}
}
return 'none';
},
SetTroopInput:function(num,troopCount) {
var troop=ById('modal_attack_unit_ipt'+num);
if(!troop) return null;
if(troop.disabled) return 'notfull'; //Disable filling in of troops if field is disabled
troop.value=troopCount;
troop.style.backgroundColor='';
// send a shift key so that it recalculates
var evt = document.createEvent("KeyboardEvent");
if(evt.initKeyboardEvent) {
evt.initKeyboardEvent("keyup",true,true,null,false,false,false,false,0x10,0);
} else {
evt.initKeyEvent("keyup",true,true,null,false,false,false,false,0x10,0);
}
troop.dispatchEvent(evt);
if(parseInt(troopCount)>0) {
if(troop.value!=troopCount) {
this.Log('Not able to set troop count:'+num+',wanted:'+troopCount+', count:'+troop.value);
troop.style.backgroundColor='#f88';
return 'notfull';
} else {
troop.style.backgroundColor='#ff8';
return 'full';
}
}
return 'none';
},
GetRandTime:function(millis) {
var millisPerc=millis*(this.options.randomPercent/100);
var randSecs=Math.floor((Math.random()*millisPerc*2)-millisPerc)+millis;
return randSecs;
},
GetAutoGold:function() {
return this.GetValue('AutoGold,'+this.GetCurrentCityId(),true);
},
SetAutoGold:function(v) {
return this.SetValue('AutoGold,'+this.GetCurrentCityId(),v);
},
GetAbandonWilds:function() {
return this.GetValue('AbandonWilds_'+this.GetCurrentCityId(),false);
},
SetAbandonWilds:function(v) {
return this.SetValue('AbandonWilds_'+this.GetCurrentCityId(),v);
},
CheckAutoRaiseGold:function() {
if(!this.GetAutoGold()) return;
var happiness=parseInt(this.GetSeed().citystats["city" + this.GetCurrentCityId()].pop[2]);
if(happiness>=this.options.autoGoldHappiness) {
this.DoUnsafeWindow("modal_raise_gold();");
}
},
CheckAbandonWilds:function() {
if(!this.GetAbandonWilds()) return;
var t=this;
var castle=ById('slot_0');
nHtml.Click(castle);
this.DoUnsafeWindow("changeCastleModalTabs(2);");
var wildsWindow=ById('castle_2');
var rows=wildsWindow.getElementsByTagName('tr');
if (rows.length==1) { //no wilds
this.DoUnsafeWindow("Modal.hideModal();");
return;
}
var commands = new Array();
for (i=0;i<rows.length;i++) {
var abandonButton=rows[i].getElementsByTagName('a')[1];
if (abandonButton==undefined) {
continue;
}
var command=abandonButton.getAttribute('onclick');
command=command.substring(0,command.length-13);
if(command.indexOf("wilderness_abandon")>-1){
var tmp_obj = new Object;
tmp_obj.command = command;
tmp_obj.clicked = false;
commands.push(tmp_obj);
}
}
var command_timer=0;
var milliseconds_between=4000;
for (var i=0;i<commands.length;i++) {
window.setTimeout(function() {
// Determine next unclicked button
var unclicked_commandObj = undefined;
for (var j=0;j<commands.length;j++) {
if(!commands[j].clicked){
t.DoUnsafeWindow(commands[j].command);
window.setTimeout(function() {
var mainbody = ById("mainbody");
if(mainbody){
var okay_btn=nHtml.FindByXPath(mainbody,".//a[contains(@class,'okay')]");
if(okay_btn){
nHtml.Click(okay_btn);
}
}
},500);
commands[j].clicked = true;
break;
}
}
},t.GetRandTime(command_timer));
command_timer+=milliseconds_between;
}
window.setTimeout(function() {
t.DoUnsafeWindow("Modal.hideModal();");
},t.GetRandTime(command_timer));
},
GetDisplayName:function(){
var DisplayName = ById('topnavDisplayName');
if(DisplayName){
DisplayName = DisplayName.innerHTML;
}else{
DisplayName = null;
}
return DisplayName
},
HandleChatPane:function() {
var t=this;
// Determine our own name so we can ignore our own requests
var DisplayName = t.GetDisplayName();
// Process chat pane
var AllianceChatBox=ById('mod_comm_list2');
if(AllianceChatBox){
var chatPosts = document.evaluate(".//div[contains(@class,'chatwrap')]", AllianceChatBox, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
if(chatPosts){
// Loop through each post
for (var i = 0; i < chatPosts.snapshotLength; i++) {
thisPost = chatPosts.snapshotItem(i);
//t.Log(thisPost.innerHTML);
// Automatically help out with alliance requests
if(this.options.autoHelpAlliance){
// Make sure that this isn't our own request
var postAuthor = document.evaluate('.//*[@class="nm"]', thisPost, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
if(postAuthor.snapshotItem(0)){
var postAuthorName = postAuthor.snapshotItem(0).innerHTML;
if(postAuthorName != DisplayName){
// Look for any alliance assist links in this current post item
var helpAllianceLinks=document.evaluate(".//a[contains(@onclick,'claimAllianceChatHelp')]", thisPost, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
if(helpAllianceLinks){
for (var j = 0; j < helpAllianceLinks.snapshotLength; j++) {
thisLink = helpAllianceLinks.snapshotItem(j);
// Check to see if link has already been clicked
var alreadyClicked = thisLink.getAttribute("clicked");
if(!alreadyClicked){
// Mark it as clicked
thisLink.setAttribute('clicked', 'true');
// Execute the onclick code
var myregexp = /(claimAllianceChatHelp\(.*\);)/;
var match = myregexp.exec(thisLink.getAttribute("onclick"));
if (match != null) {
onclickCode = match[0];
//t.Log(onclickCode);
// Check alliance help command history to make sure link hasn't already been processed
if(!t.FindInCommandHistory(onclickCode, 'alliance_help')){
t.DoUnsafeWindow(onclickCode);
// Add the onclick code to the alliance help command history
this.AddToCommandHistory(onclickCode, 'alliance_help');
}else{
//t.Log("already clicked");
}
}
}else{
//t.Log("already clicked");
}
}
}else{
//t.Log("no alliance links found in current post");
}
}else{
//t.Log("current post is by yourself");
}
}else{
//t.Log("unable to find post's author");
}
}
// Hide alliance requests in chat
if(this.options.hideAllianceHelpRequests){
// Look for any alliance assist links in this current post item
var helpAllianceLinks=document.evaluate(".//a[contains(@onclick,'claimAllianceChatHelp')]", thisPost, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
if(helpAllianceLinks){
for (var j = 0; j < helpAllianceLinks.snapshotLength; j++) {
thisLink = helpAllianceLinks.snapshotItem(j);
// Delete the post item from the DOM
thisLink.parentNode.parentNode.parentNode.parentNode.parentNode.removeChild(thisLink.parentNode.parentNode.parentNode.parentNode);
}
}
}
// Hide alliance reports in chat
if(this.options.hideAllianceHelpRequests){
// Look for any alliance assist links in this current post item
var myregexp1 = /You are # [1-5] of 5 to help/i;
var myregexp2 = /\'s Kingdom does not need help\./i;
var myregexp3 = /\'s project has already been completed\./i;
var myregexp4 = /\'s project has received the maximum amount of help\./i;
if (thisPost.innerHTML.match(myregexp1) || thisPost.innerHTML.match(myregexp2) || thisPost.innerHTML.match(myregexp3) || thisPost.innerHTML.match(myregexp4)) {
// Delete the post item from the DOM
thisPost.parentNode.removeChild(thisPost);
}
}
}
}
}
},
HandlePublishPopup:function() {
var t=this;
if (t.currentPage == "facebook_popup") {
if(t.options.autoPublishGamePopups){
// Check the app id (we only want to handle the popup for kingdoms of camelot)
var FBInputForm = ById('uiserver_form');
if(FBInputForm){
var channel_input = nHtml.FindByXPath(FBInputForm,".//input[contains(@name,'channel')]");
if(channel_input){
var current_channel_url = channel_input.value;
if (current_channel_url.match(/http:\/\/.{0,100}kingdomsofcamelot\.com\/.*?\/cross_iframe\.htm/i)) {
var publish_button = nHtml.FindByXPath(FBInputForm,".//input[@type='submit' and contains(@name,'publish')]");
var privacy_setting = nHtml.FindByXPath(FBInputForm,".//input[@type='hidden' and contains(@name, 'privacy_data') and contains(@name, 'value')]");
if(publish_button && privacy_setting){
// 80: Everyone
// 50: Friends of Friends
// 40: Friends Only
// 10: Only Me
privacy_setting.value = t.options.autoPublishPrivacySetting;
nHtml.Click(publish_button);
}
}
}
}
}
}
},
domainLoginTimer:null,
domainLoginStartTime:null,
domainLoginCurrentTime:null,
domainLoginSeconds:30,
domainLoginActionTaken:false,
HandleDomainLogin:function() {
var t=this;
if (t.currentPage == "domain_selection" && t.options.autoLogBackIn && !t.domainLoginActionTaken) {
if(!t.domainLoginStartTime){
t.domainLoginStartTime = Math.round(new Date().getTime() / 1000);
}
t.domainLoginCurrentTime = Math.round(new Date().getTime() / 1000);
var timeDifference = Math.round(t.domainLoginStartTime+t.domainLoginSeconds - t.domainLoginCurrentTime);
if(timeDifference<0){ timeDifference=0; }
var statusDiv=ById('KOCAttackLoginStatus');
if(!statusDiv) {
statusDiv=document.createElement('div');
statusDiv.id='KOCAttackLoginStatus';
statusDiv.style.position='relative';
statusDiv.style.backgroundColor='#fff';
statusDiv.style.border='3px solid #888';
statusDiv.style.margin='30px 0px 0px 0px';
statusDiv.style.padding='10px';
statusDiv.style.display='none';
var loginBox = ById("formoptions0");
loginBox.appendChild(statusDiv);
}
// Find the top-most domain in the list (the most recent one)
var playButtons=document.evaluate(".//a[contains(@class,'button20')]", unsafeWindow.document.body, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
if(playButtons && playButtons.snapshotLength>0){
//var firstPlayButton = playButtons.snapshotItem(0);
//var domain_name = firstPlayButton.parentNode.parentNode.firstChild.innerHTML;
//statusDiv.innerHTML='<center>KoCAttack Extra: Automatically logging into '+domain_name+' in '+timeDifference+' seconds...</center>';
statusDiv.innerHTML='<center>KoCAttack Extra: Automatically logging back into KoC in '+timeDifference+' seconds...</center>';
if(timeDifference==0){
//t.Log("Loading URL: "+firstPlayButton.href);
t.Log("Loading URL: http://apps.facebook.com/kingdomsofcamelot/");
//statusDiv.innerHTML='<center>KoCAttack Extra: Automatically logging into '+domain_name+' now...</center>';
statusDiv.innerHTML='<center>KoCAttack Extra: Automatically logging back into KoC now...</center>';
var functionCall = {
'action':'load_url',
//'parameters':firstPlayButton.href
'parameters':'http://apps.facebook.com/kingdomsofcamelot/'
};
t.AddCrossIframeCommand("domain_selection_app_page", functionCall);
t.domainLoginActionTaken=true;
// Reload current window if things are unsuccessful
window.setTimeout(function() {
t.ReloadWindow();
},10000);
}
}else{
statusDiv.innerHTML='<center>KoCAttack Extra: Automatically reloading page in '+timeDifference+' seconds...</center>';
if(timeDifference==0){
statusDiv.innerHTML='<center>KoCAttack Extra: Automatically reloading page now...</center>';
t.ReloadWindow();
t.domainLoginActionTaken=true;
}
}
statusDiv.style.display='block';
if(!t.domainLoginTimer && !t.domainLoginActionTaken) {
t.domainLoginTimer=window.setTimeout(function() {
t.domainLoginTimer=null;
t.HandleDomainLogin();
},1000);
}
}
},
HandleCrossIframeCommands:function() {
var t=this;
var commands = t.GetCrossIframeCommands();
if(!commands.queue) return false;
var commandsUpdated = false;
for(var i=0; i<commands.queue.length; i++) {
var command = commands.queue[i];
// Cross-iframe Command structure:
// commands {
// command {
// 'pageName' (string) - The page to execute the code on
// 'functionCall' (string) - The function to call
// }
// }
if(t.currentPage == command.pageName){
if(command.functionCall.action == "load_url"){
setTimeout (function (){window.location.href=command.functionCall.parameters;}, 0);
}
ArrayRemoveItem(commands.queue, i);
commandsUpdated=true;
}
}
if(commandsUpdated){
this.SetCrossIframeCommands(commands);
}
},
OnCastleBoxAppear:function(box) {
var raiseGold=nHtml.FindByXPath(box,".//a[contains(@onclick,'raiseGold')]");
var a=document.createElement('a');
a.className='button25';
var t=this;
function SetAutoGoldA() {
var str=t.GetAutoGold()?'Auto - On':'Auto - Off';
a.innerHTML='<span>'+str+'</span>';
}
a.addEventListener('click',function() {
var autoGold=t.GetAutoGold();
t.SetAutoGold(autoGold?false:true);
SetAutoGoldA();
},false);
SetAutoGoldA();
raiseGold.parentNode.insertBefore(a,raiseGold.nextSibling);
var productionHeader=nHtml.FindByXPath(box,".//div[contains(@class,'prodtableheader')]");
productionHeader=productionHeader.parentNode;
var b=document.createElement('a');
b.className='button25';
function SetAbandonWildsA() {
var str=t.GetAbandonWilds()?'Abandon Wilds - On':'Abandon Wilds - Off';
b.innerHTML='<span>'+str+'</span>';
}
b.addEventListener('click',function() {
var abandonWilds=t.GetAbandonWilds();
if(!abandonWilds){
var abandonWildsConfirm = confirm("Are you sure you want to automatically abandon all wildernesses?\n")
if (!abandonWildsConfirm){
return false;
}
}
t.SetAbandonWilds(abandonWilds?false:true);
SetAbandonWildsA();
},false);
SetAbandonWildsA();
//raiseGold.parentNode.insertBefore(b,raiseGold.nextSibling);
productionHeader.parentNode.insertBefore(b,productionHeader);
},
ClickShareToWall:function(box) {
var t=this;
if(t.options.autoPublishGamePopups){
var sharetowall_btn = nHtml.FindByXPath(box,".//a[contains(@onclick,'gethelp')]");
nHtml.Click(sharetowall_btn);
}
},
marketBoxTimeout:null,
OnMarketBoxAppear:function(box) {
var marketBox=ById('marketmain_bdy');
var t=this;
if(marketBox) {
window.setTimeout(function() {
t.OnMarketBoxAppear();
},250);
var amt=ById('marketmod_amount');
if(amt && amt.value=="0") amt.value='999000';
var price=ById('marketmod_price');
if(price && price.value=="0") price.value='1';
}
},
nextAutoAttackTimeout:null,
onclickTimeRe:/,([0-9]+),[0-9]+,[0-9]+,[0-9]+[^,]*$/,
waitForAttackBoxAppear:null,
knightmarchid:0,
OnAttackBoxAppear:function(box) {
var btnMarch=ById('btnMarch');
var t=this;
if(!btnMarch) {
this.Log('no march button');
window.setTimeout(function() {
t.OnAttackBoxAppear(box);
},1000);
return;
}
this.StopWaitForAttackBoxAppear();
if(ById('KocAttackComment')) {
this.Log("We already have an attack dialog opened");
return;
}
var addAttackContainerDiv=document.createElement('div');
addAttackContainerDiv.id = "addAttackButtonContainerDiv";
addAttackContainerDiv.style.position = "relative";
addAttackContainerDiv.style.width = "1px";
addAttackContainerDiv.style.height = "1px";
addAttackContainerDiv.style.overflow = "visible";
var addAttackDiv=document.createElement('div');
addAttackDiv.id = "addAttackButtonDiv";
addAttackDiv.style.width = "250px";
addAttackDiv.style.left = "430px";
addAttackDiv.style.top = "5px";
addAttackDiv.style.position = "absolute";
addAttackDiv.style.overflow = "visible";
addAttackDiv.style.textAlign="left";
var addBtn=document.createElement('a');
addBtn.className='button25';
addBtn.style.cssFloat="left";
addBtn.innerHTML='<span>Add Attack</span>';
addBtn.addEventListener('click',function() {
t.ClickMarch(null, box, true, true);
},false);
addAttackDiv.appendChild(addBtn);
addAttackContainerDiv.appendChild(addAttackDiv);
var locationTypeDiv=document.createElement('div');
locationTypeDiv.id="KOCAttackLocationTypeDiv"
locationTypeDiv.style.width="300px"
locationTypeDiv.style.position="absolute";
locationTypeDiv.style.left="0px";
locationTypeDiv.style.top="-23px";
locationTypeDiv.style.fontSize="10px";
locationTypeDiv.style.textAlign="left";
// radio boxes for defining bulk coordinate type
var arrData = [["Camp", "Camp"],["City", "City"],["Transport", "Transport"],["Wilderness", "Wilderness"]];
for (var i=0; i < arrData.length; i++){
var objRadItem = document.createElement("input");
objRadItem.type = "radio";
objRadItem.name = "KOCAttackLocationType";
objRadItem.id = "KOCAttackLocationType_" + arrData[i][0];
objRadItem.value = arrData[i][0];
if(i == 0) {objRadItem.defaultChecked = true; objRadItem.checked = true; };
var objTextNode = document.createTextNode(" " + arrData[i][1]);
var objLabel = document.createElement("label");
objLabel.htmlFor = objRadItem.id;
objLabel.appendChild(objRadItem);
objLabel.appendChild(objTextNode);
locationTypeDiv.appendChild(objLabel);
objRadItem.addEventListener('change',function() {
var locationType = "Camp"; // Set default value to camp
var locationTypeRadioBoxes = ByName('KOCAttackLocationType');
if(locationTypeRadioBoxes){
for(var i = 0; i < locationTypeRadioBoxes.length; i++) {
if(locationTypeRadioBoxes[i].checked) {
locationType = locationTypeRadioBoxes[i].value;
break;
}
}
}
// Select the same radio box in the bulk add area
var bulkLocationTypeRadioBoxes = ByName('KOCAttackBulkAddLocationType');
if(bulkLocationTypeRadioBoxes){
for(var i = 0; i < bulkLocationTypeRadioBoxes.length; i++) {
if(bulkLocationTypeRadioBoxes[i].value == locationType) {
bulkLocationTypeRadioBoxes[i].checked = true;
break;
}
}
}
},false);
};
addAttackDiv.appendChild(locationTypeDiv);
var suicideSpan=document.createElement('span');
suicideSpan.style.fontSize="11px";
var suicideCheckbox=document.createElement('input');
suicideCheckbox.id = "KOCAttackSuicideWaveCheckbox";
suicideCheckbox.name = suicideCheckbox.id;
suicideCheckbox.type='checkbox';
suicideSpan.appendChild(suicideCheckbox);
AddHtml(suicideSpan,'<label for="KOCAttackSuicideWaveCheckbox">This is a suicide wave</label>');
addAttackDiv.appendChild(suicideSpan);
suicideCheckbox.addEventListener('click',function() {
var bulkAddSuicideWaveCheckbox = ById("KOCAttackBulkAddSuicideWave");
var locationType_Wilderness = ById("KOCAttackLocationType_Wilderness");
var bulkAddLocationType_Wilderness = ById("KOCAttackBulkAddLocationType_Wilderness");
if(bulkAddSuicideWaveCheckbox && locationType_Wilderness && bulkAddLocationType_Wilderness){
if(suicideCheckbox.checked){
bulkAddSuicideWaveCheckbox.checked = true;
locationType_Wilderness.checked = true;
bulkAddLocationType_Wilderness.checked = true;
}else{
bulkAddSuicideWaveCheckbox.checked = false;
}
}
},false);
if(btnMarch){
btnMarch.parentNode.insertBefore(addAttackContainerDiv,btnMarch);
}
var comment=document.createElement('input');
comment.id='KocAttackComment';
comment.size='30';
var nowSecs=new Date().getTime()/1000;
var div=document.createElement('div');
AddText(div,'Comment:');
div.appendChild(comment);
div.appendChild(document.createElement('br'));
var div2=document.createElement('div');
var ignore=document.createElement('input');
ignore.type='checkbox';
div2.appendChild(ignore);
AddText(div2,'Ignore in the attack list');
var div3=document.createElement('div');
var deletefarmno=document.createElement('input');
deletefarmno.type='checkbox';
div3.appendChild(deletefarmno);
AddText(div3,'Do not delete this report');
var nextElement=ById('marchTypeDesc');
//nextElement.parentNode.insertBefore(div2, nextElement.nextSibling);
//div.appendChild(document.createElement('br'));
div.appendChild (div2);
div2.appendChild (div3);
var xy=this.GetGuiCoords();
var attack=null;
if(xy) {
attack=this.GetAttack(xy[0],xy[1]);
}
var notFullTroops=false;
var notFullResources=false;
var knightSelect=ById('modal_attack_knight');
var totalTroops=0;
var totalResources=0;
var attackTypeSelected = getAttackTypeSelected();
if(attack) {
ignore.checked=attack.ignore?true:false;
deletefarmno.checked=attack.deletefarmno?true:false;
if(attack.time) {
AddHtml(div,'Last attack: '+SecsToStr(nowSecs-attack.time)+' ago<br />');
}
if(attack.comment){
comment.value=attack.comment;
}
// Select the attack type radio boxes
var wildtype={
'Lake':'Wilderness',
'Mountains':'Wilderness',
'Woods':'Wilderness',
'Forest':'Wilderness',
'Plain':'Wilderness',
'Hills':'Wilderness',
'Grassland':'Wilderness',
'Wilderness':'Wilderness' // Unknown wilderness type
};
var levelInfo=this.GetLevelInfo(attack);
var locationType = "City"; // Default to city
if(levelInfo && levelInfo.type) {
locationType = levelInfo.type;
}
if(wildtype[levelInfo.type]) {
locationType = wildtype[levelInfo.type];
}
// Select the location type radio box in the normal add area
var locationTypeRadioBoxes = ByName('KOCAttackLocationType');
if(locationTypeRadioBoxes){
for(var i = 0; i < locationTypeRadioBoxes.length; i++) {
if(locationTypeRadioBoxes[i].value == locationType) {
locationTypeRadioBoxes[i].checked = true;
break;
}
}
}
// Select the location type radio box in the bulk add area
var bulkLocationTypeRadioBoxes = ByName('KOCAttackBulkAddLocationType');
if(bulkLocationTypeRadioBoxes){
for(var i = 0; i < bulkLocationTypeRadioBoxes.length; i++) {
if(bulkLocationTypeRadioBoxes[i].value == locationType) {
bulkLocationTypeRadioBoxes[i].checked = true;
break;
}
}
}
// only fill things in if we're in attack mode.
if(attackTypeSelected==0 && attack.type==0) { // if 'attack' mode
SuicideAttackDefined = this.isSuicideAttackDefinedAtLocation(xy[0], xy[1])
if(this.prevAttack) { this.Log('Previous attack:'+this.prevAttack.x+'=='+xy[0] +','+this.prevAttack.y+'=='+xy[1] ); }
var firstAttack = this.IsFirstAttackAtLocation(xy[0], xy[1]);
this.Log("current attack wave type: "+attack.currenttattackwavetype);
if(SuicideAttackDefined && firstAttack) {
// anti traps suicide wave attack
if(typeof(attack.suicidewave)=="object") {
for(var i=1; i<attack.suicidewave.length; i++) {
this.SetTroopInput(i,attack.suicidewave[i]);
totalTroops+=attack.suicidewave[i];
}
} else {
this.SetTroopInput(2,attack.suicidewave);
totalTroops+=attack.suicidewave;
}
// Check the suicide wave checkbox
suicideCheckbox.checked = true;
} else if(attack.troops) {
for(var tr=0; tr<attack.troops.length; tr++) {
var troopCount=attack.troops[tr];
if(!troopCount) continue;
totalTroops+=troopCount;
if(this.SetTroopInput(tr,troopCount)=='notfull') {
notFullTroops=true;
}
}
// Make sure the suicide wave checkbox is *not* checked
suicideCheckbox.checked = false;
}
//attackTypeSelect.selectedIndex=attack.type;
if(this.knightmarchid == knightSelect.options[knightSelect.selectedIndex].value){
knightSelect.selectedIndex = 1+Math.floor(Math.random()*(knightSelect.options.length-1)); //Select random knight if last knight didn't go out
}
} else if (attackTypeSelected==1 && attack.type==1) { // transport
ById('KOCAttackLocationType_Transport').checked;
// If transporting, we enable all troop types. No reason to restrict ourselves to just normal supply troops!
var supplyfilter_checkbox = ById('modal_attack_supplyfilter_checkbox');
if(supplyfilter_checkbox){
if(supplyfilter_checkbox.checked){
supplyfilter_checkbox.click();
}
}
var resourceTypes = new Array(
'gold',
'rec1',
'rec2',
'rec3',
'rec4'
);
for(var tr=0; tr<attack.troops.length; tr++) {
var troopCount=attack.troops[tr];
if(!troopCount) continue;
totalTroops+=troopCount;
if(this.SetTroopInput(tr,troopCount)=='notfull') {
this.Log("Input field disabled for troop type: "+tr);
notFullTroops=true;
}
}
for(var res=0; res<attack.resources.length; res++) {
var resourceCount=attack.resources[res];
if(!resourceCount) continue;
totalResources+=resourceCount;
if(this.SetResourceInput(resourceTypes[res],resourceCount)=='notfull') {
notFullResources=true;
}
}
// We don't send a knight with transports
knightSelect.selectedIndex = 0;
}
if(attack.messages) {
div.appendChild(document.createElement('br'));
for(var m=attack.messages.length-1; m>=0; m--) {
var message=attack.messages[m];
var ma=document.createElement('a');
var mess=message[0];
var timeNumM=this.onclickTimeRe.exec(message[1]);
if(timeNumM) {
var secs=nowSecs-parseInt(timeNumM[1]);
mess=SecsToStr(secs)+' ago, '+mess;
//mess=(new Date(parseFloat(timeNumM[1])*1000).toLocalString())+', '+mess;
}
ma.innerHTML=mess;
//{"time":1273315720.514,"troops":"test","type":0,"messages":[["Attack (326,97) - Barbarian Camp Lv. 2 (NewCity4216)","modal_messages_viewreports_view(\"529747\",1,51,2,0,\"Enemy\",\"0\",\"niknah\",\"M\",4,326,97,1273312617,1,333,110);return false;"],["Attack (326,97) - Barbarian Camp Lv. 2 (NewCity4216)","modal_messages_viewreports_view(\"529747\",1,51,2,0,\"Enemy\",\"0\",\"niknah\",\"M\",4,326,97,1273312617,0,333,110);return false;"]]}
ma.setAttribute('onclick',"var m=CreateMsgDiv(); "+ message[1]+'');
ma.href='javascript:;';
div.appendChild(ma);
div.appendChild(document.createElement('br'));
}
div.appendChild(document.createElement('br'));
}
// Show the "Delete Attack" button
var deleteBtnDiv=document.createElement('div');
deleteBtnDiv.id = "deleteAttackButtonDiv";
deleteBtnDiv.style.width = "115px";
deleteBtnDiv.style.left = "203px";
deleteBtnDiv.style.top = "5px";
deleteBtnDiv.style.position = "absolute";
var deleteBtn=document.createElement('a');
deleteBtn.className='button25';
deleteBtn.innerHTML='<span>Delete Attack</span>';
deleteBtn.addEventListener('click',function() {
t.DeleteAttack(xy[0],xy[1]);
t.DoUnsafeWindow('Modal.hideModalAll();');
},false);
deleteBtnDiv.appendChild(deleteBtn);
addAttackContainerDiv.appendChild(deleteBtnDiv);
//div.insertBefore (deleteBtn, div.firstChild);
}
var ChangeAttack=function() {
var xy=t.GetGuiCoords();
var attack=null;
if(xy) {
attack=t.GetAttack(xy[0],xy[1]);
}
if(!attack) attack={};
if(getAttackTypeSelected()!=attack.type) {
t.Log('We wont change an attack if the type is different. You must delete the attack to change the type');
return;
}
attack.comment=comment.value;
attack.ignore=ignore.checked?true:undefined;
attack.deletefarmno=deletefarmno.checked?true:undefined;
t.SetAttack(xy[0],xy[1],attack);
}
comment.addEventListener('change',function() { ChangeAttack(); },false);
ignore.addEventListener('change',function() { ChangeAttack(); },false);
deletefarmno.addEventListener('change',function() { ChangeAttack(); },false);
var divContainer = document.createElement ('div');
divContainer.style.padding = '0px 12px';
divContainer.style.height = '320px';
divContainer.style.maxHeight = '320px';
divContainer.style.overflowY = 'auto';
divContainer.appendChild(this.HideAttackEfforts());
divContainer.appendChild(div);
divContainer.appendChild(this.BulkAddAttackLink(box));
document.getElementById ('modal_attack').appendChild(divContainer);
this.AttachXYPaste('modal_attack_target_coords_x','modal_attack_target_coords_y');
var autoAttack=this.GetAutoAttack();
if(autoAttack && autoAttack.x==xy[0] && autoAttack.y==xy[1] && !ignore.checked) {
autoAttack.x=autoAttack.y=-1;
this.SetAutoAttack(autoAttack);
if(totalTroops>0
&& (knightSelect.options.length>1 || attackTypeSelected==1)//If transport you don't need knights(Thanks to shalm for pointing that out)
&& !notFullTroops
&& !notFullResources
&& btnMarch.className.indexOf('grey')<0
) {
this.Log('Auto attack: '+xy[0]+','+xy[1]+', from city:'+this.autoAttackCityUpto);
var t=this;
window.setTimeout(function() {
t.autoAttacksThisCity++;
t.ClickMarch(btnMarch, box, false);
this.knightmarchid = knightSelect.options[knightSelect.selectedIndex].value;
//t.ResetIdStatus();
},t.GetRandTime(1000));
if(!this.nextAutoAttackTimeout) {
this.nextAutoAttackTimeout=setTimeout(function() {
// let's attack again in a few secs.
t.nextAutoAttackTimeout=null;
t.NextAutoAttack();
},t.GetRandTime(1000*this.options.attackDelay));
} else {
this.Log('Cannot continue auto attacking, about to attack or change city');
}
return;
} else {
this.Log('Unable to send attack to '+xy[0]+','+xy[1]+', knights avail:'+(knightSelect.options.length-1)+', Not enough troops: '+notFullTroops+'(need '+totalTroops+'). Not enough resources:'+notFullResources+' (need '+totalResources+')');
this.DoUnsafeWindow("Modal.hideModal();");
this.NextAutoAttackCity();
}
}
},
ClickMarch:function(btnMarch, box, alert, resetTime){
if(!resetTime){resetTime=false;}
var t = this;
if(btnMarch){
nHtml.Click(btnMarch);
window.setTimeout(function() {
var mist=nHtml.FindByXPath(document,".//div[@class='mistwarn']");
if(mist) {
t.DoUnsafeWindow("Modal.hideModal();");
t.DoUnsafeWindow("modal_attack_do();");
}
},t.GetRandTime(200));
}
var added = t.SetAttackFromGui(box, resetTime);
t.SetValuesCache();
if(added){
if(alert){
window.alert("Added attack");
}
}
},
coordsRe:/\(([0-9]+),([0-9]+)\)/,
maptileRe:/modal_maptile.([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+)/,
OnToolTipAppear:function(box) {
var box1=box.childNodes[0].childNodes[0];
var m=this.coordsRe.exec(box.innerHTML);
if(!m || m.length==0) return;
var x=m[1]; var y=m[2];
var a=ById('l_'+x+'_t_'+y);
if(a) {
var onclick=a.getAttribute('onclick');
if(onclick) {
var titleM=this.maptileRe.exec(onclick);
if(titleM && titleM[8].indexOf('null')<0) {
AddHtml(box1,'Title: '+titleM[8].StripQuotes()+'<br />');
}
}
}
var attack=this.GetAttack(x,y);
if(!attack) return;
var troops=attack.troops;
if(troops && troops.length>0) {
var lastAttack=parseInt(attack.time);
var nowSecs=new Date().getTime()/1000;
var lastAttackStr='Last attack: '+SecsToStr(nowSecs-lastAttack)+' ago'+(attack.ignore?' <b>(ignore)</b> ':'');
AddHtml(box1,lastAttackStr+'<br />');
if(attack.comment) {
AddHtml(box1,attack.comment+'<br />');
}
}
},
/*
// don't know why but messages get duped sometimes.
FixMessages:function(attack) {
var fixed=0;
var done={};
for(var m=0; m<attack.messages.length; m++) {
if(!done[attack.messages[m][1]]) {
done[attack.messages[m][1]]=true;
GM_log('ffff:'+attack.messages[m][1]+'####'+typeof(attack.messages[m][1]));
} else {
attack.messages.splice(m,1);
fixed++;
}
}
return fixed;
},
*/
CalcXYDist:function(a,b) {
var xdist=parseInt(a.x)-parseInt(b.x);
xdist=Math.abs(xdist);
if(xdist>=375) xdist=750-xdist;
var ydist=parseInt(a.y)-parseInt(b.y);
ydist=Math.abs(ydist);
if(ydist>=375) ydist=750-ydist;
return Math.sqrt((xdist*xdist)+(ydist*ydist));
},
//attackRe:/\s+(\S+)\s+Lv\.\s*([0-9]+)/,
//javascript:Messages.viewMarchReport("22891795",0,51,10,1550996,"oftheNOOBS","M","Debby32","F",1,430,205,1302284981,1,284,83);
squareTypeNums:{
'51':'Camp',
'10':'Grassland',
'11':'Lake',
'20':'Forest',
'30':'Hills',
'40':'Mountains',
'50':'Plain',
'0':'Bog'
},
FindLevelFromMessages:function(attack) {
if(!attack || !attack.messages) return null;
for(var a=0; a<attack.messages.length; a++) {
var m=this.onclickReportRe.exec(attack.messages[a][1]);
if(!m) {
this.Log("Unable to find location level/type information in cached reports!");
continue;
}
var typeNum=m[3].replace('"','');
var type=this.squareTypeNums[typeNum];
if(!type) {
this.Log("Unable to find location type information in cached reports!");
continue;
}
if(typeNum=="51" && m[5]!='0') { //Gradually replace all attack types to follow Tom's new method of storing attacks
if(attack.type==0){
type='City';
} else if (attack.type==1){
type='Transport';
}
}
//this.Log("Target Type: "+type+", Target Level: "+m[4]);
return {'type':type,'level':m[4]};
}
return null;
},
DrawLevelIcons:function() {
var mapwindow=ById('mapwindow');
if(!mapwindow) return;
var levelIcons=ById('LevelIcons');
if(levelIcons) return;
var ss=document.evaluate(".//a[contains(@class,'slot')]",mapwindow,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
var lvRe=/_([0-9]+)/;
var idDone=false;
for(var s=0; s<ss.snapshotLength; s++) {
var a=ss.snapshotItem(s);
var onclick=a.getAttribute('onclick');
var owner='';
if(onclick) {
var onclickM=this.maptileRe.exec(onclick);
if(onclickM && onclickM[6]!='"null"' && onclickM[12]!='"city"') {
var might=onclickM[7].StripQuotes();
//var alliance=onclickM[9].StripQuotes();
//+"<br />"+(alliance=="null"?"":alliance);
owner=" "+onclickM[6].StripQuotes()+'<br />Might:'+might;
}
}
var m=lvRe.exec(a.className);
if(!m) continue;
var sp=a.getElementsByTagName('span');
if(sp.length==0) continue;
if(!idDone) { a.id='levelIcons'; idDone=true; }
sp[0].style.color='#cc0';
//sp[0].innerHTML='<center>'+m[1]+'</center>';
sp[0].innerHTML=' '+m[1]+owner;
}
},
AttachXYPaste:function(xId,yId,func) {
var x=ById(xId);
if(!x) {
this.Log('Cannot find x coord box: '+xId);
return;
}
var attached=x.getAttribute('KOCpasteAttached');
if(attached) return;
x.setAttribute('maxlength','20');
var onchange=function() {
var xValue=x.value.trim();
var xI=/^\s*([0-9]+)[\s|,|-|.]+([0-9]+)/.exec(xValue);
if(xI) {
var y=ById(yId);
x.value=xI[1]
y.value=xI[2]
if(func!=undefined) func(xI[0],xI[1]);
}
}
x.setAttribute('KOCpasteAttached',true);
x.addEventListener('keyup',function() { onchange(); },false);
x.addEventListener('change',function() { onchange(); },false);
},
GetClosestAttacks:function(x,y) {
var attacks=[];
var t=this;
this.IterateAttacks(function(name,value) {
var nameI=name.split('_');
if(nameI.length<3) return;
var xy=nameI[2].split(',');
if(value=="") return;
var attack=JSON2.parse(value);
if(!attack) return;
if(attack.ignore) return;
var dist=t.CalcXYDist({'x':xy[0],'y':xy[1]},{'x':x,'y':y});
if (dist==0) { return; } // Don't attack yourself
if(dist>=t.options.attackMaxDistance) { return; }
if(t.options.lockAttackFromCity && attack.fromCity!=unsafeWindow.currentcityid) { return; }
attacks.push({'dist':dist,'x':xy[0],'y':xy[1],'a':attack});
});
attacks.sort(function(a,b) {
return a.dist-b.dist;
});
return attacks;
},
IsEnoughTroops:function(currentTroops,neededTroops) {
for(var t=0; t<neededTroops.length; t++) {
if(!neededTroops[t]) continue;
if(parseInt(neededTroops[t])>parseInt(currentTroops[t])) {
return false;
}
}
return true;
},
IsEnoughResources:function(currentResources,neededResources) {
for(var t=0; t<neededResources.length; t++) {
if(!neededResources[t]) continue;
if((parseInt(neededResources[t])+parseInt(this.options.transportResourcesReserveAmount))>parseInt(currentResources[t])) {
return false;
}
}
return true;
},
currentMarchesNum:0,
available_marches_num:0,
DetermineCurrentMarchesNum:function() {
var marchesnum = 0;
var troopactivity = ById("untqueue_list");
if(troopactivity && troopactivity.style.display!="none" && troopactivity.style.visibility!="hidden"){
marchesnum = troopactivity.childNodes.length;
}
//this.Log("Current number of marches in this city: "+marchesnum);
this.currentMarchesNum = marchesnum;
return marchesnum;
},
currentRallyPointLevel:0,
DetermineCurrentRallyPointLevel:function() {
var rallypointlevel = 0;
var citymap = ById("citymap");
if(citymap){
var citylinks = nHtml.FindByXPath(citymap,'.//a[contains(@class, "bldg")]', XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
for (var i = 0; i < citylinks.snapshotLength; i++){
var building = citylinks.snapshotItem(i);
var style = window.getComputedStyle(building, false);
var css_bgimg = style.backgroundImage;
//this.Log("building background image "+i+": "+css_bgimg);
var myregexp = /rally_point_lvl/i;
var match = myregexp.exec(css_bgimg);
if (match != null) {
// Determine the rally point level based on the level tag overlay
var leveltag = nHtml.FindByXPath(building,'.//span[contains(@class, "level")]');
if(!leveltag){ continue; }
var levelnum = parseInt(leveltag.innerHTML);
if(levelnum>rallypointlevel){
rallypointlevel = levelnum;
}
} else {
var b_class = building.className.split("_");
if(b_class != null){
if(parseInt(b_class[1]) == 12){
rallypointlevel = parseInt(b_class[2]);
// this.Log("classname "+b_class[1] +" "+b_class[2]);
}
}
}
}
if(rallypointlevel==0){
// Couldn't find the rally point based on the background image. Odds are that the rally point exists,
// but is currently under construction. Let's see if we can deduce the rally point's level based on this assumption.
// Note: This will bug out if the city has literally no rally point at all, but who's really that stupid?
for (var i = 0; i < citylinks.snapshotLength; i++){
var building = citylinks.snapshotItem(i);
var style = window.getComputedStyle(building, false);
var css_bgimg = style.backgroundImage;
//this.Log("building background image "+i+": "+css_bgimg);
var myregexp = /construction/i;
var match = myregexp.exec(css_bgimg);
if (match != null) {
// Determine the rally point level based on the level tag overlay
var leveltag = nHtml.FindByXPath(building,'.//span[contains(@class, "level")]');
if(!leveltag){ continue; }
var levelnum = parseInt(leveltag.innerHTML);
if(levelnum>rallypointlevel){
rallypointlevel = levelnum-1;
}
}
}
}
this.Log("Rally point level in this city is: "+rallypointlevel);
}
if(rallypointlevel==12) rallypointlevel = 11;
this.currentRallyPointLevel = rallypointlevel;
return rallypointlevel;
},
GetLevelInfo:function(attack) {
if(!attack) throw('GetLevelInfo: attack is null');
var levelI=attack.levelInfo;
//if((!levelI || levelI.level==0) && attack.messages && attack.messages.length>0) {
if((!levelI || levelI.level==0 || levelI.type=="" || levelI.type=="Camp") && attack.messages && attack.messages.length>0) { //The idea is to replace all old attacks with the new one
levelI=this.FindLevelFromMessages(attack);
}
if (!levelI && (attack.currenttattackwavetype == 'transport')){
return {'type':'Transport','level':0};
}
// if (!levelI){
// return {'type':'Camp','level':0}; // Default to camp
// }
//All old attacks for city are stored as "" So disable this option for the mean time
//if(levelI.type==""){levelI.type="Camp";}
return levelI;
},
GetAttackDelay:function(attack) {
if(!attack) throw('GetAttackDelay: attack is null');
var attackDelay = 0;
var wilderness={
'Lake':1,
'Mountains':1,
'Woods':1,
'Forest':1,
'Plain':1,
'Hills':1,
'Grassland':1,
'Wilderness':1 // Unknown wilderness type
};
var levelInfo=this.GetLevelInfo(attack);
if(!levelInfo) {
this.Log("Unable to calculate attack delay: Missing level info for coordinates ("+attack.x+","+attack.y+"). Assuming delay of 0.");
}else{
if(levelInfo.type=='Camp') {
// Camp
attackDelay = this.options.attackSecsSinceLastCamp;
} else if(wilderness[levelInfo.type]) {
// Wilderness
attackDelay = this.options.attackSecsSinceLastWild;
} else if (levelInfo.type!='Camp' && !wilderness[levelInfo.type]) {
var tempAttack=this.GetAttack(attack.x,attack.y);
if(tempAttack){
if(tempAttack.type==0) {
// City
attackDelay = this.options.attackSecsSinceLastCity;
} else if(tempAttack.type==1) {
// Transport
attackDelay = this.options.attackSecsSinceLastTransport;
}else{
this.Log("Unknown attack type for ("+attack.x+","+attack.y+"). Assuming delay of 0.");
}
}else{
this.Log("Unknown/Invalid attack specified ("+attack.x+","+attack.y+").");
}
}else{
this.Log("Unknown attack type for ("+attack.x+","+attack.y+"). Assuming delay of 0.");
}
}
return attackDelay;
},
priorityattack:true,
FindBiggestCampAttack:function(attacks,currentTroops,currentResources) {
var bestAttack=null;
var bestAttackSize=0;
var bestAttackDist=10000;
var nowSecs=new Date().getTime()/1000;
var currentCity = this.GetCurrentCityId();
// Determine the current rally point level and current marches
this.DetermineCurrentRallyPointLevel();
this.DetermineCurrentMarchesNum();
this.Log("Current Rally Point Level: "+this.currentRallyPointLevel+" Current Marches: "+this.currentMarchesNum);
var wilderness={
'Lake':1,
'Mountains':1,
'Woods':1,
'Forest':1,
'Plain':1,
'Hills':1,
'Grassland':1,
'Wilderness':1 // Unknown wilderness type
};
for(var a=0; a<attacks.length; a++) {
var attack=attacks[a];
//this.Log("Inspecting attack #"+a+": "+inspect(attack,10));
var levelInfo=this.GetLevelInfo(attack.a);
if(!levelInfo) {
this.Log("Not attacking: Missing level info! for coordinates ("+attack.x+","+attack.y+")");
continue;
}
if(levelInfo.type == ""){levelInfo.type = this.FindLevelFromMessages(attack);;} // If empty look in messages
if(levelInfo.type == ""){levelInfo.type = "City";} // If still blanck default to city
if(levelInfo.type=='Camp') {
if(this.options.attackTypeCamp!=true) {
this.Log("Not attacking: Not attacking camps! for coordinates ("+attack.x+","+attack.y+")");
continue;
}
} else if(wilderness[levelInfo.type]) {
if(this.options.attackTypeWild!=true) {
this.Log("Not attacking: Not attacking wildernesses! for coordinates ("+attack.x+","+attack.y+")");
continue;
}
} else if (levelInfo.type!='Camp' && !wilderness[levelInfo.type]) {
var tempAttack=this.GetAttack(attack.x,attack.y);
if(!tempAttack){
this.Log("Not attacking: Invalid attack entered ("+attack.x+","+attack.y+")");
continue;
}
if(tempAttack.type==0) {
if(this.options.attackTypeCity!=true) {
this.Log("Not attacking: Not attacking cities for coordinates ("+attack.x+","+attack.y+")");
continue;
}
} else if(tempAttack.type==1) {
if(this.options.attackTypeTransport!=true) {
this.Log("Not attacking: Not sending transports for coordinates ("+attack.x+","+attack.y+")");
continue;
}
}
} else {
if(levelInfo.type!='City' && levelInfo.type!='Camp') {
this.Log("Not attacking: Unknown attack type for coordinates ("+attack.x+","+attack.y+")");
continue;
}
}
if(!attack.a.troops) {
this.Log("inspect1: "+inspect(attack.a),10);
this.Log("Not attacking: No troops defined for coordinates ("+attack.x+","+attack.y+")");
continue;
}
if(attack.a.ignore) {
this.Log("Not attacking: Location ignored for coordinates ("+attack.x+","+attack.y+")");
continue;
}
if(attack.dist>=this.options.attackMaxDistance) {
this.Log("Not attacking: Distance too far for coordinates ("+attack.x+","+attack.y+")");
continue;
}
if(this.options.lockAttackFromCity) {
//this.Log('fromCity='+attack.a.fromCity+', currentCity='+this.GetCurrentCityId());
if(attack.a.fromCity!=undefined) {
if(currentCity!=attack.a.fromCity) { continue; }
}
}
var troops_to_send = attack.a.troops;
if(attack.a.suicidewave){
// count up all the troops in *both* attack waves.
// we don't want to launch suicide wave if we can't follow it up.
var suicide_troops = attack.a.suicidewave;
for(var t=0; t<suicide_troops.length; t++) {
if(!suicide_troops[t]) continue;
troops_to_send[t] = troops_to_send[t] + suicide_troops[t];
}
}
//if(!this.currentMarchesNum || this.currentMarchesNum==undefined) {
// this.Log("Not attacking: Unable to determine current number of marches (refresh your window?) for coordinates ("+attack.x+","+attack.y+")");
// continue;
//}
// Make sure we have more than two available slots in attack queue if this is a suicide wave (unless there are only two slots even allowed)
this.available_marches_num = this.currentRallyPointLevel - this.currentMarchesNum - this.options.rallyKeep;
//this.Log("Available marches: "+available_marches_num);
if(attack.a.suicidewave && attack.a.currenttattackwavetype != "normal"){
//this.Log("Current attack wave type: "+attack.a.currenttattackwavetype);
if(this.available_marches_num < 2 || this.currentRallyPointLevel < 2){
// Make sure this is the first wave of the multi-wave attack and then don't send it if there aren't enough marching slots for both waves
if(this.IsFirstAttackAtLocation(attack.x, attack.y)) {
// This is the first wave
this.Log("Not attacking: Not enough available marching slots at rally point to launch both suicide wave and second wave for coordinates ("+attack.x+","+attack.y+")");
break;
}
}
}
// Make sure we have at least one available slot in attack queue for normal attack
if(this.available_marches_num<1){
this.Log("Not attacking: Not enough marching slots at rally point to launch attack for coordinates ("+attack.x+","+attack.y+")");
break;
}
if(!this.IsEnoughTroops(currentTroops,troops_to_send)) {
this.Log("Not attacking: Not enough troops for coordinates ("+attack.x+","+attack.y+")");
continue;
}
if (attack.a.type==1) {
if(!this.IsEnoughResources(currentResources,attack.a.resources)) {
this.Log("Not attacking: Not enough resources for coordinates ("+attack.x+","+attack.y+")");
continue;
}
}
var lastAttack;
if(!attack.a.time) {
lastAttack=60*60*24*31;
} else {
lastAttack=nowSecs-parseInt(attack.a.time);
}
if(levelInfo.type=='' || levelInfo.type=='City' || levelInfo.type=='Transport') {
if(attack.a.type==0) {
if(lastAttack<this.options.attackSecsSinceLastCity) {
this.Log("Not attacking: last attack ("+lastAttack+") < this.options.attackSecsSinceLastCity ("+this.options.attackSecsSinceLastCity+") for coordinates ("+attack.x+","+attack.y+")");
continue;
}
} else {
if(lastAttack<this.options.attackSecsSinceLastTransport){
this.Log("Not attacking: last attack ("+lastAttack+") < this.options.attackSecsSinceLastTransport ("+this.options.attackSecsSinceLastTransport+") for coordinates ("+attack.x+","+attack.y+")");
continue;
}
}
} else if(levelInfo.type=='Camp') {
if(lastAttack<this.options.attackSecsSinceLastCamp) {
this.Log("Not attacking: last attack ("+lastAttack+") < this.options.attackSecsSinceLastCamp ("+this.options.attackSecsSinceLastCamp+") for coordinates ("+attack.x+","+attack.y+")");
continue;
}
} else {
if(lastAttack<this.options.attackSecsSinceLastWild) {
this.Log("Not attacking: last attack ("+lastAttack+") < this.options.attackSecsSinceLastWild ("+this.options.attackSecsSinceLastWild+") for coordinates ("+attack.x+","+attack.y+")");
continue;
}
}
var armySize=0;
for(var t=0; t<attack.a.troops.length; t++) {
if(!attack.a.troops[t]) {
continue;
}
armySize+=parseInt(attack.a.troops[t]);
}
if(attack.a.suicidewave) {
var suicideArmySize=0;
for(var t=0; t<attack.a.suicidewave.length; t++) {
if(!attack.a.suicidewave[t]) {
continue;
}
suicideArmySize+=parseInt(attack.a.suicidewave[t]);
}
if(suicideArmySize<=0) {
this.Log('Invalid suicide wave army size (not enough!) for coordinates ('+attack.x+','+attack.y+')');
continue;
}
}
if(armySize<=0) {
this.Log('Invalid suicide wave army size (not enough!) for coordinates ('+attack.x+','+attack.y+')');
continue;
}
var ok=0;
if(this.options.attackOrder=='mostTroops') {
if(bestAttackSize<armySize) {
ok=1;
}
} else {
if(this.options.attackOrder!='closest') {
this.Log('Unknown order:'+this.options.attackOrder);
}
if(bestAttackDist>attack.dist) {
ok=1;
}
}
if((this.options.attackpriority == levelInfo.type || this.options.attackpriority == 'None') && ok && this.priorityattack){
bestAttack=attack;
bestAttack.type=attack.a.type;
bestAttackSize=armySize;
bestAttackDist=attack.dist;
} else if (!this.priorityattack && ok) {
bestAttack=attack;
bestAttack.type=attack.a.type;
bestAttackSize=armySize;
bestAttackDist=attack.dist;
}
}
if(bestAttack == null && this.priorityattack){
this.priorityattack = false;
bestAttack = this.FindBiggestCampAttack(attacks,currentTroops,currentResources);
} else {
this.priorityattack = true;
}
return bestAttack;
},
IsMapperRunning:function() {
if(ById('SendMap')) {
this.Log('mapper is running, do not auto attack');
return true;
}
return false;
},
GetAutoAttack:function() {
var aStr=this.GetValue('AutoAttack','');
if(aStr=='') {
return null;
}
try {
return JSON2.parse(aStr);
} catch(e) {
this.Log('failed to parse autoattack: '+aStr);
this.SetValue('AutoAttack','');
return null;
}
},
SetAutoAttack:function(s) {
if(s) {
//this.Log("Setting Auto Attack: "+JSON2.stringify(s));
this.SetValue('AutoAttack',JSON2.stringify(s));
} else {
this.SetValue('AutoAttack','');
}
},
ResetAutoAttackTarget:function() {
var autoAttack=this.GetAutoAttack();
if(autoAttack) {
autoAttack.x=undefined;
autoAttack.y=undefined;
this.SetAutoAttack(autoAttack);
}
},
GetCurrentMapCoord:function() {
// Check to see if we are on map screen
var mapbutton = ById('mod_views_map');
if(mapbutton && mapbutton.className=='sel'){
// Return xy values from form inputs
var xcoord=ById('mapXCoor');
var ycoord=ById('mapYCoor');
if(xcoord && ycoord){
return {'x':xcoord.value,'y':ycoord.value};
}
}
// Not on map screen. Return coordinates of current city
var cities=this.GetSeed().cities;
for(i=0; i<cities.length; i++){
if(cities[i][0]==unsafeWindow.currentcityid){
return {'x':cities[i][2],'y':cities[i][3]};
break;
}
}
},
hrsInput:null,
viewTypeOnly:"",
expandedInfo:false,
DrawClosestFarms:function() {
this.SetAttackStatusMessage();
var t=this;
//unsafeWindow.statusupdate();
var bookmark=ById('maparea_map');
if(!bookmark) throw("Cannot find bookmark box");
bookmark=nHtml.FindByXPath(bookmark.parentNode,".//div[@class='coords']");
var div=ById('ClosestFarms');
if(!div) {
div=document.createElement('div');
var titleA=document.createElement('a');
titleA.innerHTML='Attacks ';
titleA.title='Closest attacks, more than ? hrs since last attack';
titleA.style.cursor='pointer';
titleA.addEventListener('click',function() {
div.style.display=div.style.display=='block'?'none':'block';
setTimeout(function() {
t.SetValue('ClosestFarmDisplay',div.style.display);
},0);
},false);
var viewTypeOnlyInp=document.createElement('input');
viewTypeOnlyInp.style.width='10px';
viewTypeOnlyInp.style.fontSize="8px";
viewTypeOnlyInp.title="Type of target. ex: P, W, M, P1";
this.hrsInput=document.createElement('input');
this.hrsInput.style.width='16px';
this.hrsInput.value=this.GetMinHours();
var hrsChanged=function() {
var v=parseFloat(t.hrsInput.value);
t.viewTypeOnly=viewTypeOnlyInp.value;
if(v!=undefined && v!=NaN) {
t.SetMinHours(t.hrsInput.value);
t.DrawClosestFarms();
}
}
this.hrsInput.addEventListener('change',function() {
hrsChanged();
},false);
this.hrsInput.addEventListener('keyup',function() {
hrsChanged();
},false);
viewTypeOnlyInp.addEventListener('keyup',function() {
hrsChanged();
},false);
bookmark.appendChild(document.createElement('br'));
bookmark.appendChild(titleA);
AddText(bookmark,'>');
bookmark.appendChild(this.hrsInput);
AddText(bookmark,'hrs ');
var expandA=document.createElement('a');
expandA.innerHTML='E';
expandA.title='Expand information';
expandA.addEventListener('click',function() {
t.expandedInfo=t.expandedInfo?false:true;
t.DrawClosestFarms();
},false);
bookmark.appendChild(viewTypeOnlyInp);
bookmark.appendChild(expandA);
bookmark.appendChild(document.createElement('br'));
}
div.innerHTML='';
div.id='ClosestFarms';
div.style.overflow='scroll';
div.style.height='200px';
div.style.display=this.GetValue('ClosestFarmDisplay','block');
var currentTroops=this.GetArmySize();
var currentResources=this.GetResourcesSize();
var mapCoord=this.GetCurrentMapCoord();
var nowSecs=new Date().getTime()/1000;
var attacks=this.GetClosestAttacks(mapCoord.x,mapCoord.y);
//var bestAttack=this.FindBiggestCampAttack(attacks,currentTroops,currentResources);
var GoClosestFarm=function(e) {
var xy=e.target.parentNode.parentNode.getAttribute('xy').split(',');
t.DoUnsafeWindow("setBookmarkCoord("+xy[0]+","+xy[1]+");");
};
var AttackClosestFarm=function(e) {
var xy=e.target.parentNode.parentNode.getAttribute('xy').split(',');
var attack=t.GetAttack(xy[0],xy[1]);
if(!attack) throw("Cannot find:"+xy[0]+','+xy[1]);
if(attack.type==0) {
t.DoUnsafeWindow("modal_attack(4,"+xy[0]+","+xy[1]+");");
} else if(attack.type==1) {
t.DoUnsafeWindow("modal_attack(1,"+xy[0]+","+xy[1]+");");
}
};
var IgnoreFarm=function(e) {
var xy=e.target.parentNode.parentNode.getAttribute('xy').split(',');
var attack=t.GetAttack(xy[0],xy[1]);
if(!attack) throw("Cannot find:"+xy[0]+','+xy[1]);
attack.ignore=true;
t.SetAttack(xy[0],xy[1],attack);
};
var DeleteFarm=function(e) {
var xy=e.target.parentNode.parentNode.getAttribute('xy').split(',');
t.DeleteAttack(xy[0],xy[1]);
t.DrawClosestFarms();
};
var aDone=0;
var table=document.createElement('table');
table.className='';
var minHrsSinceAttack=parseFloat(this.hrsInput.value);
var viewType=this.viewTypeOnly.trim().toUpperCase();
for(var aUpto=0; aUpto<attacks.length; aUpto++) {
var attackI=attacks[aUpto];
try {
//attackI.a.levelInfo=this.FindLevelFromMessages(attackI.a);
//this.SetAttack(attackI.x,attackI.y,attackI.a);
if(!attackI.a.time) {
lastAttack=60*60*24*31;
} else {
lastAttack=nowSecs-parseInt(attackI.a.time);
}
if(lastAttack<(60*60*minHrsSinceAttack)) continue;
var levelI=this.GetLevelInfo(attackI.a);
var m=( (levelI!=null && levelI.type) ?(levelI.type.charAt(0)+levelI.level):'');
//this.Log("Location Type: "+m);
if(this.viewTypeOnly!="") {
if(this.viewTypeOnly==" ") {
if(m!="") {
continue;
}
} else if(viewType.length==0 || m.substring(0,viewType.length)!=viewType) {
continue;
}
}
var dist=this.CalcXYDist({'x':attackI.x,'y':attackI.y},mapCoord);
if(dist>=this.options.attackMaxDistance) {
break;
}
var tr=table.insertRow(-1);
tr.setAttribute('xy',attackI.x+','+attackI.y);
var td=tr.insertCell(-1);
td.style.whiteSpace='nowrap';
var a=document.createElement('a');
a.style.fontSize='10px';
a.innerHTML=attackI.x+','+attackI.y;
a.addEventListener('click',function(e) { GoClosestFarm(e); },false);
td.appendChild(a);
AddText(td,' ');
//td=tr.insertCell(-1);
var attackA=document.createElement('a');
attackA.style.fontSize='10px';
/* ~~~ disabled: incorrect numbers due to having to wait for attack to update.
if(bestAttack && attackI.x==bestAttack.x && attackI.y==bestAttack.y) {
attackA.style.color='#f88';
}
*/
attackA.title=(levelI!=null?(levelI.type+' '+levelI.level):'');
if(attackI.a.comment) {
attackA.title+=", "+attackI.a.comment;
}
if(attackI.a.time && !isNaN(lastAttack)) {
// if we only scouted or transported to someone they won't have a last attack time.
m=m+' @'+SecsToStr(lastAttack);
}
attackA.innerHTML=m;
attackA.addEventListener('click',function(e) { AttackClosestFarm(e); },false);
td.appendChild(attackA);
if(t.expandedInfo) {
var troops=attackI.a.troops;
if(troops) {
for(var tupto=0; tupto<troops.length; tupto++) {
var num=troops[tupto];
if(attackI.a.suicidewave) {
var am=attackI.a.suicidewave[tupto];
if(am) num+=" ("+am+")";
}
AddText(tr.insertCell(-1),num);
}
}
}
var aDelete=document.createElement('a');
aDelete.innerHTML='X';
aDelete.title='Delete';
aDelete.addEventListener('click',function(e) { DeleteFarm(e); },false);
tr.insertCell(-1).appendChild(aDelete);
aDone++;
} catch(e) {
this.Log('Error:'+e);
}
}
div.appendChild(table);
//bookmark.parentNode.insertBefore(div,bookmark);
//bookmark.parentNode.appendChild(document.createElement('br'));
bookmark.appendChild(div);
this.AttachXYPaste('mapXCoor','mapYCoor');
},
// ?,1,square type, level, player id?,
// target player name, target gender, player name, player gender, ?, target x, target y, report id, 0, x y
onclickReportRe:/(["0-9]+),(["0-9]+),(["0-9]+),(["0-9]+),(["0-9]+),("[^"]+"),("[^"]+"),("[^"]+"),("[^"]+"),(["0-9]+),(["0-9]+),(["0-9]+),/,
//modal_messages_viewreports_view("897422",0,51,9,2485358,"niknah","M","niknah","M",1,333,110,1275178036,1,286,181);
// remove the read/unread flag
onclickReadRe:/^(.*,)([0-9]+)(,[0-9]+,[0-9]+[^,]*)$/,
FixOnClick:function(a) {
var m=this.onclickReadRe.exec(a);
if(m) {
return m[1]+"0"+m[3];
}
return a;
},
IterateArmy:function(f) {
if(!this.GetSeed()) return;
var armyDiv=ById('cityinfo_3');
var units=this.GetSeed().units["city"+unsafeWindow.currentcityid];
//var unitKeys=Object.keys(units);
//for(var u=0; u<unitKeys; u++) {
var uRe=/([0-9]+)$/;
for(var u in units) {
var m=uRe.exec(u);
if(!m) continue;
f.call(this,m[1],units[u]);
}
/*
var ss=document.evaluate(".//div[@class='unit']",armyDiv,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for(var s=0; s<ss.snapshotLength; s++) {
var unit=ss.snapshotItem(s);
var amt=unit.textContent;
f.call(s,amt);
}
*/
},
GetArmySize:function() {
var troops=[];
this.IterateArmy(function(s,amt) {
troops[s]=amt;
});
return troops;
},
GetResourcesSize:function() {
var resources=[];
resources[0]=parseInt(ById('stat_gold_bar_num').innerHTML.replace(/,/g,'')); // Gold
resources[1]=parseInt(ById('stat_rec1_bar_num').innerHTML.replace(/,/g,'')); // Food
resources[2]=parseInt(ById('stat_rec2_bar_num').innerHTML.replace(/,/g,'')); // Wood
resources[3]=parseInt(ById('stat_rec3_bar_num').innerHTML.replace(/,/g,'')); // Stone
resources[4]=parseInt(ById('stat_rec4_bar_num').innerHTML.replace(/,/g,'')); // Ore
return resources;
},
OpenViewReports:function() {
this.Log('Open View Reports');
this.DoUnsafeWindow("modal_messages();");
this.DoUnsafeWindow('track_chrome_btn("messages_btn");');
this.DoUnsafeWindow('modal_messages_viewreports();');
},
//autoAttackCitiesDoneMax:3,
autoAttackCitiesDone:0,
autoAttackCityUpto:1,
autoAttackModalWaiting:false,
autoAttackTimeout:null,
autoAttacksThisCity:0,
ClearAutoAttackTimeout:function() {
if(this.autoAttackTimeout!=null) {
this.Log('reload page timer killed');
window.clearTimeout(this.autoAttackTimeout);
this.autoAttackTimeout=null;
}
},
RestartAutoAttack:function() {
this.autoAttacksThisCity=0;
this.autoAttackCitiesDone=0;
this.autoAttackCityUpto=1;
this.autoAttackModalWaiting=false;
this.NextAutoAttack();
},
StartReloadPageTimer:function(secs) {
var t=this;
if(!secs) secs=this.options.waitAfterCitiesDone;
var refreshMSecs=t.GetRandTime(1000*secs);
this.Log('refreshing in '+(refreshMSecs/1000)+' secs, all cities done:'+this.autoAttackCityUpto);
this.ClearAutoAttackTimeout();
this.autoAttackTimeout=window.setTimeout(function() {
if(t.autoAttackTimeout==null) return;
t.autoAttackTimeout=null;
if(t.IsMapperRunning() || t.IsCurrentlySendingMultipleWaves()) {
if(t.IsMapperRunning()){
t.Log("Waiting for mapping to finish");
}else{
t.Log("Waiting for multiple wave attack to finish");
}
// don't reload until the mapper or multi-wave attack has finished.
window.setTimeout(function() {
t.StartReloadPageTimer();
},0);
return;
}
t.SetValuesCache();
//window.location.reload(true);
t.ReloadWindow();
},refreshMSecs);
this.Log('reload page timer started');
},
multipleWaveTimeout:null,
ClearMultipleWaveTimeout:function() {
if(this.multipleWaveTimeout!=null) {
this.Log('city switching timer killed');
window.clearTimeout(this.multipleWaveTimeout);
this.multipleWaveTimeout=null;
}
},
StartMultipleWaveTimer:function(secs) {
var t=this;
if(!secs) secs=t.options.attackDelay;
var attackDelayMSecs=t.GetRandTime(1000*secs);
this.Log('Waiting '+(attackDelayMSecs/1000)+' secs to retry second wave attack...');
this.ClearMultipleWaveTimeout();
this.multipleWaveTimeout=window.setTimeout(function() {
if(t.multipleWaveTimeout==null) return;
t.multipleWaveTimeout=null;
if(t.IsCurrentlySendingMultipleWaves()) {
t.Log("Waiting for multiple wave attack to finish...");
// don't switch cities until the multi-wave attack has finished.
window.setTimeout(function() {
t.StartMultipleWaveTimer();
},0);
return;
}
t.NextAutoAttackCity();
},attackDelayMSecs);
this.Log('Multiple wave attack timer started');
},
lastOpenViewReports:0,
CheckReports:function() {
var t=this;
var autoAttack=this.GetAutoAttack();
if(!autoAttack) return;
// Load the reports every minute or on initial page load
if(!this.options.noViewReports) {
var nowSecs=new Date().getTime()/1000;
if((this.lastOpenViewReports+(60*1))<nowSecs) {
this.lastOpenViewReports=nowSecs;
this.OpenViewReports();
this.bringUpReports=true;
if(this.options.autoRemoveReports || this.options.autoRemoveFarmReports) {
this.autoAttackRemoveReports=true;
}
}
}
},
ClickChangeCity:function(cityA,tries) {
var t=this;
nHtml.Click(cityA);
// If this is the only city selected in the options, we just pretend to switch
var currentCityNum = this.autoAttackCityUpto;
var enabledCities = 0;
for(var i=1; i<=8; i++){
if(this.options.okCities[i]){
enabledCities++;
}
}
//t.Log("Number of enabled cities to attack from: "+enabledCities);
if(enabledCities==1){ t.prevCurrentCity = -1; }
// Determine the number of the city and store it
t.SetCurrentAttackCityNum(cityA.id.replace("citysel_",""));
t.nextAutoAttackWanted=window.setTimeout(function() {
if(t.nextAutoAttackWanted!=null) {
if(tries>4) {
t.Log("Skip city, too many retries");
t.NextAutoAttackCity();
return;
}
t.Log("We clicked change city but the city did not change, trying again");
// Didn't change city
t.ClickChangeCity(cityA,tries+1);
}
},10000);
},
NextAutoAttackCity:function() {
var t=this;
var autoAttack=this.GetAutoAttack();
if(!autoAttack) return;
if(this.IsCurrentlySendingMultipleWaves()){
this.Log('Cannot change city. Waiting for multiple wave attack to finish...');
t.ClearMultipleWaveTimeout();
t.StartMultipleWaveTimer();
return;
}else{
t.ClearMultipleWaveTimeout();
}
// change to next city
this.autoAttacksThisCity=0;
var cityA=null;
// this.autoAttackCityUpto++;
// cityA=ById('citysel_'+this.autoAttackCityUpto);
// //~~~ problem here when under attack, the city isn't marked as selected?
// // Skip to next city along the line if the current city is already selected somehow
// if(cityA && cityA.className && cityA.className.indexOf('city_selected')>=0) {
// this.Log('Skip city, current city:'+this.autoAttackCityUpto);
// this.autoAttackCityUpto++;
// }
// // Determine the next enabled city in the options
// var firstAvailableCityNum = this.autoAttackCityUpto;
// while(firstAvailableCityNum<=8){
// if(this.options.okCities[firstAvailableCityNum]){
// break;
// }else{
// firstAvailableCityNum++;
// }
// }
// // Default to city #1 if no cities are enabled
// if(!this.options.okCities[firstAvailableCityNum]){
// firstAvailableCityNum = 1;
// }
// // Check to make sure that the next city is selected in the options
// //this.Log("Currently attempting to switch to city: "+this.autoAttackCityUpto);
// var currentCityNum = this.autoAttackCityUpto;
// while(currentCityNum<=8){
// //this.Log("Is City "+currentCityNum+" Selected in options: "+this.options.okCities[currentCityNum]);
// if(!this.options.okCities[currentCityNum]){
// currentCityNum++;
// }else{
// if(currentCityNum>this.autoAttackCityUpto){
// this.Log("City "+this.autoAttackCityUpto+" not enabled in options.");
// this.autoAttackCityUpto = currentCityNum;
// }
// //this.Log("Attempting to switch to city: "+this.autoAttackCityUpto);
// break;
// }
// // No cities were available. Switching to first available city
// this.autoAttackCityUpto = firstAvailableCityNum;
// }
while(true) {
this.autoAttackCityUpto++;
cityA=ById('citysel_'+this.autoAttackCityUpto);
//~~~ problem here when under attack, the city isn't marked as selected?
if((cityA && cityA.className && cityA.className.indexOf('city_selected')>=0) || (!this.options.okCities[this.autoAttackCityUpto])) {
this.Log('Skip city, current city or city not selected: '+this.autoAttackCityUpto);
} else {
this.Log('Attempting to select this city: '+this.autoAttackCityUpto);
cityA=ById('citysel_'+this.autoAttackCityUpto);
break;
}
}
cityA=ById('citysel_'+this.autoAttackCityUpto);
if(!cityA) {
// go back to the 1st available city
this.Log('Start from 1st city again');
if(this.autoAttackCityUpto<=2) {
// only one city.
} else {
this.autoAttackCityUpto=1;
cityA=ById('citysel_'+this.autoAttackCityUpto);
}
this.autoAttackCitiesDone++;
}
if(!cityA || this.autoAttackCitiesDone>=this.options.autoAttackCitiesDoneMax) {
//Reset to first city if auto attack does the refresh
this.SetCurrentAttackCityNum(1);
// ran out of cities, let's refresh in a minute
this.StartReloadPageTimer();
return;
} else {
if(this.nextAutoAttackTimeout==null) {
var secs=t.GetRandTime(1000*t.options.changeCitySecs);
this.Log('Changing city to: '+this.autoAttackCityUpto+', in '+(secs/1000)+'secs, loop: '+this.autoAttackCitiesDone);
this.nextAutoAttackTimeout=setTimeout(function() {
t.nextAutoAttackTimeout=null;
t.SetValuesCache();
t.ClickChangeCity(cityA,0);
},secs);
} else {
this.Log('Cannot change city. Reason: about to attack or change city');
}
// this.autoAttackCityUpto++;
}
},
StopWaitForAttackBoxAppear:function() {
if(this.waitForAttackBoxAppear!=null) {
window.clearTimeout(this.waitForAttackBoxAppear);
this.waitForAttackBoxAppear=null;
}
},
OpenAttackDialog:function(bestAttack) {
var t=this;
t.StopWaitForAttackBoxAppear();
t.waitForAttackBoxAppear=window.setTimeout(function() {
if(t.waitForAttackBoxAppear==null) return;
t.waitForAttackBoxAppear=null;
t.DoUnsafeWindow('Modal.hideModalAll();');
t.DoUnsafeWindow('Modal.hideModalAll();');
try {
// something in the script is triggering a bug in
t.DoUnsafeWindow('Modal.hideCurtain();');
t.DoUnsafeWindow('Modal.hideWindow();');
} catch(e) {
// ignore
}
//window.location.reload(true);
t.ResetIdStatus();
t.Log("Attack box has not appeared, let's reopen");
window.setTimeout(function() {
t.OpenAttackDialog(bestAttack);
},0);
},5*1000);
//~~~ strange things here, sometimes the attack dialog is on screen but modalid is not updated
if(ById('modal_attack')) {
try {
var countOut=10;
while(countOut-->=0) {
t.Log('modal attck still up'+unsafeWindow.Modal.modalid);
var maxi=0;
for(var i=0; i<20; i++) {
if(ById('modalBox'+i)) {
maxi=i;
}
}
t.Log('Closing: '+maxi);
unsafeWindow.Modal.modalid=maxi;
if(maxi>0) {
unsafeWindow.Modal.hideCurtain();
unsafeWindow.Modal.hideWindow();
} else {
break;
}
}
}catch(e) {
t.Log("Mmm..."+e);
}
} else {
//t.Log('hide all: '+unsafeWindow.Modal.modalid);
unsafeWindow.Modal.hideModalAll();
}
if (bestAttack.type==0) {
unsafeWindow.modal_attack(4,bestAttack.x,bestAttack.y);
// Toggle attack waves between suicide and normal mode
this.ToggleCurrenttAttackWaveType(bestAttack.x,bestAttack.y);
// Update the last attack sent time
this.UpdateAttackLastSentTime();
} else if (bestAttack.type==1) {
unsafeWindow.modal_attack(1,bestAttack.x,bestAttack.y);
}
},
nextAutoAttackWanted:null,
NextAutoAttack:function() {
this.Log("Next auto attack");
if(this.nextAutoAttackWanted!=null) {
window.clearTimeout(this.nextAutoAttackWanted);
this.nextAutoAttackWanted=null;
}
var autoAttack=this.GetAutoAttack();
if(!this.options.okCities[this.autoAttackCityUpto]) {
this.Log('Skip city. Not enabled in options. City: '+this.autoAttackCityUpto);
this.NextAutoAttackCity();
return;
}
if(!autoAttack || (autoAttack.x!=undefined && autoAttack.x!=-1)) return;
if(this.IsMapperRunning()) {
this.StartReloadPageTimer();
return;
}
this.DetermineCurrentRallyPointLevel();
this.DetermineCurrentMarchesNum();
this.available_marches_num = this.currentRallyPointLevel - this.currentMarchesNum - this.options.rallyKeep;
var currentTroops=this.GetArmySize();
var currentResources=this.GetResourcesSize();
var mapCoord=this.GetCurrentMapCoord();
var attacks=this.GetClosestAttacks(mapCoord.x,mapCoord.y);
//this.Log("Current attacks in system: "+inspect(attacks,10));
var bestAttack=this.FindBiggestCampAttack(attacks,currentTroops,currentResources);
if(bestAttack && this.available_marches_num>0) {
// attack closest biggest barbarian/wilderness
autoAttack.x=bestAttack.x;
autoAttack.y=bestAttack.y;
this.SetAutoAttack(autoAttack);
this.autoAttackModalWaiting=true;
var t=this;
// *** we need to wait until the current attack box is off first.
var waitedCount=0;
var startAttack=function() {
waitedCount++;
//t.Log('waiting'+waitedCount);
if(waitedCount>20) {
t.Log('Force close the attack dialog');
t.DoUnsafeWindow('Modal.hideModalAll();');
}
var attackBox=document.getElementById('modal_attack');
if(!attackBox) {
t.OpenAttackDialog(bestAttack);
/*
attackBox=document.getElementById('modal_attack');
if(attackBox) {
//*** for some reason it doesn't trigger DOMInserted sometimes for the "modal_attack" div
if(t.waitForAttackBoxAppear) {
t.OnAttackBoxAppear(attackBox);
}
}
*/
return;
}
window.setTimeout(function() {
startAttack();
},1000);
}
startAttack();
} else {
autoAttack.x=autoAttack.y=-1;
this.SetAutoAttack(autoAttack);
// no valid attacks for this city.
this.Log("No valid targets, need to attack more targets or wait for troops to return.");
this.NextAutoAttackCity();
}
},
/////////////////////////
RemoveEmptyReportsDivs:function() {
var ss=document.evaluate("./div[@id='modal_msg_reports_tablediv']",document.body,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for(var s=0; s<ss.snapshotLength; s++) {
var div=ss.snapshotItem(s);
if(div.innerHTML=="") {
div.parentNode.removeChild(div);
}
}
},
IterateAllianceReports:function(f) {
return this.IterateReports('modal_alliance_reports_tablediv',0,f);
},
IterateMsgReports:function(f) {
return this.IterateReports('modal_msg_reports_tablediv',1,f);
},
IterateReports:function(id,colStart,f) {
this.RemoveEmptyReportsDivs();
var msgs=ById(id);
if(!msgs) return;
var trs=msgs.getElementsByTagName('tr');
for(var tUpto=0; tUpto<trs.length; tUpto++) {
var tr=trs[tUpto];
var a=nHtml.FindByXPath(tr,".//a[contains(@onclick,'modal_messages_viewreports') or contains(@onclick,'modal_alliance_report_view') or contains(@onclick,'viewMarchReport')]");
if(!a) continue;
if(tr.cells.length<(colStart+2)) continue;
var descCol=tr.cells[colStart+1];
var dateCol=tr.cells[colStart+0];
var desc=descCol.textContent;
var m=this.coordsRe.exec(desc);
var x=null,y=null;
if(m) {
x=m[1]; y=m[2];
}
var onclick=a.getAttribute('onclick');
if(onclick) {
var m=this.onclickReportRe.exec(onclick);
if(m) { x=m[11]; y=m[12]; }
}
if(!f.call(this,a,tr,desc,x,y)) break;
}
},
recordingReports:false,
replaceReturnRe:/return[^{}]*$/,
RecordReports:function() {
try {
if(this.recordingReports) return;
this.recordingReports=true;
this.IterateMsgReports(function(a,tr,desc,x,y) {
if(x==null || y==null) return true;
var onclick=a.getAttribute('onclick').trim();
if(this.IsOnclickMyselfToMyself(onclick)) {
return true;
}
var attack=this.GetAttack(x,y);
var saveReportAsAttack = true;
if(!attack) {
// Don't record reports as attacks if the attack doesn't already exist in the system
var saveReportAsAttack = false;
}
if(!attack) { attack={}; }
if(!attack.messages) attack.messages=[];
var onclickWithoutReturn=onclick.replace(this.replaceReturnRe,'');
a.href='javascript:'+onclickWithoutReturn;
onclick=this.FixOnClick(onclick);
var addedAlready=false;
for(var m=0; m<attack.messages.length; m++) {
if(attack.messages[m][1]==onclick) {
addedAlready=true;
break;
}
}
var changed=false;
if(!addedAlready) {
attack.messages.push([desc,onclick]);
//this.Log("attack messages: "+attack.messages);
var li=this.GetLevelInfo(attack);
//this.Log('type:'+li.type+',level:'+li.level);
if(li) attack.levelInfo=li;
changed=true;
}
if(!attack.levelInfo) {
// to fix up old scripts where this didn't work.
attack.levelInfo=this.GetLevelInfo(attack);
if(attack.levelInfo) changed=true;
}
if(changed && saveReportAsAttack) {
this.SetAttack(x,y,attack);
}
return true;
});
} finally {
this.recordingReports=false;
}
},
IsOnclickMyselfToMyself:function(onclick) {
if(!onclick) return false;
var m=this.onclickReportRe.exec(onclick);
if(m && m[6]==m[8] && m[7]==m[9]) {
return true;
}
return false;
},
DeleteWildBarbAttacks:function() {
var deletes=0;
this.IterateMsgReports(function(a,tr,desc,x,y) {
var onclick=a.getAttribute('onclick');
if(!onclick) return false;
onclick=onclick.trim();
var m=this.onclickReportRe.exec(onclick);
if(this.IsOnclickMyselfToMyself(onclick)) {
// message to myself
} else if(m && m[5]!='0') {
return true;
}
var inps=tr.getElementsByTagName('input');
if(inps.length>=1) {
inps[0].checked=true;
}
deletes++;
return true;
});
if(deletes>0) {
this.DoUnsafeWindow('modal_messages_reports_chkdel();');
}
return deletes;
},
DeleteFarmAttacks:function() {
var deletes=0;
this.IterateMsgReports(function(a,tr,desc,x,y) {
var DisplayName = this.GetDisplayName();
DisplayName = /([^"]+) ([^"]+)/.exec(DisplayName);
var onclick=a.getAttribute('onclick');
if(!onclick) return false;
onclick=onclick.trim();
var m=this.onclickReportRe.exec(onclick);
if(this.IsOnclickMyselfToMyself(onclick)) {
return true; //Don't select transports
} else if(m && m[5]=='0') {
return true; //Don't select barbs or wilds
} else if(m && m[11]=='0' && m[12]=='0') {
return true; //Don't select if empty
} else if(m && m[8].StripQuotes()!=DisplayName[2]) {
return true; //Don't select if attacker is not yourself
}
var attack = this.GetAttack(m[11],m[12]); //Check if attack exists in system
if(!attack) return true;
if(attack.deletefarmno) return true; //Don't select if checked not to delete
if(!attack.troops) return true; //Sometimes the script will record reports but u don't want them deleted
var inps=tr.getElementsByTagName('input');
if(inps.length>=1) {
inps[0].checked=true;
}
deletes++;
return true;
});
if(deletes>0) {
this.DoUnsafeWindow('modal_messages_reports_chkdel();');
}
return deletes;
},
bringUpReports:false,
AddCheckBarbarians:function() {
//var msgBody=ById('modal_msg_reports');
var msgBody=ById('modal_msg_reports_tablediv');
if(!msgBody) return;
var t=this;
var closeReports=true;
if(this.autoAttackRemoveReports) {
var reportsRemoved=0;
if(this.options.autoRemoveReports){
reportsRemoved+=this.DeleteWildBarbAttacks();
}
if(this.options.autoRemoveFarmReports){
reportsRemoved+=this.DeleteFarmAttacks();
}
if(reportsRemoved==0) {
this.autoAttackRemoveReports=false;
} else {
closeReports=false;
}
}
if(this.bringUpReports && closeReports) {
window.setTimeout(function() {
t.DoUnsafeWindow('Modal.hideModalAll();');
},t.GetRandTime(3000));
this.bringUpReports=false;
}
this.ClearMessages();
var a=document.createElement('a');
var t=this;
a.addEventListener('click',function() {
t.DeleteWildBarbAttacks();
},false);
a.className='buttonDown20';
//a.style.paddingLeft='30px';
a.innerHTML='<span>Delete Wild/Barb/Transp</span>';
if(msgBody.nextSibling) {
msgBody.nextSibling.insertBefore(a,msgBody.nextSibling.childNodes[0]);
//msgBody.nextSibling.appendChild(a);
} else {
msgBody.appendChild(a);
}
var a=document.createElement('a');
var t=this;
a.addEventListener('click',function() {
t.DeleteFarmAttacks();
},false);
a.className='buttonDown20';
//a.style.paddingLeft='30px';
a.innerHTML='<span>Delete Farm</span>';
if(msgBody.nextSibling) {
msgBody.nextSibling.insertBefore(a,msgBody.nextSibling.childNodes[0]);
//msgBody.nextSibling.appendChild(a);
} else {
msgBody.appendChild(a);
}
},
HighlightAllianceReports:function() {
var mapCoord=this.GetCurrentMapCoord();
var cities=this.GetSeed().cities;
this.IterateAllianceReports(function(a,tr,desc,x,y) {
if(x==null || y==null) return true;
var closestDist=999999;
var closestLoc=null;
for(var c=0; c<cities.length; c++) {
var city=cities[c];
var cityLoc={'x':city[2],'y':city[3]};
var dist=this.CalcXYDist({'x':x,'y':y},cityLoc);
if(dist<closestDist) { closestDist=dist; closestLoc=cityLoc; }
}
var onclick=a.getAttribute('onclick');
var m=this.onclickReportRe.exec(onclick);
if(m && m[5]=='0') {
tr.cells[1].style.color='#888';
}
if(closestLoc!=null) {
var td=tr.insertCell(-1);
td.style.textAlign='right';
var loctd=tr.insertCell(-1);
AddText(loctd,closestLoc.x+','+closestLoc.y);
AddText(td,Math.floor(closestDist) );
}
return true;
});
},
IterateAttacks:function(f) {
if(this.isChrome) {
return;
}
var names=this.browser_listValues();
var attackPrefix='attack_'+this.GetServerId()+'_';
for(var n=0; n<names.length; n++) {
var name=names[n];
if(name.substring(0,attackPrefix.length)!=attackPrefix) continue;
f(name,this.browser_getValue(name));
}
},
prevClearMessages:0,
ClearMessages:function() {
var nowSecs=new Date().getTime()/1000;
if((this.prevClearMessages+(10*60)) > nowSecs) {
return;
}
this.prevClearMessages=nowSecs;
var keepReports=this.isChrome?this.options.chromeKeepReports:this.options.keepReports;
this.Log('Clear old messages, keeping '+keepReports);
if(keepReports<=0) {
// must keep at least 1 report to get level information.
keepReports=1;
}
var t=this;
this.IterateAttacks(function(name,value) {
var attack=JSON2.parse(value);
if(attack.messages && attack.messages.length>keepReports) {
attack.messages.splice(0,attack.messages.length-keepReports+1);
}
t.browser_setValue(name,JSON2.stringify(attack));
});
},
SetupClearMessages:function() {
var t=this;
var cm=document.createElement('input');
cm.type='button';
cm.id='ClearMessages';
cm.style.display='none';
document.body.appendChild(cm);
cm.addEventListener('click',function(e) {
setTimeout(function() {
t.ClearMessages();
},0);
},false);
},
trainTroopsOnclick:/\(([0-9]+)\)/,
AddTrainTroopsLink:function() {
var startObj=ById('unit_btns_start');
if(!startObj) return;
var onclick=startObj.getAttribute('onclick');
var m=this.trainTroopsOnclick.exec(onclick);
if(!m) {
return;
}
var t=this;
var type=m[1];
var pnode=startObj.parentNode;
var a=document.createElement('a');
a.className='button25';
var setTrainTroopsA=function() {
var trainTroops=JSON2.parse(t.GetValue('TrainTroops','{}'));
a.innerHTML='<span>'+(trainTroops[t.GetCurrentCityId()]==type?'Auto Train - On':'Auto Train - Off')+'</span>';
}
a.addEventListener('click',function() {
var trainTroops=JSON2.parse(t.GetValue('TrainTroops','{}'));
trainTroops[t.GetCurrentCityId()]=trainTroops[t.GetCurrentCityId()]==type?undefined:type;
t.SetValue('TrainTroops',JSON2.stringify(trainTroops));
setTrainTroopsA();
},false);
setTrainTroopsA();
//pnode.appendChild(document.createElement('br'));
AddText(pnode,' ');
pnode.appendChild(a);
},
GetCurrentCityId:function() {
if(!unsafeWindow.currentcityid) return null;
return unsafeWindow.currentcityid;
},
GetCurrentAttackCityNum:function() {
var curCityNum=this.GetValue('CurrentAttackCityNum',null);
if(!curCityNum || !is_int(curCityNum) || curCityNum>8){
// default to first city
curCityNum=1;
}
return curCityNum;
},
SetCurrentAttackCityNum:function(curCityNum) {
if(!curCityNum){
var curCityNum = 1;
}
//this.Log("Setting current attack city to: "+curCityNum);
this.SetValue('CurrentAttackCityNum',curCityNum);
return curCityNum;
},
// returns {count, maxlevel}
getCityBuilding: function(cityId, buildingId){
var b = unsafeWindow.seed.buildings['city'+cityId];
var ret = {count:0, maxLevel:0};
for (var i=1; i<33; i++){
if (b['pos'+i] && b['pos'+i][0] == buildingId){
++ret.count;
if (parseInt(b['pos'+i][1]) > ret.maxLevel)
ret.maxLevel = parseInt(b['pos'+i][1]);
}
}
return ret;
},
lastTrainTroops:{},
CheckTrainTroops:function() {
var t=this;
if(!this.GetSeed()) return;
var cityid=this.GetCurrentCityId();
var trainTroops=JSON2.parse(this.GetValue('TrainTroops','{}'));
//var trainTroops=GM_getValue('TrainTroops_'+this.GetServerId(),0);
if(!trainTroops || !trainTroops[cityid]) {
return;
}
var trainTroopId=trainTroops[cityid];
//GM_log('buildTroops'+unsafeWindow.seed.citystats["city" +cityid ]["pop"][0]+"=="+unsafeWindow.seed.citystats["city" + cityid]["pop"][1]);
var popAvail=parseInt(unsafeWindow.seed.citystats["city" +cityid ]["pop"][0]);
var popTotal=parseInt(unsafeWindow.seed.citystats["city" + cityid]["pop"][1]);
var labourTotal=parseInt(unsafeWindow.seed.citystats["city" + cityid]["pop"][3]);
var idleTotal=popTotal-labourTotal;
var popNeeded=((t.options.percentOfPopToTrain/100)*idleTotal)+labourTotal;
// Determine number of available training slots
var availableTrainingSlots = 0;
try{
var barracksTotal = this.getCityBuilding(cityid, 13).count;
var trainingSlotsUsed = unsafeWindow.seed.queue_unt['city'+cityid].length;
if(trainingSlotsUsed!=null){
var availableTrainingSlots = barracksTotal-trainingSlotsUsed;
}
}finally{
if(availableTrainingSlots<1){ return false; }
}
//GM_log('idleTotal:'+idleTotal+', labourTotal:'+labourTotal+', popneeded:'+popNeeded);
if(popAvail>0 && popAvail>=popNeeded) {
// avoid over training.
var lastTrain=this.lastTrainTroops[cityid];
var nowSecs=new Date().getTime()/1000;
if(nowSecs<(lastTrain+(3*60))) { return; }
var startButton=ById('unit_btns_start');
if(!startButton) {
// let's bring up build troops
this.DoUnsafeWindow('modal_barracks_train('+trainTroopId+');')
return;
}
var onclick=startButton.getAttribute('onclick');
var onclickM=/\(([0-9]+)\)/.exec(onclick);
if(!onclickM || trainTroopId!=onclickM[1]) {
return;
}
this.lastTrainTroops[cityid]=nowSecs;
// let's build troops
var numInp=ById('modal_barracks_num');
var maxObj=ById('modal_barracks_max_num');
if(numInp && maxObj) {
numInp.value=Math.floor(parseInt(maxObj.textContent)*(parseInt(this.options.percentToTrainOfMax)/100));
var t=this;
window.setTimeout(function() {
if(numInp.value>parseInt(maxObj.textContent)) {
t.Log('Not training troops:'+numInp.value+'>'+maxObj.textContent);
return;
}
//var n=unsafeWindow.modal_barracks_train_max(6);
onclick=onclick.replace('return false;','');
window.setTimeout(function() {
eval('unsafeWindow.'+onclick);
},t.GetRandTime(500));
},t.GetRandTime(500));
}
}
},
DetermineCurrentPage:function() {
if(unsafeWindow.location.href.match(/kingdomsofcamelot\.com\/fb\/.*?\/standAlone\.php/i)){
this.currentPage = 'kabam_page';
}else if(unsafeWindow.location.href.match(/kingdomsofcamelot\.com\/fb\/.*?\/src\/main_src\.php/i)){
this.currentPage = "koc_game";
}else if (unsafeWindow.location.href.match(/apps\.facebook\.com\/kingdomsofcamelot\/.*?page=nogame/i)) {
this.currentPage = "domain_selection_app_page";
}else if (unsafeWindow.location.href.match(/apps\.facebook\.com\/kingdomsofcamelot/i)) {
this.currentPage = "app_page";
}else if (unsafeWindow.location.href.match(/facebook.com\/connect\/uiserver.php/i)) {
this.currentPage = "facebook_popup";
}else if(unsafeWindow.location.href.match(/kingdomsofcamelot\.com\/fb\/.*?\/src\/newgame_src\.php/i)){
this.currentPage = "domain_selection";
}else{
this.currentPage = "unknown";
}
return this.currentPage;
},
OnImpendingAttack:function() {
var t=this;
this.Log("impending attack");
var autoAttack=this.GetAutoAttack();
var url=t.options.impendingAttackUrl;
if(url!=undefined && url !="") {
GM_openInTab(url);
}
if(t.options.impendingStopAttack){
if(autoAttack){
t.ToggleAutoAttack();
}
}
},
CheckImpendingAttack:function() {
var r=false;
var seed=this.GetSeed();
if(seed && seed.queue_atkinc) {
for(k in seed.queue_atkinc){
m = seed.queue_atkinc[k];
if (m.marchType==3 || m.marchType==4){
var q=0;
var keys=unsafeWindow.Object.keys(seed.queue_atkinc);
if(keys.length>0 && keys.length<16) {
r=true;
}
}
}
}
//GM_log('imp'+r);
/*
var topNav=ById('topnav_msg');
if(!topNav || topNav.innerHTML.length==0) return;
var redIdx=topNav.innerHTML.indexOf(': red');
var r=redIdx>=0?true:false;
if(!r) {
GM_log('tnav'+topNav.innerHTML);
}
*/
var t=this;
var impendingAttack=this.GetValue('ImpendingAttack',false);
if(!impendingAttack && r) {
window.setTimeout(function() {
t.OnImpendingAttack();
},0);
}
this.SetValue('ImpendingAttack',r);
return r;
},
/*
current_modal_msg_list:"",
CheckMessageLoad:function(page) {
var t=this;
var msg=ById('modal_msg_list');
if(msg && msg.innerHTML!=t.current_modal_msg_list) {
t.current_modal_msg_list=msg.innerHTML;
var messageLoad=ById('MessageLoad');
if(!messageLoad) {
messageLoad=document.createElement('div');
messageLoad.id='MessageLoad';
messageLoad.style.position='absolute';
messageLoad.style.height='600px';
messageLoad.style.overflow='scroll';
messageLoad.style.top='10px';
messageLoad.style.zIndex='900000';
messageLoad.style.border='5px solid #000';
messageLoad.style.backgroundColor='#fff';
document.body.appendChild(messageLoad);
}
var m=document.createElement('div');
m.innerHTML=msg.innerHTML;
messageLoad.appendChild(m);
page++;
this.DoUnsafeWindow("modal_messages_listshow('inbox',page);");
}
window.setTimeout(function() {
t.CheckMessageLoad(page);
},200);
},
ReadEmails:function() {
this.current_modal_msg_list='';
this.CheckMessageLoad();
},
*/
FactoryReset:function() {
var names=this.browser_listValues();
for(var n=0; n<names.length; n++) {
this.browser_setValue(names[n],null);
}
this.SetOptions({});
},
FactoryResetCurrentServer:function() {
var names=this.browser_listValues();
var serverId=this.GetServerId();
for(var n=0; n<names.length; n++) {
var name=names[n];
var sid=this.GetServerIdFromName(name);
if(sid!=serverId) continue;
this.browser_setValue(name,null);
}
},
GetServerIdFromName:function(n) {
var nArr=n.split('_');
if(nArr.length<2) return null;
return nArr[1];
},
DeleteAllStoredAttacks:function() {
var t=this;
this.IterateAttacks(function(name,value) {
var nameI=name.split('_');
if(nameI.length<3) return;
var xy=nameI[2].split(',');
if(value=="") return;
var attack=JSON2.parse(value);
if(!attack) return;
var attackX = xy[0];
var attackY = xy[1];
if(attackX && attackY){
t.DeleteAttack(attackX, attackY);
}
return true;
});
window.alert("All stored attacks for this domain have been deleted.\nClick the ok button to reload.");
},
DeleteTransports:function() {
var t=this;
this.IterateAttacks(function(name,value) {
var nameI=name.split('_');
if(nameI.length<3) return;
var xy=nameI[2].split(',');
if(value=="") return;
var attack=JSON2.parse(value);
if(!attack) return;
var attackX = xy[0];
var attackY = xy[1];
if(attack.type == 1){
t.DeleteAttack(attackX, attackY);
}
return true;
});
window.alert("All stored transports for this domain have been deleted.\nClick the ok button to reload.");
},
ListTransports:function() {
var t=this;
var fTransport = 0;
this.IterateAttacks(function(name,value) {
var nameI=name.split('_');
if(nameI.length<3) return;
var xy=nameI[2].split(',');
if(value=="") return;
var attack=JSON2.parse(value);
if(attack.type == 1){
WinLog.write ("Name: "+name+" Value: "+value);
fTransport = 1;
return true;
}
});
if (!fTransport){
WinLog.write ("No Transports Found\n");
return true;
}
},
ListAttacks:function() {
var t=this;
this.IterateAttacks(function(name,value) {
WinLog.write (name+" "+value);
return true;
});
},
DetailAttacks:function() {
var t=this;
var names=GM_listValues();
var currentServerId = t.GetServerId();
var attackPrefix='attack_'+currentServerId+'_';
for(var n=0; n<names.length; n++) {
var name=names[n];
var nameI=name.split('_');
if(nameI.length<3) continue;
var xy=nameI[2].split(',');
if(name.substring(0,attackPrefix.length)!=attackPrefix) continue;
var value = GM_getValue(name);
if(value=="") continue;
var attack=JSON2.parse(value);
attack.xy=xy;
if(!attack) continue;
t.attacks.push(attack);
}
},
ExportAllToJSON:function() {
var names=this.browser_listValues();
var obj={};
var serverId=this.GetServerId();
for(var n=0; n<names.length; n++) {
var name=names[n];
var sid=this.GetServerIdFromName(name);
if(sid!=serverId) continue;
var v=this.browser_getValue(name,null);
if(v!=null && v!=undefined && v!="")
obj[name]=v;
}
return JSON2.stringify(obj);
},
ImportAllFromJSON:function(json) {
try {
var obj=JSON2.parse(json);
if(!obj) { return; }
this.FactoryResetCurrentServer();
var serverId=this.GetServerId();
for(var name in obj) {
var sid=this.GetServerIdFromName(name);
if(sid!=serverId) continue;
this.browser_setValue(name,obj[name]);
}
} catch(e) {
window.alert('Import failed'+e);
}
},
SetupMenu:function() {
var t=this;
GM_registerMenuCommand('KOCAttack - Options',function() {
t.ShowOptionsDialog();
});
GM_registerMenuCommand('KOCAttack - View Attacks',function() {
t.ShowViewAttacksDialog();
});
GM_registerMenuCommand('KOCAttack - Import/Export',function() {
t.ShowImportExportBox();
});
GM_registerMenuCommand('KOCAttack - Auto Attack',function() {
t.ToggleAutoAttack();
});
GM_registerMenuCommand('KOCAttack - Factory Reset!',function() {
t.FactoryReset();
});
},
/*
TimeoutZero:function(f,arg) {
setTimeout(function() {
f(arg);
},0);
},
*/
pageLoaded:false,
prevCurrentCity:-1,
currentAttackCityResumed:false,
inviteFriendsTabHidden:false,
idStatus:{},
ResetIdStatus:function() {
this.idStatus={};
},
Listen:function() {
var t=this;
t.SetupMenu();
this.GetValuesCache();
t.ResetAutoAttackTarget();
this.options=this.GetOptions();
this.startListenTime=new Date();
// Determine which page we're on
t.DetermineCurrentPage();
// Code strictly for page: koc_game
if(t.currentPage == "koc_game"){
//Check for strange majic error
//setTimeout(function(){checkStrangeMagic();},15000);
window.setTimeout(function() {
if(!t.pageLoaded && t.GetAutoAttack() && !t.IsMapperRunning()) {
GM_log("whoops, game not loaded after 60 secs problem. reloading.");
t.SetValuesCache();
t.ReloadWindow();
}
},t.GetRandTime(60*1000));
if(t.GetAutoAttack()) {
window.setTimeout(function() {
// press start on the poc timer after we reload
if(unsafeWindow.poctoggletimer && unsafeWindow.ispaused) {
unsafeWindow.poctoggletimer();
}
},5000);
}
// Hide the invite friends tab on page load
if(!t.inviteFriendsTabHidden && this.options.disableInviteFriends){
var tabBar=ById("main_engagement_tabs");
if(tabBar){
var inviteFriendsTab=nHtml.FindByXPath(tabBar,".//a[contains(@onclick,'invite_friends_popup')]");
if(inviteFriendsTab){
inviteFriendsTab.style.display="none";
t.inviteFriendsTabHidden = true;
}
}
}
} // End of code strictly for page: koc_game
var domTickTimer=null;
var domTickUpto=0;
var domTick=function(e) {
var funcsById={};
// Handle cross-iframe commands (which are currently only being used for the domain selection page)
if (t.currentPage == "domain_selection" || t.currentPage == "domain_selection_app_page"){
if((domTickUpto%20)==0) {
t.HandleCrossIframeCommands();
}
}
if (t.currentPage == 'kabam_page'){
return;
}
// Code strictly for page: koc_game
if(t.currentPage == "koc_game"){
//if(e.target.className && !/(chat|city|slot)/.exec(e.target.className)) GM_log('xxx:'+e.target.className);
//if(e.target.id && e.target.id!='tooltip' && e.target.id('_l_')<0 && e.target.id.substring(0,2)!='l_' && e.target.id.substring(0,8)!='citysel_') GM_log('id:'+e.target.id);
var cityId=t.GetCurrentCityId();
var cityChanged=cityId!=t.prevCurrentCity?true:false;
if(cityChanged) {
t.prevCurrentCity=cityId;
}
// Resume attacks at the last city we left off on (if page was reloaded)
if(!t.currentAttackCityResumed){
var currentAttackCityNum = t.GetCurrentAttackCityNum();
var currentAttackCity=ById('citysel_'+currentAttackCityNum);
//t.Log('Last known attack city from :'+currentAttackCityNum);
if(currentAttackCity){
if(currentAttackCityNum>1){ //Do not change city if the last city saved was 1
t.Log('Changing to last city before refresh:'+currentAttackCityNum);
t.autoAttackCityUpto = currentAttackCityNum;
t.ClickChangeCity(currentAttackCity,0);
}
t.currentAttackCityResumed = true;
}
}
if((domTickUpto%10)==0) {
t.HandleChatPane();
}
if((domTickUpto%20)==0) {
t.CheckImpendingAttack();
}
if(cityChanged && cityId!=null) {
// changed city
setTimeout(function() {
t.AddOptionsLink();
t.DrawClosestFarms(); // Init auto attack tab
t.AddViewAttacksLink();
//t.AddImportExportLink();
},0);
setTimeout(function() {
t.DetermineCurrentRallyPointLevel();
t.DetermineCurrentMarchesNum();
t.CheckAutoRaiseGold();
t.CheckAbandonWilds();
t.CheckTrainTroops();
},1000);
setTimeout(function() {
t.CheckReports();
},3000);
setTimeout(function() {
t.NextAutoAttack();
},5000);
}
funcsById={
'castleModalTabs':function(target) {
t.OnCastleBoxAppear(target.parentNode);
},
'marketmain_bdy':function(target) {
t.OnMarketBoxAppear(target);
},
'modal_attack':function(target) {
window.setTimeout(function() {
t.OnAttackBoxAppear(target);
},250);
},
'barracks_train':function(target) {
t.AddTrainTroopsLink();
t.CheckTrainTroops();
},
'modal_speedup':function(target) {
t.ClickShareToWall(target);
},
'invitePopup':function(target) {
if(this.options.disableInviteFriends && false){
// Hide the invite popup if auto attack is enabled
target.parentNode.removeChild(target);
}
},
};
} // End of code strictly for page: koc_game
// Handle cross-domain facebook game publish requests
funcsById.RES_ID_fb_pop_dialog_table = function(target){
if (t.currentPage == "koc_game") {
// Update the current server id locally for cross-domain access
if(t.currentServerId>0 && t.currentPage == "koc_game"){
GM_setValue("KOCAttackLastKnownServerID", t.currentServerId);
}
}
}
if(t.currentPage == "facebook_popup"){
if((domTickUpto%20)==0) {
t.HandlePublishPopup();
}
}
// Log back into domain if disconnected due to server down-time
if(t.currentPage == "domain_selection" && t.options.autoLogBackIn){
if((domTickUpto%20)==0) {
t.HandleDomainLogin();
}
}
/*
if(e.target.id && funcsById[e.target.id]) {
funcsById[e.target.id](e.target);
} else
*/
//if(e.target.className.indexOf('modalBox')>=0) {
var funcCalled=0;
if(funcCalled==0) {
for(var id in funcsById) {
var f=funcsById[id];
var div=ById(id);
if(!t.idStatus[id] && div) {
var fcall=function(func,d) {
funcCalled++;
setTimeout(function() {
try {
func(d);
} finally {
funcCalled--;
}
},0);
}
fcall(f,div);
//t.TimeoutZero(f,div);
}
var divStatus=div?true:false;
if(divStatus!=t.idStatus[id]) {
//t.Log("Status changed:"+id+","+divStatus);
}
t.idStatus[id]=divStatus;
}
}
if(!domTickTimer) {
domTickTimer=window.setTimeout(function() {
domTickTimer=null;
domTick();
domTickUpto++;
},250);
}
};
var withinDomInserted=false;
if(document.body){
document.body.addEventListener('DOMNodeInserted',function(e) {
if(withinDomInserted) return;
var isStatuses=(e.target.className && e.target.className=='statues')?true:false;
if(isStatuses){
t.pageLoaded=true;
}
if(e.target.id && e.target.id=='tooltip') {
withinDomInserted=true;
setTimeout(function() {
try {
if(this.options.disableDrawMapIcons)
t.DrawLevelIcons();
t.OnToolTipAppear(e.target);
} finally {
withinDomInserted=false;
}
},0);
} else if(e.target.className && e.target.className.indexOf('modal_msg_reports')>=0) {
withinDomInserted=true;
setTimeout(function() {
try {
t.RecordReports();
t.AddCheckBarbarians();
t.HighlightAllianceReports();
} finally {
withinDomInserted=false;
}
},0);
}
},false);
}
domTick();
},
};
unsafeWindow.aaGotoMapHide = function (x, y){
try {
unsafeWindow.Modal.hideModal();
} catch (e){ }
try {
Modal.hideModal();
} catch (e){ }
unsafeWindow.aaGotoMap (x, y);
}
unsafeWindow.aaGotoMap = function (x, y){
var close = document.getElementById('KOCAttackViewAttacksCancel');
nHtml.Click(close);
setTimeout (function (){
document.getElementById('mapXCoor').value = x;
document.getElementById('mapYCoor').value = y;
unsafeWindow.reCenterMapWithCoor();
var a = document.getElementById("mod_views").getElementsByTagName("a");
for (var b = 0; b < a.length; b++) {
a[b].className = ""
}
document.getElementById('mod_views_map').className = "sel";
document.getElementById("maparea_city").style.display = 'none';
document.getElementById("maparea_fields").style.display = 'none';
document.getElementById("maparea_map").style.display = 'block';
unsafeWindow.tutorialClear()
}, 0);
};
function SetupQuickMarchButton(useRetryMarch) {
/*
var retryMarch='var retryMarch=function() { alert("retrying march"); new (Ajax.Request)(g_ajaxpath + "ajax/march.php" + g_ajaxsuffix, {'+
'method: "post",'+
'parameters: params,'+
'onSuccess: function (transport) {'+
'var rslt = eval("(" + transport.responseText + ")");'+
'if (!rslt.ok) {'+
'if(rslt.error_code==3) {'+
'window.setTimeout(function() { retryMarch(); },1000); '+
'} else {'+
'alert("March Error:"+rslt.msg);'+
'}'+
'}'+
'}'+
'}); };';
*/
var retryMarches='var retryMarch = function() { '+
'new (Ajax.Request)(g_ajaxpath + "ajax/march.php" + g_ajaxsuffix, {'+
'method: "post",'+
'parameters: params,'+
'onSuccess: function(transport) { marchSuccess(transport); },'+
'onFailure: function () { Modal.hideModalAll(); }'+
'}); };';
if(!useRetryMarch) {
retryMarches='var retryMarch = function() { return; };';
}
var modal_attack_update_num_maxReplaces=[
[['modal_attack_update_num_max','modal_attack_update_num_maxOld']],
[['$("modal_attack_unit_ipt','var x=0; var o = getBuildingLevel(12); if(o==11){x=150000}else{x=o*10000};$("modal_attack_unit_ipt']],
[['parseInt(','x; //parseInt(']]
];
var modalAttackReplaces=[
// *** it says "new Ajax" in the source but firefox converts it to new (Ajax
[['modal_attack_do','modal_attack_doOld']],
[['onSuccess:','onSuccess: marchSuccess=']],
[['Modal.showAlert(printLocalError(','if(rslt.error_code==3 || rslt.error_code==8) { try {window.setTimeout(function() { retryMarch(); },(3*1000)); } catch(e) { alert("retry failed:"+e); } } else { Modal.hideModalAll(); } Modal.showAlert(printLocalError(']]
];
var attack_generatequeueReplaces=[
[['attack_generatequeue','attack_generatequeueOld']],
[
['class=\\"army\\">" + g_js_strings.commonstr.army + ": "','style=\\"width: 145px !important\\" class=\\"army\\">"'],
['class=\\"army\\">" + g_js_strings.commonstr.army + ": <span>"','style=\\"width: 145px !important\\" class=\\"army\\"><span style=\'display: inline\'>"']
],
[['class=\\"name','style=\\"width: 0px !important; display: none;\\" class=\\"name']],
//[/123/g,'100']
];
var attack_generatequeueReplacesU=[
[['var u = 0;','var u = "K:"+seed.knights["city" + currentcityid]["knt" + q].combat+", "; ']],
[['u += parseInt','var x = parseInt']],
[['"Count"]);','"Count"]); if(x>0) { var uname=unitcost["unt"+r][0]; u+=uname[0]+uname[uname.length-1]+":"+x+", "; } ']],
];
var attack_generatequeueReplacesR=[
[['var r = 0;','var r = "K:"+seed.knights["city" + currentcityid]["knt" + t].combat+", "; ']],
[['r += parseInt','var x = parseInt']],
[['"Count"]);','"Count"]); if(x>0) { var uname=unitcost["unt"+p][0]; r+=uname[0]+uname[uname.length-1]+":"+x+", "; } ']],
];
var attack_generatequeueReplacesS=[
[['var s = 0;','var s = "K:"+seed.knights["city" + currentcityid]["knt" + u].combat+", "; ']],
[['s += parseInt','var x = parseInt']],
[['"Count"]);','"Count"]); if(x>0) { var uname=unitcost["unt"+q][0]; s+=uname[0]+uname[uname.length-1]+":"+x+", "; } ']],
];
var attack_generatequeueReplacesT=[
[['var t = 0;','var t = "K:"+seed.knights["city" + currentcityid]["knt" + w].combat+", "; ']],
[['t += parseInt','var x = parseInt']],
[['"Count"]);','"Count"]); if(x>0) { var uname=unitcost["unt"+q][0]; t+=uname[0]+uname[uname.length-1]+":"+x+", "; } ']],
];
var attack_generatequeueReplacesV=[
[['var v = 0;','var v = "K:"+seed.knights["city" + currentcityid]["knt" + y].combat+", "; ']],
[['v += parseInt','var f = parseInt']],
[['"Count"]);','"Count"]); if(f>0) { var uname=unitcost["unt"+r][0]; v+=uname[0]+uname[uname.length-1]+":"+f+", "; } ']],
];
var attack_generatequeueReplacesW=[
[['var w = 0;','var w = "K:"+seed.knights["city" + currentcityid]["knt" + A].combat+", "; ']],
[['w += parseInt','var t = parseInt']],
[['w += parseInt','var t = parseInt']],
[['"Return"])','"Return"]); if(t>0) { var uname=unitcost["unt"+s][0]; w+=uname[0]+uname[uname.length-1]+":"+t+", "; } ']],
[['"Count"])','"Count"]); if(t>0) { var uname=unitcost["unt"+s][0]; w+=uname[0]+uname[uname.length-1]+":"+t+", "; } ']],
];
var attack_generatequeueReplacesW2=[
[['var w = 0;','var w = "K:"+seed.knights["city" + currentcityid]["knt" + E].combat+", "; ']],
[['w += y','if(y>0) { var uname=unitcost["unt"+cm.UNIT_TYPES[t]][0]; w+=uname[0]+uname[uname.length-1]+":"+y+", "; }']],
];
/*****
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
modalAttackReplaces.push([['new Ajax',"var marchSuccess=null; "+retryMarch+
(useRetryMarch?"":" Modal.hideModalAll(); ")+
"\nnew Ajax"]]);
} else {
modalAttackReplaces.push([['new (Ajax',"var marchSuccess=null; "+retryMarch+
(useRetryMarch?"":" Modal.hideModalAll(); ")+
"\nnew (Ajax"]]);
}
*****/
//modalAttackReplaces.push([['ajax.Request', "var marchSuccess=null; "+retryMarch+
//(useRetryMarch?"":" Modal.hideModalAll(); ")+ "\najax.Request"]]);
if(!useRetryMarch) modalAttackReplaces.push(['Modal.hideModalAll();','']);
var replaceFunc=function(name,replaces) {
var modalAttackFunc=window[name].toString();
var nameOld=name+'Old';
var foundFailed=false;
for(var a=0; a<replaces.length; a++) {
var found=false;
var repArr=replaces[a];
for(var ra=0; ra<repArr.length; ra++) {
var repI=repArr[ra];
if(typeof(repI[0])=="object") {
found=repI[0].exec(modalAttackFunc)?true:false;
} else {
found=modalAttackFunc.indexOf(repI[0])>=0?true:false;
}
if(found) break;
}
if(!found) {
var err="modalAttackReplace: cannot find: "+repI[0]+','+modalAttackFunc;
var sp=document.createElement('span');
sp.style.color='#ccc';
sp.appendChild(document.createTextNode(err));
document.body.insertBefore(sp,document.body.childNodes[0]);
foundFailed=true;
break;
}
modalAttackFunc=modalAttackFunc.replace(repI[0],repI[1]);
}
if(foundFailed) return;
try {
window[nameOld]=eval(modalAttackFunc);
//alert(window[nameOld].toString());
} catch(e) {
alert(e+', bad func:'+modalAttackFunc);
}
window[name]=function(e) {
// let our stuff in addListener run first.
window.setTimeout(function() {
eval(nameOld+'(e);');
},100);
}
};
var attackFuncStr=window['modal_attack_do'].toString();
//if(attackFuncStr.indexOf('ajax.Request')<0) {
modalAttackReplaces.push([
['new (Ajax',"var marchSuccess=null; "+retryMarches+
(useRetryMarch?"":" Modal.hideModalAll(); ")+
"\nnew (Ajax"],
['new Ajax',"var marchSuccess=null; "+retryMarches+
(useRetryMarch?"":" Modal.hideModalAll(); ")+
"\nnew Ajax"],
['ajax.Request',"var marchSuccess=null; "+retryMarches+
(useRetryMarch?"":" Modal.hideModalAll(); ")+
"\najax.Request"]
]);
//}
replaceFunc('modal_attack_do',modalAttackReplaces);
//replaceFunc('modal_attack_update_num_max',modal_attack_update_num_maxReplaces);
function AddArray(to,from) {
for(var c=0; c<from.length; c++) { to.push(from[c]); }
}
var arr=[];
AddArray(arr,attack_generatequeueReplaces);
var funcStr=window['attack_generatequeue'].toString();
if(funcStr.indexOf(' var w = 0;')>=0) {
// camelotmain-218
AddArray(arr,attack_generatequeueReplacesW2);
} else if(funcStr.indexOf('; var r = 0;')>=0) {
AddArray(arr,attack_generatequeueReplacesR);
} else if(funcStr.indexOf('; var s = 0;')>=0) {
AddArray(arr,attack_generatequeueReplacesS);
} else if(funcStr.indexOf('; var t = 0;')>=0) {
// camelotmain-150
AddArray(arr,attack_generatequeueReplacesT);
} else if(funcStr.indexOf('; var v = 0;')>=0) {
// camelotmain-165
AddArray(arr,attack_generatequeueReplacesV);
} else if(funcStr.indexOf('; var u = 0;')>=0) {
AddArray(arr,attack_generatequeueReplacesU);
} else {
var err="Unknown attack queue func: "+location.href+"\n"+funcStr;
GM_log(err);
}
replaceFunc('attack_generatequeue',arr);
//replaceFunc('modal_attack_update_num',modalAttackUpdateNumReplaces);
/* BAD: updateSeed.php doesn't return cityUnits
var params = Object.clone(g_ajaxparams);
new Ajax.Request(g_ajaxpath + "ajax/updateSeed.php" + g_ajaxsuffix, {
method: "post",
parameters: params,
onSuccess: function (message) {
alert(message.responseText);
}
});
*/
}
/*
function SetupClearMessages() {
modal_messages_reports_chkdelOld=modal_messages_reports_chkdel;
modal_messages_reports_chkdel=function(type) {
var d=document.createElement('div');
d.id='modal_msg_reports_tablediv';
document.body.appendChild(d);
modal_messages_reports_chkdelOld(type);
if(type=='deleteAll') {
document.getElementById('ClearMessages').click();
}
};
}
*/
function CreateMsgDiv() {
var m=document.getElementById('KOCAttackMsgDiv');
if(!m) {
var ml=document.getElementById('modal_msg_list');
if(!ml) {
ml=document.createElement('div');
ml.id='modal_msg_list';
}
m=document.createElement('div');
m.style.position='absolute';
m.style.top='0px';
m.style.left='0px';
m.style.width='700px';
m.style.zIndex='900000';
m.style.border='5px solid #000';
m.style.backgroundColor='#fff';
//m.id='modal_attack';
var close=document.createElement('a');
close.addEventListener('click',function() {
m.style.display='none';
m.removeChild(ml);
},false);
close.innerHTML='Close';
close.style.fontSize='20px';
var center=document.createElement('center');
center.appendChild(close);
m.appendChild(center);
m.appendChild(ml);
if(!document.getElementById('modal_msg_list_pagination')) {
p=document.createElement('div'); p.id='modal_msg_list_pagination';
ml.appendChild(p);
}
//document.body.insertBefore(m,document.body.childNodes[0]);
if(document.body){
document.body.appendChild(m);
}
}
m.style.display='block';
return m;
}
function AddScript(js) {
var scr=document.createElement('script');
scr.innerHTML=js;
document.body.appendChild(scr);
}
function SetupScripts() {
var options=KOCAttack.GetOptions();
var scr=document.createElement('script');
scr.innerHTML="CreateMsgDiv="+CreateMsgDiv+
";\n"+
// SetupClearMessages+"\n; SetupClearMessages();\n"+
";\n"+SetupQuickMarchButton+"\n; SetupQuickMarchButton("+options.retryMarch+"); \n";
document.body.appendChild(scr);
}
/******************* Anti-anticheat measures ******************/
var mixpanelRemoved=false;
function DisableMixpanel() {
if(unsafeWindow.cm) {
unsafeWindow.cm.MixPanelTracker.track=function() { };
}
if(unsafeWindow.MixpanelLib) {
unsafeWindow.MixpanelLib.prototype={
register:function() { },
track:function(t) {
}
};
}
if(!unsafeWindow.cm || !unsafeWindow.MixpanelLib) {
window.setTimeout(function() {
DisableMixpanel();
},100);
} else {
GM_log('Mixpanel removed');
mixpanelRemoved=true;
}
}
/******************* Check strange majic error ******************/
function checkWhiteScreen (){
window.setTimeout(function(){
GM_log("Check iFrame");
var checknumber = 0;
function checkiFrame() {
var iFrame = document.getElementById('iframe_canvas');
if (!iFrame && checknumber<10){
checknumber++;
setTimeout (checkiFrame, 1000);
return;
} else if (checknumber>=10){
KOCAttack.ReloadWindow();
GM_log("White screen error. Refreshing.....");
}
return;
}
checkiFrame();
}, 10000);
}
function checkStrangeMagic (){
GM_log("Check strange majic");
if (!document.getElementById("kochead")){
window.setTimeout ( function() { GM_log ("checkStrangeMajik REloading..."); KOCAttack.ReloadWindow(); }, 5000);
popup (100,100,500,275, "<BR><CENTER>checkStrangeMajik <BR><BR>KofC NOT FOUND<BR>Refreshing in 5 seconds ...<BR><BR>");
}
}
function popup (left, top, width, height, content){
var div = document.createElement('div');
if (width)
div.style.width = width;
if (height)
div.style.height = height;
if (left || top) {
div.style.position = "relative";
if (left)
div.style.left = left;
if (top)
div.style.top = top;
}
if (content)
div.innerHTML = content;
div.style.background = "#ffc";
div.style.border = "2px solid #000";
div.style.zIndex = "999999"; // KOC modal is 100210 ?
div.style.display = 'block';
window.document.body.insertBefore(div, window.document.body.childNodes[0]);
return div;
}
/******************* Function calls ******************/
KOCAttack.Listen();
if(unsafeWindow.cm){
unsafeWindow.cm.cheatDetector={
a:function(){ },
detect:function() { }
};
}
if(document.URL.search('apps.facebook.com/kingdomsofcamelot/')>=0) {
checkWhiteScreen();
} else {
StartAll();
}
var startAllTimeout=null;
function StartAll() {
DisableMixpanel();
var now=new Date().getTime();
if(startAllTimeout==null) {
startAllTimeout=now+5000;
}
if(mixpanelRemoved || startAllTimeout<now) {
if(startAllTimeout<now) {
GM_log("Did not remove mixpanel, starting anyways");
}
KOCAttack.SetupClearMessages();
SetupScripts();
} else {
window.setTimeout(function() { StartAll(); },200);
}
}
var WINLOG_MAX_ENTRIES = 1000; // TODO
var WinLog = {
state : null,
win: null,
eOut : null,
lastE : null,
enabled : true,
reverse : true,
busy : false,
isOpening : false,
open : function (){
var t = WinLog;
GM_log("opening WinLog");
function eventButClear(){
var t = WinLog;
t.lastE = null;
t.eOut.innerHTML ='';
}
function eventButReverse(){
var t = WinLog;
if (t.busy)
return;
t.busy = true;
if (t.reverse){
t.win.document.getElementById('wlRev').value= 'Top';
t.reverse = false;
} else{
t.win.document.getElementById('wlRev').value= 'Bottom';
t.reverse = true;
}
var n = t.eOut.childNodes.length;
if (n < 2)
return;
for (i=n-2; i>=0; i--){
t.eOut.appendChild (t.eOut.childNodes[i]);
}
t.busy = false;
}
if (!t.win || t.win.closed){
t.isOpening = true;
t.win = window.open('', 'uwtrace', 'top=30,left=0,width=900,height=700,scrollbars=no,location=no,menubar=no,directories=no,status=no');
t.isOpening = false;
t.state = null;
}
if (t.state == null){
t.win.document.body.innerHTML = '<STYLE>pre{margin:0px} hr{margin:3px; height:1px; border:0px; color:#cee; background-color:#cee}</style>\
<BODY style="margin:0px; padding:0px; border:none">\
<DIV id=winlogtop style="background-color:#d0d0d0; margin:0px; padding:0px; border:1px solid">\
<INPUT id=wlClear type=submit value="Clear"> <INPUT id=wlRev type=submit value="Bottom"></div>\
<DIV id=wlOut style="overflow-y:auto; height:100%; max-height:100%"></div></body>';
t.win.document.getElementById('wlClear').addEventListener('click', eventButClear, false);
t.win.document.getElementById('wlRev').addEventListener('click', eventButReverse, false);
t.eOut = t.win.document.getElementById('wlOut');
t.state = 1;
}
},
write : function (msg){
var t = WinLog;
if (!t.enabled || t.isOpening){
return;
}
t.open();
return;
var te = document.createElement('pre');
var now = new Date();
var m = [];
var millis = now.getMilliseconds();
m.push (now.toTimeString().substring (0,8));
m.push ('.');
if (millis<100)
m.push('0');
if (millis<10)
m.push('0');
m.push(millis);
m.push (': ');
m.push (msg);
te.innerHTML = m.join('');
if (t.reverse){
if (t.lastE == null){
t.eOut.appendChild(te);
t.lastE = te;
} else {
t.eOut.insertBefore(te, t.lastE);
}
var hr = document.createElement('hr');
t.eOut.insertBefore(hr, te);
t.lastE = hr;
} else {
t.eOut.appendChild(te);
t.eOut.appendChild(document.createElement('hr'));
}
},
};