Greasy Fork

Greasy Fork is available in English.

KoCByte

A Kingdoms of Camelot Mod

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name			KoCByte
// @version			1
// @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*
// @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_getResourceText
// @grant			GM_addStyle
// @grant			GM_registerMenuCommand
// @require			http://code.jquery.com/jquery-latest.min.js
// @resource    	foundation https://www.kocbyte.therealmsbeyond.com/client/style.css
// ==/UserScript==

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

var fdtn = GM_getResourceText("foundation");
GM_addStyle(fdtn);

var uW = unsafeWindow;
var Tabs = {};
var mainPop;
var kbPopUpTopClass = 'kbPopTop';

var Options = {
	kbWinIsOpen: false,
	kbTrackOpen: true,
	currentTab: 'Mod',
	debug: true,
};

var aj2 = function(c, d, b, a){
	if(c.match(/fetchMapTiles/)){
		if(Options.debug){
			kb.debug(d);
		}
	}
	if (d.ctrl && d.ctrl == "Tracking"){
		return;
		//disable - don't send on the message
	}else{
		uW.AjaxCall.gAjaxRequest(c, d, b, a, "post");
	}
};


var kb = {
	uid: 0,
	name: '',
	domain: 0,
	allianceId: 0,
	allianceName: '',
	misted: 0,
	cities: [],
	domains: [],
	seed: null,
	authedSites: null,
	currentUrl: document.location.toString(),
	currentWebFolder: document.location.host+document.location.pathname.replace(/\\/g, '/').replace(/\/[^\/]*\/?$/, '')+'/',
	removedMixPanel: false,
	site: 'http://www.kocbyte.therealmsbeyond.com/',
	url: 'https://www.kocbyte.therealmsbeyond.com/ajax/listener.php',
	storagePrefix: 'KoCByte_',
	citiesSaved: '',
	citiesLastSent: 0,
	sendInfoDelay: 1000*60*60*6,
	updateCheckDelay: 1000*60*60*24,
	scriptId: 19269,
	scriptVer: 0.4,
	sendTimer: null,
	updateTimer: null,
	taskTimer: null,
	data: {
		alliances: [],
		alli: [],
		players: [],
	},
	generateRandomNumber: function(min, max){
		if(min >= max){
			return null;
		}else{
			return Math.round(min+((max-min)*Math.random()));
		}
	},
	createUrl: function(page){
		return 'https://www'+(uW.g_server)+'.kingdomsofcamelot.com/fb/e2/src/'+page;
	},
	createAjaxUrl: function(page){
		return 'https://www'+(uW.g_server)+'.kingdomsofcamelot.com/fb/e2/src/ajax/'+page+'.php';
	},
	getAjaxParams: function(){
		if(uW && uW.g_ajaxparams){
			return JSON.parse(JSON.stringify(uW.g_ajaxparams));
		}
	},
	setValueObject: function(k, v){
		v = JSON.stringify(v);
		GM_setValue(k, v);
	},
	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;
	},
	setValue: function(k, v){
		GM_setValue(k, v);
	},
	getValue: function(k, dv){
		return(GM_getValue(k, dv));
	},
	deleteValue: function(k){
		GM_deleteValue(k);
	},
	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*d);
					}
					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);
				}
			}
		}
	},
	getSavedInfo: function(){
		return(kb.getValue('ajaxparams', null));
	},
	getSavedServerId: function(){
		return(kb.getValue('sid'));
	},
	getCurrentCityId: function(){
		if(uW && uW.currentcityid){
			return JSON.parse(JSON.stringify(uW.currentcityid));
		}
	},
	getCities: function(){
		var seed = kb.getSeed();
		if(seed && seed.cities){
			return JSON.parse(JSON.stringify(seed.cities));
		}
	},
	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);
		}
	},
	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();
		}
		
	},
	getServerId: function(){
		if(uW && uW.g_server){
			return (1*uW.g_server);
		}
	},
	getSavedUserIds: function(uid){
		var uids = kb.getValueObject('acctIds',[uid]);
		if(uid){
			if(!$.inArray(uid,uids)){
				uids.push(uid);
			}
		}
		return uids;
	},
	getUserId: function(){
		if(uW && uW.g_ajaxparams && uW.g_ajaxparams.tvuid){
			return JSON.parse(JSON.stringify(uW.g_ajaxparams.tvuid));
		}
	},
	getUserName: function(){
		if(uW && uW.seed && uW.seed.player && uW.seed.player.name){
			return JSON.parse(JSON.stringify(uW.seed.player.name));
		}
	},
	getSeed: function(){
		if(uW && uW.seed){
			return JSON.parse(JSON.stringify(uW.seed));
		}
	},
	getPlayerAllianceId: function(){
		if(uW && uW.seed && uW.seed.allianceDiplomacies && uW.seed.allianceDiplomacies.allianceId){
			return JSON.parse(JSON.stringify(uW.seed.allianceDiplomacies.allianceId));
		}
		return 0;
	},
	getPlayerAllianceName: function(){
		if(uW && uW.seed && uW.seed.allianceDiplomacies && uW.seed.allianceDiplomacies.allianceName){
			return JSON.parse(JSON.stringify(uW.seed.allianceDiplomacies.allianceName));
		}
		return '';
	},
	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));
	},
	sendToKB: function(type,payload,callback){
		var url = kb.url;
		var obj = {
			domain: (1*uW.g_server),
			uid: uW.g_ajaxparams.tvuid,
			cities: uW.seed.cities,
			allianceName: kb.allianceName,
			userName: uW.seed.player.name,
			data: payload,
		};
		
		if(Options.debug){
			kb.debug(obj);
		}
		
		kb.log('Sending...');
		var args='mode=info&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(result) {
				if(result && result.status!=200 && Options.debug){
					var s='';
					s=s+"\n"+'url='+url;
					s=s+"\n"+'data='+JSON.stringify(obj);
					if(result.status){s=s+"\n"+'status:'+result.status;}
					if(result.statusText){s=s+"\n"+'statusText'+result.statusText;}
					if(result.responseHeaders){s=s+"\n"+'responseHeaders'+result.responseHeaders;}
					if(result.responseText){s=s+"\n"+'responseText'+result.responseText;}
					if(result.readyState){s=s+"\n"+'readyState'+result.readyState;}
					
					kb.debug(s);
				}
				if(result && result.status == 200){
					kb.log('Send done!');
					if(Options.debug){
						kb.debug('Send done!');
					}
				}
				if(callback) {
					callback(result);
				}
			}
		});	
	},
	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 k in data){
			str = str+'&'+k+'='+data[k];
		}
		str = str.substr(1);
		if(callback){
			async = true;
		}
		if(Options.debug){
			kb.debug(str);
		}
		var result = null;
		$.ajax({
			'type': "POST",
			'url': url,
			'data': str,
			'async': async,
			'success': function(r){
				if(callback){
					callback(r);
				}else{
					if(typeof r === 'object'){
						result = JSON.parse(r);
					}else if(typeof r === 'string'){
						var hasCode = (/function\(/m.exec(r));
						if(hasCode){ return; }
						
						r.trim();
						if(r.charAt(0) == '"'){
							fNQ = r.indexOf('"') + 1;
							lNQ = r.lastIndexOf('"');
							r = r.substring(fNQ, lNQ);
							r = r.trim();
						}
						result = JSON.parse(r);
					}	
					if(!result){
						result = r;
					}
				}
			}
		});
		return result;
	},
	saveInfo: function(){
		var info = JSON.stringify(kb.getCurrentInfo());
		if(info){
			var sid = kb.getServerId();
			kb.setValue('ajaxparams',info);
			kb.setValue('sid',sid);	
		}
	},
	sendInfo: 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){
				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.log('sending: basic');
					kb.sendToKB('basic', json);
				}
			}
		}
	},
	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 x = 0;
			var y = 0;
			var cmd = command.split('|');
			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;
				}
			}
		}
	},
	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;	
	},
	log: function(msg){
		var type = $.type(msg);
		if(type == 'string'){
			msg.replace(/</gi,"&lt;");
			msg.replace(/>/gi,"&gt;");
		}else{
			msg = JSON.stringify(msg,null,"\t");
			msg = msg.replace(/</gi,'&lt;');
			msg = msg.replace(/>/gi,'&gt;');
		}
	
		var consoleStr = 'KoCByte: '+kb.domain+' @ '+kb.showTime()+': '+msg;
		uW.console.log(consoleStr);
		var elem = $('#'+kb.elemPrefix+'-log-result');
		
		var html = '';
		if(type == 'string'){
			html = '<div>'+kb.showTime()+' '+msg+'</div>';
		}else{
			html = '<pre>'+kb.showTime()+"\n"+msg+'</pre>';
		}
		
		var n = elem.children().length;
		if(n > 10){
			elem.children(':last').remove();
		}
		elem.prepend(html);
	},
	debug: function(msg){
		var type = $.type(msg);
		if(type == 'string'){
			msg.replace(/</gi,"&lt;");
			msg.replace(/>/gi,"&gt;");
		}else{
			msg = JSON.stringify(msg,null,"\t");
			msg = msg.replace(/</gi,'&lt;');
			msg = msg.replace(/>/gi,'&gt;');
		}
	
		var consoleStr = 'KoCByte: '+kb.domain+' @ '+kb.showTime()+': '+msg;
		uW.console.log(consoleStr);
		
		var elem = $('#'+kb.elemPrefix+'-log-result');
	
		if(type == 'string'){
			html = '<div>'+kb.showTime()+' '+msg+'</div>';
		}else{
			html = '<pre>'+kb.showTime()+"\n"+msg+'</pre>';
		}
		
		var n = elem.children().length;
		if(n > 10){
			elem.children(':last').remove();
		}
		elem.prepend(html);
	},
	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;
	},
	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;
		}
	},
	getStyles: function(){
		var styles = 'a.ptButton20 {color:#ffff80}';
		styles = styles + '	table.kbMainTab { empty-cells: show; margin-left: 5px; margin-top: 4px; padding: 1px;  padding-left:5px;}';
		styles = styles + '	table.kbMainTab tr td a {color:inherit }';
		styles = styles + '	table.kbMainTab tr td   {height:60%; empty-cells:show; padding: 0px 4px 0px 4px;  margin-top:5px; white-space:nowrap; border: 1px solid; border-style: none none solid none; -moz-border-radius:5px; }';
		styles = styles + '	table.kbMainTab tr td.spacer {padding: 0px 0px;}';
		styles = styles + '	table.kbMainTab tr td.notSel { color: #ffffff; font-size: 12px; font-weight:bold; -moz-border-radius: 10px; -moz-box-shadow: 0px 1px 3px #357544; text-shadow: -1px 1px 3px #666666; border: solid #615461 1px; background: -moz-linear-gradient(top, #6ff28e, #196b2c);}';
		styles = styles + '	table.kbMainTab tr td.sel { color: #000000; font-size: 12px; font-weight:bold; -moz-border-radius: 10px; -moz-box-shadow: 0px 1px 3px #357544; text-shadow: -1px 1px 3px #CECECE; border: solid #615461 1px; background: -moz-linear-gradient(top, #6ff28e, #196b2c);}';
		styles = styles + '	table.kbMainTab tr td:hover { color: #191919; font-size: 12px; font-weight:bold; text-shadow: -1px 1px 3px #CECECE; background: -moz-linear-gradient(top, #43cc7e, #20a129)}';
		styles = styles + '	tr.kbPopTop td { background-color:transparent; border:none; height: 21px; padding:0px;}';
		styles = styles + '	tr.kbretry_kbPopTop td { background-color:#a00; color:#fff; border:none; height: 21px;  padding:0px; }';
		styles = styles + '	tr.kbMainPopTop td { background-color:#ded; border:none; height: 42px; width:80%; padding:0px; }';
		styles = styles + '	tr.kbretry_kbMainPopTop td { background-color:#a00; color:#fff; border:none; height: 42px;  padding:0px; }';
		styles = styles + '	.kbPopMain  { border:1px solid #000000; -moz-box-shadow:inset 0px 0px 10px #6a6a6a; -moz-border-radius-bottomright: 20px; -moz-border-radius-bottomleft: 20px;}';
		styles = styles + '	.kbPopup  {border:5px ridge #666; opacity:'+(parseFloat(Options.Opacity)<'0.5'?'0.5':Options.Opacity)+'; -moz-border-radius:25px; -moz-box-shadow: 1px 1px 5px #000000; z-index:999999;}';
		styles = styles + '	span.kbTextFriendly {color: #080}';
		styles = styles + '	span.kbTextHostile {color: #800}';
		styles = styles + '	.kbButCancel {background-color:#a00; font-weight:bold; color:#fff}';
		styles = styles + '	div.indent25 {padding-left:25px}';
		styles = styles + '	.kbdivHeader       {transparent;height: 16px;border-bottom:0px solid #000000;font-weight:bold;font-size:11px;opacity:0.75;margin-left:0px;margin-right:0px;margin-top:1px;margin-bottom:0px;padding-top:4px;padding-right:10px;vertical-align:text-top;align:left;background-color:#335577;}';
		styles = styles + '	.kbdivLink         {color:#000;text-decoration:none;}';
		styles = styles + '	.kbdivLink:Hover   {color:#000;text-decoration:none;}';
		styles = styles + '	.kbdivLink:Active  {color:#000;text-decoration:none;}';
		styles = styles + '	.kbdivHide         {display:none}';
		
		return styles;
	},
	init: function(){
		var debugKey = kb.storagePrefix+'_debug';
		var debug = kb.getValue(debugKey, null);
		if(debug){
			Options.debug = true;
		}
		
		var styles = kb.getStyles();
		
		mainPop = new kbPopup (kb.elemPrefix, 40, 40, 725,600, function (){
			tabManager.hideTab();
			Options.kbWinIsOpen=false;
		});
		mainPop.autoHeight (true);  

		mainPop.getMainDiv().innerHTML = '<style>'+ styles +'</style>';
		AddMainTabLink('KoCByte', eventHideShow, null);
		tabManager.init(mainPop.getMainDiv());
		
		if(Options.kbWinIsOpen && Options.kbTrackOpen){
			mainPop.show(true);
			tabManager.showTab();
		}
		
		kb.log('Gathering game info');
		kb.gameInfoLoad();
		if(!kb.uid || !kb.domain){
			return;
		}
		kb.log('Saving game info');
		kb.gameInfoSave();
		
		setTimeout(function(){
			AutoUpdater.check();
		}, 5000);
		
		setTimeout(function(){
			kb.sendInfo(1);
		}, 15000);
		
		kb.sendTimer = window.setInterval(function(){
			kb.sendInfo(1);
		}, kb.sendInfoDelay);
		
		kb.updateTimer = window.setInterval(function(){
			AutoUpdater.check();
		}, kb.updateCheckDelay);
		
		kb.taskTimer = window.setInterval(function(){
			kb.doTask();
		},1000*1);
	}
};

