KoCByte

A Kingdoms of Camelot Mod

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

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