OGame: Messages

Messages espionage table

当前为 2016-02-08 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name OGame: Messages
  3. // @description Messages espionage table
  4. // @namespace OGame: Messages
  5. // @version 0.9.5
  6. // @creator ter3ter
  7. // @include http://*/game/index.php?page=messages*
  8. // @include https://*/game/index.php?page=messages*
  9. // ==/UserScript==
  10.  
  11. function strtotime(text, now) {
  12. // discuss at: http://phpjs.org/functions/strtotime/
  13. // version: 1109.2016
  14. // original by: Caio Ariede (http://caioariede.com)
  15. // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  16. // improved by: Caio Ariede (http://caioariede.com)
  17. // improved by: A. Matías Quezada (http://amatiasq.com)
  18. // improved by: preuter
  19. // improved by: Brett Zamir (http://brett-zamir.me)
  20. // improved by: Mirko Faber
  21. // input by: David
  22. // bugfixed by: Wagner B. Soares
  23. // bugfixed by: Artur Tchernychev
  24. // note: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
  25. // example 1: strtotime('+1 day', 1129633200);
  26. // returns 1: 1129719600
  27. // example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
  28. // returns 2: 1130425202
  29. // example 3: strtotime('last month', 1129633200);
  30. // returns 3: 1127041200
  31. // example 4: strtotime('2009-05-04 08:30:00 GMT');
  32. // returns 4: 1241425800
  33.  
  34. var parsed, match, today, year, date, days, ranges, len, times, regex, i, fail = false;
  35.  
  36. if (!text) {
  37. return fail;
  38. }
  39.  
  40. // Unecessary spaces
  41. text = text.replace(/^\s+|\s+$/g, '')
  42. .replace(/\s{2,}/g, ' ')
  43. .replace(/[\t\r\n]/g, '')
  44. .toLowerCase();
  45.  
  46. // in contrast to php, js Date.parse function interprets:
  47. // dates given as yyyy-mm-dd as in timezone: UTC,
  48. // dates with "." or "-" as MDY instead of DMY
  49. // dates with two-digit years differently
  50. // etc...etc...
  51. // ...therefore we manually parse lots of common date formats
  52. match = text.match(
  53. /^(\d{1,4})([\-\.\/\:])(\d{1,2})([\-\.\/\:])(\d{1,4})(?:\s(\d{1,2}):(\d{2})?:?(\d{2})?)?(?:\s([A-Z]+)?)?$/);
  54.  
  55. if (match && match[2] === match[4]) {
  56. if (match[1] > 1901) {
  57. switch (match[2]) {
  58. case '-':
  59. { // YYYY-M-D
  60. if (match[3] > 12 || match[5] > 31) {
  61. return fail;
  62. }
  63.  
  64. return new Date(match[1], parseInt(match[3], 10) - 1, match[5],
  65. match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
  66. }
  67. case '.':
  68. { // YYYY.M.D is not parsed by strtotime()
  69. return fail;
  70. }
  71. case '/':
  72. { // YYYY/M/D
  73. if (match[3] > 12 || match[5] > 31) {
  74. return fail;
  75. }
  76.  
  77. return new Date(match[1], parseInt(match[3], 10) - 1, match[5],
  78. match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
  79. }
  80. }
  81. } else if (match[5] > 1901) {
  82. switch (match[2]) {
  83. case '-':
  84. { // D-M-YYYY
  85. if (match[3] > 12 || match[1] > 31) {
  86. return fail;
  87. }
  88.  
  89. return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
  90. match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
  91. }
  92. case '.':
  93. { // D.M.YYYY
  94. if (match[3] > 12 || match[1] > 31) {
  95. return fail;
  96. }
  97.  
  98. return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
  99. match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
  100. }
  101. case '/':
  102. { // M/D/YYYY
  103. if (match[1] > 12 || match[3] > 31) {
  104. return fail;
  105. }
  106.  
  107. return new Date(match[5], parseInt(match[1], 10) - 1, match[3],
  108. match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
  109. }
  110. }
  111. } else {
  112. switch (match[2]) {
  113. case '-':
  114. { // YY-M-D
  115. if (match[3] > 12 || match[5] > 31 || (match[1] < 70 && match[1] > 38)) {
  116. return fail;
  117. }
  118.  
  119. year = match[1] >= 0 && match[1] <= 38 ? +match[1] + 2000 : match[1];
  120. return new Date(year, parseInt(match[3], 10) - 1, match[5],
  121. match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
  122. }
  123. case '.':
  124. { // D.M.YY or H.MM.SS
  125. if (match[5] >= 70) { // D.M.YY
  126. if (match[3] > 12 || match[1] > 31) {
  127. return fail;
  128. }
  129.  
  130. return new Date(match[5], parseInt(match[3], 10) - 1, match[1],
  131. match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
  132. }
  133. if (match[5] < 60 && !match[6]) { // H.MM.SS
  134. if (match[1] > 23 || match[3] > 59) {
  135. return fail;
  136. }
  137.  
  138. today = new Date();
  139. return new Date(today.getFullYear(), today.getMonth(), today.getDate(),
  140. match[1] || 0, match[3] || 0, match[5] || 0, match[9] || 0) / 1000;
  141. }
  142.  
  143. return fail; // invalid format, cannot be parsed
  144. }
  145. case '/':
  146. { // M/D/YY
  147. if (match[1] > 12 || match[3] > 31 || (match[5] < 70 && match[5] > 38)) {
  148. return fail;
  149. }
  150.  
  151. year = match[5] >= 0 && match[5] <= 38 ? +match[5] + 2000 : match[5];
  152. return new Date(year, parseInt(match[1], 10) - 1, match[3],
  153. match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000;
  154. }
  155. case ':':
  156. { // HH:MM:SS
  157. if (match[1] > 23 || match[3] > 59 || match[5] > 59) {
  158. return fail;
  159. }
  160.  
  161. today = new Date();
  162. return new Date(today.getFullYear(), today.getMonth(), today.getDate(),
  163. match[1] || 0, match[3] || 0, match[5] || 0) / 1000;
  164. }
  165. }
  166. }
  167. }
  168.  
  169. // other formats and "now" should be parsed by Date.parse()
  170. if (text === 'now') {
  171. return now === null || isNaN(now) ? new Date()
  172. .getTime() / 1000 | 0 : now | 0;
  173. }
  174. if (!isNaN(parsed = Date.parse(text))) {
  175. return parsed / 1000 | 0;
  176. }
  177.  
  178. date = now ? new Date(now * 1000) : new Date();
  179. days = {
  180. 'sun': 0,
  181. 'mon': 1,
  182. 'tue': 2,
  183. 'wed': 3,
  184. 'thu': 4,
  185. 'fri': 5,
  186. 'sat': 6
  187. };
  188. ranges = {
  189. 'yea': 'FullYear',
  190. 'mon': 'Month',
  191. 'day': 'Date',
  192. 'hou': 'Hours',
  193. 'min': 'Minutes',
  194. 'sec': 'Seconds'
  195. };
  196.  
  197. function lastNext(type, range, modifier) {
  198. var diff, day = days[range];
  199.  
  200. if (typeof day !== 'undefined') {
  201. diff = day - date.getDay();
  202.  
  203. if (diff === 0) {
  204. diff = 7 * modifier;
  205. } else if (diff > 0 && type === 'last') {
  206. diff -= 7;
  207. } else if (diff < 0 && type === 'next') {
  208. diff += 7;
  209. }
  210.  
  211. date.setDate(date.getDate() + diff);
  212. }
  213. }
  214.  
  215. function process(val) {
  216. var splt = val.split(' '), // Todo: Reconcile this with regex using \s, taking into account browser issues with split and regexes
  217. type = splt[0],
  218. range = splt[1].substring(0, 3),
  219. typeIsNumber = /\d+/.test(type),
  220. ago = splt[2] === 'ago',
  221. num = (type === 'last' ? -1 : 1) * (ago ? -1 : 1);
  222.  
  223. if (typeIsNumber) {
  224. num *= parseInt(type, 10);
  225. }
  226.  
  227. if (ranges.hasOwnProperty(range) && !splt[1].match(/^mon(day|\.)?$/i)) {
  228. return date['set' + ranges[range]](date['get' + ranges[range]]() + num);
  229. }
  230.  
  231. if (range === 'wee') {
  232. return date.setDate(date.getDate() + (num * 7));
  233. }
  234.  
  235. if (type === 'next' || type === 'last') {
  236. lastNext(type, range, num);
  237. } else if (!typeIsNumber) {
  238. return false;
  239. }
  240.  
  241. return true;
  242. }
  243.  
  244. times = '(years?|months?|weeks?|days?|hours?|minutes?|min|seconds?|sec' +
  245. '|sunday|sun\\.?|monday|mon\\.?|tuesday|tue\\.?|wednesday|wed\\.?' +
  246. '|thursday|thu\\.?|friday|fri\\.?|saturday|sat\\.?)';
  247. regex = '([+-]?\\d+\\s' + times + '|' + '(last|next)\\s' + times + ')(\\sago)?';
  248.  
  249. match = text.match(new RegExp(regex, 'gi'));
  250. if (!match) {
  251. return fail;
  252. }
  253.  
  254. for (i = 0, len = match.length; i < len; i++) {
  255. if (!process(match[i])) {
  256. return fail;
  257. }
  258. }
  259.  
  260. return (date.getTime() / 1000);
  261. }
  262.  
  263. function shipCount (m, k, d, cargo)
  264. {
  265. return Math.ceil (Math.ceil (Math.max (m + k + d, Math.min (0.75 * (m * 2 + k + d), m * 2 + d))) / cargo);
  266. }
  267.  
  268. function norm_val(s) {
  269. var mn = 1;
  270. s = s.replace(/,/, '.');
  271. if (s.match(/M/)) {
  272. var rpos = s.length - s.indexOf('.');
  273. if (rpos == 3) {
  274. mn = 100000;
  275. } else if (rpos == 4) {
  276. mn = 10000;
  277. } else if (rpos == 5) {
  278. mn = 1000;
  279. } else {
  280. mn = 1000000;
  281. }
  282. }
  283. s = s.replace(/[M,\.]/g, "");
  284. s *= mn;
  285. return s;
  286. }
  287.  
  288. var messages = [];
  289.  
  290. function parse_messages() {
  291. $('li.msg').each(function() {
  292. if ($(this).find('.msg_content>div').length == 4) {
  293. var coords = $(this).find('.msg_head>span>a').closest('span');
  294. var met = $(this).find('.msg_content>div.compacting:eq(1)>span.ctn4>span.resspan:eq(0)').text().substring(1).replace(/М/, 'M').replace(/[^0-9M,\.]/g,"");
  295. met = norm_val(met);
  296. var kris = $(this).find('.msg_content>div.compacting:eq(1)>span.ctn4>span.resspan:eq(1)').text().replace(/М/, 'M').replace(/[^0-9M,\.]/g,"");
  297. kris = norm_val(kris);
  298. var deut = $(this).find('.msg_content>div.compacting:eq(1)>span.ctn4>span.resspan:eq(2)').text().replace(/М/, 'M').replace(/[^0-9M,\.]/g,"");
  299. deut = norm_val(deut);
  300. var fleet = $(this).find('.msg_content>div.compacting:eq(3)>span.ctn.ctn4.tooltipLeft').text().replace(/М/, 'M').replace(/[^0-9M,\.]/g,"");
  301. if (!fleet) {
  302. fleet = 'Н/Д';
  303. }
  304. var def = $(this).find('.msg_content>div.compacting:eq(3)>span.ctn.ctn4.tooltipRight').text().replace(/М/, 'M').replace(/[^0-9M,\.]/g,"");
  305. if (!def) {
  306. def = 'Н/Д';
  307. }
  308. var link = $(this).find('.msg_actions>a.msg_action_link').attr('href');
  309. var time = $(this).find('.msg_head>span.msg_date.fright').text();
  310. var nick;
  311. var status;
  312. if ($(this).find('.msg_content>div>span.status_abbr_honorableTarget').length) {
  313. nick = $(this).find('.msg_content>div>span.status_abbr_honorableTarget').text().substr(2);
  314. status = 'status_abbr_honorableTarget';
  315. } else if ($(this).find('.msg_content>div>span.status_abbr_longinactive').length) {
  316. nick = $(this).find('.msg_content>div>span.status_abbr_longinactive').text().substr(2);
  317. status = 'status_abbr_longinactive';
  318. } else if ($(this).find('.msg_content>div>span.status_abbr_inactive').length) {
  319. nick = $(this).find('.msg_content>div>span.status_abbr_inactive').text().substr(2);
  320. status = 'status_abbr_inactive';
  321. } else if ($(this).find('.msg_content>div>span.status_abbr_outlaw').length) {
  322. nick = $(this).find('.msg_content>div>span.status_abbr_outlaw').text().substr(2);
  323. status = 'status_abbr_outlaw';
  324. } else if ($(this).find('.msg_content>div>span.status_abbr_noob').length) {
  325. nick = $(this).find('.msg_content>div>span.status_abbr_noob').text().substr(2);
  326. status = 'status_abbr_noob';
  327. } else if ($(this).find('.msg_content>div>span.status_abbr_active').length) {
  328. nick = $(this).find('.msg_content>div>span.status_abbr_active').text().substr(2);
  329. status = 'status_abbr_active';
  330. }
  331. var loot =$(this).find('.msg_content>div.compacting:eq(2)>span.ctn.ctn4').text().replace(/\D+/g,"");
  332. var activ = ' (' + $(this).find('.msg_content>div.compacting:eq(0)>span.fright').text().replace(/\D+/g,"") + ')';
  333. var all_res = met*1 + kris*1 + deut*1;
  334. all_res *= loot/100;
  335. all_res = Math.round(all_res);
  336. kris *= loot/100;
  337. kris = Math.round(kris);
  338. met *= loot/100;
  339. met = Math.round(met);
  340. deut *= loot/100;
  341. deut = Math.round(deut);
  342. var coords_array = $(this).find('.msg_head>span>a').text().match(/\[([0-9]):([0-9]+):([0-9]+)\]/);
  343. messages.push({
  344. coords: coords,
  345. coords_array: coords_array[0].match(/[0-9]+/g),
  346. met: met,
  347. kris: kris,
  348. deut: deut,
  349. fleet: fleet,
  350. def: def,
  351. loot: loot,
  352. all_res: all_res,
  353. nick: nick,
  354. link: link,
  355. time: time,
  356. activ: activ,
  357. mt_count: shipCount(met, kris, deut, 5000),
  358. bt_count: shipCount(met, kris, deut, 25000),
  359. api: $($(this).find('.msg_actions .icon_apikey').attr('title')).attr('value')
  360. });
  361. }
  362. });
  363. }
  364.  
  365. function sort_by_res() {
  366. messages.sort(function(a, b) {
  367. return b.all_res - a.all_res;
  368. });
  369. }
  370. function sort_by_time() {
  371. messages.sort(function(a, b) {
  372. var d1 = strtotime(a.time);
  373. var d2 = strtotime(b.time);
  374. return d2 - d1;
  375. });
  376. }
  377. function sort_by_def() {
  378. messages.sort(function(a, b) {
  379. if (b.def == 'Н/Д') {
  380. //alert(b.coords);
  381. return -1;
  382. }
  383. if (a.def == 'Н/Д') {
  384. return 1;
  385. }
  386. console.log(b.def);
  387. //console.log(b.def == 'Н/Д');
  388. return norm_val(b.def) - norm_val(a.def);
  389. });
  390. }
  391. function sort_by_fleet() {
  392. messages.sort(function(a, b) {
  393. if (b.fleet == 'Н/Д') {
  394. return -1;
  395. }
  396. if (a.fleet == 'Н/Д') {
  397. return 1;
  398. }
  399. return norm_val(b.fleet) - norm_val(a.fleet);
  400. });
  401. }
  402.  
  403. function show_table() {
  404. if ($('#scan_table').length > 0) {
  405. $('#scan_table').remove();
  406. }
  407. var cont = $('.pagination:first');
  408. var s = '<li id="scan_table"><table style="width: 100%;padding:5px">';
  409. s += '<tr><th></th><th id="order_time">Время</th><th>Ник</th><th>Координаты</th><th id="order_res">Добыча</th><th id="order_fleet">Флот</th><th id="order_def">Оборона</th><th></th><th></th><th>МТ</th><th>БТ</th></tr>';
  410. for(var i in messages) {
  411. var msg = messages[i];
  412. s += '<tr>';
  413. s += '<td style="padding:3px"><input type="checkbox"></td>';
  414. s += '<td>' + msg.time.substr(11) + '</td>';
  415. s += '<td><a class="txt_link msg_action_link overlay" href="'+msg.link+'">' + msg.nick + msg.activ + '</a></td>';
  416. s += '<td><a href="' + msg.coords.find('a').attr('href') + '">'+msg.coords.find('a').text().match(/\[[0-9]:[0-9]+:[0-9]+\]/)+'</a></td>';
  417. s += '<td title="met: '+msg.met+' kris:'+msg.kris+' deut:'+msg.deut+'">' + msg.all_res.toString().replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 ') + '</td>';
  418. s += '<td>' + msg.fleet + '</td>';
  419. s += '<td>' + msg.def + '</td>';
  420. s += '<td><a target="_blank" href="http://topraider.eu/index.php?SR_KEY='+msg.api+'&speed='+document.getElementsByName('ogame-universe-speed-fleet')[0].content+'">sim1</a></td>';
  421. s += '<td><a href="#none" class="open_websim" lootp="'+msg.loot+'">sim2</a></td>';
  422. s += '<td><a href="/game/index.php?page=fleet1&galaxy='+msg.coords_array[0]+'&system='+msg.coords_array[1]+'&position='+msg.coords_array[2]+'&type=1&mission=1&am202='+msg.mt_count+'">'+msg.mt_count+'</a></td>';
  423. s += '<td><a href="/game/index.php?page=fleet1&galaxy='+msg.coords_array[0]+'&system='+msg.coords_array[1]+'&position='+msg.coords_array[2]+'&type=1&mission=1&am203='+msg.bt_count+'">' + msg.bt_count + '</a></td>';
  424. }
  425. s += '</table></li>';
  426. cont.after(s);
  427. $('#order_time').click(function() {
  428. sort_by_time();
  429. show_table();
  430. });
  431. $('#order_res').click(function() {
  432. sort_by_res();
  433. show_table();
  434. });
  435. $('#order_def').click(function() {
  436. sort_by_def();
  437. show_table();
  438. });
  439. $('#order_fleet').click(function() {
  440. sort_by_fleet();
  441. show_table();
  442. });
  443. $('.open_websim').click(function() {
  444. var tr = $(this).closest('tr');
  445. var full_link = tr.find('td>a.msg_action_link').attr('href');
  446. $.get(full_link, function(data) {
  447. var dom = $(data);
  448. var ships = {};
  449. var url = 'http://websim.speedsim.net/?';
  450. for (i = 202;i<216;i++) {
  451. if (dom.find('.tech'+i).length == 1) {
  452. var num = i - 202;
  453. url += 'ship_d0_'+num+'_b='+dom.find('.tech'+i).closest('.detail_list_el').find('span.fright').text().replace(/\D+/g,"")+'&';
  454. }
  455. }
  456. for (i = 401;i<409;i++) {
  457. if (dom.find('.defense'+i).length == 1) {
  458. var num = i - 401 + 14;
  459. url += 'ship_d0_'+num+'_b='+dom.find('.defense'+i).closest('.detail_list_el').find('span.fright').text().replace(/\D+/g,"")+'&';
  460. }
  461. }
  462. url += 'enemy_metal=' + norm_val(dom.find('.resourceIcon.metal').closest('.resource_list_el').find('.res_value').text());
  463. url += '&enemy_crystal=' + norm_val(dom.find('.resourceIcon.crystal').closest('.resource_list_el').find('.res_value').text());
  464. url += '&enemy_deut=' + norm_val(dom.find('.resourceIcon.deuterium').closest('.resource_list_el').find('.res_value').text());
  465. url += '&enemy_pos=' + tr.find('td:eq(3)>a').text().replace(/[\[\]]/g,'');
  466. console.log(dom.find('.research109').closest('.detail_list_el.odd').find('.fright').text());
  467. if (dom.find('.research109').length == 1) {
  468. url += '&tech_d0_0='+dom.find('.research109').closest('.detail_list_el').find('.fright').text();
  469. }
  470. if (dom.find('.research110').length == 1) {
  471. url += '&tech_d0_1='+dom.find('.research110').closest('.detail_list_el').find('.fright').text();
  472. }
  473. if (dom.find('.research111').length == 1) {
  474. url += '&tech_d0_2='+dom.find('.research111').closest('.detail_list_el').find('.fright').text();
  475. }
  476. url += '&uni_speed=' + $("meta[name=ogame-universe-speed-fleet]").attr('content');
  477. url += '&start_pos=' + $("meta[name=ogame-planet-coordinates]").attr('content');
  478. url += '&plunder_perc=' + tr.find('a.open_websim').attr('lootp');
  479. var api_url = 'http://' + $("meta[name=ogame-universe]").attr('content') + '/api/serverData.xml';
  480. $.get(api_url, function(data) {
  481. url += '&perc-df='+$(data).find('debrisFactor').text()*100;
  482. url += '&def_to_df='+$(data).find('defToTF').text();
  483. if (navigator.userAgent.search(/Firefox/) > -1) {
  484. unsafeWindow.open(url, '_blank');
  485. } else {
  486. GM_openInTab(url);
  487. }
  488. });
  489. return false;
  490. });
  491.  
  492. });
  493. }
  494.  
  495. function do_msg() {
  496. parse_messages();
  497.  
  498. show_table()
  499. }
  500. function wait_msg() {
  501. if ($('.msg_status').length > 0) {
  502. do_msg();
  503. } else {
  504. setTimeout(wait_msg, 1000);
  505. }
  506. }
  507. wait_msg();
  508.  
  509. $(document).ready(function() {
  510. $(document).on('click', '#subtabs-nfFleet20', function() {
  511. setTimeout(wait_msg, 1000);
  512. });
  513. });