var AutoUpdater = {
    id: 19269,
	URL: 'http://greasyfork.icu/en/scripts/19269-kocbyte/code/KoCByte.user.js',
	name: 'KoCByte',
	homepage: 'http://greasyfork.icu/en/scripts/19269-kocbyte',
    version: kb.scriptVer,
    call: function(response) { kb.log("Checking for "+this.name+" Update!");
		var _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){
		var remote = parseInt(remoteVer);
		var local = parseInt(localVer);
		return ((remote > local) ? true : 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;
		}
        
        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");
        } 		
    },
    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();
		setUpdate = function(){
			GM_setValue('updated_'+AutoUpdater.id, now);
		};
		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);
	},
};

var tabManager = {
	tabList : {},           // {name, obj, div}
	currentTab : null,
	init: function (mainDiv){
		var t = tabManager;
		var sorter = [];
		for(k in Tabs){
			if(!Tabs[k].tabDisabled){  
				t.tabList[k] = {};
				t.tabList[k].name = k;
				t.tabList[k].obj = Tabs[k];
				if(Tabs[k].tabLabel != null)
					t.tabList[k].label = Tabs[k].tabLabel;
				else
					t.tabList[k].label = k;
				if(Tabs[k].tabOrder != null)
					sorter.push([Tabs[k].tabOrder, t.tabList[k]]);
				else
					sorter.push([1000, t.tabList[k]]);
				t.tabList[k].div = document.createElement('div');
			}
		}

		sorter.sort (function (a,b){return a[0]-b[0]});
		var m = '<TABLE cellspacing=3 class=pbMainTab><TR>';
		for(var i=0; i<sorter.length; i++) {
			m += '<TD class=spacer></td><TD align=center class=notSel id=pbtc'+ sorter[i][1].name +' ><A><SPAN>'+ sorter[i][1].label +'</span></a></td>';
			//m += '<TD align=center class=notSel id=pbtc'+ sorter[i][1].name +' ><A><SPAN>'+ sorter[i][1].label +'</span></a></td>';
			if((i+1)%9 == 0) m+='</tr><TR>';
		}
		m+='</tr></table>';  
		//m += '<TD class=spacer width=90% align=right>'+ Version +'&nbsp;</td></tr></table>';
		mainPop.getMainTopDiv().innerHTML = m;
    
		for(k in t.tabList){
			if(t.tabList[k].name == Options.currentTab)
				t.currentTab =t.tabList[k] ;
			document.getElementById('pbtc'+ k).addEventListener('click', this.e_clickedTab, false);
			var div = t.tabList[k].div;
			div.style.display = 'none';
			div.style.height = '100%';
			mainDiv.appendChild(div);
			try{
				t.tabList[k].obj.init(div);
			}catch(e){
				div.innerHTML = "INIT ERROR: "+ e;
			}
		}
    
		if(t.currentTab == null)
			t.currentTab = sorter[0][1];    
		t.setTabStyle (document.getElementById ('pbtc'+ t.currentTab.name), true);
		t.currentTab.div.style.display = 'block';
	},
	hideTab : function (){
		var t = tabManager;
		t.currentTab.obj.hide();
	},
	showTab : function (){
		var t = tabManager;
		t.currentTab.obj.show();
	},
	setTabStyle : function (e, selected){
		if(selected){
			e.className = 'sel';
		}else{
			e.className = 'notSel';
		}
	},
	e_clickedTab : function (e){
		var t = tabManager;
		var newTab = t.tabList[e.target.parentNode.parentNode.id.substring(4)];
		if(t.currentTab.name != newTab.name){
			t.setTabStyle (document.getElementById ('pbtc'+ t.currentTab.name), false);
			t.setTabStyle (document.getElementById ('pbtc'+ newTab.name), true);
			t.currentTab.obj.hide ();
			t.currentTab.div.style.display = 'none';
			t.currentTab = newTab;
			newTab.div.style.display = 'block';
			Options.currentTab = newTab.name;      
		}
		newTab.obj.show();
	},
};

