There are 29 previous versions of this script.
the source is over 100KB, syntax highlighting in the browser is too slow
// ==UserScript==
// @name KOCAttack
// @namespace KOCAttack
// @description Kingdoms of Camelot attacker
// @include http://*.kingdomsofcamelot.com/*main_src.php*
// @require http://sizzlemctwizzle.com/updater.php?id=76594
// ==/UserScript==
/*
// @include http://apps.facebook.com/kingdomsofcamelot/*
*/
var kocattack_version='2010-04-02';
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }
String.prototype.StripQuotes = function() {
return this.replace(/"/g,'');
};
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 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) {
try {
var q=document.evaluate(xpath,obj,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null);
} catch(e) {
GM_log('bad xpath:'+xpath);
}
if(q && q.singleNodeValue) { return q.singleNodeValue; }
return null;
},
FindAllByXPath:function(obj,xpath) {
var ss=document.evaluate(xpath,obj,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
var iconEdits=[];
for(var s=0; s<ss.snapshotLength; s++) {
var a=ss.snapshotItem(s);
iconEdits.push(a);
}
return iconEdits;
},
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 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;
}
var KOCAttack={
startListenTime:null,
prevAttack:{'x':"333",'y':'111'},
options:null,
isChrome:navigator.userAgent.toLowerCase().indexOf('chrome') > -1,
valuesCache:{},
seed:{},
DoUnsafeWindow:function(func) {
if(this.isChrome) {
var scr=document.createElement('script');
scr.innerHTML=func;
document.body.appendChild(scr);
} else {
eval("unsafeWindow."+func);
}
},
GetSeed:function() {
if(this.isChrome) {
//~~~ get seed
return this.seed;
}
return unsafeWindow.seed;
},
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';
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>';
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'>Version: "+kocattack_version+"<br />"+
"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> "+
"<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"+
"</div>"+
"<br />"+
"<input id='KOCAttackMaxDistance' value='"+(this.options.attackMaxDistance)+"' size='3' /> max distance away from city to attack.<br />"+
"<input id='KOCAttackLockAttackFromCity' type='checkbox' "+(this.options.lockAttackFromCity?'checked':'')+" /> Only launch attacks from city they were last launched from.<br />"+
"<input id='KOCAttackRemoteAttack' type='checkbox' "+(this.options.remoteAttack?'checked':'')+" /> Enable remote attack features.<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 />"+
"Open up this url in a tab when we're under attack...<br /><input id='KOCAttackImpendingAttackUrl' size='60' value='"+(this.options.impendingAttackUrl)+"' /><br />"+
"</td></tr>"+
//http://cdn1.kingdomsofcamelot.com/fb/e2/src/img/units/unit_6_50.jpg?6545
"<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='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/happiness.png' /></td><td valign='top'>"+
"<input id='KOCAttackPercentOfPopToTrain' value='"+this.options.percentOfPopToTrain+"' size='3' />% of idle population available before we do auto training.<br />"+
"<input id='KOCAttackAutoGoldHappiness' value='"+this.options.autoGoldHappiness+"' size='3' />% happiness before we click auto gold.<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'>"+
"<input id='KOCAttackRandom' value='"+this.options.randomPercent+"' size='3' />% random adjustment for all delays (to look more human).<br />"+
"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>"+
"<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></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();
t.ReloadWindow();
// window.history.go(0);
// window.location.reload(true);
},false);
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;
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.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.randomPercent=parseFloat(ById('KOCAttackRandom').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.remoteAttack=ById('KOCAttackRemoteAttack').checked;
t.options.autoRemoveReports=ById('KOCAttackRemoveReports').checked;
t.options.retryMarch=ById('KOCAttackRetryMarch').checked;
t.options.impendingAttackUrl=ById('KOCAttackImpendingAttackUrl').value;
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);
},
AddTabLink:function(html) {
var a=document.createElement('a');
a.className='navTab';
// a.style.color='#fff';
a.innerHTML='<span>'+html+'</span>';
var tabs=ById('main_engagement_tabs');
/*
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.insertBefore(a,tabs.childNodes[0]);
return a;
}
return null;
},
ToggleAutoAttack:function() {
var t=this;
var a=t.GetAutoAttack();
if(!a) {
t.SetAutoAttack({'barbarian':true,'cities':{}});
t.RestartAutoAttack();
} else {
t.ClearAutoAttackTimeout();
t.SetAutoAttack(null);
}
/*
// 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);
}
*/
t.SetAttackStatusMessage();
},
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</span>';
} else {
toggle.innerHTML='<span>No auto attack</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) {
str=this.GetServerId()+":"+str;
GM_log(str);
if(unsafeWindow.poclog) {
unsafeWindow.poclog.add(str);
}
},
GetServerId:function() {
var m=/^[a-zA-Z]+([0-9]+)\./.exec(document.location.hostname);
if(!m) m=/s=([0-9]+)/.exec(document.location.search);
if(m) {
return m[1];
}
return -1;
},
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",
"autoRemoveReports":true,
"attackSecsSinceLastCity":60*60*12,
"attackSecsSinceLastCamp":3600,
"attackSecsSinceLastWild":3600,
"attackSecsSinceLastTransport":60,
"randomPercent":20,
"keepReports":10,
"attackMaxDistance":60,
"waitAfterCitiesDone":15,
"autoAttackCitiesDoneMax":3,
"changeCitySecs":15,
"retryMarch":true,
"noViewReports":false,
"chromeKeepReports":2,
"percentOfPopToTrain":100,
"autoGoldHappiness":99,
"okCities":[1,1,1,1,1,1,1,1,1,1],
'remoteAttackTypeAllowed':[0,1,1,1,1],
'remoteAttack':true,
'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));
},
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));
},
IsFirstAttackAtLocation:function(x,y) {
if(!this.prevAttack) return true;
return ((this.prevAttack.x==x && this.prevAttack.y==y)?false:true);
},
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;
}
return [x.value,y.value];
},
SetAttackFromGui:function(box) {
var xy=this.GetGuiCoords();
if(!xy) return null;
return this.SetAttackFromGuiXY(xy[0],xy[1],box);
},
// new: 0=transport, 1=reinforce, 2=scout, 3=attack, 4=reassign,
// old??? 0=attack, 1=transport, 2=scout, 3=reinforce, 4=reassign
newAttackTypeToOld:[1,3,2,0,4],
GetAttackTypeFromGui:function() {
var type=ById('modal_attack_atktype');
if(!type) return null;
if(!ById('modal_attack_tab_1')) {
// old interface
return type.selectedIndex;
}
return this.newAttackTypeToOld[type.selectedIndex];
},
SetOldAttackTypeToGui:function(type) {
var t=this;
if(!ById('modal_attack_tab_1')) {
// old interface
ById('modal_attack_atktype').selectedIndex=type;
}
// new interface
for(var a=0; a<t.newAttackTypeToOld.length; a++) {
if(t.newAttackTypeToOld[a]==type) {
nHtml.Click(ById('modal_attack_tab_'+(a+1)));
ById('modal_attack_atktype').selectedIndex=a;
}
}
},
GetAttackFromGui:function() {
var comment=ById('KocAttackComment');
var type=this.GetAttackTypeFromGui();
if(type==null || type==undefined) {
throw("Cannot find attack type");
}
var troops=[];
var totalTroops=0;
for(var tr=0; tr<100; 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 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;
}
}
var xy=this.GetGuiCoords();
var attack={
'x':xy[0],'y':xy[1],
'type':type,
'comment':'',
'troops':troops,
'resources':resources,
'totalTroops':totalTroops
};
if(comment)
attack.comment=comment.value;
return attack;
},
SetAttackFromGuiXY:function(x,y,box) {
var attackInfo=this.GetAttackFromGui();
if(attackInfo.totalTroops<=0) {
this.Log("No troops, not saving attack");
return null;
}
var troops=attackInfo.troops;
// ignore anything other than attack
if(attackInfo.type==0) {
var attack=this.GetAttack(x,y);
if(!attack) attack={};
attack.type=attackInfo.type;
attack.comment=attackInfo.comment;
var nowSecs=new Date().getTime()/1000;
var firstAttack=this.IsFirstAttackAtLocation(x,y);
if(attackInfo.totalTroops>0 && (troops[2]+troops[10])==attackInfo.totalTroops && firstAttack) {
// nothing but militiamen/ballista, anti defence attack
attack.militiaonly=troops;
} else {
attack.time=nowSecs;
if(firstAttack) { attack.militiaonly=undefined; }
attack.troops=troops;
}
//if (this.options.lockAttackFromCity) {
attack.fromCity=this.GetCurrentCityId();
//}
//attack.ignore=undefined;
this.prevAttack={'x':x,'y':y};
this.SetAttack(x,y,attack);
return attack;
} else if(attackInfo.type==1) {
// try to parse transports
var attack=this.GetAttack(x,y);
if(!attack) attack={};
attack.type=attackInfo.type;
//attack.ignore=true; // We set this to ignore for now until I can get the auto attack working
attack.comment=attackInfo.comment;
var nowSecs=new Date().getTime()/1000;
var firstAttack=this.IsFirstAttackAtLocation(x,y);
attack.time=nowSecs;
attack.troops=attackInfo.troops;
attack.resources=attackInfo.resources;
//if (this.options.lockAttackFromCity) {
attack.fromCity=this.GetCurrentCityId();
//}
//attack.ignore=undefined;
this.prevAttack={'x':x,'y':y};
this.SetAttack(x,y,attack);
return attack;
} else {
this.prevAttack=null;
}
return null;
},
BulkAddCoords:function(box,coordsText,force) {
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);
if(attack && !force) {
this.Log(x+','+y+' has already been added.');
continue;
}
var attack=this.SetAttackFromGuiXY(x,y,box);
if(attack) {
attack.levelInfo={'type':'Camp','level':0};
attack.time=0;
attack.ignore=undefined;
this.SetAttack(x,y,attack);
this.Log(x+','+y+' attack setup');
added++;
}
}
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,"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' /> Overwrite existing attack if one already exists<br />");
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() {
var added=t.BulkAddCoords(box,coords.value,ById('KOCAttackBulkAddForce').checked);
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() {
bulkAddDiv.style.display='inline';
bulkAddAttackLink.style.display='none';
},false);
div.appendChild(bulkAddTable);
div.appendChild(bulkAddAttackLink);
return div;
},
HideAttackEfforts:function() {
var items=ById('modal_attack_attack_boost');
if(!items) return;
var defense=ById('modal_attack_defense_boost');
var march=ById('modal_attack_march_boost');
var speed=ById('modal_attack_speed_boost');
if(!defense || !march || !speed) {
throw("Cannot find defense");
}
var est=nHtml.FindByXPath(speed,".//div[contains(@class,'estimated')]");
if(est)
speed.parentNode.appendChild(est);
//items=items.parentNode.parentNode;
var a=document.createElement('a');
a.innerHTML='Hide/Show attack boosts';
//a.href='javascript:;';
a.style.cursor='pointer';
items.style.display='none';
defense.style.display='none';
march.style.display='none';
speed.style.display='none';
a.addEventListener('click',function() {
items.style.display=items.style.display=='none'?'block':'none';
defense.style.display=defense.style.display=='none'?'block':'none';
march.style.display=march.style.display=='none'?'block':'none';
speed.style.display=speed.style.display=='none'?'block':'none';
},false);
return a;
},
SetResourceInputs:function(resources) {
var resourceTypes = new Array(
'gold',
'rec1',
'rec2',
'rec3',
'rec4'
);
var notFullResources=false;
var totalResources=0;
for(var res=0; res<resources.length; res++) {
var resourceCount=resources[res];
if(!resourceCount) continue;
totalResources+=resourceCount;
if(this.SetResourceInput(resourceTypes[res],resourceCount)=='notfull') {
notFullResources=true;
}
}
return {'totalResources':totalResources,'notFullResources':notFullResources};
},
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';
},
SetTroopInputs:function(troops) {
var totalTroops=0;
var notFullTroops=false;
for(var tr=0; tr<troops.length; tr++) {
var troopCount=troops[tr];
if(!troopCount) continue;
totalTroops+=troopCount;
if(this.SetTroopInput(tr,troopCount)=='notfull') {
notFullTroops=true;
}
}
return {'totalTroops':totalTroops,'notFullTroops':notFullTroops};
},
SetTroopInput:function(num,troopCount) {
var troop=ById('modal_attack_unit_ipt'+num);
if(!troop) return null;
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);
var maxNumObj=troop.parentNode.previousSibling;
var maxNum=0;
if(maxNumObj) {
maxNum=parseInt(maxNumObj.textContent);
}
if(parseInt(troopCount)>parseInt(maxNum)) {
//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(),false);
},
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 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(rows.length);
for (i=0;i<rows.length;i++) {
var abandonButton=rows[i].getElementsByTagName('a')[0];
if (abandonButton==undefined) {
continue;
}
var command=abandonButton.getAttribute('onclick');
command=command.substring(0,command.length-13);
commands[i] = command;
}
this.DoUnsafeWindow("Modal.hideModal();");
for (i=0;i<commands.length;i++) {
this.DoUnsafeWindow(commands[i]);
}
},
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':'No auto';
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':'Keep Wilds';
b.innerHTML='<span>'+str+'</span>';
}
b.addEventListener('click',function() {
var abandonWilds=t.GetAbandonWilds();
t.SetAbandonWilds(abandonWilds?false:true);
SetAbandonWildsA();
},false);
SetAbandonWildsA();
//raiseGold.parentNode.insertBefore(b,raiseGold.nextSibling);
productionHeader.parentNode.insertBefore(b,productionHeader);
},
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';
}
},
AddRemoteAttackButton:function(box) {
var t=this;
if(!t.options.remoteAttack) return;
var div=document.createElement('div');
var player=document.createElement('input');
var city=document.createElement('input');
var remoteAttack=document.createElement('a');
remoteAttack.className='button25';
remoteAttack.innerHTML='<span>Remote Attack</span>';
div.appendChild(document.createTextNode('Remote Player:'));
div.appendChild(player);
div.appendChild(document.createTextNode(' Remote City:'));
div.appendChild(city);
div.appendChild(remoteAttack);
remoteAttack.addEventListener('click',function() {
window.setTimeout(function() {
var attack=t.GetAttackFromGui();
var playerName=player.value.trim();
var cityName=city.value.trim();
if(playerName=="" || cityName=="") {
window.alert("Must pick another player + city");
return;
}
t.SendChat(playerName,"attack?"+JSON2.stringify({'city':cityName,'attack':attack}));
t.DoUnsafeWindow("Modal.hideModalAll();");
},0);
},false);
var btnMarch=ById('btnMarch');
btnMarch.parentNode.insertBefore(div,btnMarch);
},
/*
MakeTroopBoxesUnlimited:function() {
for(var tr=0; tr<100; tr++) {
var id='modal_attack_unit_ipt'+tr;
var troop=ById(id);
if(!troop) continue;
var troopNew=document.createElement('input');
troopNew.name=tr;
troopNew.id=id;
var p=troop.parentNode;
p.removeChild(troop);
p.insertBefore(troop,p.childNodes[0]);
}
},
*/
nextAutoAttackTimeout:null,
onclickTimeRe:/,([0-9]+),[0-9]+,[0-9]+,[0-9]+[^,]*$/,
waitForAttackBoxAppear:null,
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;
}
var attackType=t.GetAttackTypeFromGui();
//var attackTypeSelect=ById('modal_attack_atktype');
this.StopWaitForAttackBoxAppear();
if(ById('KocAttackComment')) {
this.Log("We already have an attack dialog opened");
return;
}
var autoAttack=this.GetAutoAttack();
var knightSelect=ById('modal_attack_knight')
//this.MakeTroopBoxesUnlimited();
this.AddRemoteAttackButton(box);
var cityName=t.GetCurrentCityName();
var remoteAttack=t.GetValue('RemoteAttack_'+cityName,'');
if(autoAttack && remoteAttack!="") {
var attack=JSON2.parse(remoteAttack);
t.Log('Remote attack:'+JSON2.stringify(attack));
var setTroops=t.SetTroopInputs(attack.troops);
if(setTroops.notfullTroops) {
t.SendChat(attack.fromPlayer,"attack.Not enough troops");
} else {
this.SetOldAttackTypeToGui(attack.type);
if(attack.type==0) {
knightSelect.selectedIndex=1+Math.floor(Math.random()*(knightSelect.options.length-1));
}
// set resources + target
var x=ById('modal_attack_target_coords_x');
var y=ById('modal_attack_target_coords_y');
x.value=attack.x;
y.value=attack.y;
if(attack.resources) {
var setResources=t.SetResourceInputs(attack.resources);
if(setResources.notfullResources) {
t.SendChat(attack.fromPlayer,"attack.Not enough resources");
return;
}
}
t.SendChat(attack.fromPlayer,"attack.Attempted");
nHtml.Click(btnMarch);
t.SetValue('RemoteAttack_'+cityName,undefined);
window.setTimeout(function() {
autoAttack.x=autoAttack.y=-1;
t.SetAutoAttack(autoAttack);
t.NextAutoAttack();
},1000);
return;
}
}
btnMarch.addEventListener('click',function(e) {
window.setTimeout(function() {
t.SetAttackFromGui(box);
t.SetValuesCache();
// we want to keep the scroll bar at the same position, don't redraw
//~~~ mmm... need to wait for attack to finish before the numbers will update.
//t.DrawClosestFarms();
},0);
},false);
var comment=document.createElement('input');
comment.id='KocAttackComment';
comment.size='30';
var nowSecs=new Date().getTime()/1000;
var div=document.createElement('div');
div.style.overflow='scroll';
div.style.height='280px';
AddText(div,'Comment:');
div.appendChild(document.createElement('br'));
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 nextElement=ById('modal_attack_attack_boost');
nextElement.parentNode.insertBefore(div2, nextElement);
//div.appendChild(document.createElement('br'));
var xy=this.GetGuiCoords();
var attack=null;
if(xy) {
attack=this.GetAttack(xy[0],xy[1]);
}
//var notFullTroops=false;
var setTroops={'totalTroops':0};
var setResources={};
if(attack) {
ignore.checked=attack.ignore?true:false;
if(attack.time) {
AddHtml(div,'Last attack: '+SecsToStr(nowSecs-attack.time)+' ago<br />');
}
if(attack.comment)
comment.value=attack.comment;
// only fill things in if we're in attack mode.
if(attackType==0 && attack.type==0) {
//if(this.prevAttack)GM_log('militia:'+this.prevAttack.x+'=='+xy[0] +','+this.prevAttack.y+'=='+xy[1] );
if(attack.militiaonly
&& this.IsFirstAttackAtLocation(xy[0],xy[1])
) {
// anti traps attack
if(typeof(attack.militiaonly)=="object") {
setTroops=this.SetTroopInputs(attack.militiaonly);
/*
for(var i=1; i<attack.militiaonly.length; i++) {
this.SetTroopInput(i,attack.militiaonly[i]);
setTroops.totalTroops+=attack.militiaonly[i];
}
*/
} else {
this.SetTroopInput(2,attack.militiaonly);
setTroops.totalTroops+=attack.militiaonly;
}
} else if(attack.troops) {
setTroops=this.SetTroopInputs(attack.troops);
}
//attackTypeSelect.selectedIndex=attack.type;
knightSelect.selectedIndex=1+Math.floor(Math.random()*(knightSelect.options.length-1));
} else if (attackType==1 && attack.type==1) {
t.SetOldAttackTypeToGui(attack.type);
setTroops=t.SetTroopInputs(attack.troops);
setResources=t.SetResourceInputs(attack.resources);
// We don't send a knight with transports
}
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'));
}
var deleteBtn=document.createElement('a');
deleteBtn.className='button25';
deleteBtn.innerHTML='<span>Delete Attack</span>';
deleteBtn.addEventListener('click',function() {
t.DeleteAttack(xy[0],xy[1]);
},false);
var unitList=ById('modal_attack_unitlist');
if(unitList) {
unitList.parentNode.insertBefore(deleteBtn,unitList.nextSibling);
} else {
var attackTypeSelect=ById('modal_attack_atktype');
if(attackTypeSelect)
attackTypeSelect.parentNode.insertBefore(deleteBtn,attackTypeSelect.nextSibling);
}
}
var ChangeAttack=function() {
var xy=t.GetGuiCoords();
var attack=null;
var attackType=GetAttackTypeFromGui();
//var attackTypeSelect=ById('modal_attack_atktype');
if(xy) {
attack=t.GetAttack(xy[0],xy[1]);
}
if(!attack) attack={};
if(attackType!=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;
t.SetAttack(xy[0],xy[1],attack);
}
comment.addEventListener('change',function() { ChangeAttack(); },false);
ignore.addEventListener('change',function() { ChangeAttack(); },false);
var parentDiv=ById('modal_attack_attack_boost');
parentDiv.parentNode.insertBefore(div,parentDiv);
parentDiv.parentNode.insertBefore(this.HideAttackEfforts(),parentDiv);
parentDiv.parentNode.insertBefore(this.BulkAddAttackLink(box),parentDiv);
this.AttachXYPaste('modal_attack_target_coords_x','modal_attack_target_coords_y');
if(autoAttack && autoAttack.x==xy[0] && autoAttack.y==xy[1] && !ignore.checked) {
autoAttack.x=autoAttack.y=-1;
this.SetAutoAttack(autoAttack);
if(setTroops.totalTroops>0
&& knightSelect.options.length>1
&& !setTroops.notFullTroops
&& !setResources.notFullResources
&& btnMarch.style.opacity!=0.5
) {
this.Log('Auto attack:'+xy[0]+','+xy[1]+', from city:'+this.autoAttackCityUpto);
var t=this;
window.setTimeout(function() {
t.autoAttacksThisCity++;
nHtml.Click(btnMarch);
//t.ResetIdStatus();
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));
},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('auto attack, not enough troops/knights: '+xy[0]+','+xy[1]+
", knights avail:"+(knightSelect.options.length-1)+", Not enough troops/resources:"+setTroops.notFullTroops+'/'+setResources.notFullResources+', needed:'+setTroops.totalTroops+'/'+setResources.totalResources);
this.DoUnsafeWindow("Modal.hideModal();");
this.NextAutoAttackCity();
}
}
},
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]+)/,
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) continue;
var typeNum=m[3].replace('"','');
var type=this.squareTypeNums[typeNum];
if(!type) continue;
if(typeNum=="51" && m[5]!='0') {
type='';
}
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; }
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(currentResources[t])) {
return false;
}
}
return true;
},
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) {
levelI=this.FindLevelFromMessages(attack);
}
return levelI;
},
FindBiggestCampAttack:function(attacks,currentTroops,currentResources) {
var bestAttack=null;
var bestAttackSize=0;
var bestAttackDist=10000;
var nowSecs=new Date().getTime()/1000;
var wilderness={
'Lake':1,
'Mountains':1,
'Woods':1,
'Forest':1,
'Plain':1,
'Hills':1,
'Grassland':1
};
for(var a=0; a<attacks.length; a++) {
var attack=attacks[a];
var levelInfo=this.GetLevelInfo(attack.a);
if(!levelInfo) continue;
if(levelInfo.type=='Camp') {
if(this.options.attackTypeCamp!=true) {
continue;
}
} else if(wilderness[levelInfo.type]) {
if(this.options.attackTypeWild!=true) {
continue;
}
} else if (levelInfo.type!='Camp' && !wilderness[levelInfo.type]) {
var tempAttack=this.GetAttack(attack.x,attack.y);
if(tempAttack.type==0) {
if(this.options.attackTypeCity!=true) { continue; }
} else if(tempAttack.type==1) {
if(this.options.attackTypeTransport!=true) { continue; }
}
} else {
if(levelInfo.type!='' && levelInfo.type!='Camp') { continue; }
}
if(!attack.a.troops) continue;
if(attack.a.ignore) continue;
if(attack.dist>=this.options.attackMaxDistance) { continue; }
if(this.options.lockAttackFromCity) {
this.Log('fromCity='+attack.a.fromCity+', currentCity='+this.GetCurrentCityId());
if(attack.a.fromCity!=undefined) {
if(this.GetCurrentCityId()!=attack.a.fromCity) { continue; }
}
}
if(!this.IsEnoughTroops(currentTroops,attack.a.troops)) {
continue;
}
if (attack.a.type==1) {
if(!this.IsEnoughResources(currentResources,attack.a.resources)) {
continue;
}
}
var lastAttack;
if(!attack.a.time) {
lastAttack=60*60*24*31;
} else {
lastAttack=nowSecs-parseInt(attack.a.time);
}
if(levelInfo.type=='') {
if(attack.a.type==0) {
if(lastAttack<this.options.attackSecsSinceLastCity) continue;
} else {
if(lastAttack<this.options.attackSecsSinceLastTransport) continue;
}
} else if(levelInfo.type=='Camp') {
if(lastAttack<this.options.attackSecsSinceLastCamp) continue;
} else {
if(lastAttack<this.options.attackSecsSinceLastWild) 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.militiaonly) {
var militiaSize=0;
for(var t=0; t<attack.a.militiaonly.length; t++) {
if(!attack.a.militiaonly[t]) continue;
militiaSize+=parseInt(attack.a.militiaonly[t]);
}
if(militiaSize<=0) {
this.Log('Invalid militia attack size:'+attack.x+','+attack.y);
continue;
}
}
if(armySize<=0) {
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;
bestAttackDist=attack.dist;
}
}
if(ok) {
bestAttack=attack;
bestAttack.type=attack.a.type;
bestAttackSize=armySize;
}
}
return bestAttack;
},
IsMapperRunning:function() {
if(ById('SendMap')) {
//GM_log('mapper is running, do not auto attack');
return true;
}
return false;
},
GetAutoAttack:function() {
var aStr=this.GetValue('AutoAttack','');
//var aStr=GM_getValue('AutoAttack_'+this.GetServerId(),'');
if(aStr=='') {
return null;
}
try {
return JSON2.parse(aStr);
} catch(e) {
GM_log('failed to parse autoattack:'+aStr);
return null;
}
},
SetAutoAttack:function(s) {
if(s==null) {
this.SetValue('AutoAttack','');
//GM_setValue('AutoAttack_'+this.GetServerId(),'');
return;
}
this.SetValue('AutoAttack',JSON2.stringify(s));
//GM_setValue('AutoAttack_'+this.GetServerId(),JSON.stringify(s));
},
ResetAutoAttackTarget:function() {
var autoAttack=this.GetAutoAttack();
if(autoAttack) {
autoAttack.x=autoAttack.y=undefined;
this.SetAutoAttack(autoAttack);
}
},
GetCurrentMapCoord:function() {
var xcoord=ById('mapXCoor');
var ycoord=ById('mapYCoor');
return {'x':xcoord.value,'y':ycoord.value};
},
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);
setTimeout(function() {
t.DrawClosestFarms();
},0);
};
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):'');
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.militiaonly) {
var am=attackI.a.militiaonly[tupto];
if(am) num+=" ("+am+")";
}
AddText(tr.insertCell(-1),num);
}
}
}
var aDelete=document.createElement('a');
aDelete.innerHTML='X';
aDelete.title='Ignore';
aDelete.addEventListener('click',function(e) { IgnoreFarm(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]=ById('stat_gold_num'); // Gold
resources[1]=ById('stat_rec1_num'); // Food
resources[2]=ById('stat_rec2_num'); // Wood
resources[3]=ById('stat_rec3_num'); // Stone
resources[4]=ById('stat_rec4_num'); // 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.Log("Waiting for mapping to finish");
// don't reload until the mapper has finished.
window.setTimeout(function() {
t.StartReloadPageTimer(10*60);
},0);
return;
}
t.SetValuesCache();
t.ReloadWindow();
},refreshMSecs);
this.Log('reload page timer started');
},
ClickChangeCity:function(cityA,tries) {
var t=this;
nHtml.Click(cityA);
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);
},
lastOpenViewReports:0,
NextAutoAttackCity:function() {
var t=this;
var autoAttack=this.GetAutoAttack();
if(!autoAttack) return;
// change to next city
this.autoAttacksThisCity=0;
var cityA=null;
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.Log('Skip city, current city:'+this.autoAttackCityUpto);
this.autoAttackCityUpto++;
cityA=ById('citysel_'+this.autoAttackCityUpto);
}
break;
}
if(!cityA) {
// go back to the 1st city
//this.Log('Start from 1st city again');
if(!this.options.noViewReports) {
var nowSecs=new Date().getTime()/1000;
if((this.lastOpenViewReports+(60*10))<nowSecs) {
this.lastOpenViewReports=nowSecs;
this.OpenViewReports();
this.bringUpReports=true;
if(this.options.autoRemoveReports) {
this.autoAttackRemoveReports=true;
}
}
}
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) {
// 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('change city:'+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, about to attack or change city');
}
// this.autoAttackCityUpto++;
}
},
StopWaitForAttackBoxAppear:function() {
if(this.waitForAttackBoxAppear!=null) {
window.clearTimeout(this.waitForAttackBoxAppear);
this.waitForAttackBoxAppear=null;
return true;
}
return false;
},
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);
},15*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);
} else if (bestAttack.type==1) {
unsafeWindow.modal_attack(1,bestAttack.x,bestAttack.y);
}
},
nextAutoAttackWanted:null,
NextAutoAttack:function() {
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 set in options:'+this.autoAttackCityUpto);
this.NextAutoAttackCity();
return;
}
if(!autoAttack || (autoAttack.x!=undefined && autoAttack.x!=-1)) return;
if(this.IsMapperRunning()) {
this.StartReloadPageTimer();
return;
}
var currentTroops=this.GetArmySize();
var currentResources=this.GetResourcesSize();
var mapCoord=this.GetCurrentMapCoord();
var attacks=this.GetClosestAttacks(mapCoord.x,mapCoord.y);
var bestAttack=this.FindBiggestCampAttack(attacks,currentTroops,currentResources);
if(bestAttack && this.autoAttacksThisCity<10) {
// attack closest biggest barbarian
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();
},250);
}
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);
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]);
var li=this.GetLevelInfo(attack);
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) {
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;
},
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=this.DeleteWildBarbAttacks();
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);
}
},
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 training':'No auto training')+'</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;
},
GetCurrentCityName:function() {
var t=this;
var h=t.GetCitiesHash(t.GetSeed().cities);
return h[t.GetCurrentCityId()][1];
},
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;
//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=maxObj.textContent;
var t=this;
window.setTimeout(function() {
if(numInp.value!=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));
}
}
},
OnImpendingAttack:function() {
var t=this;
this.Log("impending attack");
var url=t.options.impendingAttackUrl;
if(url!=undefined && url !="") {
GM_openInTab(url);
}
},
CheckImpendingAttack:function() {
var r=false;
var seed=this.GetSeed();
if(seed && seed.queue_atkinc) {
var q=0;
// if(unsafeWindow.Object.isArray(seed.queue_atkinc)) {
var keys=unsafeWindow.Object.keys(seed.queue_atkinc);
if(keys.length>0 && keys.length<16) {
//GM_log('impppp'+keys.length);
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();
},
*/
SendChat:function(name,mess) {
// <div class="postaction"><input id="mod_comm_input" autocomplete="off" type="text"><a class="button20"><input value="SEND" style="display: none;" type="submit"><span>Chat</span></a></div>
// div id=mod_comm_list2
var t=this;
var inp=document.getElementById('mod_comm_input');
inp.value="@"+name+' '+mess;
t.Log('Send chat:'+mess);
unsafeWindow.Chat.sendChat();
},
GetLatestChatStr:function(chatObj) {
return chatObj.name+'#'+chatObj.time+'#'+chatObj.text.split(/[\.\?]/)[0];
},
GetLatestChat:function(h) {
var t=this;
var latestChats=JSON2.parse(t.GetValue('LatestChat','[]'));
if(latestChats.length>25) {
latestChats.splice(0,1);
}
for(var c=0; c<latestChats.length; c++) {
var chatObj=latestChats[c];
h[t.GetLatestChatStr(chatObj)]=1;
}
return latestChats;
},
SetLatestChat:function(chatObj) {
var t=this;
t.SetValue('LatestChat',JSON2.stringify(chatObj));
},
GetChatTimeNum:function(time) {
var tarr=time.split(':');
if(!time) return undefined;
var timeNum=(tarr[0]*60)+tarr[1];
return timeNum;
},
GetChatObj:function(htmlObj) {
var nm=nHtml.FindByXPath(htmlObj,".//a[contains(@class,'nm')]");
var fromMe=nHtml.FindByXPath(htmlObj,".//span[contains(@class,'nm')]");
var time=nHtml.FindByXPath(htmlObj,".//span[contains(@class,'time')]");
var tx=nHtml.FindByXPath(htmlObj,".//div[contains(@class,'tx')]");
if(!nm || !time || !tx) { return undefined; }
var nameArr=nm.innerHTML.split(' ',2);
return {
'obj':htmlObj,'textObj':tx, 'name':nm.innerHTML,
'time':time.innerHTML,'text':tx.innerHTML,
'shortName':nameArr[1],
'timeNum':this.GetChatTimeNum(time.innerHTML),'fromMe':fromMe?1:0
};
},
IterateChat:function(func) {
var t=this;
var comm=document.getElementById('mod_comm_list2');
var directs=nHtml.FindAllByXPath(comm,".//div[contains(@class,'direct')]");
var chats=[];
for(var d=directs.length-1; d>=0; d--) {
var direct=directs[d];
var chatObj=this.GetChatObj(direct);
//t.CleanChat(chatObj);
if(chatObj) {
chats.push([direct,chatObj]);
}
}
var latestChatFound=null;
var lastNotProcessed=null;
//var chatsOk=[];
var latestChatsH={};
var latestChats=t.GetLatestChat(latestChatsH);
for(var c=0; c<chats.length; c++) {
var chatObj=chats[c][1];
var cstr=t.GetLatestChatStr(chatObj);
if(!latestChatsH[cstr]) {
chatObj.notProcessed=true;
latestChatsH[cstr]=chatObj;
latestChats.push(chatObj);
}
}
t.SetLatestChat(latestChats);
for(var c=0; c<chats.length; c++) {
var chatI=chats[c];
var direct=chatI[0];
var chatObj=chatI[1];
func.call(this,direct,chatObj);
}
},
//latestChat:0,
/*
HideChat:function() {
this.IterateChat(function(direct,chatObj) {
if(chatObj.latestChat>t.latestChat) {
t.latestChat=chatObj.latestChat;
if(chatObj.text.substr(0,1)=='#') {
direct.style.display='none';
}
}
});
},
*/
AddChatButtons:function() {
var t=this;
if(document.getElementById('KOCAttackChat')) return;
var inp=document.getElementById('mod_comm_input');
var div=document.createElement('div');
div.id='KOCAttackChat';
div.style.display='none';
var remoteControl=document.createElement('a');
var onlyNonAttacks=document.createElement('input');
onlyNonAttacks.type='checkbox';
onlyNonAttacks.checked=t.options.remoteAttackTypeAllowed[0]?false:true;
function onlyNonAttacksChanged() {
t.options=t.GetOptions();
t.options.remoteAttackTypeAllowed=onlyNonAttacks.checked?[0,1,1,1,1,1]:[1,1,1,1,1,1];
t.SetOptions(t.options);
}
onlyNonAttacks.addEventListener('click',function() {
onlyNonAttacksChanged();
},false);
onlyNonAttacks.addEventListener('change',function() {
onlyNonAttacksChanged();
},false);
div.appendChild(document.createElement("br"));
div.appendChild(onlyNonAttacks);
div.appendChild(document.createTextNode("Only allow non attacks"));
var allowUserBox=document.createElement('textarea');
allowUserBox.cols='20'; allowUserBox.rows='6';
var allowUsersHash=JSON2.parse(t.GetValue('AllowUsersRemoteControl','{}'));
var txt='';
for(var user in allowUsersHash) {
txt+=user+"\n";
}
allowUserBox.value=txt;
var player=document.createElement('input');
var status=document.createElement('a');
status.innerHTML='<span>Status</span>';
status.className='button25';
status.href='javascript:;';
status.addEventListener('click',function() {
t.SendChat(player.value,"units?");
},false);
function ChangeAllowUserBox() {
var users=allowUserBox.value.split("\n");
var usersHash={};
for(var u=0; u<users.length; u++) {
var user=users[u].trim();
if(user!="") {
usersHash[user]=1;
}
}
t.SetValue('AllowUsersRemoteControl',JSON2.stringify(usersHash));
t.allowUsersHash=null;
}
allowUserBox.addEventListener('change',function() {ChangeAllowUserBox();},false);
allowUserBox.addEventListener('keyup',function() {ChangeAllowUserBox();},false);
div.appendChild(document.createElement("br"));
div.appendChild(document.createTextNode("Allow these players to control you..."));
div.appendChild(allowUserBox);
remoteControl.innerHTML='<span>Remote control</span>';
remoteControl.className='button25';
div.appendChild(document.createElement("br"));
div.appendChild(document.createTextNode("Player:"));
div.appendChild(player);
div.appendChild(status);
remoteControl.addEventListener('click',function() {
div.style.display=div.style.display=='none'?'block':'none';
},false);
inp.parentNode.appendChild(remoteControl);
inp.parentNode.appendChild(div);
},
GetCitiesHash:function(arr) {
var h={};
for(var a=0; a<arr.length; a++) {
var city=arr[a];
var newA=[]
Array.prototype.push.apply(newA, city);
h[city[0]]=newA;
}
return h;
},
ChatFuncs:{
'attack':{
'question':function(chatObj,info) {
// save an attack
var t=this;
if(info!="" && info.substr(0,1)=="{") {
var i=JSON2.parse(info);
i.attack.fromPlayer=chatObj.shortName;
chatObj.textObj.innerHTML="attack?To:"+i.attack.x+','+i.attack.y+', Troops:'+i.attack.troops.join(',').replace('null','');
}
if(!chatObj.notProcessed) { return; }
if(!t.options.remoteAttackTypeAllowed[i.attack.type]) {
t.Log("Remote attack type "+i.attack.type+" not allowed");
t.SendChat(chatObj.shortName,"attack.Failed, attack type not allowed");
return;
}
t.Log("Remote attack for:"+i.city+', from:'+chatObj.shortName);
t.SetValue('RemoteAttack_'+i.city,JSON2.stringify(i.attack));
var autoAttack=this.GetAutoAttack();
if(!autoAttack) {
//~~~ we have to move to the correct city??
}
},
'answer':function(chatObj,info) {
if(chatObj.textObj.innerHTML!=chatObj.text) {
chatObj.textObj.innerHTML=chatObj.text;
}
}
},
'units':{
'question':function(chatObj,info) {
if(!chatObj.notProcessed) { return; }
var t=this;
var seed=t.GetSeed();
t.SendChat(chatObj.shortName,"units."+JSON2.stringify({
'cities':t.GetCitiesHash(seed.cities),
'units':seed.units,
}));
},
'answer':function(chatObj,info) {
var t=this;
// {"city24479":{"tick":1297589617,"rec1":"[756220044, 2592000000, 7100, 3033]","rec2":"[539696566, 1836000000, 5000, 0]","rec3":"[191319892, 1548000000, 4200, 0]","rec4":"[4512787, 1512000000, 4100, 0]"}}
var infoObj=JSON2.parse(info);
var res=infoObj.units;
var cities=infoObj.cities;
chatObj.textObj.innerHTML='';
var table=document.createElement('table');
//table.className='direct';
function AddCell(tr) {
var td=tr.insertCell(-1);
//td.className='direct';
td.style.backgroundColor='#ffde75';
td.style.textAlign='right';
return td;
}
for(var city in res) {
var resObj=res[city];
var tr=table.insertRow(-1);
//var cityTd=tr.insertCell(-1);
var cityTd=AddCell(tr);
cityTd.colspan='4';
cityTd.style.fontWeight='bold';
var cityM=/([0-9]+)$/.exec(city);
var cityObj=cities[cityM[1]];
if(!cityObj) {
t.Log('Cannot find city:'+cityM[1]);
continue;
}
cityTd.innerHTML=cityObj[1];
//for(var r=1; r<=4; r++ ) {
for(var unt in resObj) {
//var rarr=JSON2.parse(resObj['rec'+r].replace(' ',''));
var units=parseInt(resObj[unt]);
if(units<=0) continue;
var tr=table.insertRow(-1);
AddCell(tr).innerHTML=unsafeWindow.unitcost[unt][0];
AddCell(tr).innerHTML=units;
}
}
chatObj.textObj.appendChild(table);
},
}
},
allowUsersHash:null,
allowUsersHashCount:0,
ChatAdded:function(chatObj) {
var t=this;
if(chatObj) {
if(t.allowUsersHash==null) {
t.allowUsersHashCount=0;
t.allowUsersHash=JSON2.parse(t.GetValue('AllowUsersRemoteControl','{}'));
for(var u in t.allowUsersHash) {
t.allowUsersHashCount++;
}
}
if(t.allowUsersHashCount==0) { return; }
var cArr=/^([^\?\.]+)([\.\?])(.*)$/.exec(chatObj.text);
if(!cArr) {
return;
}
var cmd=cArr[1]
var info=cArr[3];
var question=false;
if(chatObj.fromMe) {
chatObj.obj.style.borderBottom='1px solid #0f0';
}
if(chatObj.notProcessed) {
chatObj.obj.style.borderLeft='1px solid #ff0';
//chatObj.obj.appendChild(document.createTextNode(' notprocessed '));
}
var cmdInfo=t.ChatFuncs[cmd];
if(cArr[2]=='?') {
question=true;
} else {
}
if(cmdInfo) {
// hide unreadable requests that are json
var shortCmd=(cmd+cArr[2]);
if(chatObj.textObj.innerHTML!=shortCmd && info.substr(0,1)=='{') {
chatObj.textObj.innerHTML=shortCmd;
}
}
if(chatObj.fromMe) {
return;
}
var done=0;
// process chat
if(chatObj.notProcessed) {
t.Log('remote command:'+cmd+cArr[2]+', not processed:'+chatObj.notProcessed);
}
if(cmdInfo) {
window.setTimeout(function() {
if(question) {
if(t.allowUsersHash[chatObj.shortName]) {
cmdInfo['question'].call(t,chatObj,info);
} else {
chatObj.obj.appendChild(document.createTextNode("Player does not have permission: "+chatObj.shortName));
}
} else {
cmdInfo['answer'].call(t,chatObj,info);
}
},0);
}
} else {
t.Log('Chat object failed');
}
return true;
},
CheckChat:function() {
var t=this;
var comm=document.getElementById('mod_comm_list2');
var firstChatRecv=false;
var firstTimeout=null;
if(!t.options.remoteAttack) { return; }
if(comm) {
t.AddChatButtons();
comm.addEventListener('DOMNodeInserted',function(e) {
window.setTimeout(function() {
if(firstTimeout==null) {
firstTimeout=window.setTimeout(function() {
t.IterateChat(function(direct,chatObj) {
t.ChatAdded(chatObj);
});
firstTimeout=null;
},200);
} else {
// t.Log("Maybe too many chat messages, chat already processing.");
}
},0);
},false);
return;
}
window.setTimeout(function() {
t.CheckChat();
},2000);
},
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];
},
ExportAllToJSON:function() {
var t=this;
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!="") {
var ch=v.substr(0,1);
if(ch=='[' || ch=='{') {
try {
obj[name]=JSON2.parse(v);
} catch(e) {
t.Log('Bad value for export:'+name+'='+v);
obj[name]=v;
}
} else {
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;
var v=obj[name];
if(typeof(v)=='object') {
v=JSON2.stringify(v);
}
this.browser_setValue(name,v);
}
} catch(e) {
window.alert('Import failed'+e);
}
},
SetupMenu:function() {
var t=this;
GM_registerMenuCommand('KOCAttack - Options',function() {
t.ShowOptionsDialog();
});
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,
idStatus:{},
ResetIdStatus:function() {
this.idStatus={};
},
Listen:function() {
var t=this;
t.SetupMenu();
this.GetValuesCache();
t.ResetAutoAttackTarget();
this.options=this.GetOptions();
this.startListenTime=new Date();
window.setTimeout(function() {
if(!t.pageLoaded && t.GetAutoAttack() && !t.IsMapperRunning()) {
GM_log("whoops, game not loaded after 60 secs problem. reloading.");
t.SetValuesCache();
//window.location.reload(true);
t.ReloadWindow();
// window.history.go(0);
}
},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);
}
var domTickTimer=null;
var domTickUpto=0;
var domTick=function(e) {
//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();
if(cityId!=null) t.pageLoaded=true;
var cityChanged=cityId!=t.prevCurrentCity?true:false;
if(cityChanged) {
t.prevCurrentCity=cityId;
}
if((domTickUpto%20)==0) {
t.CheckImpendingAttack();
}
if(cityChanged && cityId!=null) {
// changed city
setTimeout(function() {
t.AddOptionsLink();
t.DrawClosestFarms();
},0);
setTimeout(function() {
t.CheckAutoRaiseGold();
t.CheckAbandonWilds();
t.CheckTrainTroops();
},1000);
setTimeout(function() {
t.NextAutoAttack();
},5000);
}
//if(e.target.id) GM_log('ttt'+e.target.id);
var 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();
},
};
/*
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);
}
};
this.CheckChat();
var withinDomInserted=false;
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 {
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();
},
/*
AClearMessages:function() {
GM_log('ClearMessages');
var names=GM_listValues();
var attackPrefix='attack_'+this.GetServerId()+'_';
for(var n=0; n<names.length; n++) {
var name=names[n];
if(name.substring(0,7)!="attack_") continue;
GM_setValue(attackPrefix+name.substring(7),GM_getValue(name));
}
}
*/
ReloadWindow:function (){
var serverId=this.GetServerId();
if (serverId == null){
history.go(0);
return;
}
var go = 'http://apps.facebook.com/kingdomsofcamelot/?s='+serverId;
var t = '<FORM target="_top" action="'+ go +'" method=post><INPUT id=xxButReload type=submit value=RELOAD><input type=hidden name=s value="'+ serverId +'"</form>';
var e = document.createElement ('div');
e.innerHTML = t;
document.body.appendChild (e);
setTimeout (function (){document.getElementById('xxButReload').click();}, 0);
},
/*
WaitForReload:function() {
var reload=this.GetValue('reload',0);
if(reload) {
this.SetValue('reload',0);
GM_log('reload domain:'+this.GetServerId()+','+window.location.href);
window.location.href=window.location.href;
}
var t=this;
window.setTimeout(function() {
t.WaitForReload();
},2000);
}
*/
};
/*
if(location.href.indexOf('apps.facebook.com')>=0) {
var FixFacebook={
FixIFrame:function() {
var iframe=nHtml.FindByXPath(document,"//iframe[contains(@class,'canvas_iframe_util')]");
while(iframe) {
iframe.style.overflow='visible';
iframe.style.width=window.innerWidth+'px';
iframe=iframe.parentNode;
if(iframe.tagName=='BODY') break;
// if(iframe.id && iframe.id.indexOf('content')>=0) { break; }
// if(iframe.className && iframe.className.indexOf('UIStandardFrame_Content')>=0) { break; }
}
}
};
FixFacebook.FixIFrame();
}
*/
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 retryMarch='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) {
retryMarch='var retryMarch=function() { return; };';
}
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(']]
];
// make the attack troop boxes unlimited
var modalAttackUpdateNumReplaces=[
[['modal_attack_update_num','modal_attack_update_numOld']],
[['e.value = d','']]
];
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 x = parseInt']],
[['"Count"]);','"Count"]); if(x>0) { var uname=unitcost["unt"+q][0]; v+=uname[0]+uname[uname.length-1]+":"+x+", "; } ']],
];
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]);
document.body.appendChild(sp);
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; "+retryMarch+
(useRetryMarch?"":" Modal.hideModalAll(); ")+
"\nnew (Ajax"],
['new Ajax',"var marchSuccess=null; "+retryMarch+
(useRetryMarch?"":" Modal.hideModalAll(); ")+
"\nnew Ajax"],
['ajax.Request',"var marchSuccess=null; "+retryMarch+
(useRetryMarch?"":" Modal.hideModalAll(); ")+
"\najax.Request"]
]);
}
replaceFunc('modal_attack_do',modalAttackReplaces);
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 v = 0;')>=0) {
AddArray(arr,attack_generatequeueReplacesV);
} else if(funcStr.indexOf('; var u = 0;')>=0) {
AddArray(arr,attack_generatequeueReplacesU);
} 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 {
var err="Unknown attack queue func: "+location.href+"\n"+funcStr;
document.body.appendChild(document.createTextNode(err));
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]);
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);
}
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;
}
}
DisableMixpanel();
unsafeWindow.cm.cheatDetector={
detect:function() { }
};
var startAllTimeout=null;
function StartAll() {
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.Listen();
KOCAttack.SetupClearMessages();
SetupScripts();
} else {
window.setTimeout(function() { StartAll(); },200);
}
}
if(location.href.indexOf('apps.facebook.com/kingdomsofcamelot/')>=0) {
window.setTimeout(function() {
},10000);
} else {
StartAll();
}