KoCByte

A Kingdoms of Camelot Mod

As of 2016-05-03. See the latest version.

// ==UserScript==
// @name			KoCByte
// @version			0.3
// @description		A Kingdoms of Camelot Mod
// @namespace		kocbyte.com
// @icon			http://www.gravatar.com/avatar/f93cdced9c9b863a7d9e4b9988886015
// @include			http://www.kocbyte.therealmsbeyond.com/*
// @include			https://www.kocbyte.therealmsbeyond.com/*
// @include			*.kingdomsofcamelot.com/fb/e2/src/main_src.php*
// @include			http://*
// @grant			unsafeWindow
// @grant			GM_getValue
// @grant			GM_setValue
// @grant			GM_deleteValue
// @grant			GM_xmlhttpRequest
// @grant			GM_openInTab
// @grant			GM_log
// @grant			GM_listValues
// @grant			GM_addStyle
// @grant			GM_registerMenuCommand
// @require			http://code.jquery.com/jquery-latest.min.js
// ==/UserScript==

//============================================================================

var uW = unsafeWindow;
var kb={};
kb.uid = 0;
kb.name = '';
kb.domain = 0;
kb.allianceId = 0;
kb.allianceName = '';
kb.misted = 0;
kb.cities = [];
kb.domains = [];
kb.seed = null;
kb.authedSites=null;
kb.currentUrl=""+document.location.toString();
kb.currentWebFolder=document.location.host+""+document.location.pathname.replace(/\\/g, '/').replace(/\/[^\/]*\/?$/, '')+'/';
kb.removedMixPanel=false;
kb.site='http://www.kocbyte.therealmsbeyond.com/';
kb.url='http://www.kocbyte.therealmsbeyond.com/ajax/listener.php';
kb.storagePrefix = 'KoCByte_';
kb.citiesSaved = '';
kb.citiesLastSent = 0;
kb.sendInfoDelay=1000*60*60*6; //every 6 hours
kb.sendSeedDelay=1000*60*60*24; //once a day
kb.updateCheckDelay=1000*60*60*24; //once a day
kb.debug=false;
kb.scriptId=19269;
kb.scriptVer=0.2;
kb.extList=[];
kb.modLang='eng';
kb.initTimeRemaining=0;
kb.localize=[];
kb.localize.eng=[];
kb.localize.eng[0]=null;
kb.localize.eng[1]='Would you like to update %0?';
kb.localize.eng[2]='No update needed';
kb.localize.eng[3]='Your using an alpha version, do you want to downgrade %0?';
kb.localize.eng[4]='Not allowed on this website';

kb.ADDWINDOWTIMMER=null;
kb.correctWindowTimer=null;
kb.sendInfoTimer=null;
kb.taskTimer=null;

kb.imgs=[];
kb.imgs[0]='data:image/png;base64,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';      