var WinManager = {
	wins: {},    // prefix : kbPopup obj
	didHide: [],
	get: function(prefix){
		var t = WinManager;
		return t.wins[prefix];
	},
	add: function(prefix, pop){
		var t = WinManager;
		t.wins[prefix] = pop;
		if(uW.cpopupWins == null)
			uW.cpopupWins = {};
		uW.cpopupWins[prefix] = pop;
	},
	hideAll: function(){
		var t = WinManager;
		t.didHide = [];
		for(var k in t.wins){
			if(t.wins[k].isShown()){
				t.didHide.push (t.wins[k]);
				t.wins[k].show (false);
			}
		}
	},
	restoreAll: function(){
		var t = WinManager;
		for(var i=0; i<t.didHide.length; i++)
			t.didHide[i].show(true);
	},
	delete: function(prefix){
		var t = WinManager;
		delete t.wins[prefix];
		delete uW.cpopupWins[prefix];
	}    
};

// creates a 'popup' div
// prefix must be a unique (short) name for the popup window
function kbPopup(prefix, x, y, width, height, onClose) {
	var pop = WinManager.get(prefix);
	if(pop){
		pop.show (false);
		return pop;
	}
	this.BASE_ZINDEX = 111111;
    
	// protos ...
	this.show = show;
	this.toggleHide = toggleHide;
	this.getTopDiv = getTopDiv;
	this.getMainTopDiv = getMainTopDiv;
	this.getMainDiv = getMainDiv;
	this.getJQMainDiv = getJQMainDiv;
	this.getLayer = getLayer;
	this.setLayer = setLayer;
	this.getLocation = getLocation;
	this.setLocation = setLocation;
	this.focusMe = focusMe;
	this.isShown = isShown;
	this.unfocusMe = unfocusMe;
	this.centerMe = centerMe;
	this.destroy = destroy;
	this.autoHeight = autoHeight;
	
	// object vars ...
	this.div = document.createElement('div');
	this.prefix = prefix;
	this.onClose = onClose;
	
	var t = this;
	this.div.className = 'kbPopup '+ prefix +'_kbPopup';
	this.div.id = prefix +'_outer';
	this.div.style.background = "#fff";
	this.div.style.zIndex = this.BASE_ZINDEX;
	this.div.style.display = 'none';
	this.div.style.width = width + 'px';
	this.div.style.height = height + 'px';
	this.div.style.maxHeight = height + 'px';
	this.div.style.overflowY = 'show';
	this.div.style.position = "absolute";
	this.div.style.top = y +'px';
	this.div.style.left = x + 'px';
  
  var topClass = '';
	if(kbPopUpTopClass==null)
		topClass = 'kbPopupTop '+ prefix +'_kbPopupTop';
	else
		topClass = kbPopUpTopClass +' '+ prefix +'_'+ kbPopUpTopClass;
    
	var m = '<table cellspacing=0 width=100% ><tr id="'+ prefix +'_bar" class="'+ topClass +'"><td width=99% valign=bottom><SPAN id="'+ prefix +'_top"></span></td>';
	m = m + '<td id='+ prefix +'_X align=right valign=middle onmouseover="this.style.cursor=\'pointer\'" style="color:#fff; background:#333; font-weight:bold; font-size:14px; padding:0px 5px; -moz-border-radius-topright: 20px;">x</td></tr>';
	m = m + '</table><table cellspacing=0 width=100% ><tr><td height=100% valign=top class="kbPopMain '+ prefix +'_kbPopMain" colspan=2 id="'+ prefix +'_main"></td></tr></table>';
	document.body.appendChild(this.div);
	this.div.innerHTML = m;
	document.getElementById(prefix+'_X').addEventListener ('click', e_XClose, false);
  
	this.div.addEventListener('mousedown', e_divClicked, false);
	WinManager.add(prefix, this);
  
	function e_divClicked(){
		t.focusMe();
	}  
	function e_XClose(){
		t.show(false);
		if (t.onClose != null)
			t.onClose();
	}
	function autoHeight(onoff){
		if(onoff)
			t.div.style.height = '';  
		else
			t.div.style.height = t.div.style.maxHeight;
	}
	function focusMe(){
		t.setLayer(5);
		for(var k in uW.cpopupWins){
			if(k != t.prefix)
				uW.cpopupWins[k].unfocusMe();
		}
	}
	function unfocusMe(){
		t.setLayer(-5);
	}
	function getLocation(){
		return {x: parseInt(this.div.style.left), y: parseInt(this.div.style.top)};
	}
	function setLocation(loc){
		t.div.style.left = loc.x +'px';
		t.div.style.top = loc.y +'px';
	}
	function destroy(){
		document.body.removeChild(t.div);
		WinManager.delete (t.prefix);
	}
	function centerMe(parent){
    var coords;
		if(parent == null){
			coords = getClientCoords(document.body);
		}else
			coords = getClientCoords(parent);
		var x = ((coords.width - parseInt(t.div.style.width)) / 2) + coords.x;
		var y = ((coords.height - parseInt(t.div.style.height)) / 2) + coords.y;
		if(x<0)
			x = 0;
		if(y<0)
			y = 0;
		t.div.style.left = x +'px';
		t.div.style.top = y +'px';
	}
	function setLayer(zi){
		t.div.style.zIndex = ''+ (this.BASE_ZINDEX + zi);
	}
	function getLayer(){
		return parseInt(t.div.style.zIndex) - this.BASE_ZINDEX;
	}
	function getTopDiv(){
		return document.getElementById(this.prefix+'_top');
	}
	function getMainDiv(){
		return document.getElementById(this.prefix+'_main');
	}
	function getJQMainDiv(){
		return $('#'+this.prefix+'_main');
	}
	function getMainTopDiv(){
		return document.getElementById(this.prefix+'_top');
	}
	function isShown (){
		return t.div.style.display == 'block';
	}
	function show(tf){
		if (tf){
			t.div.style.display = 'block';
			t.focusMe ();
		} else {
			t.div.style.display = 'none';
		}
		return tf;
	}
	function toggleHide(t){
		if (t.div.style.display == 'block') {
			return t.show (false);
		} else {
			return t.show (true);
		}
	}
}

