Slither.io Server Picker

Pings available servers and lets you pick the one you want. This is a good plugin for playing with friends.

目前為 2017-01-12 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Slither.io Server Picker
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1.10
  5. // @description Pings available servers and lets you pick the one you want. This is a good plugin for playing with friends.
  6. // @author SystemDisc
  7. // @match http://slither.io/
  8. // @grant none
  9. // @run-at document-start
  10. // @require https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. let serverData = $.ajax({
  17. type: 'GET',
  18. url: 'http://slither.io/i33628.txt',
  19. async: false
  20. }).responseText;
  21.  
  22. let servers = loadSos(serverData);
  23. let currentZoom = 0.9;
  24.  
  25. $(function() {
  26. let css = `
  27. iframe[src="/social-box/"] {
  28. display: none !important;
  29. }
  30. #HUD, #sidebar {
  31. position: fixed;
  32. top: 0;
  33. left: 0;
  34. z-index: 20;
  35. padding: 15px;
  36. background-color: rgba(0,0,0,0.5);
  37. color: #fff;
  38. }
  39. #sidebar {
  40. height: 100vh;
  41. overflow: auto;
  42. }
  43. #connectForm {
  44. margin-bottom: 15px;
  45. }
  46. #serverList > .server-listing {
  47. margin-bottom: 5px;
  48. cursor: pointer;
  49. }
  50. #serverList > .server-listing > .server-name, #serverList > .server-listing > .server-ping {
  51. display: inline-block;
  52. }
  53. #serverList > .server-listing > .server-ping {
  54. margin-left: 10px;
  55. color: green;
  56. }
  57. #serverList > .server-listing > .server-ping.bad {
  58. color: red;
  59. }
  60. `;
  61. let styleSheet = $('<style type="text/css">');
  62. styleSheet.html(css);
  63.  
  64. let HUD = $('<div id="HUD">');
  65. let server = $('<div class="server">');
  66. let coordinates = $('<div class="coordinates">');
  67. let section = $('<div class="section">');
  68. HUD.append(server);
  69. HUD.append(coordinates);
  70. HUD.append(section);
  71.  
  72. let sidebar = $('<div id="sidebar">');
  73.  
  74. let connectForm = $('<div id="connectForm">');
  75. let serverInput = $('<input class="server-input" type="test" name="serverHostname" placeholder="ip:port">');
  76. let serverConnect = $('<button class="connect-button" type="button">Connect</button>');
  77. connectForm.append(serverInput);
  78. connectForm.append(serverConnect);
  79.  
  80. let serverList = $('<div id="serverList">');
  81. let promises = [];
  82. let savedServers = window.localStorage.getItem('servers');
  83. if (!savedServers) {
  84. savedServers = {};
  85. }
  86. else {
  87. savedServers = JSON.parse(savedServers);
  88. }
  89. for (let servername in savedServers) {
  90. let ip;
  91. let port;
  92. [ip, port] = servername.split(':');
  93. servers.push({ip: ip, po: port});
  94. }
  95. servers.forEach(function(server) {
  96. let serverElem = $('<div id="' + server.ip + '" class="server-listing">');
  97. let serverNameElem = $('<div class="server-name">');
  98. let serverPingElem = $('<div class="server-ping">');
  99. serverNameElem.text(server.ip + ':' + server.po);
  100. serverElem.append(serverNameElem);
  101. serverElem.append(serverPingElem);
  102. serverList.append(serverElem);
  103. let promise = pingServer(server.ip).then(function(ping) {
  104. if (savedServers[server.ip + ':' + server.po]) {
  105. ping = Math.round((savedServers[server.ip + ':' + server.po] + ping) / 2);
  106. }
  107. let pingElem = $('[id="' + server.ip + '"]').find('.server-ping');
  108. pingElem.text(ping);
  109. if (ping > 75) {
  110. pingElem.addClass('bad');
  111. delete savedServers[server.ip + ':' + server.po];
  112. }
  113. else {
  114. savedServers[server.ip + ':' + server.po] = ping;
  115. pingElem.removeClass('bad');
  116. }
  117. let serverList = $('#serverList');
  118. let serverElems = serverList.children();
  119. serverElems.sort(function(a, b) {
  120. let an = +$(a).find('.server-ping').text();
  121. let bn = +$(b).find('.server-ping').text();
  122. if (an === 0) {
  123. an = 1000;
  124. }
  125. if (bn === 0) {
  126. bn = 1000;
  127. }
  128. return an > bn? 1:(an < bn? -1:0);
  129. });
  130. serverElems.detach().appendTo(serverList);
  131. $('.server-input').val(serverElems.first().find('.server-name').text());
  132. }).catch(function(err) {
  133. $('[id="' + server.ip + '"]').remove();
  134. delete savedServers[server.ip + ':' + server.po];
  135. return false;
  136. });
  137. promises.push(promise);
  138. });
  139.  
  140. Promise.all(promises).then(function() {
  141. localStorage.setItem('servers', JSON.stringify(savedServers));
  142. selectServer($('.server-input').val());
  143. });
  144.  
  145. sidebar.append(connectForm);
  146. sidebar.append(serverList);
  147. $('body').append(HUD);
  148. $('body').append(sidebar);
  149. $('head').append(styleSheet);
  150.  
  151. $('#HUD').hide();
  152.  
  153. $(document).on('click', '#connectForm > .connect-button', function(e) {
  154. selectServer($('.server-input').val());
  155. });
  156.  
  157. $(document).on('click', '#serverList > .server-listing', function(e) {
  158. selectServer($(e.currentTarget).find('.server-name').text());
  159. });
  160.  
  161. setInterval(function() {
  162. if (!window.playing) {
  163. $('#sidebar').show();
  164. $('#HUD').hide();
  165. if (!$('#nick').hasClass('loaded')) {
  166. $('#nick').val(localStorage.getItem('savedNick'));
  167. $('#nick').addClass('loaded');
  168. }
  169. }
  170. else {
  171. $('#sidebar').hide();
  172. $('#HUD').show();
  173. }
  174. window.want_quality = 1;
  175. window.render_mode = 1;
  176. window.high_quality = true;
  177. window.gla = false;
  178. window.ggbg = false;
  179. if (window.gbgi) {
  180. window.gbgi.src = '';
  181. window.gbgi.onload = null;
  182. window.gbgi = null;
  183. if (window.gbgmc) {
  184. window.gbgmc = null;
  185. }
  186. }
  187.  
  188. window.gsc = currentZoom;
  189.  
  190. if (window.snake) {
  191. $('#HUD').find('.server').text('Server: ' + window.bso.ip + ':' + window.bso.po);
  192. $('#HUD').find('.coordinates').text('Coordinates: ' + Math.round(window.snake.xx / 100) + ', ' + Math.round(window.snake.yy / 100));
  193. $('#HUD').find('.section').text('Section: ' + Math.round((window.snake.xx - 22000) / 1000) + ', ' + Math.round((window.snake.yy - 22000)/1000));
  194. localStorage.setItem('savedNick', snake.nk);
  195. }
  196.  
  197. if (window.bso && window.bso.ip) {
  198. document.title = 'slither.io - ' + window.bso.ip + ':' + window.bso.po;
  199. }
  200. else {
  201. document.title = 'slither.io - disconnected'
  202. }
  203. }, 15);
  204.  
  205. $(document).bind('DOMMouseScroll mousewheel', zoom);
  206.  
  207. $(window).keydown(function(e) {
  208. console.log('keydown: ' + e.keyCode);
  209.  
  210. if (e.keyCode === 27) {
  211. quit();
  212. }
  213.  
  214. if (e.keyCode === 90) {
  215. currentZoom = 0.9;
  216. }
  217. });
  218. });
  219.  
  220. console.log(servers);
  221.  
  222. function quit() {
  223. if (window.playing && window.resetGame) {
  224. window.want_close_socket = true;
  225. window.dead_mtm = 0;
  226. if (window.play_btn) {
  227. window.play_btn.setEnabled(true);
  228. }
  229. window.resetGame();
  230. }
  231. }
  232.  
  233. function zoom(e) {
  234. console.log(window.gsc);
  235. if (!window.gsc) {
  236. return;
  237. }
  238. currentZoom *= Math.pow(0.9, e.originalEvent.wheelDelta / -120 || e.originalEvent.detail / 2 || 0);
  239. }
  240.  
  241. function selectServer(servername) {
  242. let ip;
  243. let port;
  244. [ip, port] = servername.split(':');
  245. console.log(ip, +port);
  246. window.forceServer(ip, +port);
  247. let serverElem = $('[id="' + ip + '"]');
  248. serverElem.addClass('selected');
  249. serverElem.siblings().removeClass('selected');
  250. $('.server-input').val(servername);
  251. }
  252.  
  253.  
  254. function loadSos(chars) {
  255. /** @type {Array} */
  256. sos = [];
  257. /** @type {Array} */
  258. clus = [];
  259. chars.charAt(0);
  260. /** @type {number} */
  261. var i = 1;
  262. var d = {};
  263. /** @type {number} */
  264. var index = 0;
  265. /** @type {number} */
  266. d = index = 0;
  267. var c;
  268. /** @type {number} */
  269. var data = 0;
  270. /** @type {number} */
  271. var handle = 0;
  272. /** @type {Array} */
  273. var split = [];
  274. /** @type {Array} */
  275. var m = [];
  276. /** @type {Array} */
  277. var messages = [];
  278. /** @type {Array} */
  279. var received = [];
  280. for (;i < chars.length;) {
  281. if (c = (chars.charCodeAt(i++) - 97 - handle) % 26, 0 > c && (c += 26), data *= 16, data += c, handle += 7, 1 == d) {
  282. if (0 == index) {
  283. split.push(data);
  284. if (4 == split.length) {
  285. index++;
  286. }
  287. } else {
  288. if (1 == index) {
  289. m.push(data);
  290. if (3 == m.length) {
  291. index++;
  292. }
  293. } else {
  294. if (2 == index) {
  295. messages.push(data);
  296. if (3 == messages.length) {
  297. index++;
  298. }
  299. } else {
  300. if (3 == index && (received.push(data), 1 == received.length)) {
  301. d = {};
  302. /** @type {number} */
  303. index = c = 0;
  304. for (;index < m.length;index++) {
  305. c *= 256;
  306. c += m[index];
  307. }
  308. /** @type {number} */
  309. index = m = 0;
  310. for (;index < messages.length;index++) {
  311. m *= 256;
  312. m += messages[index];
  313. }
  314. /** @type {string} */
  315. d.ip = split.join(".");
  316. d.po = c;
  317. d.ac = m;
  318. d.wg = m + 5;
  319. d.clu = received[0];
  320. /** @type {Array} */
  321. sos.push(d);
  322. /** @type {Array} */
  323. split = [];
  324. /** @type {Array} */
  325. m = [];
  326. /** @type {Array} */
  327. messages = [];
  328. /** @type {Array} */
  329. received = [];
  330. /** @type {number} */
  331. index = 0;
  332. }
  333. }
  334. }
  335. }
  336. /** @type {number} */
  337. d = data = 0;
  338. } else {
  339. d++;
  340. }
  341. }
  342. return sos;
  343. }
  344.  
  345. function pingServer(ip) {
  346. return new Promise(function(resolve, reject) {
  347. let handle = null;
  348. let ping = Date.now();
  349. try {
  350. handle = new WebSocket('ws://' + ip + ':80/ptc');
  351. }
  352. catch (e) {
  353. handle = null;
  354. reject(e);
  355. }
  356. if (handle) {
  357. handle.binaryType = "arraybuffer";
  358. handle.onerror = function(err) {
  359. reject(err);
  360. };
  361. handle.onmessage = function(data) {
  362. let pong = Date.now();
  363. if (testing) {
  364. console.log(ip, ping, pong, pong - ping, data);
  365. }
  366. resolve(pong - ping);
  367. };
  368. handle.onopen = function(body) {
  369. console.log(body);
  370. ping = Date.now();
  371. let data = new Uint8Array(1);
  372. data[0] = 112;
  373. this.send(data);
  374. };
  375. }
  376. });
  377. }
  378. })();