SpyShare

SpyShare for Ogame: Allows you to share spy reports with your buddies even if you are not in the same alliance

  1. // ==UserScript==
  2. // @name SpyShare
  3. // @namespace SpyShareNamespace
  4. // @author [TSN]Kanly
  5. // @include *.ogame.gameforge.com/game/*
  6. // @require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
  7. // @description SpyShare for Ogame: Allows you to share spy reports with your buddies even if you are not in the same alliance
  8. // @version 2.0
  9. // ==/UserScript==
  10.  
  11. var SSR = {};
  12. var noSpyShareTxt = "\n\n\ If you see this message then you don't have the SpyShare Tool, it is not active/working or Commander is not activated. For more info check the[url=https://greasyfork.org/scripts/4739-spyshare] SpyShare Page[/url]";
  13.  
  14. function main() {
  15. SSR.Data.init();
  16. SSR.Updater.check();
  17. SSR.Init.init();
  18. }
  19.  
  20. SSR.Updater = {
  21. scriptId: 4739,
  22. updStr: "",
  23. scriptName: "",
  24. checkD: 1,
  25. checkH: 0,
  26. checkM: 0,
  27. checkS: 0,
  28. checkInterval: 0,
  29. currVersion: 0,
  30.  
  31. parseVersion: function(data) {
  32. return parseInt(data.match(/@version\s+\d+/)[0].match(/\d+/));
  33. },
  34. call: function(alertResp) {
  35. GM_xmlhttpRequest({
  36. method: 'GET',
  37. url: 'https://greasyfork.org/scripts/4739-spyshare/code/' + this.scriptId + '.meta.js',
  38. onload: function (response) {
  39. SSR.Updater.compare(response.responseText, alertResp);
  40. }
  41. });
  42. },
  43. compare: function(metaData, alertResp) {
  44. try{
  45. var newVersion = parseInt(metaData.match(/@version\s+[\d\.]+/)[0].match(/[\d\.]+/)[0].replace(".",""));
  46. if (newVersion > this.currVersion) {
  47. if (confirm('A new version of the ' + this.scriptName + ' user script is available. Do you want to update?')) {
  48. SSR.Storage.store(this.updStr, new Date().getTime() + "");
  49. top.location.href = 'https://greasyfork.org/scripts/4739-spyshare/code/' + this.scriptId + '.user.js';
  50. }
  51. else {
  52. if (confirm('Do you want to turn off auto updating for this script?')) {
  53. SSR.Storage.store(this.updStr, "off");
  54. GM_registerMenuCommand("Auto Update " + this.scriptName,
  55. function () {
  56. SSR.Storage.store(SSR.Updater.updStr, new Date().getTime() + "");
  57. SSR.Updater.call(true);
  58. });
  59. alert('Automatic updates can be re-enabled for this script from the User Script Commands submenu.');
  60. }
  61. else {
  62. SSR.Storage.store(this.updStr, new Date().getTime() + "");
  63. }
  64. }
  65. }
  66. else {
  67. if (alertResp)
  68. alert('No updates available for ' + this.scriptName);
  69. SSR.Storage.store(this.updStr, new Date().getTime()+ "");
  70. }
  71. }catch(e){}
  72. },
  73. check: function() {
  74. try {
  75. var meta = GM_getResourceText('meta');
  76. var updStat;
  77. var timeNow = new Date().getTime();
  78.  
  79. //this.scriptName = meta.match(/@name\s+(.*)\s*\n/i)[1];
  80. this.scriptName = GM_info.script.name;
  81. //this.currVersion = meta.match(/@version\s+\d+/)[0].match(/\d+/);
  82. this.currVersion = parseInt(GM_info.script.version.replace(".",""));
  83. this.updStr = "updated_" + this.scriptId;
  84. this.checkInterval = ((((this.checkD*24 + this.checkH)*60 + this.checkH)*60 + this.checkM)*60 + this.checkS)*1000;
  85.  
  86. updStat = SSR.Storage.get(this.updStr, 0);
  87. if (updStat === "off") {
  88. GM_registerMenuCommand("Enable " + this.scriptName + " updates",
  89. function () {
  90. SSR.Storage.store(SSR.Updater.updStr, new Date().getTime() + "");
  91. SSR.Updater.call(true);
  92. });
  93. }
  94. else {
  95. if (timeNow > parseInt(updStat) + this.checkInterval) {
  96. SSR.Storage.store(this.updStr, timeNow + "");
  97. this.call();
  98. }
  99.  
  100. }
  101. GM_registerMenuCommand("Check " + this.scriptName + " for updates",
  102. function () {
  103. SSR.Storage.store(SSR.Updater.updStr, new Date().getTime() + '');
  104. SSR.Updater.call(true);
  105. });
  106. }catch(e){}
  107. }
  108. };
  109.  
  110. SSR.Data = {
  111. universe: '',
  112. playerId: 0,
  113. buddies: [],
  114. page: '',
  115. allianceName: '',
  116.  
  117. init: function() {
  118. SSR.Data.playerId = document.getElementsByName("ogame-player-id")[0].content;
  119. SSR.Data.universe = document.getElementsByName("ogame-universe")[0].content;
  120. SSR.Data.allianceName = document.getElementsByName("ogame-alliance-tag")[0].content;
  121. SSR.Data.page = (unsafeWindow.location+"").match(/page=[^&]+((?=&)|(?=#)|)/g)[0].replace("page=", "");
  122. }
  123. };
  124.  
  125. SSR.Storage = {
  126. getPrefix: function() {
  127. var s = SSR.Data.universe+"::"+SSR.Data.playerId+":::";
  128. return s;
  129. },
  130.  
  131. store: function(name, value) {
  132. GM_setValue(SSR.Storage.getPrefix()+name, value);
  133. },
  134.  
  135. get: function(name, defValue) {
  136. return GM_getValue(SSR.Storage.getPrefix()+name, defValue);
  137. },
  138.  
  139. remove: function(name) {
  140. GM_deleteValue(SSR.Storage.getPrefix()+name);
  141. }
  142. };
  143.  
  144. SSR.Init = {
  145. init: function() {
  146. if (SSR.Init.hasCommander() === false)
  147. return;
  148.  
  149. SSR.Buddies.getBuddies();
  150.  
  151. if (SSR.Data.page === "messages") {
  152. GM_addStyle(SSR.shareSection.getCss());
  153.  
  154. SSR.Utils.waitForKeyElements('#mailz', SSR.Reports.fullSpyReports, false);
  155. SSR.Utils.waitForKeyElements('.read.messagebox', SSR.Reports.widgetMessagePopUp, false);
  156. }
  157. },
  158. hasCommander: function() {
  159. var found = false;
  160.  
  161. $('#officers').find('a.tooltipHTML.on').each(function() {
  162. var cls = $(this).attr('class');
  163. if (cls.indexOf('commander') != -1)
  164. found = true;
  165. });
  166. return found;
  167. }
  168. };
  169.  
  170. SSR.Reports = {
  171. widgetMessagePopUp: function(jNode) {
  172. var widget = jNode;
  173. var isSharedRep = false;
  174. var isSpyReport = false;
  175. var isAllianceSharedRep = false;
  176. if (jNode.find('.infohead th[scope="row"]').next().text().match(/\[spyShare\]/g)) {
  177. isSharedRep = true;
  178. }
  179. else if ((kk = jNode.find('.textWrapper .note').text().match(/_SPY_SHARE_/g)) && kk && kk.length === 2) {
  180. isSharedRep = true;
  181. isAllianceSharedRep = true;
  182. }
  183. else if ($('.infohead span.playerName a[target="_parent"]').exists() === false && $('.defenseattack.spy').exists()) {
  184. isSpyReport = true;
  185. }
  186. if (isSharedRep === false && isSpyReport === false)
  187. return;
  188. if (isSharedRep) {
  189. var info = jNode.find('.note .other.newMessage');
  190. if (info.exists() === false && isAllianceSharedRep === true)
  191. info = jNode.find('.textWrapper .note');
  192. info = info.text();
  193. info = info.match(/_SPY_SHARE_.+_SPY_SHARE_/g)[0].replace(/_SPY_SHARE_/g, '');
  194. info = JSON.decode(info);
  195.  
  196. jNode.find('.showMsgNavi').remove();
  197. jNode.find('.answerHeadline.open').remove();
  198. jNode.find('.answerForm').remove();
  199.  
  200. jNode.find('.note').html(SSR.Reports.formSharedReportHtml(info));
  201. }
  202. else if (isSpyReport) {
  203. jNode.find('.defenseattack.spy').parent().append(SSR.shareSection.getHtml(true));
  204. jNode.find('.textWrapper').css('max-height', 'none');
  205.  
  206. SSR.shareSection.initEvents(jNode);
  207. }
  208. },
  209.  
  210. fullSpyReports: function(jNode) {
  211. $('[id^="spioDetails_"]').each(function () {
  212. $(this).find('.defenseattack.spy').parent().append(SSR.shareSection.getHtml(true));
  213. });
  214.  
  215. SSR.shareSection.initEvents(jNode);
  216. },
  217.  
  218. formSharedReportHtml: function(info) {
  219. var html = '';
  220. var resTable = '';
  221. var tables = '';
  222. var header = '';
  223.  
  224. html = formHeader(info.header);
  225. html += formResTable(info.resources);
  226.  
  227. for (var section in info.data) {
  228. if (info.data.hasOwnProperty(section) && section !== "resources") {
  229. html += formTable(section+"", info.data[section]);
  230. }
  231. }
  232.  
  233. function formHeader(hdr) {
  234. var s =
  235. '<table cellpadding="0" cellspacing="0" class="material spy">'+
  236. '<tbody>'+
  237. '<tr>'+
  238. '<th class="area" style="color: #6f9fc8" colspan="6" plunder_status='+hdr.pl_st+'>'+
  239. '<span style="float: left; color: '+hdr.act_clr+';" title='+hdr.act_title+'>&nbsp;&nbsp;'+hdr.act+'</span>'+hdr.part1+
  240. '<a target="_parent" href="javascript:showGalaxy('+SSR.Utils.formatCoords(hdr.coords, true)+')">'+SSR.Utils.formatCoords(hdr.coords, false)+'</a>'+hdr.part2+
  241. '<span class='+hdr.tar_class+'>'+hdr.player+'</span>)'+hdr.part3+
  242. '</th>'+
  243. '</tr>';
  244.  
  245. return s;
  246. }
  247.  
  248. function formResTable(res) {
  249. var s =
  250. '<tr class="areadetail">'+
  251. '<td colspan="6">'+
  252. '<table class="fragment spy2">'+
  253. '<tbody>'+
  254. '<tr>'+
  255. '<td class="item">'+res[0].name+'</td>'+
  256. '<td>'+res[0].value+'</td>'+
  257. '<td class="item">'+res[1].name+'</td>'+
  258. '<td>'+res[1].value+'</td>'+
  259. '</tr>'+
  260. '<tr>'+
  261. '<td class="item">'+res[2].name+'</td>'+
  262. '<td>'+res[2].value+'</td>'+
  263. '<td class="item">'+res[3].name+'</td>'+
  264. '<td>'+res[3].value+'</td>'+
  265. '</tr>'+
  266. '</tbody>'+
  267. '</table>';
  268.  
  269. return s;
  270. };
  271.  
  272. function formTable(title, data) {
  273. var html = '<table cellpadding="0" cellspacing="0" class="fleetdefbuildings spy">'+
  274. '<tbody>'+
  275. '<tr>'+
  276. '<th class="area" colspan="4">'+title+'</th>'+
  277. '</tr>';
  278. var n = 0;
  279. for (var entry in data) {
  280. if (data.hasOwnProperty(entry)) {
  281. if (n%2 === 0)
  282. html += '<tr>';
  283. html += '<td class="key">'+entry+'</td>'+
  284. '<td class="value">'+data[entry]+'</td>';
  285.  
  286. if (n%2 === 1)
  287. html += '</tr>';
  288.  
  289. n++;
  290. }
  291. }
  292. html += '</tbody>'+
  293. '</table>';
  294. return html;
  295. }
  296. return html;
  297. },
  298.  
  299. extractSpyReportData: function(buttTable) {
  300. var item = buttTable;
  301. var info = {};
  302. var res = [];
  303. var curRes = {};
  304. var header = {};
  305. var fltdefbuilt = {};
  306.  
  307. /*
  308. header:{
  309. pl_st:1,
  310. act_title: Activitate,
  311. tar_class: status_abbr_honorableTarget,
  312. act:33,
  313. act_clr: #848484
  314. player: nume,
  315. coords:["1", "167", "12"],
  316. part1: Resurse la Planeta',
  317. part2: Jucator:,
  318. part3: in 02-02 18:28:02
  319. }
  320.  
  321. <th class="area" colspan="6" plunder_status="1">
  322. <span style="float: left; color: #848484;" title="Activitate">&nbsp;&nbsp;-- </span>
  323. Resurse la<figure class="planetIcon planet tooltip js_hideTipOnMobile" title="Planeta"></figure>Caledonia <a target="_parent" href="javascript:showGalaxy(1,172,8)">[1:172:8]</a>
  324. (Jucator: <span class="status_abbr_honorableTarget">focul</span>) in 02-02 14:33:23
  325. </th>
  326.  
  327. '53 ' 'Resurse la HomeDepo' '[1:167:12]' '(Jucator: ' 'Billy') ' in 02-02 18:28:02'
  328. activity part1 coords part2 player date
  329. */
  330.  
  331. // get activity
  332. item.siblings('.aktiv.spy').each(function () {
  333. var item = $(this);
  334.  
  335. header.act_title = item.find('th.area').text();
  336. if (item.find('font').exists()) {
  337. header.act_clr = item.find('font').attr('color');
  338. header.act = item.find('font').text();
  339. }
  340. else {
  341. header.act_clr = "#848484";
  342. header.act = "-- ";
  343. }
  344. });
  345. // get header info
  346. item.siblings('.material.spy').find('th.area').each(function () {
  347. var item = $(this);
  348. var coords = {};
  349. var txt;
  350.  
  351. // plunder status
  352. header.pl_st = (item.is('[plunder_status]') === true) ? item.attr("plunder_status") : "0";
  353.  
  354. // get target name
  355. item.find('span:last').each(function() {
  356. header.player = $(this).text();
  357. header.tar_class = $(this).attr("class");
  358. });
  359.  
  360. txt = item.text();
  361. txt = txt.replace(header.act, '');
  362. txt = txt.replace(header.player, '');
  363.  
  364. // get coords
  365. var coordsStr = txt.match(/\[[^\]]+\]/g);
  366. if (coordsStr && coordsStr[0]) {
  367. header.coords = coordsStr[0].match(/\d+/g);
  368. txt = txt.replace(coordsStr, '');
  369. }
  370. else
  371. header.coords = ["0", "0", "0"];
  372.  
  373. // get "(Player: "
  374. var playerSec = txt.match(/\([^\)]+/g);
  375. if (playerSec && playerSec[0]) {
  376. header.part2 = playerSec[0];
  377. txt = txt.replace(playerSec, '');
  378. } else
  379. header.part2 = "(Player: ";
  380. // get time
  381. var dateSec = txt.match(/[^\)]+(.+)/);
  382. if (dateSec && dateSec[1]) {
  383. header.part3 = dateSec[1].replace(')', '');
  384. txt = txt.replace(dateSec[1], '');
  385. }
  386. else
  387. header.part3 = " no time available";
  388. header.part1 = txt;
  389. });
  390. info.header = header;
  391.  
  392. // get resources
  393. item.siblings('.material.spy').find('.fragment.spy2').each(function() {
  394. var resCont = $(this);
  395. resCont.find('td').each(function() {
  396. var item = $(this);
  397. if (item.attr('class') === 'item')
  398. curRes.name = item.text();
  399. else {
  400. curRes.value = item.text();
  401. res.push(curRes);
  402. curRes = {};
  403. }
  404. });
  405. });
  406. info.resources = res;
  407.  
  408. // get fleet
  409. item.siblings('.fleetdefbuildings.spy').each(function() {
  410. var section = $(this).find('th.area').text();
  411. var values = {};
  412. $(this).find('td.key').each(function() {
  413. values[$(this).text()] = $(this).next().text();
  414. });
  415. fltdefbuilt[section] = values;
  416. });
  417. info.data = fltdefbuilt;
  418.  
  419. return info;
  420. }
  421. };
  422.  
  423. SSR.Buddies = {
  424. getBuddies: function() {
  425. SSR.Data.buddies = JSON.decode(SSR.Storage.get("myBuddies", '[]'));
  426.  
  427. SSR.Utils.waitForKeyElements('#buddylist', SSR.Buddies.extractBuddies, false);
  428.  
  429. if (SSR.Data.buddies.length === 0)
  430. SSR.Buddies.requestBuddies();
  431. },
  432.  
  433. requestBuddies: function() {
  434. var url = 'http://'+SSR.Data.universe+'/game/index.php?page=buddies&action=9&ajax=1';
  435. var host = SSR.Data.universe;
  436. var ref = 'http://'+SSR.Data.universe+'/game/index.php?page=overview';
  437. var contType = 'application/x-www-form-urlencoded';
  438. var payload = '';
  439.  
  440. SSR.Utils.sendRequest({
  441. method: 'GET',
  442. url: url,
  443. host: host,
  444. acc: '*/*',
  445. ref: ref,
  446. contType: contType,
  447. payload: '',
  448. onloadFun: SSR.Buddies.parseBuddiesStr});
  449. },
  450.  
  451. parseBuddiesStr: function(resp) {
  452. var html = $.parseHTML(resp);
  453.  
  454. SSR.Buddies.extractBuddies($(html, 'table#buddylist'));
  455. },
  456.  
  457. extractBuddies: function(jNode) {
  458. SSR.Data.buddies.length = 0;
  459. jNode.find('tbody tr').each(function() {
  460. var item = $(this);
  461. var name = item.find('span:first').text();
  462. var id = item.find('.deleteBuddy').attr('id');
  463.  
  464. SSR.Data.buddies.push({id:id, name:name});
  465. });
  466.  
  467. SSR.Storage.remove("myBuddies");
  468. SSR.Storage.store("myBuddies", JSON.encode(SSR.Data.buddies));
  469. }
  470. };
  471.  
  472. SSR.shareSection = {
  473. getCss: function() {
  474. var css =
  475. 'a.sendShareInfo.ok {'+
  476. 'color: green;'+
  477. '}'+
  478. 'a.sendShareInfo.err {'+
  479. 'color: red;'+
  480. '}'+
  481. 'td.blockTD {'+
  482. 'display: inline-block;'+
  483. '}'+
  484. '.dropdown-check-list {'+
  485. 'display: inline-block;'+
  486. 'font-family: Verdana,Arial,SunSans-Regular,Sans-Serif;'+
  487. 'font-size: 12px;'+
  488. '}'+
  489. '.dropdown-check-list .anchor {'+
  490. 'position: relative;'+
  491. 'cursor: pointer;'+
  492. 'display: inline-block;'+
  493. 'padding: 5px 50px 5px 10px;'+
  494. 'background-color: #23282d;'+
  495. 'border: 1px solid #000;'+
  496. 'color:#6f9fc8;'+
  497. '-webkit-touch-callout: none;'+
  498. '-webkit-user-select: none;'+
  499. '-khtml-user-select: none;'+
  500. '-moz-user-select: none;'+
  501. '-ms-user-select: none;'+
  502. 'user-select: none;'+
  503. '}'+
  504. '.dropdown-check-list .anchor:after {'+
  505. 'position: absolute;'+
  506. 'content: "";'+
  507. 'border-left: 2px solid lawnGreen;'+
  508. 'border-top: 2px solid lawnGreen;'+
  509. 'padding: 5px;'+
  510. 'right: 10px;'+
  511. 'top: 20%;'+
  512. '-moz-transform: rotate(-135deg);'+
  513. '-ms-transform: rotate(-135deg);'+
  514. '-o-transform: rotate(-135deg);'+
  515. '-webkit-transform: rotate(-135deg);'+
  516. 'transform: rotate(-135deg);'+
  517. '}'+
  518. '.dropdown-check-list.visible .anchor:after {'+
  519. 'top: 40%;'+
  520. '-moz-transform: rotate(45deg);'+
  521. '-ms-transform: rotate(45deg);'+
  522. '-o-transform: rotate(45deg);'+
  523. '-webkit-transform: rotate(45deg);'+
  524. 'transform: rotate(45deg);'+
  525. '}'+
  526. '.dropdown-check-list ul.items {'+
  527. 'padding: 2px;'+
  528. 'display: none;'+
  529. 'margin: 0;'+
  530. 'border: 1px solid #000;'+
  531. 'border-top: none;'+
  532. 'background-color: #161A1F;'+
  533. 'color: #848484;'+
  534. '}'+
  535. '.dropdown-check-list ul.items li, .dropdown-check-list ul.items input {'+
  536. 'cursor: pointer;'+
  537. 'list-style: none;'+
  538. '-webkit-touch-callout: none;'+
  539. '-webkit-user-select: none;'+
  540. '-khtml-user-select: none;'+
  541. '-moz-user-select: none;'+
  542. '-ms-user-select: none;'+
  543. 'user-select: none;'+
  544. '}'+
  545. '.dropdown-check-list.visible li.groupHeader {'+
  546. 'color: #6f9fc8;'+
  547. '}'+
  548. '.dropdown-check-list.visible .items {'+
  549. 'display: block;'+
  550. '}';
  551. return css;
  552. },
  553. getHtml: function(addTable) {
  554. var html = '';
  555. if (addTable)
  556. html += '<table cellpadding="0" cellspacing="0" class="spy"><tbody>'+
  557. '<tr><th class="area" colspan="4">Share it</th></tr>';
  558. html +=
  559. '<tr>'+
  560. '<td>' + SSR.shareSection.getListHtml() + '</td>'+
  561. '<td class="blockTD"><a class="btn_blue share_button">Share</a></td>'+
  562. '<td class="blockTD"><a class="sendShareInfo"></a></td>'+
  563. '</tr>';
  564. if (addTable)
  565. html += '</tbody></table>';
  566. return html;
  567. },
  568. getListHtml: function() {
  569. // buddies: [{id:id, name:name}, ... ]
  570. var html =
  571. '<div class="shareList dropdown-check-list">'+
  572. '<span class="anchor">Share With</span>'+
  573. '<ul class="items">';
  574. if (SSR.Data.buddies.length !== 0)
  575. html += '<li class="groupHeader"><input type="checkbox" data="Friend" class="shareGroup"/>All Friends </li>';
  576. for (var bud in SSR.Data.buddies) {
  577. html += '<li><input type="checkbox" data="'+SSR.Data.buddies[bud].id+'" class="share Friend" />'+SSR.Data.buddies[bud].name+'</li>';
  578. }
  579.  
  580. html += '<li class="groupHeader"><input type="checkbox" id="allianceShare" data="Ally" class="shareGroup" />'+SSR.Data.allianceName+' Alliance </li>';
  581. /*
  582. for (var allId in allies) {
  583. if (allies.hasOwnProperty(allId))
  584. html += '<li><input type="checkbox" data="'+allId+'" class="share Ally" />'+allies[allId]+'</li>';
  585. }
  586. */
  587. html += '</ul>'+
  588. '</div>';
  589.  
  590. return html;
  591. },
  592.  
  593. updateShareNote: function(jNode, status, txt) {
  594. if (status === 'err')
  595. jNode.parent().siblings().find('a.sendShareInfo').removeClass('ok').addClass('err');
  596. else
  597. jNode.parent().siblings().find('a.sendShareInfo').removeClass('err').addClass('ok');
  598.  
  599. jNode.parent().siblings().find('a.sendShareInfo').text(txt);
  600. },
  601.  
  602. initEvents: function(wrapper) {
  603. // show/hide list
  604. wrapper.find('.shareList .anchor').click(function(ev) {
  605. var item = $(this).parent();
  606. if (item.hasClass('visible'))
  607. item.removeClass('visible');
  608. else
  609. item.addClass('visible');
  610. });
  611.  
  612. // check/uncheck groups
  613. wrapper.find('.shareList input:checkbox.shareGroup').click(function(ev) {
  614. var item = $(this);
  615. var newState = item.is(':checked');
  616. var cls = item.attr('data');
  617.  
  618. if (!newState)
  619. item.parent().siblings().find('input:checkbox:checked.'+cls).click();
  620. else
  621. item.parent().siblings().find('input:checkbox.'+cls).not(':checked').click();
  622. });
  623.  
  624. // share button
  625. wrapper.find('a.share_button').click(function(ev) {
  626. var item = $(this);
  627. var dest = [];
  628. var inf = '';
  629. var allianceShare = false;
  630.  
  631. ev.preventDefault();
  632.  
  633. item.parent().siblings().find('input:checked.share').each(function() {
  634. dest.push($(this).attr('data'));
  635. });
  636.  
  637. allianceShare = item.parent().siblings().find('#allianceShare:checked').exists();
  638. if (dest.length === 0 && allianceShare === false) {
  639. SSR.shareSection.updateShareNote(item, 'err', 'No destination selected!');
  640. return;
  641. }
  642. else {
  643. info = SSR.Reports.extractSpyReportData(item.closest('table'));
  644. SSR.Utils.sendSharedMessages(item, dest,
  645. '[spyShare] '+info.header.player+" ["+SSR.Utils.formatCoords(info.header.coords, false)+"]",
  646. "_SPY_SHARE_"+JSON.encode(info)+"_SPY_SHARE_"+noSpyShareTxt, allianceShare);
  647. }
  648. });
  649. }
  650. };
  651.  
  652. SSR.Utils = {
  653. sendRequest: function(opts) {
  654. var hdr = {
  655. 'Accept-Language': 'en-us,en;q=0.5',
  656. 'Accept-Encoding': 'gzip, deflate',
  657. 'Connection': 'keep-alive'
  658. };
  659. var onLoadFun = opts.onLoadFun;
  660.  
  661. hdr.Accept = (opts.acc && opts.acc !== '') ? opts.acc : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
  662. if (opts.host) hdr.Host = opts.host;
  663. if (opts.ref) hdr.Referer = opts.ref;
  664. if (opts.contType) hdr['Content-Type'] = opts.contType;
  665.  
  666. GM_xmlhttpRequest({
  667. method: opts.method,
  668. url: opts.url,
  669. headers: hdr,
  670. data: opts.payload,
  671.  
  672. onload: function(response) {
  673. if (opts.onloadFun)
  674. opts.onloadFun(response.responseText);
  675. },
  676. onabort: function(resp) {
  677. if (opts.onabortFun)
  678. opts.onabortFun(resp.responseText);
  679. },
  680. onerror: function(resp) {
  681. if (opts.onerrorFun)
  682. opts.onerrorFun(resp.responseText);
  683. },
  684. ontimeout: function(resp) {
  685. if (opts.ontimeoutFun)
  686. opts.ontimeoutFun(resp.responseText);
  687. }
  688. });
  689. },
  690.  
  691. sendSharedMessages: function(jNode, dest, subj, content, allianceShare) {
  692. var sent = 0;
  693. var curBuddy = 0;
  694. var totalMsg = dest.length;
  695.  
  696. if (allianceShare) {
  697. totalMsg++;
  698. curBuddy = -1;
  699. sendAlliance();
  700. }
  701. else {
  702. sendSingle(dest[curBuddy]);
  703. }
  704.  
  705. function sendAlliance() {
  706. var url = 'http://'+SSR.Data.universe+'/game/index.php?page=allianceBroadcast';
  707. var host = SSR.Data.universe;
  708. var ref = 'http://'+SSR.Data.universe+'/game/index.php?page=alliance';
  709. var contType = 'application/x-www-form-urlencoded';
  710. var payload = 'empfaenger=200&'+'&text='+content+'&ajax=1';
  711.  
  712. SSR.Utils.sendRequest({
  713. method: 'POST',
  714. url: url,
  715. host: host,
  716. acc: '',
  717. ref: ref,
  718. contType: contType,
  719. payload: payload,
  720. onloadFun: messageSentOk});
  721. }
  722.  
  723. function sendSingle() {
  724. var url = 'http://'+SSR.Data.universe+'/game/index.php?page=messages&to='+dest[curBuddy];
  725. var host = SSR.Data.universe;
  726. var ref = 'http://'+SSR.Data.universe+'/game/index.php?page=messages';
  727. var contType = 'application/x-www-form-urlencoded';
  728. var payload = 'betreff='+subj+'&text='+content;
  729.  
  730. SSR.Utils.sendRequest({
  731. method: 'POST',
  732. url: url,
  733. host: host,
  734. acc: '',
  735. ref: ref,
  736. contType: contType,
  737. payload: payload,
  738. onloadFun: messageSentOk});
  739. }
  740.  
  741. function messageSentOk(resp) {
  742. sent++;
  743. curBuddy++;
  744. SSR.shareSection.updateShareNote(jNode, 'ok', sent+'/'+totalMsg+' messages sent!');
  745.  
  746. if (curBuddy < dest.length)
  747. unsafeWindow.setTimeout(sendSingle, 300);
  748. }
  749. },
  750.  
  751. formatCoords: function(coords, isHref) {
  752. var del = (isHref ? ',' : ':');
  753. var s = parseInt(coords[0]) + del + parseInt(coords[1]) + del + parseInt(coords[2]);
  754.  
  755. return s;
  756. },
  757. waitForKeyElements: function (selectorTxt, actionFunction, bWaitOnce, iframeSelector) {
  758. var targetNodes, btargetsFound;
  759.  
  760. if (typeof iframeSelector == "undefined")
  761. targetNodes = $(selectorTxt);
  762. else
  763. targetNodes = $(iframeSelector).contents()
  764. .find(selectorTxt);
  765.  
  766. if (targetNodes && targetNodes.length > 0) {
  767. /*--- Found target node(s). Go through each and act if they
  768. are new.
  769. */
  770. targetNodes.each(function () {
  771. var jThis = $(this);
  772. var alreadyFound = jThis.data('alreadyFound') || false;
  773.  
  774. if (!alreadyFound) {
  775. //--- Call the payload function.
  776. unsafeWindow.setTimeout(function () {
  777. actionFunction(jThis);
  778. }, 100);
  779. jThis.data('alreadyFound', true);
  780. }
  781. });
  782. btargetsFound = true;
  783. } else {
  784. btargetsFound = false;
  785. }
  786.  
  787. //--- Get the timer-control variable for this selector.
  788. var controlObj = SSR.Utils.waitForKeyElements.controlObj || {};
  789. var controlKey = selectorTxt.replace(/[^\w]/g, "_");
  790. var timeControl = controlObj[controlKey];
  791.  
  792. //--- Now set or clear the timer as appropriate.
  793. if (btargetsFound && bWaitOnce && timeControl) {
  794. //--- The only condition where we need to clear the timer.
  795. clearInterval(timeControl);
  796. delete controlObj[controlKey]
  797. } else {
  798. //--- Set a timer, if needed.
  799. if (!timeControl) {
  800. timeControl = setInterval(function () {
  801. SSR.Utils.waitForKeyElements(selectorTxt,
  802. actionFunction,
  803. bWaitOnce,
  804. iframeSelector
  805. );
  806. },
  807. 2000
  808. );
  809. controlObj[controlKey] = timeControl;
  810. }
  811. }
  812. SSR.Utils.waitForKeyElements.controlObj = controlObj;
  813. }
  814. };
  815.  
  816. JSON=new function(){this.encode=function(){var self=arguments.length?arguments[0]:this,result,tmp;if(self===null)
  817. result="null";else if(self!==undefined&&(tmp=$[typeof self](self))){switch(tmp){case Array:result=[];for(var i=0,j=0,k=self.length;j<k;j++){if(self[j]!==undefined&&(tmp=JSON.encode(self[j])))
  818. result[i++]=tmp;};result="[".concat(result.join(","),"]");break;case Boolean:result=String(self);break;case Date:result='"'.concat(self.getFullYear(),'-',d(self.getMonth()+1),'-',d(self.getDate()),'T',d(self.getHours()),':',d(self.getMinutes()),':',d(self.getSeconds()),'"');break;case Function:break;case Number:result=isFinite(self)?String(self):"null";break;case String:result='"'.concat(self.replace(rs,s).replace(ru,u),'"');break;default:var i=0,key;result=[];for(key in self){if(self[key]!==undefined&&(tmp=JSON.encode(self[key])))
  819. result[i++]='"'.concat(key.replace(rs,s).replace(ru,u),'":',tmp);};result="{".concat(result.join(","),"}");break;}};return result;};var c={"\b":"b","\t":"t","\n":"n","\f":"f","\r":"r",'"':'"',"\\":"\\","/":"/"},d=function(n){return n<10?"0".concat(n):n},e=function(c,f,e){e=eval;delete eval;if(typeof eval==="undefined")eval=e;f=eval(""+c);eval=e;return f},i=function(e,p,l){return 1*e.substr(p,l)},p=["","000","00","0",""],rc=null,rd=/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/,rs=/(\x5c|\x2F|\x22|[\x0c-\x0d]|[\x08-\x0a])/g,rt=/^([0-9]+|[0-9]+[,\.][0-9]{1,3})$/,ru=/([\x00-\x07]|\x0b|[\x0e-\x1f])/g,s=function(i,d){return"\\".concat(c[d])},u=function(i,d){var n=d.charCodeAt(0).toString(16);return"\\u".concat(p[n.length],n)},v=function(k,v){return $[typeof result](result)!==Function&&(v.hasOwnProperty?v.hasOwnProperty(k):v.constructor.prototype[k]!==v[k])},$={"boolean":function(){return Boolean},"function":function(){return Function},"number":function(){return Number},"object":function(o){return o instanceof o.constructor?o.constructor:null},"string":function(){return String},"undefined":function(){return null}},$$=function(m){function $(c,t){t=c[m];delete c[m];try{e(c)}catch(z){c[m]=t;return 1}};return $(Array)&&$(Object)};try{rc=new RegExp('^("(\\\\.|[^"\\\\\\n\\r])*?"|[,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t])+?$')}
  820. catch(z){rc=/^(true|false|null|\[.*\]|\{.*\}|".*"|\d+|\d+\.\d+)$/};this.decode=function(string, secure) {
  821. if (typeof(string) != 'string' || !string.length) return new Object();
  822. if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '')))
  823. return new Object();
  824. return eval('(' + string + ')');
  825. }}
  826.  
  827. $.fn.exists = function () {
  828. return this.length !== 0;
  829. }
  830.  
  831. if (document.body) {
  832. main();
  833. }