kb.cleanArray=function(actual){
	var newArray = [];
	for(var i = 0; i<actual.length; i++){
		if(actual[i]){
			newArray.push(actual[i]);
		}
	}
	return newArray;
};
kb.generateRandomNumber=function(min,max){
	if (min >= max) {
		return null;
	}
	else {
		return Math.round(min+((max-min)*Math.random()));
	}	
};
kb.updateSeed=function(url,args,json){
	var me=this;
	var i=0;
	switch(url){
		case 'ajax/_dispatch53.php':
			if(args.ctrl){
				if(args.ctrl=='throneRoom%5CThroneRoomServiceAjax'){
					if(args.action){
						if(args.action=='timeRepair'){
							if(json.error_code){
								if(json.error_code===0){
							
								}
								else if(json.error_code==256){
									window.seed.throne.inventory[args.throneRoomItemId].status=1;
								}
								else{
									
								}
							}
							else{
								if(json.eta){//start repair
									kb.log('repair of item #'+args.throneRoomItemId+' will be done in '+kb.timeUntill(Math.floor(json.eta)));
									
									window.seed.throne.inventory[args.throneRoomItemId].status=4;
									
									var t1=Math.floor(json.eta*1000);
									var t2=new Date().getTime();
									var wait=t1-t2;
									setTimeout(function(){
										window.seed.throne.inventory[args.throneRoomItemId].status=1;
									},wait);
								}
							}
						}
						else if(args.action=='upgradeQuality'){
							if(json.error_code){
								if(json.error_code===0){
							
								}
								else if(json.error_code==256){
									//window.seed.throne.inventory[args.throneRoomItemId].status=1;
								}
								else{
									
								}
							}
							else{
								if(args.payment && args.cityId){
									if(args.payment=='aetherstone' && json.aetherstones){
										window.seed.cityData.city[args.cityId].production.AETHERSTONE=window.seed.cityData.city[args.cityId].production.AETHERSTONE-json.aetherstones;										
									}
									if(args.payment=='gem' && json.gems){//payment = gem or gems not sure because i don't have any so i can't test
										window.seed.player.gems=window.seed.player.gems-json.gems;									
									}
								}
								if(json.success && json.success===true){
									window.seed.throne.inventory[args.throneRoomItemId].status=1;
								}
								if(json['break'] && json['break']===true){
									window.seed.throne.inventory[args.throneRoomItemId].status=3;
								}
								if(args.throneRoomItemId && json.item){
									if(json.item[0]){
										//fix because the programmers at kabam are dumbasses
										//the server returns zero as item id so we use the id from the request params
										json.item[0].id=args.throneRoomItemId;
										window.seed.throne.inventory[args.throneRoomItemId]=json.item[0].faction;
									}
								}
								if(json.heatupModifier){
									window.seed.throne.heatupModifier=json.heatupModifier;
								}
								if(json.forgeMasterModifier){
									//TODO no idea what the name of the origional is so i can't update.
								}
								if(json.lastAttemptTime){
									window.seed.throne.lastAttemptTime=json.lastAttemptTime;
								}
								if(json.downgrade && json.downgrade===true){
									//TODO not sure how to deal with this
								}
								if(args.buffItemId){
									//TODO have to adjust item count
								}
							}
						}
						else if(args.action=='upgradeLevel'){
							if(args.payment && args.cityId){
								if(args.payment=='aetherstone' && json.aetherstones){
									window.seed.cityData.city[args.cityId].production.AETHERSTONE=window.seed.cityData.city[args.cityId].production.AETHERSTONE-json.aetherstones;										
								}
								if(args.payment=='gem' && json.gems){//payment = gem or gems not sure because i don't have any so i can't test
									window.seed.player.gems=window.seed.player.gems-json.gems;									
								}
							}
							if(json.success && json.success===true){
								window.seed.throne.inventory[args.throneRoomItemId].status=1;
							}
							if(json['break'] && json['break']===true){
								window.seed.throne.inventory[args.throneRoomItemId].status=3;
							}
							if(args.throneRoomItemId && json.item){
								if(json.item[0]){
									json.item[0].id=args.throneRoomItemId;
									window.seed.throne.inventory[args.throneRoomItemId]=json.item[0].faction;
								}
							}
							if(json.heatupModifier){
								window.seed.throne.heatupModifier=json.heatupModifier;
							}
							if(json.forgeMasterModifier){
								//TODO no idea what the name of the origional is so i can't update.
							}
							if(json.lastAttemptTime){
								window.seed.throne.lastAttemptTime=json.lastAttemptTime;
							}
							if(json.downgrade && json.downgrade===true){
								//TODO not sure how to deal with this
							}
							if(args.buffItemId){
								//TODO have to adjust item count
							}
						}
					}
				}
			}
			break;
		default:
			break;
	}
};
kb.authorizedWebsiteStatus=function(){
	if(!kb.authedSites){
		kb.authedSites=kb.authorizedWebsiteGet();
	}
	var folder=document.location.host+""+document.location.pathname.replace(/\\/g, '/').replace(/\/[^\/]*\/?$/, '')+'/';
	for(var i=0;i<kb.authedSites.length;i++){
		var site = kb.authedSites[i];
		if(folder.indexOf(site) === 0){
			return true;
		}
	}
	return false;
};
kb.removeAjaxParams=function(params){
	if(!params){return;}
	var result=JSON.parse(JSON.stringify(params));
	if(!result){return;}
	var kabam=JSON.parse(JSON.stringify(uW.g_ajaxparams));
	for(var i in result){
		if(kabam[i]){
			delete result[i];
		}
	}	
	return result;
};
kb.deparam=function(str){
	str = decodeURIComponent(str);
	var chunks = str.split('&');
	var obj = {};
	for(var c=0; c < chunks.length; c++) {
		var split = chunks[c].split('=', 2);
	    obj[split[0]] = split[1];
	}
	delete obj.fb_sig_in_iframe;
	delete obj.fb_sig_expires;
	delete obj.fb_sig_api_key;
	delete obj.fb_sig_added;
	delete obj.fb_sig;
	delete obj.fb_sig_time;
	delete obj.fb_sig_user;
	delete obj.fb_sig_session_key;
	delete obj.fb_sig_profile_update_time;
	delete obj.tvuid;
	delete obj.kabamuid;
	delete obj.tpuid;
	delete obj.lang;
	delete obj.standalone;
	delete obj.signed_request;
	delete obj.pf;
	delete obj.pg;
	delete obj.__kraken_network;
	return obj;
};
kb.getTranslation=function(word,replace){
	var str='';
	if(word && kb.localize){
		if(kb.localize[kb.modLang] && kb.localize[kb.modLang][word]){
			str=kb.localize[kb.modLang][word];
		}
		else if(kb.localize.eng && kb.localize.eng[word]){
			str=kb.localize.eng[word];
		}
		else{
			return;
		}
		if(replace){
			if($.isArray(replace)) {
				for (var i=0; i<replace.length; i++) {
					str = str.replace('%'+i,replace[i]);
				}
			} else {
				str = str.replace('%0',replace);
			}
		}
	}
	return str;
};
kb.getAetherstone=function(cityId){
	if(!cityId){return;}
	if(uW && uW.seed && uW.seed.cityData && uW.seed.cityData.city && uW.seed.cityData.city[cityId] && uW.seed.cityData.city[cityId].production && uW.seed.cityData.city[cityId].production.AETHERSTONE){
		return (1*uW.seed.cityData.city[cityId].production.AETHERSTONE);
	}
};
kb.setTranslation=function(w,r,lang){
	if(!kb.localize[lang]){
		kb.localize[lang]=[];
	}
	kb.localize[lang][w]=r;
};
kb.extend=function(extension,obj){
	kb.ext[extension]=obj;
	alert('extension2='+JSON.stringify(kb.ext[extension], null, "\t"));
};
kb.extensionGetValue=function(extension,name,value){
	return kb.getValue(kb.storagePrefix+'ext_'+extension+'_'+name,value);
};
kb.extensionSetValue=function(extension,name,value){
	kb.setValue(kb.storagePrefix+'ext_'+extension+'_'+name,value);
};
kb.extensionDeleteValue=function(extension,name){
	kb.deleteValue(kb.storagePrefix+'ext_'+extension+'_'+name);
};
kb.is=function(a){
	var is={
		Null:function(a){
			return a===null;
		},
		Undefined:function(a){
			return a===undefined;
		},
		nt:function(a){
			return(a===null||a===undefined);
		},
		Function:function(a){
			return(typeof(a)==='function')?a.constructor.toString().match(/Function/)!==null:false;
		},
		String:function(a){
			return(typeof(a)==='string')?true:(typeof(a)==='object')?a.constructor.toString().match(/string/i)!==null:false;
		},
		Array:function(a){
			return(typeof(a)==='object')?a.constructor.toString().match(/array/i)!==null||a.length!==undefined:false;
		},
		Boolean:function(a){
			return(typeof(a)==='boolean')?true:(typeof(a)==='object')?a.constructor.toString().match(/boolean/i)!==null:false;
		},
		Date:function(a){
			return(typeof(a)==='date')?true:(typeof(a)==='object')?a.constructor.toString().match(/date/i)!==null:false;
		},
		HTML:function(a){
			return(typeof(a)==='object')?a.constructor.toString().match(/html/i)!==null:false;
		},
		Number:function(a){
			return(typeof(a)==='number')?true:(typeof(a)==='object')?a.constructor.toString().match(/Number/)!==null:false;
		},
		Object:function(a){
			return(typeof(a)==='object')?a.constructor.toString().match(/object/i)!==null:false;
		},
		RegExp:function(a){
			return(typeof(a)==='function')?a.constructor.toString().match(/regexp/i)!==null:false;
		}
	};
	return(is[a]);
};
kb.getDistance=function(x1,y1,x2,y2,max){
	var dx = 0;
	var dy = 0;
	var dist = 0;
	if(!max){max=750;}
	if (x1 > x2){
	     dx = x1 - x2;
	}else{
	     dx = x2 - x1;
	}
	if ((max - x2 + x1) < dx){
	     dx = max - x2 + x1;
	}
	if ((x1 + max - x2) < dx){
	     dx = x1 + max - x2;
	}
	if (y1 > y2){
	     dy = y1 - y2;
	}else{
	     dy = y2 - y1;
	}
	if ((max - y2 + y1) < dy){
	     dy = max - y2 + y1;
	}
	if ((y1 + max - y2) < dy){
	     dy = y1 + max - y2;
	}
	dist = Math.sqrt((dx*dx)+(dy*dy));
	return(dist);
};
kb.getBlockCoords=function(x,y){
	var blocks=[];
	//round to nearest 5
	x=Math.floor(1*x/5)*5;
	y=Math.floor(1*y/5)*5;
	//server requests are formated like this
	blocks.push([x-5,y-5]);
	blocks.push([x-5,y]);
	blocks.push([x-5,1*y+5]);
	blocks.push([x,y-5]);
	blocks.push([x,y]);
	blocks.push([x,1*y+5]);
	blocks.push([1*x+5,y-5]);
	blocks.push([1*x+5,y]);
	blocks.push([1*x+5,1*y+5]);
	for(var i=0;i<blocks.length;i++){
		if(blocks[i][0]<0){blocks[i][0]=750-(-1*blocks[i][0]);}
		if(blocks[i][0]>749){blocks[i][0]=blocks[i][0]-750;}
		if(blocks[i][1]<0){blocks[i][1]=750-(-1*blocks[i][1]);}
		if(blocks[i][1]>749){blocks[i][1]=blocks[i][1]-750;}
	}
	return blocks;
};
kb.htmlEntities=function(str){
	return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
};
kb.setValueObject=function(k,v){
	v=JSON.stringify(v);
	GM_setValue(k,v);
};
kb.getValueObject=function(k,dv){
	var v=GM_getValue(k,dv);
	if(!v || v===undefined){
		return null;
	}
	v=JSON.parse(v);
	if(!v){
		if(!dv){
			v=null;
		}
		else{
			v=dv;
		}	
	}
	return v;
};
kb.setValue=function(k,v){
	GM_setValue(k,v);
};
kb.getValue=function(k,dv){
	return(GM_getValue(k,dv));
};
kb.deleteValue=function(k){
	GM_deleteValue(k);
};
kb.getThroneStatus=function(){
	if(uW && uW.seed && uW.seed.queue_throne){
		return JSON.parse(JSON.stringify(uW.seed.queue_throne));
	}
};
kb.getDomains=function(force){
	if(uW.g_ajaxparams){
		var now=new Date().getTime()*1;
		var wait=86400000;//1 day
		var k=kb.storagePrefix+'getDomains_lastcheck';
		var lastsent=kb.getValue(k,0);
		if(force || 1*lastsent+wait<now){
			var args = {};
			args.v2=true;
			var json=kb.sendToKabam(args,'myServers',null,true);
			if(json && json.selectableServers && json.selectableServers.servers){
				var domains=[];
				for(var i in json.selectableServers.servers){
					var d = json.selectableServers.servers[i].serverId;
					domains.push(1*i);
				}
				domains.sort(); 
				kb.log('getDomains();');
				kb.setValue(''+k,''+now);
				return domains;
			}
		}
		else{
			var playerdomains=kb.getValue('domains');
			if(!playerdomains){
				playerdomains=[]; playerdomains.push(1*kb.domain);
				return playerdomains;
			}
			else{
				return JSON.parse(''+playerdomains);
			}
		}
	}
};
kb.getSavedInfo=function(){
	return(kb.getValue('ajaxparams',null));
};
kb.getSavedServerId=function(){
	return(kb.getValue('sid'));
};
kb.getCurrentCityId=function(){
	if(uW && uW.currentcityid){
		return JSON.parse(JSON.stringify(uW.currentcityid));
	}
};
kb.getCities=function(){
	var seed = kb.getSeed();
	if(seed && seed.cities){
		return JSON.parse(JSON.stringify(seed.cities));
	}
};
kb.gameInfoSave=function(){
	if(uW && uW.seed){
		kb.setValue('domain',			kb.domain);
		kb.setValue('uid',			kb.uid);
		kb.setValue('name',			kb.name);
		kb.setValue('allianceId',		kb.allianceId);
		kb.setValue('allianceName',	kb.allianceName);
		kb.setValue('misted',			kb.misted);
		kb.setValueObject('cities',	kb.cities);
		kb.setValueObject('domains',	kb.domains);

		var current=null;
		var saved=null;
		var tmp=null;
		var thekey='';
		
		//seed
		tmp=[];
		for(var i in kb.seed){
			thekey = kb.storagePrefix+'SEED_'+i;
			kb.setValueObject(thekey,kb.seed[i]);
			tmp.push(i);
			//console.log(kb.getValueObject(thekey));
		}
		kb.setValueObject(kb.storagePrefix+'SEEDKEYS',tmp);
		
		//cities
		current=kb.getValueObject('cities');
		thekey=kb.storagePrefix+'CITIES';
		saved=kb.getValueObject(thekey);
		if(current!=saved){
			kb.setValueObject(				kb.storagePrefix+'CITIES',current);
		}
		kb.setValueObject('acctIds',		kb.acctIds);
	}
};
kb.gameInfoLoad=function(){
	if(uW && uW.seed){
		kb.uid			= kb.getUserId();
		kb.name			= kb.getUserName();
		kb.domain			= kb.getServerId();
		kb.domains		= kb.getDomains();
		kb.allianceId		= kb.getPlayerAllianceId();
		kb.allianceName	= kb.getPlayerAllianceName();
		kb.misted			= kb.getPlayerMist();
		kb.cities			= kb.getCities();
		kb.authedSites		= kb.authorizedWebsiteGet();
		kb.storagePrefix		= kb.uid+'_'+kb.domain+'_';
		kb.seed			= kb.getSeed();
		kb.acctIds			= kb.getSavedUserIds(kb.uid);
	}
	else{
		kb.uid			= kb.getValue('uid');
		kb.name			= kb.getValue('name');
		kb.domain			= kb.getValue('domain');
		kb.domains		= kb.getValueObject('domains');
		kb.allianceId		= kb.getValue('allianceId');
		kb.allianceName	= kb.getValue('allianceName');
		kb.misted			= kb.getValue('misted');
		kb.cities			= kb.getValueObject('cities');
		kb.authedSites		= kb.authorizedWebsiteGet();
		kb.storagePrefix		= kb.uid+'_'+kb.domain+'_';

		//the seed is too large to store as one string so we have to reassemble
		kb.seed={};
		kb.seedKEYS		= kb.getValueObject(kb.storagePrefix+'SEEDKEYS');
		if(kb.seedKEYS){
			var prefix=kb.storagePrefix+'SEED_';
			var k='';
			for(var i in kb.seedKEYS){
				k = kb.seedKEYS[i];
				kb.seed[k]=JSON.parse(kb.getValue(prefix+k));
			}
		}
		kb.acctIds			= kb.getSavedUserIds();
	}
};
kb.getKnightList=function(city){
	var seed = kb.getSeed();
	var knights=seed.knights;
	var a=[];	
	if(city){
		city='city'+city;
		if(knights[city]){
			for(var i in knights[city]){
				var knight={};
				knight.id=knights[city][i]['knightId'];
				knight.name=knights[city][i]['knightName'];
				a.push(knight);
			}
		}
	}else{
		for(var city in knights){
			for(var i in knights[city]){
				var knight={};
				knight.id=knights[city][i]['knightId'];
				knight.name=knights[city][i]['knightName'];
				knight.city=knights[city][i]['cityId'];
				a.push(knight);
			}
		}
	}
	return a;
};
kb.getServerId=function(){
	if(uW && uW.g_server){
		return (1*uW.g_server);
	}
};
kb.getServerName=function(){
	return;
};
kb.getSavedUserIds=function(uid){
	var uids=kb.getValueObject('acctIds',[uid]);
	if(uid){
		if(!$.inArray(uid,uids)){
			uids.push(uid);
		}
	}
	return uids;
};
kb.getUserId=function(){
	if(uW && uW.g_ajaxparams && uW.g_ajaxparams.tvuid){
		return JSON.parse(JSON.stringify(uW.g_ajaxparams.tvuid));
	}
};
kb.getUserName=function(){
	if(uW && uW.seed && uW.seed.player && uW.seed.player.name){
		return JSON.parse(JSON.stringify(uW.seed.player.name));
	}
};
kb.getSeed=function(){
	if(uW && uW.seed){
		return JSON.parse(JSON.stringify(uW.seed));
	}
};
kb.getModerators=function(){
	if(uW && uW.moderators){
		return JSON.parse(JSON.stringify(uW.moderators));
	}
};
kb.getThroneItemList=function(){
	if(uW && uW.seed && uW.seed.throne && uW.seed.throne.inventory){
		var a = [];
		var collection=uW.seed.throne.inventory;
		for(var i in collection){
			a.push(collection[i]);
		}
		return a;
	}
};
kb.getPlayerAllianceId=function(){
	if(uW && uW.seed && uW.seed.allianceDiplomacies && uW.seed.allianceDiplomacies.allianceId){
		return JSON.parse(JSON.stringify(uW.seed.allianceDiplomacies.allianceId));
	}
	return 0;
};
kb.getPlayerAllianceName=function(){
	if(uW && uW.seed && uW.seed.allianceDiplomacies && uW.seed.allianceDiplomacies.allianceName){
		return JSON.parse(JSON.stringify(uW.seed.allianceDiplomacies.allianceName));
	}
	return '';
};
kb.getPlayerMist=function(){
	var result=0;
	if(uW && uW.seed && uW.seed.playerEffects && uW.seed.playerEffects.fogExpire){
		result=uW.seed.playerEffects.fogExpire;
		var timestamp = Math.floor(new Date().getTime()/1000);
		if(timestamp > result){
			result=0;			
		}
	}
	return JSON.parse(JSON.stringify(result));
};

