KoCByte

A Kingdoms of Camelot Mod

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

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