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