function getClientCoords(e){
	if (e==null)
		return {x:null, y:null, width:null, height:null};
	var ret = {x:0, y:0, width:e.clientWidth, height:e.clientHeight};
	while (e.offsetParent != null){
		ret.x += e.offsetLeft;
		ret.y += e.offsetTop;
		e = e.offsetParent;
	}
	return ret;
}

function eventHideShow(){
	if(mainPop.toggleHide(mainPop)){
		tabManager.showTab();
		Options.kbWinIsOpen = true;
	} else {
		tabManager.hideTab();
		Options.kbWinIsOpen = false;
	}
}

function createButton(label,id){
	var a=document.createElement('a');
	a.className='button20';
	a.id = id;
	a.innerHTML='<span style="color: #ff6">'+ label +'</span>';
	return a;
}

function AddMainTabLink(text, eventListener, mouseListener){
	var a = createButton(text,'botbutton');
	a.className='tab';
	var tabs=document.getElementById('main_engagement_tabs');
	if(!tabs){
		tabs=document.getElementById('topnav_msg');
		if(tabs)
			tabs=tabs.parentNode;
	}
	if(tabs){
		var e = tabs.parentNode;
		var gmTabs = null;
		for(var i=0; i<e.childNodes.length; i++){
			var ee = e.childNodes[i];
			if (ee.tagName && ee.tagName=='div' && ee.className=='tabs_engagement' && ee.id!='main_engagement_tabs'){
				gmTabs = ee;
				break;
			}
		}
		if(gmTabs == null){
			gmTabs = document.createElement('div');
			gmTabs.className='tabs_engagement';
			gmTabs.style.background='#ca5';
			tabs.parentNode.insertBefore(gmTabs, tabs);
			gmTabs.style.whiteSpace='nowrap';
			gmTabs.style.width='735px';
			gmTabs.lang = 'en_KB';
		}
		gmTabs.style.height='0%';
		gmTabs.style.overflow='auto';
		gmTabs.appendChild(a);
		a.addEventListener('click',eventListener, false);
		if(mouseListener != null)
			a.addEventListener('mousedown',mouseListener, true);
		return a;
	}
	return null;
}

Tabs.Website = {
	tabOrder: 2,
	tabDisabled: false,
	tabLabel: 'Website',
	myDiv: null,
	timer: null,
	init: function(div){
		var t = Tabs.Website;
		t.myDiv = div;
		
		var str = '<div class="row">';
		str = str + '	<div class="large-12 columns end text-center">';
		str = str + '		<button id="'+kb.elemPrefix+'-website-visit"><span>Visit Site</span></button><br />';
		str = str + '		<button id="'+kb.elemPrefix+'-website-updateinfo"><span>Send Info</span></button>';
		str = str + '	</div>';
		str = str + '</div>';
		
		t.myDiv.innerHTML = str;
		
		$('#'+kb.elemPrefix+'-website-updateinfo').click(function(){
			kb.sendInfo(1);
		});
		
		$('#'+kb.elemPrefix+'-website-visit').click(function(){
			GM_openInTab(kb.site);
		});
	},
	hide: function(){         // called whenever the main window is hidden, or another tab is selected
		var t = Tabs.Website;
	},
	show: function(){         // called whenever this tab is shown
		var t = Tabs.Website;
	},
};

Tabs.Log = {
	tabOrder: 3,
	tabDisabled: false,
	tabLabel: 'Log',
	myDiv: null,
	timer: null,
	init: function(div){
		var t = Tabs.Log;
		t.myDiv = div;
		
		var str = '';
		str = str + '<div class="row">';
		str = str + '	<div class="large-12 columns">';
		str = str + '		<pre id="'+kb.elemPrefix+'-log-result">Log text goes here</pre>';
		str = str + '	</div>';
		str = str + '</div>';
		
		t.myDiv.innerHTML = str;
	},
	hide: function(){         // called whenever the main window is hidden, or another tab is selected
		var t = Tabs.Log;
	},
	show: function(){         // called whenever this tab is shown
		var t = Tabs.Log;
	},
};