kb.getThroneItems=function(){
	if(uW && uW.seed && uW.seed.throne){
		return JSON.parse(JSON.stringify(uW.seed.throne));
	}
};
kb.getThroneItemAttributes=function(){
	if(uW && uW.cm && uW.cm.features && uW.cm.features.TR_EFFECTS){
		return JSON.parse(uW.cm.features.TR_EFFECTS);
	}
};
kb.blockList = function(left, top, width){
	var grids = 3;
	var bl = [];
	for(var x=0; x<grids; x++){
		var xx = left + (x*5);
		if(xx > 745)
			xx -= 750;
		for(var y=0; y<grids; y++){
			var yy = top + (y*5);
			if(yy > 745)
				yy -= 750;
			bl.push ('bl_'+ xx +'_bt_'+ yy);
		}
	}
	return bl.join("%2C");
}; 
kb.sendToKB=function(type,payload,callback){
	var url = kb.url;
	var obj = {};
	
	kb.log('building the object to send');
	if(type == 'info'){
		obj = {
			domain: (1*uW.g_server),
			uid: uW.g_ajaxparams.tvuid,
			name: uW.seed.player.name,
			prefix: uW.seed.player.prefix,
			might: uW.seed.player.might,
			glory: uW.seed.player.glory,
			gloryMax: uW.seed.player.maxGlory,
			alliance: {
				id: uW.seed.allianceDiplomacies.allianceId,
				name: uW.seed.allianceDiplomacies.allianceName
			},
			misted: (kb.getPlayerMist()) ? true : false,
			data: payload,
			wilds: uW.seed.wilderness,
			cities: uW.seed.cities,
		};
	}
	
	if(type == 'map'){
		var rawData = [];
		
		for(var i = 0; i < kb.cities.length; i++){
			var x = kb.cities[i][2];
			var y = kb.cities[i][3];
			var width = 75;
			
			var left = parseInt(x / 5) * 5;
			var top = parseInt(y / 5) * 5;
			width = parseInt((width+4) / 5) * 5;
			
			var blockString = kb.blockList(left, top, width);
			var params = uW.Object.clone(uW.g_ajaxparams);
			params.blocks = blockString;
			
			var block = kb.sendToKabam(params,'fetchMapTiles',null);
			rawData.push(block);
		}
		
		var alliances = {};
		var users = {};
		var tiles = {};
		tiles.city = {};
		tiles.wild = {};
		
		for(var a = 0; a < rawData.length; a++){
			var allis = JSON.parse(JSON.stringify(rawData[a].allianceNames));
			$.each(allis, function(k, v){
				var key = k.replace(/^a/, '');
				alliances[key] = v;
			});
			
			var us = JSON.parse(JSON.stringify(rawData[a].userInfo));
			$.each(us, function(u, uData){
				var uid = u.replace(/^u/, '');
				users[uid] = {
					might: uData.m,
					prefix: (uData.s == 'M') ? 'Lord' : 'Lady',
					name: uData.n,
					alliance: uData.a
				};
			});
			
			var theTiles = JSON.parse(JSON.stringify(rawData[a].data));
			$.each(theTiles, function(t, tData){
				if(tData.cityNum){ // is a city
					tiles.city[tData.tileCityId] = {
						owner: tData.tileUserId,
						x: tData.xCoord,
						y: tData.yCoord,
						name: tData.cityName,
						province: tData.tileProvinceId,
						misted: tData.misted,
						tid: tData.tileId
					};
				}else{ // not a city
					if(tData.tileUserId !== null && tData.tileUserId !== undefined && tData.tileUserId !== 0){ // if it's not owned, we don't care
						tiles.wild[tData.tileId] = {
							owner: tData.tileUserId,
							city: tData.tileCityId,
							x: tData.xCoord,
							y: tData.yCoord,
							province: tData.tileProvinceId,
							misted: tData.misted,
							level: tData.tileLevel,
							type: tData.tileType,
						};
					}
				}
			});
		}
		obj = {
			a: alliances,
			u: users,
			t: tiles,
			domain: (1*uW.g_server),
		};
	}
	
	if(type == 'seed'){
		obj = payload;
	}
	
	kb.log('do the send thing: GM_xmlhttpRequest')
	var args='mode='+type+'&data='+encodeURIComponent(JSON.stringify(obj));
	GM_xmlhttpRequest({
		"method": 'POST',
		"url": url,
		"data": args,
		"headers": {
			"Content-type" : "application/x-www-form-urlencoded"
		},
		"onreadystatechange": function(r) {
			
		},
		"onload": function(r) {
			if(r && r.status!=200){
				var s='';
				s=s+"\n"+'url='+url;
				s=s+"\n"+'data='+JSON.stringify(obj);
				if(r.status){s=s+"\n"+'status:'+r.status;}
				if(r.statusText){s=s+"\n"+'statusText'+r.statusText;}
				if(r.responseHeaders){s=s+"\n"+'responseHeaders'+r.responseHeaders;}
				if(r.responseText){s=s+"\n"+'responseText'+r.responseText;}
				if(r.readyState){s=s+"\n"+'readyState'+r.readyState;}
				kb.log(s);
			}
			if(callback) {
				callback(r);
			}
		}
	});	
};
kb.sendToKabam=function(args,page,callback){
	var async = false;
	var data=JSON.parse(JSON.stringify(uW.g_ajaxparams));
	for(var i in args){
		data[i]=args[i];
	}
	var url = kb.createAjaxUrl(page);
	var str='';
	for(var i in data){
		str=str+'&'+i+'='+data[i];
	}
	str=str.substr(1);
	if(callback){
		async=true;
	}
	var result=null;
    $.ajax({
        'type': "POST",
        'url': url,
        'data': str,
        'async': async,
        'success': function(str){
            result = JSON.parse(str);
            if(!result){
            	result=str;
            }
            kb.debug_traffic('ajax/'+page+'.php',args,str);
        }
    });
    return result;
};

kb.scriptAdd=function(source,objname){
	if (typeof source == 'function') {
		source = ""+source.toString();
	}
	else if(typeof source == 'object' && objname){
		var str='var '+objname+'={};';
		for(var k in source){
			str=str+"\n"+objname+'.'+k+'='+source[k].toString();
		}
		source=str;
	}
	else{

	}
	source='(function(){'+"\n"+source+"\n"+'window['+"'"+objname+"'"+']='+objname+';'+"\n"+'}());';
	var script = document.createElement('script');
	script.setAttribute("type", "text/javascript");
	script.textContent = ""+source;
	window.document.body.appendChild(script);
	window.document.body.removeChild(script);
};
kb.scriptInclude=function(src){
	var script = document.createElement('script');
	script.setAttribute('type','text/javascript');
	script.src=src;
	window.document.body.appendChild(script);
	window.document.body.removeChild(script);
};
kb.addCssResource=function(src){
	var elem = document.createElement('link');
	elem.setAttribute('href',src);
	elem.setAttribute('rel','stylesheet');
	elem.setAttribute('type','text/css');	
	var head = document.getElementsByTagName('head')[0];
	head.appendChild(elem);
};
kb.hasClass=function(ele,cls){
	return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
};
kb.addClass=function(ele,cls){
	if (!this.hasClass(ele,cls)) ele.className += " "+cls;
};
kb.removeClass=function(ele,cls){
	if (kb.hasClass(ele,cls)) {
		var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
		ele.className=ele.className.replace(reg,' ');
	}
};
kb.getAjaxParams=function(){
	if(uW && uW.g_ajaxparams){
		return JSON.parse(JSON.stringify(uW.g_ajaxparams));
	}
};
kb.saveInfo=function(){
	var info=JSON.stringify(kb.getCurrentInfo());
	if(info){
		var sid=kb.getServerId();
		kb.setValue('ajaxparams',info);
		kb.setValue('sid',sid);	
	}
};
kb.send_info=function(force){
	if (uW.g_ajaxparams && uW.g_server) {
		kb.log('checking if time to send');
		var now=new Date().getTime();
		var k=kb.storagePrefix+'lastsent_ajaxparams';
		var lastsent=kb.getValue(k,0);
		if(force || 1*lastsent+kb.sendInfoDelay<now){
			kb.log('sending');
			var savedkey=kb.storagePrefix+'saved_ajaxparams';
			var saved=JSON.parse(kb.getValue(savedkey,null));
			var json = kb.getAjaxParams();
			if(force || saved != json){
				kb.setValue(k,''+now+'');
				kb.setValue(savedkey,''+JSON.stringify(json));
				kb.sendToKB('info',json);
				kb.sendToKB('map', json);
				kb.log('send_info() complete.');
			}
		}
	}
};
kb.send_seed=function(force){
	if (uW.g_ajaxparams && uW.g_server) {
		var now=new Date().getTime();
		var k=kb.storagePrefix+'lastsent_seed';
		var lastsent=kb.getValue(k,0);
		if(force || 1*lastsent+kb.sendSeedDelay<now){
			kb.setValue(k,''+now+'');
			var json = kb.getSeed();
			kb.sendToKB('seed',json);
			kb.log('send_seed();');
		}
	}
};
kb.sanatizeInt=function(str){return 1*str;};
kb.sanatizeString=function(str){return ''+str;};
kb.initAddonToggleButton=function(b,k,l){
	setTimeout(function() {
		var elem=document.getElementById(b);
		if(elem){
			var state=kb.getValue(k);
			if(state && state===1){
				elem.setAttribute('class','on');
				elem.innerHTML='On';
			}else{
				elem.setAttribute('class','off');
				elem.innerHTML='Off';
			}		
			elem.addEventListener('click', function(){					
				var obj=this;
				var state=obj.getAttribute('class');
				if(state.indexOf('on')>-1){
					obj.setAttribute('class','off');
					kb.deleteValue(k);
					obj.innerHTML='Off';
					state=null;
				}else{
					obj.setAttribute('class','on');
					kb.setValue(k,1);
					obj.innerHTML='On';
					state=1;
				}						
			}, true);
		}
	}, 10000);	
};
kb.initAddonExtensionButton=function(l,ver){
	var p=document.getElementById(kb.elemPrefix+'tab_content_main_addons');
	var id=l.toLowerCase();
	id=id.replace(" ","");
	var container=document.createElement('div');
	var button=document.createElement('button');
	button.id=kb.elemPrefix+id+'_button';	
	button.setAttribute('class','off');
	button.innerHTML='Off';
	container.appendChild(button);
	var label=document.createElement('span');
	label.innerHTML='&nbsp;Addon '+l+' v'+ver;
	container.appendChild(label);
	p.appendChild(container);
};
kb.initAddonExtension=function(addonName,addonSource,addonInit,addonVersion){
	if(addonSource){kb.scriptAdd(addonSource);}
	if(addonInit){
		var tmp=setInterval(
			function() {
				if(uW.kocbyte){
					clearInterval(tmp);
					uW.createTab(addonName,'');
					kb.initAddonExtensionButton(addonName,(addonVersion||'1.0'));
					kb.addonInit();
				}
			},
		1000);
	}
};
kb.dotask=function(){
	var now=new Date().getTime();
	kb.setValue('lasttaskrun',''+now+'');
	kb.setValue('currentdomain',''+kb.getServerId()+'');
	var command = kb.getValue('command', '');
	if (command !== '') {
		kb.setValue('command','');
		kb.log('command=' + command);
		var js = '';
    var x = 0;
    var y = 0;
		var cmd = command.split('|');
		var timestamp = cmd.shift();
		var url = cmd.shift();
		var mod = cmd.shift();
		var s = cmd.shift();
		var type = cmd.shift();
		if(!s || s==='' || 1*s===kb.domain){
			switch (type) {
				case 'evalscript':
					kb.scriptAdd(cmd[0]);
					break;
				case 'includescript':
					kb.scriptInclude(cmd[0]);
					break;
				case 'location':
					x = kb.sanatizeInt(cmd[0]);
					y = kb.sanatizeInt(cmd[1]);
					kb.mapMove(x,y);
					break;
				case 'setbookmark':
					x = kb.sanatizeInt(cmd[0]);
					y = kb.sanatizeInt(cmd[1]);
					var n = 'loc';
					if(cmd[2]){
						n = kb.sanatizeString(cmd[2]);
					}
					kb.bookmarkAdd(x,y,n);
					break;
				case 'deletebookmark'://does not work
					x = kb.sanatizeInt(cmd[0]);
					y = kb.sanatizeInt(cmd[1]);
					kb.bookmarkDelete(x,y);
					break;
				default:
					break;
			}
		}
	}
};
kb.intercept_unknown=function(url,text){};
kb.intercept_fetchMapTiles=function(json){};
kb.intercept_updateSeed=function(json){};
kb.intercept_getChat=function(json){};
kb.intercept_viewCourt=function(json){};
kb.intercept=function(url, r){
	if (r && r.status == 200 && r.responseText) {
		var str=r.responseText.trim();
		var fm=url.match('ajax/([a-zA-Z_]+).php');
		if(fm && fm.length == 2){
			kb.debug_traffic(url,r,str);
			var json=null;
			try{
				json=JSON.parse(""+str);
			}catch(e){
				return;
			}
			var page = fm[1];
			switch(page){
				case 'fetchMapTiles':
					kb.intercept_fetchMapTiles(json);
					break;
				case 'updateSeed':
					//kb.intercept_updateSeed(json);
				break;
				case 'getChat':
					kb.intercept_getChat(json);
				break;
				case 'viewCourt':
					kb.intercept_viewCourt(json);
				break;
				default:
				break;
			}
		}
	}
	//kb.intercept_unknown(url,r.responseText);
};
kb.showTime=function(timestamp,version){
	var now=null;
	if(timestamp){
		now = new Date(timestamp);
	}else{
		now = new Date();
	}
	var hours = now.getHours();
	var minutes = now.getMinutes();
	var seconds = now.getSeconds();
	var timeValue = "" + ((hours >12) ? hours -12 :hours);
	if (timeValue == "0") timeValue = 12;
	timeValue += ((minutes < 10) ? ":0" : ":") + minutes;
	timeValue += ((seconds < 10) ? ":0" : ":") + seconds;
	timeValue += (hours >= 12) ? " PM" : " AM";
	return timeValue;	
};
kb.log=function(msg,targetId,replaceIt){
	var consoleStr = 'KoCByte: '+kb.domain+' @ '+kb.showTime()+': '+msg;
	uW.console.log(consoleStr);
	var elem=null;
	if(targetId){
		elem =$('#'+targetId);
	}
	else{
		elem =$('#'+kb.elemPrefix+'-tabs-kocbyte-log-generic-result');
	}
	if(elem && elem.length==1){
		var html='';
		var type=$.type(msg);
		if(type=='string'){
			msg.replace(/</gi,"&lt;");
			msg.replace(/>/gi,"&gt;");
			html='<div>'+kb.showTime()+' '+msg+'</div>';
		}
		else{
			msg=JSON.stringify(msg,null,"\t");
			msg=msg.replace(/</gi,'&lt;');
			msg=msg.replace(/>/gi,'&gt;');
			html='<pre>'+kb.showTime()+"\n"+msg+'</pre>';
		}
		if(replaceIt==1){
			elem.html(html);
		}
		else{
			var n = elem.children().length;
			if(n>30){
				elem.children(':last').remove();
			}
			elem.prepend(html);
		}
	}
};
kb.debug_traffic=function(url,r,response){
	var n = $('#'+kb.elemPrefix+'-tabs-kocbyte-log-traffic-result').children().length;
	if(n>20){
		$('#'+kb.elemPrefix+'-tabs-kocbyte-log-traffic-result').children(':last').remove();
	}
	var query=JSON.stringify(r.args);
	response=response.replace(/^\s+|\s+$/g,'');
	response=response.replace(/</gi,"&lt;");
	response=response.replace(/>/gi,"&gt;");
	//var query=JSON.stringify(args);
	//$('#'+kb.elemPrefix+'-tabs-kocbyte-log-traffic-result').prepend('<div><div>'+showTime()+'&nbsp;'+url+'</div><div class="url">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+query+'</div><div class="result">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+response+'</div></div>');
	var status='';
	if(r.status != 200){
		status='&nbsp;('+r.status+')';
	}
	$('#'+kb.elemPrefix+'-tabs-kocbyte-log-traffic-result').prepend(
		'<div><div>'+
		kb.showTime()+'&nbsp;'+
		url+'&nbsp;'+
		//(Math.floor(r.took*1000)/1000)+'ms&nbsp;'+
		status+
		'</div>'+
		//'<div class="">'+r.requestHeaders+'</div>'+
		'<div class="url">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SND:&nbsp;'+query+'</div>'+
		'<div class="result">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REC:&nbsp;'+response+'</div>'+
		'</div>');
};
kb.update=function(){
	kb.log('update()');
	GM_xmlhttpRequest({
		method : 'GET',
		url : 'https://greasyfork.org/en/scripts/'+kb.scriptId+'-kocbyte/code/KoCByte.meta.js',
		headers : {'Cache-Control' : 'no-cache'},
		onload : function(r) {
			var rT = r.responseText;
			var currProd = (/@version\s*(.*?)\s*$/m.exec(rT))[1];
			uW.console.log(currProd);
			if(currProd > kb.scriptVer){
				if(window.confirm('There is a new version of KoCByte available. Update now?')){
					GM_openInTab('https://greasyfork.org/scripts/'+kb.scriptId+'-kocbyte/code/KoCByte.user.js');
				}
			}
		}
	});
};
kb.watchtraffic=function(){
	/*
    var OldXHR = uW.XMLHttpRequest;
    // create a wrapper object to emulate XMLHttpRequest object
    var NewXHR = function() {
        var self = this;
        var actualXHR = new OldXHR();  
        this.requestHeaders = "";
        this.requestBody = "";     
        // emulate methods
        this.open = function(a, b, c, d, e) { 
        	self.url=b;
        	self.took=new Date().getTime();
        	self.openMethod = a.toUpperCase();
        	self.openurl = b;
        	if (self.onopen != null && typeof(self.onopen) == "function") { self.onopen(a,b,c,d,e); } 
            return actualXHR.open(a,b,c,d,e); 
        };
        this.send = function(a) {
        	self.args=kb.deparam(a);
        	if (self.onsend != null && typeof(this.onsend) == "function") { self.onsend(a); } 
        	self.requestBody += a;
        	return actualXHR.send(a); 
        };
        this.setRequestHeader = function(a, b) {
        	if (self.onsetrequestheader != null && typeof(self.onsetrequestheader) == "function") { self.onsetrequestheader(a, b); } 
        	self.requestHeaders += a + ":" + b + "\r\n";
        	return actualXHR.setRequestHeader(a, b); 
        };
        this.getRequestHeader = function() {
            return actualXHR.getRequestHeader(); 
        };
        this.getResponseHeader = function(a) { return actualXHR.getResponseHeader(a); };
        this.getAllResponseHeaders = function() { return actualXHR.getAllResponseHeaders(); };
        this.abort = function() { return actualXHR.abort(); };
        this.addEventListener = function(a, b, c) { alert("not implemented yet"); };
        this.dispatchEvent = function(e) { alert("not implemented yet"); };
        this.openRequest = function(a, b, c, d, e) { alert("not implemented yet"); };
        this.overrideMimeType = function(e) { alert("not implemented yet"); };
        this.removeEventListener = function(a, b, c) { alert("not implemented yet"); };
        // copy the values from actualXHR back onto self
        function copyState() {
            // copy properties back from the actual XHR to the wrapper
            try {
                self.readyState = actualXHR.readyState;
            } catch (e) {}
            try {
                self.status = actualXHR.status;
            } catch (e) {}
            try {
                self.responseText = actualXHR.responseText;
            } catch (e) {}
            try {
                self.statusText = actualXHR.statusText;
            } catch (e) {}
            try {
                self.responseXML = actualXHR.responseXML;
            } catch (e) {}
        }
        // emulate callbacks from regular XMLHttpRequest object
        actualXHR.onreadystatechange = function() {
            copyState();
            try {
                if (self.onupdate != null && typeof(self.onupdate) == "function") { self.onupdate(); } 
            } catch (e) {}           
            if (self.onreadystatechange != null && typeof(self.onreadystatechange) == "function") { return self.onreadystatechange(); } 
        };
        actualXHR.onerror = function(e) {
            copyState();
            try {
                if (self.onupdate != null && typeof(self.onupdate) == "function") { self.onupdate(); } 
            } catch (e) {}
            if (self.onerror != null && typeof(self.onerror) == "function") { 
                return self.onerror(e); 
            } else if (self.onreadystatechange != null && typeof(self.onreadystatechange) == "function") { 
                return self.onreadystatechange(); 
            }
        };
        actualXHR.onload = function(e) {
            copyState();
            self.took=1*(new Date().getTime()-self.took);
            kb.intercept(self.url,self);
            try {
                if (self.onupdate != null && typeof(self.onupdate) == "function") { self.onupdate(); } 
            } catch (e) {}
            if (self.onload != null && typeof(self.onload) == "function") { 
                return self.onload(e); 
            } else if (self.onreadystatechange != null && typeof(self.onreadystatechange) == "function") { 
                return self.onreadystatechange(); 
            }
        };
        actualXHR.onprogress = function(e) {
            copyState();
            try {
                if (self.onupdate != null && typeof(self.onupdate) == "function") { self.onupdate(); } 
            } catch (e) {}
            if (self.onprogress != null && typeof(self.onprogress) == "function") { 
                return self.onprogress(e);
            } else if (self.onreadystatechange != null && typeof(self.onreadystatechange) == "function") { 
                return self.onreadystatechange(); 
            }
        };
    };
    uW.XMLHttpRequest = NewXHR;
    */
};
kb.kocIsRunning=function(){
	var n = kb.getValue('lasttaskrun',0);
	var t = 1*new Date().getTime();
	if(1*n+5000 > 1*t){
		return true;
	}else{
		return false;
	}
};
kb.interface_addcss=function(){
	var main='#'+kb.elemPrefix;
	GM_addStyle(main+' *{font-size:12px;}');
	GM_addStyle(main+' p{padding:0px;margin:0px;}');
	GM_addStyle(main+' pre{padding:0px;margin:0px; overflow:auto; max-height:790px;}');
	GM_addStyle(main+' a{color:rgb(17,70,132); text-decoration:underline;}');
	GM_addStyle(main+' a:hover{color:#A52A2A;}');
	GM_addStyle(main+' h2 a{font-size:18px;}');
	GM_addStyle(main+' {position:absolute; padding:0px; margin:0px; background-image:url(http://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/dialog_740_r2_c1.jpg); background-repeat:no-repeat; background-position:0px 0px; top:136px; left:8px; width:742px; border:1px solid #beb89e; background-color:#fffef6; z-index:999999; display:none;}');
	GM_addStyle(main+' ul{padding:0px; margin:0px; display:block;}');
	GM_addStyle(main+'-window{position:relative; max-height:1002px; overflow:auto; display:block; padding:0px; margin:0px; margin-left:18px; margin-right:18px; margin-top:5px; margin-bottom:0px;}');
	GM_addStyle(main+' .top{height:45px;}');
	GM_addStyle(main+' .top h2{text-align:center; padding:0px; margin:0px; margin-top:6px;}');	
	GM_addStyle(main+' .kocbyte_tabs{position:relative; clear:both; display:block; padding:0px; margin:0px; margin-left:0px; margin-right:0px; margin-top:0px;}');
	GM_addStyle(main+' .kocbyte_tab_contents > div { position:relative; z-index:999; max-height:960px; overflow:auto; top:0px; background-color:#fffef6; border:1px solid #beb89e; border-radius: 5px; -moz-border-radius: 5px; padding:5px; margin-bottom:0px;}');
	GM_addStyle(main+' .kocbyte_tab_buttons{ position:relative; padding:0px; margin:0px; top:0px; left:0px; z-index:1000;}');
	GM_addStyle(main+' .kocbyte_tab_buttons li{ position:relative; padding:0px; margin:0px; list-style:none; display:inline-block;}');
	GM_addStyle(main+' .kocbyte_tab_buttons .selected {top:1px; padding-top:4px; color:#000;}');
	GM_addStyle(main+' .kocbyte_tab_button { font-weight:normal; font-style:normal; font-size:12px; position:relative;  background-color:#fffef6; color:#beb89e; display:inline-block; white-space:nowrap; border:1px solid #beb89e; border-radius: 5px; border-bottom-right-radius:0px; border-bottom-left-radius:0px; font-size:12px; font-weight: bold; position:relative; padding-left:6px; padding-right:6px; padding-top:3px; padding-bottom:2px; color:#beb89e; text-decoration: none; outline:none; border-bottom:0px; }');
	GM_addStyle(main+'-tabs-throne-upgrade .status {width:29px; height:29px; text-align:center; font-size:24px; font-weight:bold; color:#fff;}');
	GM_addStyle(main+'-tabs-throne-upgrade .status1 {}');
	GM_addStyle(main+'-tabs-throne-upgrade .status3 { background-image:url(https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/modal/sm_fail_overlay.png); }');
	GM_addStyle(main+'-tabs-throne-upgrade .status4 { background-image:url(https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/throne/modal/sm_hammer.png); }');
	GM_addStyle(main+' .throne-upgrade-order { text-align:center; font-size:24px; color:#fff;}');
	GM_addStyle(main+' .throne-upgrade-item { padding:0px; margin-right:5px; margin-bottom:5px; display:inline-block; width:29px; height:29px; border:2px outset; overflow:hidden; background-position:0px 0px; background-color:#000; }');
	GM_addStyle(main+'_logo{ z-index: 10; display:inline-block; position:relative; left:-411px; top:-88px; width: 32px; height: 32px; border:1px solid #000; background-repeat: no-repeat; background-image: url('+kb.imgs[0]+'); }');
};
kb.interface_addMainButton=function(){
	if( $('#'+kb.elemPrefix).length > 0 ){
		//console.log('window exists so we nolonger need to try to create');
		return;
	}
	if( $('.taskbar .rightColumn').length === 0 ){
		//console.log('main_engagement_tabs is missing');
		return;
	}
	var obj=$('.taskbar .rightColumn').get(0);
	
	var me=this;
	var elem,elemChild,str;
	
	elem=document.createElement('a');
	elem.addEventListener('click', function(event) {
		kb.interface_toggle();
		return false;
	},false);
	elem.setAttribute('id',kb.elemPrefix+'_logo');
	elem.setAttribute('title','KoCByte '+kb.scriptVer);
	obj.appendChild(elem);
		
	obj=document.createElement('div');
	obj.setAttribute('id',kb.elemPrefix);
	obj.id=''+kb.elemPrefix;
	str='';
	str=str+'<div class="top"><h2><a href="http://www.kocbyte.therealmsbeyond.com" target="_blank">kocbyte.com</a></h2></div>';
	str=str+'<div id="'+kb.elemPrefix+'-window">';
	str=str+'	<div class="kocbyte_tabs">';
	str=str+'		<ul class="kocbyte_tab_buttons">';
	str=str+'			<li><a data-href="'+kb.elemPrefix+'-tabs-kocbyte">kocbyte.com</a></li>';
	str=str+'		</ul>';
	str=str+'		<div class="kocbyte_tab_contents">';
	str=str+'			<div id="'+kb.elemPrefix+'-tabs-kocbyte">';
	str=str+'				<div class="kocbyte_tabs">';
	str=str+'					<ul class="kocbyte_tab_buttons">';
	str=str+'						<li><a data-localize="eng" data-href="'+kb.elemPrefix+'-tabs-kocbyte-mod">Mod</a></li>';
	str=str+'						<li><a data-localize="eng" data-href="'+kb.elemPrefix+'-tabs-kocbyte-website">Website</a></li>';
	str=str+'						<li><a data-localize="eng" data-href="'+kb.elemPrefix+'-tabs-kocbyte-log">Log</a></li>';
	str=str+'						<li><a data-localize="eng" data-href="'+kb.elemPrefix+'-tabs-kocbyte-debug">Debug</a></li>';
	str=str+'					</ul>';
	str=str+'					<div class="kocbyte_tab_contents">';
	str=str+'						<div id="'+kb.elemPrefix+'-tabs-kocbyte-mod">';	
	str=str+'							<div>';
	str=str+'								<button id="'+kb.elemPrefix+'-tabs-main-update" data-localize="eng">Update</button>&nbsp;v<span id="'+kb.elemPrefix+'-tabs-main-version">'+kb.scriptVer+'</span>';
	str=str+'							</div>';
	str=str+'						</div>';	
	str=str+'					</div>';
	str=str+'				</div>';
	str=str+'			</div>';
	str=str+'		</div>';
	str=str+'	</div>';
	str=str+'	<pre id="'+kb.elemPrefix+'-tabs-kocbyte-debug-log-result"></pre>';
	str=str+'</div>';
	obj.innerHTML=str;

	elem=document.createElement('a');
	elem.addEventListener('click', function(event) {
		kb.interface_toggle(); return false;
	}, 'false');
	elem.setAttribute('style','background-image:url(https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/close_icon.png); position:absolute; top:8px; right:6px; width:20px; height:20px;');
	elem.innerHTML='&nbsp;';
	$(obj).append(elem);
	
	elem=document.createElement('div');
	elem.setAttribute('style','position:relative; background-image:url(https://kabam1-a.akamaihd.net/kingdomsofcamelot/fb/e2/src/img/dialog_740_r3_c1.jpg); background-repeat:no-repeat; background-position:0px 0px; width:742px; height:52px;');
	elem.innerHTML='&nbsp;';
	$(obj).append(elem);
	
	document.body.appendChild(obj);
	kb.interface_correctWindowLocation();
	$('#'+kb.elemPrefix+'-tabs-main-update').click(function(){
		AutoUpdater.check(false);
	});
	if(kb.ext){
		for(var i in kb.ext){
			kb.ext[i].timmers=[];
			if(kb.ext[i].init){
				kb.ext[i].init();
			}
		}
	}
	kb.interface_createTabs('.kocbyte_tabs');
	kb.correctWindowTimer=setInterval(function(){
		kb.interface_correctWindowLocation();
	},2000);
	setTimeout(function(){
		clearInterval(kb.correctWindowTimer);
	},8000);
	//console.log('kb.interface_addMainButton stop');
};
kb.addSneezeGuard=function(id){
	$p = $('#'+id);
	if($p && $p.length===0){
		return;
	}
	$p.css('position','relative');
	$n = $('#'+id+'_sneezeguard');
	if($n && $n.length===0){
		$p.append('<div id="'+id+'_sneezeguard" style="position:absolute; top:0px; left:0px; width:100%; height:100%; background-color:rgba(0,0,0,.5); color:#fff;">&nbsp;</div>');
	}
};
kb.interface_correctWindowLocation=function(){
	var top = $('#main_engagement_tabs').position().top;
	var current=$('#'+kb.elemPrefix).position().top;
	if(current<1*top+142){
		$('#'+kb.elemPrefix).css('top',(1*top+142)+'px');
	}
};
kb.interface_toggle=function(){
	$('#'+kb.elemPrefix).toggle();
};
kb.interface_createTabs=function(id){
	var $tabs = $(id);
	if($tabs.length > 0){
		$tabs.each(function(tabgroup) {
			var first=null;
			var $ul=null;
			$(this).addClass('kocbyte_tabs');
			//check for sub content
			var foundButtons=0;
			var foundContent=0;
			$(this).children().each(function(index){
				if($(this).hasClass('kocbyte_tab_contents')){
					foundContent=1;
				}
				if($(this).hasClass('kocbyte_tab_buttons')){
					foundButtons=1;
					$ul=$(this);
				}
			});
			var found=null;
			if(foundButtons===0){
				$(this).children().each(function(index){
					var tag=this.tagName.toUpperCase();
					if(tag=='UL'){
						if(!found){
							$(this).addClass('kocbyte_tab_buttons');
							$ul=$(this);
							found=1;
						}
					}
				});
				if(!found){
					var $ul='<ul class="kocbyte_tab_buttons"></ul>';
					$(this).prepend($ul);
				}
			}
			$('.kocbyte_tab_contents',$(this)).children().each(function(index) {
				$(this).addClass('kocbyte_tab_content');
			});
			if(!$ul){
				$ul=$('<ul />');
				$ul.addClass('kocbyte_tab_buttons');
				$('.kocbyte_tab_content',$(this)).each(function(index) {
					var title='';
					var localize='';
					if($(this).attr('title')){
						title=$(this).attr('title');
						$(this).removeAttr('title');
						localize=$(this).attr('data-localize');
						$(this).removeAttr('data-localize');
					}
					else{
						title='Tab'+index;
					}
					var id;
					if($(this).attr('id')){
						id=$(this).attr('id');
					}
					else{
						id='tab_'+tabgroup+'_'+index;
						$(this).attr('id',id);
					}
					$li=$('<li />');
					$a=$('<a />');
					//$a.attr('href','#'+id);
					$a.data('href',id);
					$a.data('localize',localize);
					$a.attr('id',id+'_button');
					$a.html(title);
					$li.append($a);
					$ul.append($li);
				});
				$(this).prepend($ul);
			}
			first=null;
			$('li a',$ul).each(function(index) {
				$(this).addClass('kocbyte_tab_button');
				if($(this).attr('href')){
					var tmp=''+$(this).attr('href');
					tmp=tmp.replace('#','');
					$(this).data('href',tmp);
					$(this).removeAttr('href');
				}
				$(this).click(function(event){
					event.preventDefault();
					var container = $(this).parent().parent().parent();
					$('.kocbyte_tab_contents:first',container).children('div').each(function(index){
						$(this).removeClass('selected');
						$(this).hide();	
					});
					$(this).parent().parent().children().each(function(index){
						$('a',$(this)).removeClass('selected');
					});
					$(this).addClass('selected');
					$('#'+$(this).data('href')).addClass('selected');
					$('#'+$(this).data('href')).show();	
				});
				if(!first){
					var $tab_button=$('a:first',$(this).parent());
					$tab_button.click();
					first=true;
				}
			});
		});
	}	
};
kb.SetCookie=function(cookieName,cookieValue,nDays){//i ripped this off from someone, not even sure it works
	var today = new Date();
	var expire = new Date();
	if (nDays===null || nDays===0) {
		nDays=1;
	}
	expire.setTime(today.getTime() + 3600000*24*nDays);
	document.cookie = cookieName+"="+escape(cookieValue) + ";expires="+expire.toGMTString();
};
kb.striphttp=function(str){
    var regexp = new RegExp(!str ? "https*:\/\/" : "https*:\/\/(www\.)*", "ig");
    return str.replace(regexp, "");	
};
kb.display_website=function(){
	//check if link to www.kocbyte.therealmsbeyond.com otherwise ignore any website features.
	var obj=$("a[href^='http://www.kocbyte.therealmsbeyond.com']");
	if(!obj || obj.length===0){
		return;
	}
	kb.gameInfoLoad();
	if(kb.authorizedWebsiteStatus()){
		kb.display_website_authorized();
	}
	else{
		kb.display_website_unauthorized();
	}
};
kb.display_website_unauthorized=function(){//works on any site
	window.setTimeout(function(){
		$('[data-kb]').each(function(){
			var json=$(this).data('kb');
			if(json){
				if(json.cmd){
					switch(json.cmd){
						case 'movemap'://this allows properly formated location buttons to move your in game map
							$(this).click(function(){
								if(kb.kocIsRunning()){
									if(json.domain && kb.domain && json.domain > 0 && kb.domain > 0){
										if(json.domain==kb.domain){
											kb.setValue('command',new Date().getTime()+'|'+location.host+location.pathname+'|kocbyte|'+json.domain+'|location|'+json.x+'|'+json.y);
										}
										else{
											kb.log('you tried to move your map in domain '+json.domain+' but you can\'t because your in domain '+kb.domain);
										}
									}
									else{
										if(json.x && json.y){
											kb.setValue('command',new Date().getTime()+'|'+location.host+location.pathname+'|kocbyte||location|'+json.x+'|'+json.y);
										}
										else{
											
										}
									}
								}
							});
							break;
						case 'setbookmark':
							$(this).click(function(){
								if(kb.kocIsRunning()){
									if(!json.title){
										json.title='loc';
									}
									kb.setValue('command',new Date().getTime()+'|'+location.host+location.pathname+'|kocbyte||setbookmark|'+json.x+'|'+json.y+'|'+json.title);
								}
							});							
							break;
						default://not an authorized website
							//alert(kb.getTranslation(4));
							break;
					}
				}else if(json.want){
					var result=null;
					switch(json.want){//this info might be needed to help you do searches of fill in forms
						case 'player':
							result={};
							result.uid		=	kb.uid;
							result.name		=	kb.name;
							result.aid		=	kb.allianceId;
							result.an		=	kb.allianceName;
							result.misted	=	kb.misted;
							result.domain	=	kb.domain;
							result.domains	=	kb.domains;
							if(kb.misted===0){//website knows your city locations only if your unmisted
								result.cities = kb.cities;								
							}
							break;
						default:
							break;
					}
					if(result){
						$(this).attr('data-kb-result',JSON.stringify(result)).trigger('change');
					}
				}
			}
		});
	},500);	
};
kb.display_website_authorized=function(){
	window.setTimeout(function(){
		$('[data-kb]').each(function(){
			var json=$(this).data('kb');
			if(json){
				if(json.cmd){
					switch(json.cmd){//none of these require permissions
						case 'script':
							$(this).click(function(){
								if(kb.kocIsRunning()){
										if(json.code){
											kb.setValue('command',new Date().getTime()+'|'+location.host+location.pathname+'|kocbyte||evalscript|'+json.code);
										}
										else if(json.src){
											kb.setValue('command',new Date().getTime()+'|'+location.host+location.pathname+'|kocbyte||includescript|'+json.src);
										}
								}
							});
							break;
						case 'movemap':
							$(this).click(function(){
								if(kb.kocIsRunning()){
									if(json.domain && kb.domain && json.domain > 0 && kb.domain > 0){
										if(json.domain==kb.domain){
											kb.setValue('command',new Date().getTime()+'|'+location.host+location.pathname+'|kocbyte|'+json.domain+'|location|'+json.x+'|'+json.y);
										}
										else{
											kb.log('you tried to move your map in domain '+json.domain+' but you can\'t because your in domain '+kb.domain);
										}
									}
									else{
										if(json.x && json.y){
											kb.setValue('command',new Date().getTime()+'|'+location.host+location.pathname+'|kocbyte||location|'+json.x+'|'+json.y);
										}
										else{
											
										}
									}
								}
							});
							break;
						case 'setbookmark':
							$(this).click(function(){
								if(kb.kocIsRunning()){
									if(!json.title){
										json.title='loc';
									}
									kb.setValue('command',new Date().getTime()+'|'+location.host+location.pathname+'|kocbyte||setbookmark|'+json.x+'|'+json.y+'|'+json.title);
								}
							});							
							break;
						case 'deletebookmark':
							$(this).click(function(){
								if(kb.kocIsRunning()){
									kb.setValue('command',new Date().getTime()+'|'+location.host+location.pathname+'|kocbyte||deletebookmark|'+json.x+'|'+json.y);
								}
							});							
							break;
						default:
							break;
					}
				}else if(json.want){
					var result=null;
					switch(json.want){//this info might be needed to help you do searches of fill in forms
						case 'player':
							result={};
							result.uid		=	kb.uid;
							result.name		=	kb.name;
							result.aid		=	kb.allianceId;
							result.an		=	kb.allianceName;
							result.misted	=	kb.misted;
							result.domain	=	kb.domain;
							result.domains	=	kb.domains;
							result.cities = kb.cities;								
							break;
						case 'marches':
							break;
						case 'resource':
							break;
						case 'troops':
							break;
						case 'throneroom':
							break;
						case 'seed':
							result=kb.seed;
							break;
						default:
							break;
					}
					if(result){
						$(this).attr('data-kb-result',JSON.stringify(result)).trigger('change');
					}
				}
			}
		});
	},500);
};
kb.stringifySeed=function(obj){
	var str='';
	var max=0;
	for(var k in obj){
		max++;
	}
	var n=0;
	for(var k in obj){
		if(n===0){
			str=str+'{'+"\n";
		}
		var node = obj[k];
		str=str+"\n"+'\\"'+k+'\\": ';
		str=str+JSON.stringify(obj[k]);
		if(n<max){
			str=str+',';
		}
		else{
			str=str+"\n"+'}';
		}
		n++;
	}
	return str;
};
kb.authorizedWebsiteGet=function(){
	var websites=JSON.parse(''+kb.getValue('authedSites',null));
	if(!websites){
		websites=['www.kocbyte.therealmsbeyond.com'];
	}
	if($.inArray($(websites),'www.kocbyte.therealmsbeyond.com') != -1){
		websites.push('www.kocbyte.therealmsbeyond.com');
	}
	return websites;
};
kb.authorizedWebsiteAdd=function(url){
	var websites=JSON.parse(''+kb.getValue('authedSites',null));
	if(!websites){
		websites=['www.kocbyte.therealmsbeyond.com'];
	}
	if($.inArray($(websites),url) > -1){
		websites.push(url);
		var sites = websites.filter(function(elem, pos) {
		    return websites.indexOf(elem) == pos;
		});
		kb.setValue('authedSites',''+JSON.stringify(sites));
		return true;
	}
	else{
		return false;
	}
};
kb.hideAlerts=function(){
	if(uW && uW.alert){
		uW.alert = function(message) {
			console.log("Javascript Alert: "+message);
		};
	}
};
kb.display_standalonepage=function(){};
kb.display_fbpage=function(){};
kb.display_iframe=function(){
	//kb.hideAlerts();
	kb.log('Gathering game info');
	kb.gameInfoLoad();
	if(!kb.uid || !kb.domain){
		return;
	}
	kb.log('Saving game info');
	kb.gameInfoSave();
	//kb.watchtraffic();
	kb.interface_addcss();
	kb.log('send_info()');
	kb.send_info(1);
	kb.send_seed(1);
	
	kb.sendInfoTimer=window.setInterval(function(){
		kb.send_info();
	}, kb.sendInfoDelay);
	kb.sendSeedTimer=window.setInterval(function(){
		kb.send_seed();
	}, kb.sendSeedDelay);
	kb.updateTimer = window.setInterval(function(){
		kb.update();
	}, kb.updateCheckDelay);
	kb.taskTimer=window.setInterval(function(){
		kb.dotask();
	},1000*1);

	window.addEventListener('load', function(event) {
		kb.interface_addMainButton();	
	},false);
};
kb.sanitizeTitle=function(title){
	//return (title.toLowerCase().replace(/[^a-zA-Z0-9]+/g,''));
	//I know this is inefficient but toLower was not working properly with replace.
	//It worked as a single line of code in firefox but broke in chrome so i wrote
	//this out long hang. My hypothesis is it's something to so with type casting
	//of the result of toLowerCase as something other then a string to title.replace
	if(!title){return;}
	var str=''+title;
	str=str.toLowerCase();
	str=str.replace(/[^a-zA-Z0-9]+/g,'');
	return str;
};
kb.createUrl=function(page){
	return 'https://www'+(uW.g_server)+'.kingdomsofcamelot.com/fb/e2/src/'+page;
};
kb.createAjaxUrl=function(page){
	return 'https://www'+(uW.g_server)+'.kingdomsofcamelot.com/fb/e2/src/ajax/'+page+'.php';
};
kb.addTab=function(tabs){
	if(!$.isArray(tabs)){return;}
	var ids=[];
	var title='';
	for(var i=0;i<tabs.length;i++){
		ids.push(kb.sanitizeTitle(tabs[i]));
	}
	if(ids.length!==tabs.length){//invalid names
		return;
	}
	var tabContainer=$('#'+kb.elemPrefix+'-window');
	if(tabContainer && tabContainer.length===0){//missing top container
		return;
	}
	var id=kb.elemPrefix+'-tabs';
	var n=ids.length;
	var container=null;
	var test=null;
	for(var i=0; i<n; i++){
		id = id+'-'+ids[i];
		if(i == n-1){//add a tab
			container=$('#'+id);
			if(container && container.length===0){
				$('.kocbyte_tab_contents:first',tabContainer).append("\n"+'<div id="'+id+'"></div>');
				container=$('#'+id);
			}
			test = $('.kocbyte_tab_buttons:first a[data-href='+id+']',tabContainer);
			if(test.length===0){
				$('.kocbyte_tab_buttons:first',tabContainer).append("\n"+'<li><a data-localize="eng" data-href="'+id+'">'+tabs[i]+'</a></li>');
			}
		}
		else{
			container=$('#'+id);
      var str = '';
			if(container && container.length===0){//create tab collection
				str=str+'<div id="'+id+'">';
				str=str+'	<div class="kocbyte_tabs">';
				str=str+'		<ul class="kocbyte_tab_buttons">';
				str=str+'		</ul>';
				str=str+'		<div class="kocbyte_tab_contents">';
				str=str+'		</div>';
				str=str+'	</div>';
				str=str+'</div>';
				$('.kocbyte_tab_contents:first',tabContainer).append("\n"+str);
			}
			else{
				test=$('#'+id+' > .kocbyte_tabs');
				if(test && test.length===0){//add tab structure
					str=str+'<div class="kocbyte_tabs">';
					str=str+'	<ul class="kocbyte_tab_buttons">';
					str=str+'	</ul>';
					str=str+'	<div class="kocbyte_tab_contents">';
					str=str+'	</div>';
					str=str+'</div>';					
					container.prepend(str+"\n");
				}
			}
			tabContainer=$('#'+id);
		}
	}
	return container;
};
kb.timeUntill=function(timestamp){
	var time='';
	var d=Math.floor(new Date().getTime()/1000);
	if(d>timestamp){d=timestamp;}
	var seconds=timestamp-d;
	var minutes=Math.floor(seconds/60);
	if(minutes>0){
		time=time+''+minutes+'m ';
		seconds=Math.floor(seconds-(minutes*60));
	}
	if(seconds===0){
		time=time+'0s';
	}
	else{
		time=time+Math.ceil(seconds)+'s';
	}
	return time;
};
kb.timeSince=function(timestamp){
	var time='';
	var d=Math.floor(new Date().getTime()/1000);
	if(d<timestamp){timestamp=d;}
	var seconds=d-timestamp;
	var minutes=Math.floor(seconds/60);
	if(minutes>0){
		time=time+''+minutes+'m ';
		seconds=Math.floor(seconds-(minutes*60));
	}
	if(seconds>0){
		time=time+Math.ceil(seconds)+'s';
	}
	return time;
};
kb.mapMove=function(x,y){
	kb.scriptAdd('cm.formatModel.jumpTo('+x+','+y+');');
};
kb.bookmarkAdd=function(x,y,title){
	var me=this;
	if(!title || title===''){
		title='location';
	}
	var tid=kb.convertCoordToTile(x,y);
	kb.scriptAdd('setBookmarkLocation('+tid+',"'+title+'");');
};
kb.bookmarkDelete=function(x,y){
	var args = {};
	args.requestType='GET_BOOKMARK_INFO';
	var json=kb.sendToKabam(args,'tileBookmark');
	if(json && json.ok && json.bookmarkInfo){
		for(var i in json.bookmarkInfo){
			var bookmark=json.bookmarkInfo[i];
			if(bookmark.bookmarkId && bookmark.xCoord && bookmark.yCoord){
				if(1*bookmark.xCoord==x && 1*bookmark.yCoord==y){
					kb.scriptAdd('deleteBookmark(null,'+(1*bookmark.bookmarkId)+');');
				}
			}
		}
	}
};
kb.convertCoordToTile=function(x,y){
	if(x<0 || x>749 || y<0 || y>749){return 0;}
	if(x>299 && y>299 && x<450 && y<450){return 0;}
	var tid=0;
	var xx=x*150;
	var yy=Math.floor(y/150);
	tid=tid+(yy*112500);
	var yyy=y-(yy*150);
	tid=tid+xx+(yyy);
	if(x>449 || y>449){
		tid=tid-22500;
	}
	tid++;
	return tid;
};

//extensions
kb.ext=[];
kb.ext["debug"]={};
kb.ext["debug"].title='Debug';
kb.ext["debug"].version=1;
kb.ext["debug"].init=function(){
	var container=kb.addTab(['kocbyte.com','Debug']);
	if(container && container.length>0){
		container.append('<br /><pre id="'+kb.elemPrefix+'-tabs-kocbyte-debug-action-result">Debug text goes here</pre>');
		//add buttons
		container.prepend('<button id="'+kb.elemPrefix+'-tabs-kocbyte-debug-display-throne">Throne</button>');
		container.prepend('<button id="'+kb.elemPrefix+'-tabs-kocbyte-debug-display-thronestatus">Throne status</button>');
		container.prepend('<button id="'+kb.elemPrefix+'-tabs-kocbyte-debug-display-moderators">Moderators Ids</button>');
		container.prepend('<button id="'+kb.elemPrefix+'-tabs-kocbyte-debug-display-info">Info</button>');
		container.prepend('<button id="'+kb.elemPrefix+'-tabs-kocbyte-debug-display-seed">Seed</button>');
		//add button hooks
		var elem;
		elem=$('#'+kb.elemPrefix+'-tabs-kocbyte-debug-display-seed'); if(elem.length==1){ elem.click(function(){ kb.ext["debug"].showSeed(); }); }
		elem=$('#'+kb.elemPrefix+'-tabs-kocbyte-debug-display-moderators'); if(elem.length==1){ elem.click(function(){ kb.ext["debug"].showModerators(); }); }
		elem=$('#'+kb.elemPrefix+'-tabs-kocbyte-debug-display-thronestatus'); if(elem.length==1){ elem.click(function(){ kb.ext["debug"].showThroneStatus(); }); }
		elem=$('#'+kb.elemPrefix+'-tabs-kocbyte-debug-display-throne'); if(elem.length==1){ elem.click(function(){ kb.ext["debug"].showThrone(); }); }
		elem=$('#'+kb.elemPrefix+'-tabs-kocbyte-debug-display-info'); if(elem.length==1){ elem.click(function(){ kb.ext["debug"].showInfo(); }); }
	}
	else{
		kb.log('debug container missing');
	}
};
kb.ext["debug"].showSeed=function(){
	var json=kb.getSeed();
	$('#'+kb.elemPrefix+'-tabs-kocbyte-debug-action-result').html('<div>'+JSON.stringify(json, null, "\t")+'</div>');
};
kb.ext["debug"].showModerators=function(){
	var arr=kb.getModerators();
	var str='';
	for(var i in arr){
		str=str+"\n"+arr[i];
	}
	$('#'+kb.elemPrefix+'-tabs-kocbyte-debug-action-result').html('<div>'+str+'</div>');	
};
kb.ext["debug"].showThrone=function(){
	var json=kb.getThroneItems();
	$('#'+kb.elemPrefix+'-tabs-kocbyte-debug-action-result').html('<div>'+JSON.stringify(json, null, "\t")+'</div>');	
};
kb.ext["debug"].showThroneStatus=function(){
	var json=kb.getThroneStatus();
	$('#'+kb.elemPrefix+'-tabs-kocbyte-debug-action-result').html('<div>'+JSON.stringify(json, null, "\t")+'</div>');
};
kb.ext["debug"].showInfo=function(){
	var json=kb.getAjaxParams();
	$('#'+kb.elemPrefix+'-tabs-kocbyte-debug-action-result').html('<div>'+JSON.stringify(json, null, "\t")+'</div>');	
};
kb.ext["log"]={};
kb.ext["log"].init=function(){
	var container = kb.addTab(['kocbyte.com','Log','Traffic']);
	if(container && container.length>0){
		container.append('<pre id="'+kb.elemPrefix+'-tabs-kocbyte-log-traffic-result"></pre>');
	}
	var container = kb.addTab(['kocbyte.com','Log','Generic']);
	if(container && container.length>0){
		container.append('<pre id="'+kb.elemPrefix+'-tabs-kocbyte-log-generic-result"></pre>');
		kb.log('Started');
	}
};
kb.ext["website"]={};
kb.ext["website"].init=function(){
	var container = kb.addTab(['kocbyte.com','Website']);
	if(container && container.length>0){
		container.append('<button id="'+kb.elemPrefix+'-tabs-kocbyte-website-updateinfo"><span data-localize="eng">Send info</span></button>');
		$('#'+kb.elemPrefix+'-tabs-kocbyte-website-updateinfo').click(function(){
			kb.send_info(1);
		});
	}
};

var AutoUpdater = {
    id: 19269,
	URL: 'https://greasyfork.org/en/scripts/19269-kocbyte/code/KoCByte.user.js',
	name: 'KoCByte',
	homepage: 'https://greasyfork.org/en/scripts/19269-kocbyte',
    version: kb.scriptVer,
    call: function(response) { kb.log("Checking for "+this.name+" Update!");
		_s = this;
		GM_xmlhttpRequest({
            method: 'GET',
			url: _s.URL,
			onload: function(xpr) {_s.compare(xpr,response);},
            onerror: function(xpr) {_s.compare({responseText:""},response);}
        });
    },
    compareVersion: function(remoteVer, localVer) {
		return (remoteVer !== localVer) ? remoteVer > localVer :false;
    },
    compare: function(xpr,response) {
        this.xversion=(/@version\s*(.*?)\s*$/m.exec(xpr.responseText));   
        if(this.xversion){
			this.xversion = this.xversion[1];
		}else{
			if(response){
				uW.Modal.showAlert('<div align="center">Unable to check for updates to '+this.name+'.<br>Please change the update options or visit the<br><a href="'+this.homepage+'" target="_blank">script homepage</a></div>');
			}
			kb.log("Unable to check for updates");
			return;
		}
        this.xrelnotes=/\/\/\s*@releasenotes\s+(.+)\s*\n/i.exec(xpr.responseText);   
        if (this.xrelnotes) this.xrelnotes = this.xrelnotes[1];
        var updated = this.compareVersion(this.xversion, this.version);   
        if (updated) {
			kb.log('New Version Available!');                  
 			var body = '<BR><DIV align=center><FONT size=3><B>New version '+this.xversion+' is available!</b></font></div><BR>';
			if (this.xrelnotes){
				body+='<BR><div align="center" style="border:0;width:470px;height:120px;max-height:120px;overflow:auto"><b>New Features!</b><p>'+this.xrelnotes+'</p></div><BR>';
			}
 			body+='<BR><DIV align=center><a class="gemButtonv2 green" id="doBotUpdate">Update</a></div>';
 			this.ShowUpdate(body);
        }else{
			kb.log("No updates available :(");
			if(response){
				uW.Modal.showAlert('<div align="center">No updates available for '+this.name+' at this time.</div>');
			}
        } 		
    },
    check: function() {
    	var now = uW.unixtime();
    	var lastCheck = 0;
    	if (GM_getValue('updated_'+this.id, 0)) lastCheck = parseInt(GM_getValue('updated_'+this.id, 0));
		if (now > (lastCheck + 60*1)) this.call(false);
    },
	ShowUpdate: function (body) {
		var now = uW.unixtime();	 
		uW.cm.ModalManager.addMedium({
			title: this.name,
			body: body,
			closeNow: false,
			close: function (){
				setTimeout (function (){GM_setValue('updated_'+AutoUpdater.id, now);}, 0);
				uW.cm.ModalManager.closeAll();
			},
			"class": "Warning",
			curtain: false,
			width: 500,
			height: 700,
			left: 140,
			top: 140
		});
		document.getElementById('doBotUpdate').addEventListener('click', this.doUpdate, false);   
	},
	doUpdate: function () {
		uW.cm.ModalManager.closeAll();
		uW.cm.ModalManager.close();
		var now = uW.unixtime();
		GM_setValue('updated_'+AutoUpdater.id, now);
		GM_openInTab(AutoUpdater.URL);
	},
};

kb.log('KoCByte Starting');
kb.initTimeRemaining=1*(new Date().getTime())+15*1000;
kb.elemPrefix='kb_'+kb.generateRandomNumber(0,65535);

var k=kb.storagePrefix+'lastsent_ajaxparams';
kb.setValue(k,kb.sendInfoDelay + 300);
setTimeout(function(){AutoUpdater.check();},15000);

if(kb.currentUrl.match('src/main_src.php')){//the game
	kb.display_iframe();
}else if(kb.currentUrl.match('apps.facebook.com/kingdomsofcamelot/')){//facebook app page
	kb.display_fbpage();
}else if(kb.currentUrl.match('www.kabam.com/kingdoms-of-camelot/play')){//standalone game
	kb.display_standalonepage();
}else{//websites
	kb.display_website();
}