KoCByte

A Kingdoms of Camelot Tracker (Kocmon replacement)

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

  1. // ==UserScript==
  2. // @name KoCByte
  3. // @version 1.1
  4. // @description A Kingdoms of Camelot Tracker (Kocmon replacement)
  5. // @namespace kocbyte.com
  6. // @icon http://www.gravatar.com/avatar/f93cdced9c9b863a7d9e4b9988886015
  7. // @include *.kocbyte.com/*
  8. // @include *.kingdomsofcamelot.com/fb/e2/src/main_src.php*
  9. // @grant unsafeWindow
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @grant GM_deleteValue
  13. // @grant GM_xmlhttpRequest
  14. // @grant GM_openInTab
  15. // @grant GM_log
  16. // @grant GM_listValues
  17. // @grant GM_getResourceText
  18. // @grant GM_addStyle
  19. // @grant GM_registerMenuCommand
  20. // @require http://code.jquery.com/jquery-latest.min.js
  21. // @resource foundation https://www.kocbyte.therealmsbeyond.com/client/style.css
  22. // ==/UserScript==
  23.  
  24. //============================================================================
  25.  
  26. var fdtn = GM_getResourceText("foundation");
  27. GM_addStyle(fdtn);
  28.  
  29. var uW = unsafeWindow;
  30. var Tabs = {};
  31. var mainPop;
  32. var kbPopUpTopClass = 'kbPopTop';
  33.  
  34. var Options = {
  35. kbWinIsOpen: false,
  36. kbTrackOpen: true,
  37. currentTab: 'Mod',
  38. debug: true,
  39. };
  40.  
  41. var aj2 = function(c, d, b, a){
  42. if(c.match(/fetchMapTiles/)){
  43. if(Options.debug){
  44. kb.debug(d);
  45. }
  46. }
  47. if (d.ctrl && d.ctrl == "Tracking"){
  48. return;
  49. //disable - don't send on the message
  50. }else{
  51. uW.AjaxCall.gAjaxRequest(c, d, b, a, "post");
  52. }
  53. };
  54.  
  55.  
  56. var kb = {
  57. uid: 0,
  58. name: '',
  59. domain: 0,
  60. allianceId: 0,
  61. allianceName: '',
  62. misted: 0,
  63. cities: [],
  64. domains: [],
  65. seed: null,
  66. target: {
  67. x: 0,
  68. y: 0
  69. },
  70. authedSites: null,
  71. currentUrl: document.location.toString(),
  72. currentWebFolder: document.location.host+document.location.pathname.replace(/\\/g, '/').replace(/\/[^\/]*\/?$/, '')+'/',
  73. removedMixPanel: false,
  74. site: 'https://www.kocbyte.com/',
  75. url: 'https://www.kocbyte.com/ajax/listener.php',
  76. storagePrefix: 'KoCByte_',
  77. citiesSaved: '',
  78. citiesLastSent: 0,
  79. sendInfoDelay: 1000*60*60*6,
  80. updateCheckDelay: 1000*60*60*24,
  81. scriptId: 19269,
  82. scriptVer: 1.1,
  83. sendTimer: null,
  84. updateTimer: null,
  85. taskTimer: null,
  86. data: {
  87. alliances: [],
  88. alli: [],
  89. players: [],
  90. },
  91. generateRandomNumber: function(min, max){
  92. if(min >= max){
  93. return null;
  94. }else{
  95. return Math.round(min+((max-min)*Math.random()));
  96. }
  97. },
  98. createUrl: function(page){
  99. return 'https://www'+(uW.g_server)+'.kingdomsofcamelot.com/fb/e2/src/'+page;
  100. },
  101. createAjaxUrl: function(page){
  102. return 'https://www'+(uW.g_server)+'.kingdomsofcamelot.com/fb/e2/src/ajax/'+page+'.php';
  103. },
  104. getAjaxParams: function(){
  105. if(uW && uW.g_ajaxparams){
  106. return JSON.parse(JSON.stringify(uW.g_ajaxparams));
  107. }
  108. },
  109. setValueObject: function(k, v){
  110. v = JSON.stringify(v);
  111. GM_setValue(k, v);
  112. },
  113. getValueObject: function(k, dv){
  114. var v = GM_getValue(k, dv);
  115. if(!v || v === undefined){
  116. return null;
  117. }
  118. v = JSON.parse(v);
  119. if(!v){
  120. if(!dv){
  121. v = null;
  122. }
  123. else{
  124. v = dv;
  125. }
  126. }
  127. return v;
  128. },
  129. setValue: function(k, v){
  130. GM_setValue(k, v);
  131. },
  132. getValue: function(k, dv){
  133. return(GM_getValue(k, dv));
  134. },
  135. deleteValue: function(k){
  136. GM_deleteValue(k);
  137. },
  138. getDomains: function(force){
  139. if(uW.g_ajaxparams){
  140. var now = new Date().getTime()*1;
  141. var wait = 86400000;//1 day
  142. var k = kb.storagePrefix+'getDomains_lastcheck';
  143. var lastsent = kb.getValue(k,0);
  144. if(force || 1*lastsent+wait < now){
  145. var args = {};
  146. args.v2 = true;
  147. var json = kb.sendToKabam(args,'myServers',null,true);
  148. if(json && json.selectableServers && json.selectableServers.servers){
  149. var domains = [];
  150. for(var i in json.selectableServers.servers){
  151. var d = json.selectableServers.servers[i].serverId;
  152. domains.push(1*d);
  153. }
  154. domains.sort();
  155. kb.log('getDomains();');
  156. kb.setValue(''+k,''+now);
  157. return domains;
  158. }
  159. }else{
  160. var playerdomains=kb.getValue('domains');
  161. if(!playerdomains){
  162. playerdomains = [];
  163. playerdomains.push(1*kb.domain);
  164. return playerdomains;
  165. }else{
  166. return JSON.parse(''+playerdomains);
  167. }
  168. }
  169. }
  170. },
  171. getSavedInfo: function(){
  172. return(kb.getValue('ajaxparams', null));
  173. },
  174. getSavedServerId: function(){
  175. return(kb.getValue('sid'));
  176. },
  177. getCurrentCityId: function(){
  178. if(uW && uW.currentcityid){
  179. return JSON.parse(JSON.stringify(uW.currentcityid));
  180. }
  181. },
  182. getCities: function(){
  183. var seed = kb.getSeed();
  184. if(seed && seed.cities){
  185. return JSON.parse(JSON.stringify(seed.cities));
  186. }
  187. },
  188. gameInfoSave: function(){
  189. if(uW && uW.seed){
  190. kb.setValue('domain', kb.domain);
  191. kb.setValue('uid', kb.uid);
  192. kb.setValue('name', kb.name);
  193. kb.setValue('allianceId', kb.allianceId);
  194. kb.setValue('allianceName', kb.allianceName);
  195. kb.setValue('misted', kb.misted);
  196. kb.setValueObject('cities', kb.cities);
  197. kb.setValueObject('domains', kb.domains);
  198.  
  199. var current = null;
  200. var saved = null;
  201. var tmp = null;
  202. var thekey = '';
  203. //seed
  204. tmp = [];
  205. for(var i in kb.seed){
  206. thekey = kb.storagePrefix+'SEED_'+i;
  207. kb.setValueObject(thekey,kb.seed[i]);
  208. tmp.push(i);
  209. //console.log(kb.getValueObject(thekey));
  210. }
  211. kb.setValueObject(kb.storagePrefix+'SEEDKEYS',tmp);
  212. //cities
  213. current = kb.getValueObject('cities');
  214. thekey = kb.storagePrefix+'CITIES';
  215. saved = kb.getValueObject(thekey);
  216. if(current != saved){
  217. kb.setValueObject( kb.storagePrefix+'CITIES',current);
  218. }
  219. kb.setValueObject('acctIds', kb.acctIds);
  220. }
  221. },
  222. gameInfoLoad: function(){
  223. if(uW && uW.seed){
  224. kb.uid = kb.getUserId();
  225. kb.name = kb.getUserName();
  226. kb.domain = kb.getServerId();
  227. kb.domains = kb.getDomains();
  228. kb.allianceId = kb.getPlayerAllianceId();
  229. kb.allianceName = kb.getPlayerAllianceName();
  230. kb.misted = kb.getPlayerMist();
  231. kb.cities = kb.getCities();
  232. kb.authedSites = kb.authorizedWebsiteGet();
  233. kb.storagePrefix = kb.uid+'_'+kb.domain+'_';
  234. kb.seed = kb.getSeed();
  235. kb.acctIds = kb.getSavedUserIds(kb.uid);
  236. }else{
  237. kb.uid = kb.getValue('uid');
  238. kb.name = kb.getValue('name');
  239. kb.domain = kb.getValue('domain');
  240. kb.domains = kb.getValueObject('domains');
  241. kb.allianceId = kb.getValue('allianceId');
  242. kb.allianceName = kb.getValue('allianceName');
  243. kb.misted = kb.getValue('misted');
  244. kb.cities = kb.getValueObject('cities');
  245. kb.authedSites = kb.authorizedWebsiteGet();
  246. kb.storagePrefix = kb.uid+'_'+kb.domain+'_';
  247.  
  248. //the seed is too large to store as one string so we have to reassemble
  249. kb.seed = {};
  250. kb.seedKEYS = kb.getValueObject(kb.storagePrefix+'SEEDKEYS');
  251. if(kb.seedKEYS){
  252. var prefix = kb.storagePrefix+'SEED_';
  253. var k='';
  254. for(var i in kb.seedKEYS){
  255. k = kb.seedKEYS[i];
  256. kb.seed[k] = JSON.parse(kb.getValue(prefix+k));
  257. }
  258. }
  259. kb.acctIds = kb.getSavedUserIds();
  260. }
  261. },
  262. getServerId: function(){
  263. if(uW && uW.g_server){
  264. return (1*uW.g_server);
  265. }
  266. },
  267. getSavedUserIds: function(uid){
  268. var uids = kb.getValueObject('acctIds',[uid]);
  269. if(uid){
  270. if(!$.inArray(uid,uids)){
  271. uids.push(uid);
  272. }
  273. }
  274. return uids;
  275. },
  276. getUserId: function(){
  277. if(uW && uW.g_ajaxparams && uW.g_ajaxparams.tvuid){
  278. return JSON.parse(JSON.stringify(uW.g_ajaxparams.tvuid));
  279. }
  280. },
  281. getUserName: function(){
  282. if(uW && uW.seed && uW.seed.player && uW.seed.player.name){
  283. return JSON.parse(JSON.stringify(uW.seed.player.name));
  284. }
  285. },
  286. getSeed: function(){
  287. if(uW && uW.seed){
  288. return JSON.parse(JSON.stringify(uW.seed));
  289. }
  290. },
  291. getPlayerAllianceId: function(){
  292. if(uW && uW.seed && uW.seed.allianceDiplomacies && uW.seed.allianceDiplomacies.allianceId){
  293. return JSON.parse(JSON.stringify(uW.seed.allianceDiplomacies.allianceId));
  294. }
  295. return 0;
  296. },
  297. getPlayerAllianceName: function(){
  298. if(uW && uW.seed && uW.seed.allianceDiplomacies && uW.seed.allianceDiplomacies.allianceName){
  299. return JSON.parse(JSON.stringify(uW.seed.allianceDiplomacies.allianceName));
  300. }
  301. return '';
  302. },
  303. getPlayerMist: function(){
  304. var result=0;
  305. if(uW && uW.seed && uW.seed.playerEffects && uW.seed.playerEffects.fogExpire){
  306. result = uW.seed.playerEffects.fogExpire;
  307. var timestamp = Math.floor(new Date().getTime()/1000);
  308. if(timestamp > result){
  309. result=0;
  310. }
  311. }
  312. return JSON.parse(JSON.stringify(result));
  313. },
  314. sendToKB: function(type,payload,callback){
  315. var url = kb.url;
  316. var obj = {
  317. domain: kb.domain,
  318. uid: kb.uid,
  319. cities: kb.cities,
  320. allianceName: encodeURIComponent(kb.allianceName),
  321. userName: encodeURIComponent(kb.name),
  322. data: payload,
  323. };
  324. if(Options.debug){
  325. kb.debug(obj);
  326. }
  327. kb.log('Sending...');
  328. var args='mode=info&data='+encodeURIComponent(JSON.stringify(obj));
  329. GM_xmlhttpRequest({
  330. "method": 'POST',
  331. "url": url,
  332. "data": args,
  333. "headers": {
  334. "Content-type" : "application/x-www-form-urlencoded"
  335. },
  336. "onreadystatechange": function(r) {
  337. },
  338. "onload": function(result) {
  339. if(result && result.status!=200 && Options.debug){
  340. var s='';
  341. s=s+"\n"+'url='+url;
  342. s=s+"\n"+'data='+JSON.stringify(obj);
  343. if(result.status){s=s+"\n"+'status:'+result.status;}
  344. if(result.statusText){s=s+"\n"+'statusText'+result.statusText;}
  345. if(result.responseHeaders){s=s+"\n"+'responseHeaders'+result.responseHeaders;}
  346. if(result.responseText){s=s+"\n"+'responseText'+result.responseText;}
  347. if(result.readyState){s=s+"\n"+'readyState'+result.readyState;}
  348. kb.debug(s);
  349. }
  350. if(result && result.status == 200){
  351. kb.log('Send done!');
  352. if(Options.debug){
  353. kb.debug('Send done!');
  354. }
  355. }
  356. if(callback) {
  357. callback(result);
  358. }
  359. }
  360. });
  361. },
  362. sendToKabam: function(args,page,callback){
  363. var async = false;
  364. var data = JSON.parse(JSON.stringify(uW.g_ajaxparams));
  365. for(var i in args){
  366. data[i] = args[i];
  367. }
  368. var url = kb.createAjaxUrl(page);
  369. var str = '';
  370. for(var k in data){
  371. str = str+'&'+k+'='+data[k];
  372. }
  373. str = str.substr(1);
  374. if(callback){
  375. async = true;
  376. }
  377. if(Options.debug){
  378. kb.debug(str);
  379. }
  380. var result = null;
  381. $.ajax({
  382. 'type': "POST",
  383. 'url': url,
  384. 'data': str,
  385. 'async': async,
  386. 'success': function(r){
  387. if(callback){
  388. callback(r);
  389. }else{
  390. if(typeof r === 'object'){
  391. result = JSON.parse(r);
  392. }else if(typeof r === 'string'){
  393. var hasCode = (/function\(/m.exec(r));
  394. if(hasCode){ return; }
  395. r.trim();
  396. if(r.charAt(0) == '"'){
  397. fNQ = r.indexOf('"') + 1;
  398. lNQ = r.lastIndexOf('"');
  399. r = r.substring(fNQ, lNQ);
  400. r = r.trim();
  401. }
  402. result = JSON.parse(r);
  403. }
  404. if(!result){
  405. result = r;
  406. }
  407. }
  408. }
  409. });
  410. return result;
  411. },
  412. saveInfo: function(){
  413. var info = JSON.stringify(kb.getCurrentInfo());
  414. if(info){
  415. var sid = kb.getServerId();
  416. kb.setValue('ajaxparams',info);
  417. kb.setValue('sid',sid);
  418. }
  419. },
  420. sendInfo: function(force){
  421. if(uW.g_ajaxparams && uW.g_server){
  422. kb.log('checking if time to send');
  423. var now = new Date().getTime();
  424. var k = kb.storagePrefix+'lastsent_ajaxparams';
  425. var lastsent = kb.getValue(k,0);
  426. if(force || 1*lastsent+kb.sendInfoDelay<now){
  427. var savedkey = kb.storagePrefix+'saved_ajaxparams';
  428. var saved = JSON.parse(kb.getValue(savedkey,null));
  429. var json = kb.getAjaxParams();
  430. if(force || saved != json){
  431. kb.setValue(k,''+now+'');
  432. kb.setValue(savedkey,''+JSON.stringify(json));
  433. kb.log('sending: basic');
  434. kb.sendToKB('basic', json);
  435. }
  436. }
  437. }
  438. },
  439. showTime: function(timestamp,version){
  440. var now = null;
  441. if(timestamp){
  442. now = new Date(timestamp);
  443. }else{
  444. now = new Date();
  445. }
  446. var hours = now.getHours();
  447. var minutes = now.getMinutes();
  448. var seconds = now.getSeconds();
  449. var timeValue = "" + ((hours >12) ? hours -12 :hours);
  450. if (timeValue == "0") timeValue = 12;
  451. timeValue += ((minutes < 10) ? ":0" : ":") + minutes;
  452. timeValue += ((seconds < 10) ? ":0" : ":") + seconds;
  453. timeValue += (hours >= 12) ? " PM" : " AM";
  454. return timeValue;
  455. },
  456. log: function(msg){
  457. var type = $.type(msg);
  458. if(type == 'string'){
  459. msg.replace(/</gi,"&lt;");
  460. msg.replace(/>/gi,"&gt;");
  461. }else{
  462. msg = JSON.stringify(msg,null,"\t");
  463. msg = msg.replace(/</gi,'&lt;');
  464. msg = msg.replace(/>/gi,'&gt;');
  465. }
  466. var consoleStr = 'KoCByte: '+kb.domain+' @ '+kb.showTime()+': '+msg;
  467. uW.console.log(consoleStr);
  468. var elem = $('#'+kb.elemPrefix+'-log-result');
  469. var html = '';
  470. if(type == 'string'){
  471. html = '<div>'+kb.showTime()+' '+msg+'</div>';
  472. }else{
  473. html = '<pre>'+kb.showTime()+"\n"+msg+'</pre>';
  474. }
  475. var n = elem.children().length;
  476. if(n > 10){
  477. elem.children(':last').remove();
  478. }
  479. elem.prepend(html);
  480. },
  481. debug: function(msg){
  482. var type = $.type(msg);
  483. if(type == 'string'){
  484. msg.replace(/</gi,"&lt;");
  485. msg.replace(/>/gi,"&gt;");
  486. }else{
  487. msg = JSON.stringify(msg,null,"\t");
  488. msg = msg.replace(/</gi,'&lt;');
  489. msg = msg.replace(/>/gi,'&gt;');
  490. }
  491. var consoleStr = 'KoCByte: '+kb.domain+' @ '+kb.showTime()+': '+msg;
  492. uW.console.log(consoleStr);
  493. var elem = $('#'+kb.elemPrefix+'-log-result');
  494. if(type == 'string'){
  495. html = '<div>'+kb.showTime()+' '+msg+'</div>';
  496. }else{
  497. html = '<pre>'+kb.showTime()+"\n"+msg+'</pre>';
  498. }
  499. var n = elem.children().length;
  500. if(n > 10){
  501. elem.children(':last').remove();
  502. }
  503. elem.prepend(html);
  504. },
  505. authorizedWebsiteGet: function(){
  506. var websites = JSON.parse(''+kb.getValue('authedSites',null));
  507. if(!websites){
  508. websites = ['www.kocbyte.com'];
  509. }
  510. if($.inArray($(websites),'www.kocbyte.com') != -1){
  511. websites.push('www.kocbyte.com');
  512. }
  513. return websites;
  514. },
  515. authorizedWebsiteAdd: function(url){
  516. var websites = JSON.parse(''+kb.getValue('authedSites',null));
  517. if(!websites){
  518. websites = ['www.kocbyte.com'];
  519. }
  520. if($.inArray($(websites),url) > -1){
  521. websites.push(url);
  522. var sites = websites.filter(function(elem, pos) {
  523. return websites.indexOf(elem) == pos;
  524. });
  525. kb.setValue('authedSites',''+JSON.stringify(sites));
  526. return true;
  527. }else{
  528. return false;
  529. }
  530. },
  531. getStyles: function(){
  532. var styles = 'a.ptButton20 {color:#ffff80}';
  533. styles = styles + ' table.kbMainTab { empty-cells: show; margin-left: 5px; margin-top: 4px; padding: 1px; padding-left:5px;}';
  534. styles = styles + ' table.kbMainTab tr td a {color:inherit }';
  535. 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; }';
  536. styles = styles + ' table.kbMainTab tr td.spacer {padding: 0px 0px;}';
  537. 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);}';
  538. 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);}';
  539. 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)}';
  540. styles = styles + ' tr.kbPopTop td { background-color:transparent; border:none; height: 21px; padding:0px;}';
  541. styles = styles + ' tr.kbretry_kbPopTop td { background-color:#a00; color:#fff; border:none; height: 21px; padding:0px; }';
  542. styles = styles + ' tr.kbMainPopTop td { background-color:#ded; border:none; height: 42px; width:80%; padding:0px; }';
  543. styles = styles + ' tr.kbretry_kbMainPopTop td { background-color:#a00; color:#fff; border:none; height: 42px; padding:0px; }';
  544. 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;}';
  545. 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;}';
  546. styles = styles + ' span.kbTextFriendly {color: #080}';
  547. styles = styles + ' span.kbTextHostile {color: #800}';
  548. styles = styles + ' .kbButCancel {background-color:#a00; font-weight:bold; color:#fff}';
  549. styles = styles + ' div.indent25 {padding-left:25px}';
  550. 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;}';
  551. styles = styles + ' .kbdivLink {color:#000;text-decoration:none;}';
  552. styles = styles + ' .kbdivLink:Hover {color:#000;text-decoration:none;}';
  553. styles = styles + ' .kbdivLink:Active {color:#000;text-decoration:none;}';
  554. styles = styles + ' .kbdivHide {display:none}';
  555. return styles;
  556. },
  557. init: function(){
  558. var debugKey = kb.storagePrefix+'_debug';
  559. var debug = kb.getValue(debugKey, null);
  560. if(debug){
  561. Options.debug = true;
  562. }
  563. var styles = kb.getStyles();
  564. mainPop = new kbPopup (kb.elemPrefix, 40, 40, 725,600, function (){
  565. tabManager.hideTab();
  566. Options.kbWinIsOpen=false;
  567. });
  568. mainPop.autoHeight (true);
  569.  
  570. mainPop.getMainDiv().innerHTML = '<style>'+ styles +'</style>';
  571. AddMainTabLink('KoCByte', eventHideShow, null);
  572. tabManager.init(mainPop.getMainDiv());
  573. if(Options.kbWinIsOpen && Options.kbTrackOpen){
  574. mainPop.show(true);
  575. tabManager.showTab();
  576. }
  577. kb.log('Gathering game info');
  578. kb.gameInfoLoad();
  579. if(!kb.uid || !kb.domain){
  580. return;
  581. }
  582. kb.log('Saving game info');
  583. kb.gameInfoSave();
  584. setTimeout(function(){
  585. AutoUpdater.check();
  586. }, 5000);
  587. setTimeout(function(){
  588. kb.sendInfo(1);
  589. }, 15000);
  590. kb.sendTimer = window.setInterval(function(){
  591. kb.sendInfo(1);
  592. }, kb.sendInfoDelay);
  593. kb.updateTimer = window.setInterval(function(){
  594. AutoUpdater.check();
  595. }, kb.updateCheckDelay);
  596. kb.taskTimer = window.setInterval(function(){
  597. kb.doTask();
  598. },1000*1);
  599. },
  600. initSite: function(){
  601. $('.cityCoords').on('click', function(e){
  602. e.preventDefault();
  603. var x = $(this).attr('data-x');
  604. var y = $(this).attr('data-y');
  605. var d = $(this).attr('data-domain');
  606. kb.setValue('command', 'location|'+d+'|'+x+'|'+y);
  607. });
  608. },
  609. doTask: function(){
  610. var now = new Date().getTime();
  611. kb.setValue('lasttaskrun',''+now+'');
  612. kb.setValue('currentdomain',''+kb.getServerId()+'');
  613. var command = kb.getValue('command', '');
  614. if (command !== '') {
  615. kb.setValue('command','');
  616. kb.log('command=' + command);
  617. var x = 0;
  618. var y = 0;
  619. var cmd = command.split('|');
  620. var type = cmd[0];
  621. var domain = 1*cmd[1];
  622. switch(type){
  623. case 'location':
  624. if(domain == kb.domain){
  625. x = 1*cmd[2];
  626. y = 1*cmd[3];
  627. uW.console.log(x+','+y);
  628. uW.cm.formatModel.jumpTo(x, y);
  629. }else{
  630. kb.log('You\'re in the wrong domain to do this action!');
  631. }
  632. break;
  633. }
  634. }
  635. },
  636. };
  637.  
  638. var AutoUpdater = {
  639. id: 19269,
  640. URL: 'https://greasyfork.org/en/scripts/19269-kocbyte/code/KoCByte.user.js',
  641. name: 'KoCByte',
  642. homepage: 'https://greasyfork.org/en/scripts/19269-kocbyte',
  643. version: kb.scriptVer,
  644. call: function(response) { kb.log("Checking for "+this.name+" Update!");
  645. var _s = this;
  646. GM_xmlhttpRequest({
  647. method: 'GET',
  648. url: _s.URL,
  649. onload: function(xpr) {_s.compare(xpr,response);},
  650. onerror: function(xpr) {_s.compare({responseText:""},response);}
  651. });
  652. },
  653. compareVersion: function(remoteVer, localVer){
  654. var remote = parseInt(remoteVer);
  655. var local = parseInt(localVer);
  656. return ((remote > local) ? true : false);
  657. },
  658. compare: function(xpr,response) {
  659. this.xversion=(/@version\s*(.*?)\s*$/m.exec(xpr.responseText));
  660. if(this.xversion){
  661. this.xversion = this.xversion[1];
  662. }else{
  663. if(response){
  664. 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>');
  665. }
  666. kb.log("Unable to check for updates");
  667. return;
  668. }
  669. var updated = this.compareVersion(this.xversion, this.version);
  670. if (updated) {
  671. kb.log('New Version Available!');
  672. var body = '<BR><DIV align=center><FONT size=3><B>New version '+this.xversion+' is available!</b></font></div><BR>';
  673. if (this.xrelnotes){
  674. 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>';
  675. }
  676. body+='<BR><DIV align=center><a class="gemButtonv2 green" id="doBotUpdate">Update</a></div>';
  677. this.ShowUpdate(body);
  678. }else{
  679. kb.log("No updates available");
  680. }
  681. },
  682. check: function() {
  683. var now = uW.unixtime();
  684. var lastCheck = 0;
  685. if (GM_getValue('updated_'+this.id, 0)) lastCheck = parseInt(GM_getValue('updated_'+this.id, 0));
  686. if (now > (lastCheck + 60*1)) this.call(false);
  687. },
  688. ShowUpdate: function (body) {
  689. var now = uW.unixtime();
  690. setUpdate = function(){
  691. GM_setValue('updated_'+AutoUpdater.id, now);
  692. };
  693. uW.cm.ModalManager.addMedium({
  694. title: this.name,
  695. body: body,
  696. closeNow: false,
  697. close: function (){
  698. setTimeout (function (){GM_setValue('updated_'+AutoUpdater.id, now);}, 0);
  699. uW.cm.ModalManager.closeAll();
  700. },
  701. "class": "Warning",
  702. curtain: false,
  703. width: 500,
  704. height: 700,
  705. left: 140,
  706. top: 140
  707. });
  708.  
  709. document.getElementById('doBotUpdate').addEventListener('click', this.doUpdate, false);
  710. },
  711. doUpdate: function () {
  712. uW.cm.ModalManager.closeAll();
  713. uW.cm.ModalManager.close();
  714. var now = uW.unixtime();
  715. GM_setValue('updated_'+AutoUpdater.id, now);
  716. GM_openInTab(AutoUpdater.URL);
  717. },
  718. };
  719.  
  720. var tabManager = {
  721. tabList : {}, // {name, obj, div}
  722. currentTab : null,
  723. init: function (mainDiv){
  724. var t = tabManager;
  725. var sorter = [];
  726. for(k in Tabs){
  727. if(!Tabs[k].tabDisabled){
  728. t.tabList[k] = {};
  729. t.tabList[k].name = k;
  730. t.tabList[k].obj = Tabs[k];
  731. if(Tabs[k].tabLabel != null)
  732. t.tabList[k].label = Tabs[k].tabLabel;
  733. else
  734. t.tabList[k].label = k;
  735. if(Tabs[k].tabOrder != null)
  736. sorter.push([Tabs[k].tabOrder, t.tabList[k]]);
  737. else
  738. sorter.push([1000, t.tabList[k]]);
  739. t.tabList[k].div = document.createElement('div');
  740. }
  741. }
  742.  
  743. sorter.sort (function (a,b){return a[0]-b[0]});
  744. var m = '<TABLE cellspacing=3 class=pbMainTab><TR>';
  745. for(var i=0; i<sorter.length; i++) {
  746. 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>';
  747. //m += '<TD align=center class=notSel id=pbtc'+ sorter[i][1].name +' ><A><SPAN>'+ sorter[i][1].label +'</span></a></td>';
  748. if((i+1)%9 == 0) m+='</tr><TR>';
  749. }
  750. m+='</tr></table>';
  751. //m += '<TD class=spacer width=90% align=right>'+ Version +'&nbsp;</td></tr></table>';
  752. mainPop.getMainTopDiv().innerHTML = m;
  753. for(k in t.tabList){
  754. if(t.tabList[k].name == Options.currentTab)
  755. t.currentTab =t.tabList[k] ;
  756. document.getElementById('pbtc'+ k).addEventListener('click', this.e_clickedTab, false);
  757. var div = t.tabList[k].div;
  758. div.style.display = 'none';
  759. div.style.height = '100%';
  760. mainDiv.appendChild(div);
  761. try{
  762. t.tabList[k].obj.init(div);
  763. }catch(e){
  764. div.innerHTML = "INIT ERROR: "+ e;
  765. }
  766. }
  767. if(t.currentTab == null)
  768. t.currentTab = sorter[0][1];
  769. t.setTabStyle (document.getElementById ('pbtc'+ t.currentTab.name), true);
  770. t.currentTab.div.style.display = 'block';
  771. },
  772. hideTab : function (){
  773. var t = tabManager;
  774. t.currentTab.obj.hide();
  775. },
  776. showTab : function (){
  777. var t = tabManager;
  778. t.currentTab.obj.show();
  779. },
  780. setTabStyle : function (e, selected){
  781. if(selected){
  782. e.className = 'sel';
  783. }else{
  784. e.className = 'notSel';
  785. }
  786. },
  787. e_clickedTab : function (e){
  788. var t = tabManager;
  789. var newTab = t.tabList[e.target.parentNode.parentNode.id.substring(4)];
  790. if(t.currentTab.name != newTab.name){
  791. t.setTabStyle (document.getElementById ('pbtc'+ t.currentTab.name), false);
  792. t.setTabStyle (document.getElementById ('pbtc'+ newTab.name), true);
  793. t.currentTab.obj.hide ();
  794. t.currentTab.div.style.display = 'none';
  795. t.currentTab = newTab;
  796. newTab.div.style.display = 'block';
  797. Options.currentTab = newTab.name;
  798. }
  799. newTab.obj.show();
  800. },
  801. };
  802.  
  803. var WinManager = {
  804. wins: {}, // prefix : kbPopup obj
  805. didHide: [],
  806. get: function(prefix){
  807. var t = WinManager;
  808. return t.wins[prefix];
  809. },
  810. add: function(prefix, pop){
  811. var t = WinManager;
  812. t.wins[prefix] = pop;
  813. if(uW.cpopupWins == null)
  814. uW.cpopupWins = {};
  815. uW.cpopupWins[prefix] = pop;
  816. },
  817. hideAll: function(){
  818. var t = WinManager;
  819. t.didHide = [];
  820. for(var k in t.wins){
  821. if(t.wins[k].isShown()){
  822. t.didHide.push (t.wins[k]);
  823. t.wins[k].show (false);
  824. }
  825. }
  826. },
  827. restoreAll: function(){
  828. var t = WinManager;
  829. for(var i=0; i<t.didHide.length; i++)
  830. t.didHide[i].show(true);
  831. },
  832. delete: function(prefix){
  833. var t = WinManager;
  834. delete t.wins[prefix];
  835. delete uW.cpopupWins[prefix];
  836. }
  837. };
  838.  
  839. // creates a 'popup' div
  840. // prefix must be a unique (short) name for the popup window
  841. function kbPopup(prefix, x, y, width, height, onClose) {
  842. var pop = WinManager.get(prefix);
  843. if(pop){
  844. pop.show (false);
  845. return pop;
  846. }
  847. this.BASE_ZINDEX = 111111;
  848. // protos ...
  849. this.show = show;
  850. this.toggleHide = toggleHide;
  851. this.getTopDiv = getTopDiv;
  852. this.getMainTopDiv = getMainTopDiv;
  853. this.getMainDiv = getMainDiv;
  854. this.getJQMainDiv = getJQMainDiv;
  855. this.getLayer = getLayer;
  856. this.setLayer = setLayer;
  857. this.getLocation = getLocation;
  858. this.setLocation = setLocation;
  859. this.focusMe = focusMe;
  860. this.isShown = isShown;
  861. this.unfocusMe = unfocusMe;
  862. this.centerMe = centerMe;
  863. this.destroy = destroy;
  864. this.autoHeight = autoHeight;
  865. // object vars ...
  866. this.div = document.createElement('div');
  867. this.prefix = prefix;
  868. this.onClose = onClose;
  869. var t = this;
  870. this.div.className = 'kbPopup '+ prefix +'_kbPopup';
  871. this.div.id = prefix +'_outer';
  872. this.div.style.background = "#fff";
  873. this.div.style.zIndex = this.BASE_ZINDEX;
  874. this.div.style.display = 'none';
  875. this.div.style.width = width + 'px';
  876. this.div.style.height = height + 'px';
  877. this.div.style.maxHeight = height + 'px';
  878. this.div.style.overflowY = 'show';
  879. this.div.style.position = "absolute";
  880. this.div.style.top = y +'px';
  881. this.div.style.left = x + 'px';
  882. var topClass = '';
  883. if(kbPopUpTopClass==null)
  884. topClass = 'kbPopupTop '+ prefix +'_kbPopupTop';
  885. else
  886. topClass = kbPopUpTopClass +' '+ prefix +'_'+ kbPopUpTopClass;
  887. var m = '<table cellspacing=0 width=100% ><tr id="'+ prefix +'_bar" class="'+ topClass +'"><td width=99% valign=bottom><SPAN id="'+ prefix +'_top"></span></td>';
  888. 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>';
  889. 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>';
  890. document.body.appendChild(this.div);
  891. this.div.innerHTML = m;
  892. document.getElementById(prefix+'_X').addEventListener ('click', e_XClose, false);
  893. this.div.addEventListener('mousedown', e_divClicked, false);
  894. WinManager.add(prefix, this);
  895. function e_divClicked(){
  896. t.focusMe();
  897. }
  898. function e_XClose(){
  899. t.show(false);
  900. if (t.onClose != null)
  901. t.onClose();
  902. }
  903. function autoHeight(onoff){
  904. if(onoff)
  905. t.div.style.height = '';
  906. else
  907. t.div.style.height = t.div.style.maxHeight;
  908. }
  909. function focusMe(){
  910. t.setLayer(5);
  911. for(var k in uW.cpopupWins){
  912. if(k != t.prefix)
  913. uW.cpopupWins[k].unfocusMe();
  914. }
  915. }
  916. function unfocusMe(){
  917. t.setLayer(-5);
  918. }
  919. function getLocation(){
  920. return {x: parseInt(this.div.style.left), y: parseInt(this.div.style.top)};
  921. }
  922. function setLocation(loc){
  923. t.div.style.left = loc.x +'px';
  924. t.div.style.top = loc.y +'px';
  925. }
  926. function destroy(){
  927. document.body.removeChild(t.div);
  928. WinManager.delete (t.prefix);
  929. }
  930. function centerMe(parent){
  931. var coords;
  932. if(parent == null){
  933. coords = getClientCoords(document.body);
  934. }else
  935. coords = getClientCoords(parent);
  936. var x = ((coords.width - parseInt(t.div.style.width)) / 2) + coords.x;
  937. var y = ((coords.height - parseInt(t.div.style.height)) / 2) + coords.y;
  938. if(x<0)
  939. x = 0;
  940. if(y<0)
  941. y = 0;
  942. t.div.style.left = x +'px';
  943. t.div.style.top = y +'px';
  944. }
  945. function setLayer(zi){
  946. t.div.style.zIndex = ''+ (this.BASE_ZINDEX + zi);
  947. }
  948. function getLayer(){
  949. return parseInt(t.div.style.zIndex) - this.BASE_ZINDEX;
  950. }
  951. function getTopDiv(){
  952. return document.getElementById(this.prefix+'_top');
  953. }
  954. function getMainDiv(){
  955. return document.getElementById(this.prefix+'_main');
  956. }
  957. function getJQMainDiv(){
  958. return $('#'+this.prefix+'_main');
  959. }
  960. function getMainTopDiv(){
  961. return document.getElementById(this.prefix+'_top');
  962. }
  963. function isShown (){
  964. return t.div.style.display == 'block';
  965. }
  966. function show(tf){
  967. if (tf){
  968. t.div.style.display = 'block';
  969. t.focusMe ();
  970. } else {
  971. t.div.style.display = 'none';
  972. }
  973. return tf;
  974. }
  975. function toggleHide(t){
  976. if (t.div.style.display == 'block') {
  977. return t.show (false);
  978. } else {
  979. return t.show (true);
  980. }
  981. }
  982. }
  983.  
  984. function getClientCoords(e){
  985. if (e==null)
  986. return {x:null, y:null, width:null, height:null};
  987. var ret = {x:0, y:0, width:e.clientWidth, height:e.clientHeight};
  988. while (e.offsetParent != null){
  989. ret.x += e.offsetLeft;
  990. ret.y += e.offsetTop;
  991. e = e.offsetParent;
  992. }
  993. return ret;
  994. }
  995.  
  996. function eventHideShow(){
  997. if(mainPop.toggleHide(mainPop)){
  998. tabManager.showTab();
  999. Options.kbWinIsOpen = true;
  1000. } else {
  1001. tabManager.hideTab();
  1002. Options.kbWinIsOpen = false;
  1003. }
  1004. }
  1005.  
  1006. function createButton(label,id){
  1007. var a=document.createElement('a');
  1008. a.className='button20';
  1009. a.id = id;
  1010. a.innerHTML='<span style="color: #ff6">'+ label +'</span>';
  1011. return a;
  1012. }
  1013.  
  1014. function AddMainTabLink(text, eventListener, mouseListener){
  1015. var a = createButton(text,'botbutton');
  1016. a.className='tab';
  1017. var tabs=document.getElementById('main_engagement_tabs');
  1018. if(!tabs){
  1019. tabs=document.getElementById('topnav_msg');
  1020. if(tabs)
  1021. tabs=tabs.parentNode;
  1022. }
  1023. if(tabs){
  1024. var e = tabs.parentNode;
  1025. var gmTabs = null;
  1026. for(var i=0; i<e.childNodes.length; i++){
  1027. var ee = e.childNodes[i];
  1028. if (ee.tagName && ee.tagName=='div' && ee.className=='tabs_engagement' && ee.id!='main_engagement_tabs'){
  1029. gmTabs = ee;
  1030. break;
  1031. }
  1032. }
  1033. if(gmTabs == null){
  1034. gmTabs = document.createElement('div');
  1035. gmTabs.className='tabs_engagement';
  1036. tabs.parentNode.insertBefore(gmTabs, tabs);
  1037. gmTabs.style.whiteSpace='nowrap';
  1038. gmTabs.style.width='735px';
  1039. gmTabs.lang = 'en_KB';
  1040. }
  1041. gmTabs.style.height='0%';
  1042. gmTabs.style.overflow='auto';
  1043. gmTabs.appendChild(a);
  1044. a.addEventListener('click',eventListener, false);
  1045. if(mouseListener != null)
  1046. a.addEventListener('mousedown',mouseListener, true);
  1047. return a;
  1048. }
  1049. return null;
  1050. }
  1051.  
  1052. Tabs.Website = {
  1053. tabOrder: 2,
  1054. tabDisabled: false,
  1055. tabLabel: 'Website',
  1056. myDiv: null,
  1057. timer: null,
  1058. init: function(div){
  1059. var t = Tabs.Website;
  1060. t.myDiv = div;
  1061. var str = '<div class="row">';
  1062. str = str + ' <div class="large-12 columns end text-center">';
  1063. str = str + ' <button id="'+kb.elemPrefix+'-website-visit"><span>Visit Site</span></button><br />';
  1064. str = str + ' <button id="'+kb.elemPrefix+'-website-updateinfo"><span>Send Info</span></button>';
  1065. str = str + ' </div>';
  1066. str = str + '</div>';
  1067. t.myDiv.innerHTML = str;
  1068. $('#'+kb.elemPrefix+'-website-updateinfo').click(function(){
  1069. kb.sendInfo(1);
  1070. });
  1071. $('#'+kb.elemPrefix+'-website-visit').click(function(){
  1072. GM_openInTab(kb.site);
  1073. });
  1074. },
  1075. hide: function(){ // called whenever the main window is hidden, or another tab is selected
  1076. var t = Tabs.Website;
  1077. },
  1078. show: function(){ // called whenever this tab is shown
  1079. var t = Tabs.Website;
  1080. },
  1081. };
  1082.  
  1083. Tabs.Log = {
  1084. tabOrder: 3,
  1085. tabDisabled: false,
  1086. tabLabel: 'Log',
  1087. myDiv: null,
  1088. timer: null,
  1089. init: function(div){
  1090. var t = Tabs.Log;
  1091. t.myDiv = div;
  1092. var str = '';
  1093. str = str + '<div class="row">';
  1094. str = str + ' <div class="large-12 columns">';
  1095. str = str + ' <pre id="'+kb.elemPrefix+'-log-result">Log text goes here</pre>';
  1096. str = str + ' </div>';
  1097. str = str + '</div>';
  1098. t.myDiv.innerHTML = str;
  1099. },
  1100. hide: function(){ // called whenever the main window is hidden, or another tab is selected
  1101. var t = Tabs.Log;
  1102. },
  1103. show: function(){ // called whenever this tab is shown
  1104. var t = Tabs.Log;
  1105. },
  1106. };
  1107.  
  1108. Tabs.Debug = {
  1109. tabOrder: 4,
  1110. tabDisabled: false,
  1111. tabLabel: 'Debug',
  1112. myDiv: null,
  1113. timer: null,
  1114. init: function(div){
  1115. var t = Tabs.Debug;
  1116. t.myDiv = div;
  1117. var str = '';
  1118. str = str + '<div class="row">';
  1119. str = str + ' <div class="large-12 columns">';
  1120. str = str + ' <pre id="'+kb.elemPrefix+'-debug-result">Debug text goes here</pre>';
  1121. str = str + ' </div>';
  1122. str = str + '</div>';
  1123. t.myDiv.innerHTML = str;
  1124. },
  1125. hide: function(){ // called whenever the main window is hidden, or another tab is selected
  1126. var t = Tabs.Debug;
  1127. },
  1128. show: function(){ // called whenever this tab is shown
  1129. var t = Tabs.debug;
  1130. },
  1131. };
  1132.  
  1133. Tabs.Mod = {
  1134. tabOrder: 1,
  1135. tabDisabled: false,
  1136. tabLabel: 'Mod',
  1137. myDiv: null,
  1138. timer: null,
  1139. init: function(div){ // called once, upon script startup
  1140. var t = Tabs.Mod;
  1141. t.myDiv = div;
  1142. var str = '';
  1143. str = str + '<div class="row">';
  1144. str = str + ' <div class="large-12 columns text-center">';
  1145. str = str + ' <button id="'+kb.elemPrefix+'-main-update">Update</button>&nbsp;v<span id="'+kb.elemPrefix+'-main-version">'+kb.scriptVer+'</span><br />';
  1146. str = str + ' <button id="'+kb.elemPrefix+'-main-debug"><span id="'+kb.elemPrefix+'-debug-toggle">Debug: '+((Options.debug) ? 'On' : 'Off')+'</span></button>';
  1147. str = str + ' </div>';
  1148. str = str + '</div>';
  1149. t.myDiv.innerHTML = str;
  1150. $('#'+kb.elemPrefix+'-main-update').click(function(){
  1151. AutoUpdater.check(false);
  1152. });
  1153. $('#'+kb.elemPrefix+'-main-debug').click(function(){
  1154. var debug = (Options.debug) ? false : true;
  1155. $('#'+kb.elemPrefix+'-debug-toggle').html('Debug: '+((debug) ? 'On' : 'Off'));
  1156. Options.debug = debug;
  1157. var debugKey = kb.storagePrefix+'_debug';
  1158. kb.setValue(debugKey, debug);
  1159. });
  1160. },
  1161. hide: function(){ // called whenever the main window is hidden, or another tab is selected
  1162. var t = Tabs.Mod;
  1163. },
  1164. show: function(){ // called whenever this tab is shown
  1165. var t = Tabs.Mod;
  1166. },
  1167. };
  1168.  
  1169. kb.elemPrefix = 'kb-'+kb.generateRandomNumber(0,65535);
  1170.  
  1171. if(uW.AjaxCall){
  1172. uW.AjaxCall.unwatch("gPostRequest");
  1173. uW.AjaxCall.gPostRequest = aj2;
  1174. }
  1175.  
  1176. if(kb.currentUrl.match('src/main_src.php')){
  1177. kb.init();
  1178. }else if(kb.currentUrl.match('apps.facebook.com/kingdomsofcamelot/')){
  1179. kb.init();
  1180. }else if(kb.currentUrl.match('www.kabam.com/games/kingdoms-of-camelot/play')){
  1181. kb.init();
  1182. }else if(kb.currentUrl.match('www.kocbyte.com')){
  1183. kb.initSite();
  1184. }