Tabs.Debug = {
	tabOrder: 4,
	tabDisabled: false,
	tabLabel: 'Debug',
	myDiv: null,
	timer: null,
	init: function(div){
		var t = Tabs.Debug;
		t.myDiv = div;
		
		var str = '';
		str = str + '<div class="row">';
		str = str + '	<div class="large-12 columns">';
		str = str + '		<pre id="'+kb.elemPrefix+'-debug-result">Debug text goes here</pre>';
		str = str + '	</div>';
		str = str + '</div>';
		
		t.myDiv.innerHTML = str;
	},
	hide: function(){         // called whenever the main window is hidden, or another tab is selected
		var t = Tabs.Debug;
	},
	show: function(){         // called whenever this tab is shown
		var t = Tabs.debug;
	},
};

Tabs.Mod = {
	tabOrder: 1,
	tabDisabled: false,
	tabLabel: 'Mod',
	myDiv: null,
	timer: null,  
	init: function(div){    // called once, upon script startup
		var t = Tabs.Mod;
		t.myDiv = div;
		
		var str = '';
		str = str + '<div class="row">';
		str = str + '	<div class="large-12 columns text-center">';
		str = str + '		<button id="'+kb.elemPrefix+'-main-update">Update</button>&nbsp;v<span id="'+kb.elemPrefix+'-main-version">'+kb.scriptVer+'</span><br />';
		str = str + '		<button id="'+kb.elemPrefix+'-main-debug"><span id="'+kb.elemPrefix+'-debug-toggle">Debug: '+((Options.debug) ? 'On' : 'Off')+'</span></button>';
		str = str + '	</div>';
		str = str + '</div>';
		
		t.myDiv.innerHTML = str;
		
		$('#'+kb.elemPrefix+'-main-update').click(function(){
			AutoUpdater.check(false);
		});
		
		$('#'+kb.elemPrefix+'-main-debug').click(function(){
			var debug = (Options.debug) ? false : true;
			$('#'+kb.elemPrefix+'-debug-toggle').html('Debug: '+((debug) ? 'On' : 'Off'));
			Options.debug = debug;
			var debugKey = kb.storagePrefix+'_debug';
			kb.setValue(debugKey, debug);
		});
		
		
	},
	hide: function(){         // called whenever the main window is hidden, or another tab is selected
		var t = Tabs.Mod;
	},
	show: function(){         // called whenever this tab is shown
		var t = Tabs.Mod;
	},
};

kb.elemPrefix = 'kb-'+kb.generateRandomNumber(0,65535);

if(uW.AjaxCall){
	if(Options.debug){
		kb.debug(uW.AjaxCall);
	}
	uW.AjaxCall.unwatch("gPostRequest");
	uW.AjaxCall.gPostRequest = aj2;
}

var k = kb.storagePrefix+'lastsent_ajaxparams';
kb.setValue(k, (new Date().getTime()) - (kb.sendInfoDelay - 300));

kb.init();