// ==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/*
*/
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;
},
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'>"+
"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 />"+
"<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.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='tab';
a.style.color='#fff';
a.innerHTML='<span>'+html+'</span>';
var tabs=ById('KOCAttackTabs');
if(!tabs) {
var ptabs=ById('main_engagement_tabs');
if(!ptabs) {
ptabs=ById('topnav_msg');
if(ptabs)ptabs=ptabs.parentNode;
}
if(!ptabs) {
ptabs=document.body;
}
tabs=document.createElement('span');
tabs.id='KOCAttackTabs';
ptabs.insertBefore(tabs,ptabs.childNodes[0]);
}
if(tabs) {
tabs.style.whiteSpace='nowrap';
tabs.style.width='1600px';
tabs.appendChild(a);
return a;
}
return null;
},
ToggleAutoAttack:function() {
var t=this;
var a=t.GetAutoAttack();
if(!a) {
t.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],
'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);
},
SetAttackFromGuiXY:function(x,y,box) {
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 comment=ById('KocAttackComment');
var type=ById('modal_attack_atktype');
if(!type) {
throw("Cannot find attack type");
}
if(totalTroops<=0) {
this.Log("No troops, not saving attack");
return null;
}
// ignore anything other than attack
if(type.selectedIndex==0) {
var attack=this.GetAttack(x,y);
if(!attack) attack={};
attack.type=type.selectedIndex;
if(comment)
attack.comment=comment.value;
var nowSecs=new Date().getTime()/1000;
var firstAttack=this.IsFirstAttackAtLocation(x,y);
if(totalTroops>0 && (troops[2]+troops[10])==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(type.selectedIndex==1) {
// try to parse transports
var attack=this.GetAttack(x,y);
if(!attack) attack={};
attack.type=type.selectedIndex;
//attack.ignore=true; // We set this to ignore for now until I can get the auto attack working
if(comment)
attack.comment=comment.value;
var nowSecs=new Date().getTime()/1000;
var firstAttack=this.IsFirstAttackAtLocation(x,y);
attack.time=nowSecs;
attack.troops=troops;
var resources=[];
var resourceTypes = new Array(
'gold',
'rec1',
'rec2',
'rec3',
'rec4'
);
for(var res=0; res<resourceTypes.length; res++) {
var resource=ById('modal_attack_'+resourceTypes[res]);
if(!resource) continue;
try {
var v=parseInt(resource.value);
resources[res]=v;
totalResources+=v;
} catch(e) {
continue;
}
}
attack.resources=resources;
//if (this.options.lockAttackFromCity) {
attack.fromCity=this.GetCurrentCityId();
//}
//attack.ignore=undefined;
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_items');
if(!items) return;
var type=ById('modal_attack_atktype');
if(!type) {
throw("Cannot find attack type");
}
//items=items.parentNode.parentNode;
var a=document.createElement('a');
a.innerHTML='Hide/Show attack efforts';
//a.href='javascript:;';
a.style.cursor='pointer';
items.style.display='none';
a.addEventListener('click',function() {
items.style.display=items.style.display=='none'?'block':'none';
},false);
return a;
},
SetResourceInput:function(num,resourceCount) {
var resource=ById('modal_attack_'+num);
if(!resource) return null;
resource.value=resourceCount;
resource.style.backgroundColor='';
// send a shift key so that it recalculates
var evt = document.createEvent("KeyboardEvent");
if(evt.initKeyboardEvent) {
evt.initKeyboardEvent("keyup",true,true,null,false,false,false,false,0x10,0);
} else {
evt.initKeyEvent("keyup",true,true,null,false,false,false,false,0x10,0);
}
resource.dispatchEvent(evt);
if(parseInt(resourceCount)>0) {
if(resource.value!=resourceCount) {
this.Log('Not able to set resource count:'+num+',wanted:'+resourceCount+', count:'+resource.value);
resource.style.backgroundColor='#f88';
return 'notfull';
} else {
resource.style.backgroundColor='#ff8';
return 'full';
}
}
return 'none';
},
SetTroopInput:function(num,troopCount) {
var troop=ById('modal_attack_unit_ipt'+num);
if(!troop) return null;
troop.value=troopCount;
troop.style.backgroundColor='';
// send a shift key so that it recalculates
var evt = document.createEvent("KeyboardEvent");
if(evt.initKeyboardEvent) {
evt.initKeyboardEvent("keyup",true,true,null,false,false,false,false,0x10,0);
} else {
evt.initKeyEvent("keyup",true,true,null,false,false,false,false,0x10,0);
}
troop.dispatchEvent(evt);
if(parseInt(troopCount)>0) {
if(troop.value!=troopCount) {
this.Log('Not able to set troop count:'+num+',wanted:'+troopCount+', count:'+troop.value);
troop.style.backgroundColor='#f88';
return 'notfull';
} else {
troop.style.backgroundColor='#ff8';
return 'full';
}
}
return 'none';
},
GetRandTime:function(millis) {
var millisPerc=millis*(this.options.randomPercent/100);
var randSecs=Math.floor((Math.random()*millisPerc*2)-millisPerc)+millis;
return randSecs;
},
GetAutoGold:function() {
return this.GetValue('AutoGold,'+this.GetCurrentCityId(),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';
}
},
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;
}
this.StopWaitForAttackBoxAppear();
if(ById('KocAttackComment')) {
this.Log("We already have an attack dialog opened");
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('marchTypeDesc');
nextElement.parentNode.insertBefore(div2, nextElement.nextSibling);
//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 notFullResources=false;
var knightSelect=ById('modal_attack_knight')
var totalTroops=0;
var totalResources=0;
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;
var attackTypeSelect=ById('modal_attack_atktype');
// only fill things in if we're in attack mode.
if(attackTypeSelect.selectedIndex==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") {
for(var i=1; i<attack.militiaonly.length; i++) {
this.SetTroopInput(i,attack.militiaonly[i]);
totalTroops+=attack.militiaonly[i];
}
} else {
this.SetTroopInput(2,attack.militiaonly);
totalTroops+=attack.militiaonly;
}
} else if(attack.troops) {
for(var tr=0; tr<attack.troops.length; tr++) {
var troopCount=attack.troops[tr];
if(!troopCount) continue;
totalTroops+=troopCount;
if(this.SetTroopInput(tr,troopCount)=='notfull') {
notFullTroops=true;
}
}
}
//attackTypeSelect.selectedIndex=attack.type;
knightSelect.selectedIndex=1+Math.floor(Math.random()*(knightSelect.options.length-1));
} else if (attackTypeSelect.selectedIndex==1 && attack.type==1) {
attackTypeSelect.selectedIndex=attack.type;
var resourceTypes = new Array(
'gold',
'rec1',
'rec2',
'rec3',
'rec4'
);
for(var tr=0; tr<attack.troops.length; tr++) {
var troopCount=attack.troops[tr];
if(!troopCount) continue;
totalTroops+=troopCount;
if(this.SetTroopInput(tr,troopCount)=='notfull') {
notFullTroops=true;
}
}
for(var res=0; res<attack.resources.length; res++) {
var resourceCount=attack.resources[res];
if(!resourceCount) continue;
totalResources+=resourceCount;
if(this.SetResourceInput(resourceTypes[res],resourceCount)=='notfull') {
notFullResources=true;
}
}
// We don't send a knight with transports
}
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);
attackTypeSelect.parentNode.insertBefore(deleteBtn,attackTypeSelect.nextSibling);
}
var ChangeAttack=function() {
var xy=t.GetGuiCoords();
var attack=null;
var attackTypeSelect=ById('modal_attack_atktype');
if(xy) {
attack=t.GetAttack(xy[0],xy[1]);
}
if(!attack) attack={};
if(attackTypeSelect.selectedIndex!=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_items');
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');
var autoAttack=this.GetAutoAttack();
if(autoAttack && autoAttack.x==xy[0] && autoAttack.y==xy[1] && !ignore.checked) {
autoAttack.x=autoAttack.y=-1;
this.SetAutoAttack(autoAttack);
if(totalTroops>0
&& knightSelect.options.length>1
&& !notFullTroops
&& !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:"+notFullTroops+'/'+notFullResources+', needed:'+totalTroops+'/'+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;
}
},
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;
},
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(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
},
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 names=this.browser_listValues();
var obj={};
var serverId=this.GetServerId();
for(var n=0; n<names.length; n++) {
var name=names[n];
var sid=this.GetServerIdFromName(name);
if(sid!=serverId) continue;
var v=this.browser_getValue(name,null);
if(v!=null && v!=undefined && v!="")
obj[name]=v;
}
return JSON2.stringify(obj);
},
ImportAllFromJSON:function(json) {
try {
var obj=JSON2.parse(json);
if(!obj) { return; }
this.FactoryResetCurrentServer();
var serverId=this.GetServerId();
for(var name in obj) {
var sid=this.GetServerIdFromName(name);
if(sid!=serverId) continue;
this.browser_setValue(name,obj[name]);
}
} catch(e) {
window.alert('Import failed'+e);
}
},
SetupMenu:function() {
var t=this;
GM_registerMenuCommand('KOCAttack - Options',function() {
t.ShowOptionsDialog();
});
GM_registerMenuCommand('KOCAttack - 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);
}
};
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 {retryMarch(); } catch(e) { alert("retry failed:"+e); } } else { Modal.hideModalAll(); } Modal.showAlert(printLocalError('],
['Modal.showAlert(printLocalError(','if(rslt.error_code==3 || rslt.error_code==8) { try {window.setTimeout(function() { retryMarch(); },(3*1000)); } catch(e) { alert("retry failed:"+e); } } else { Modal.hideModalAll(); } Modal.showAlert(printLocalError(']
];
var attack_generatequeueReplaces=[
['attack_generatequeue','attack_generatequeueOld'],
['class=\\"army\\">" + g_js_strings.commonstr.army + ": "','style=\\"width: 145px !important\\" class=\\"army\\">"'],
['class=\\"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+", "; } '],
];
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
modalAttackReplaces.push(['new Ajax',"var marchSuccess=null; "+retryMarch+
(useRetryMarch?"":" Modal.hideModalAll(); ")+
"\nnew Ajax"]);
} else {
modalAttackReplaces.push(['new (Ajax',"var marchSuccess=null; "+retryMarch+
(useRetryMarch?"":" Modal.hideModalAll(); ")+
"\nnew (Ajax"]);
}
if(!useRetryMarch) modalAttackReplaces.push(['Modal.hideModalAll();','']);
var replaceFunc=function(name,replaces) {
var modalAttackFunc=window[name].toString();
var nameOld=name+'Old';
for(var a=0; a<replaces.length; a++) {
var found=false;
var repI=replaces[a];
if(typeof(repI[0])=="object") {
found=repI[0].exec(modalAttackFunc)?true:false;
} else {
found=modalAttackFunc.indexOf(repI[0])>=0?true:false;
}
if(!found) {
alert("modalAttackReplace: cannot find: "+repI[0]+','+modalAttackFunc);
}
modalAttackFunc=modalAttackFunc.replace(repI[0],repI[1]);
}
try {
window[nameOld]=eval(modalAttackFunc);
//alert(window[nameOld].toString());
} catch(e) {
alert(e+', bad func:'+modalAttackFunc);
}
window[name]=function() {
// let our stuff in addListener run first.
window.setTimeout(function() {
eval(nameOld+'();');
},100);
}
};
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 u = 0')>=0) {
AddArray(arr,attack_generatequeueReplacesU);
} else {
AddArray(arr,attack_generatequeueReplacesR);
}
replaceFunc('attack_generatequeue',arr);
/* 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);
}
if(location.href.indexOf('apps.facebook.com/kingdomsofcamelot/')>=0) {
KOCAttack.WaitForReload();
} else {
KOCAttack.Listen();
KOCAttack.SetupClearMessages();
SetupScripts();
}
Mozilla add on,User script,Grease Monkey Script, greasemonkey userscripts, updater userscripts mafia wars userscripts mafia wars autoplayer userscripts mafia wars wall userscripts scripts userscripts travian greasemonkey greasemonkey download greasemonkey facebook greasemonkey tutorial greasemonkey youtube greasemonkey travian greasemonkey chrome greasemonkey mafia wars greasemonkey mafia wars autoplayer
Friday, February 4, 2011
Kingdoms of Camelot Attack helper
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment