Greasy Fork

Greasy Fork is available in English.

KoCByte

A Kingdoms of Camelot Mod

当前为 2016-05-03 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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 : 'http://greasyfork.icu/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('http://greasyfork.icu/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: 'http://greasyfork.icu/scripts/'+this.id+'-kocbyte/code/KoCByte.user.js',
	name: 'KoCByte',
	homepage: 'http://greasyfork.icu/en/scripts/'+this.id+'-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(r_version, l_version) {
            var r_parts = r_version.split(''),
            l_parts = l_version.split(''),
            r_len = r_parts.length,
            l_len = l_parts.length,
            r = l = 0;
            for(var i = 0, len = (r_len > l_len ? r_len : l_len); i < len && r == l; ++i) {
                r = +(r_parts[i] || '0');
                l = +(l_parts[i] || '0');
            }
            return (r !== l) ? r > l : false;
    },
    compare: function(xpr,response) {
        this.xversion=/\/\/\s*@version\s+(.+)\s*\n/i.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 = unixTime();
    	var lastCheck = 0;
    	if (GM_getValue('updated_'+this.id, 0)) lastCheck = parseInt(GM_getValue('updated_'+this.id, 0));
		if (now > (lastCheck + 60*60*12)) this.call(false);
    },
	ShowUpdate: function (body) {
		var now = 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 = unixTime();
		GM_setValue('updated_'+AutoUpdater.id, now);
		var DownloadURL = AutoUpdater.URL;
		location.href = 'https://'+DownloadURL;
	},
};

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();
}