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.8
  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. servers.forEach(function(server) {
  83. let serverElem = $('<div id="' + server.ip + '" class="server-listing">');
  84. let serverNameElem = $('<div class="server-name">');
  85. let serverPingElem = $('<div class="server-ping">');
  86. serverNameElem.text(server.ip + ':' + server.po);
  87. serverElem.append(serverNameElem);
  88. serverElem.append(serverPingElem);
  89. serverList.append(serverElem);
  90. let promise = pingServer(server.ip).then(function(ping) {
  91. let pingElem = $('[id="' + server.ip + '"]').find('.server-ping');
  92. pingElem.text(ping);
  93. if (ping > 75) {
  94. pingElem.addClass('bad');
  95. }
  96. let serverList = $('#serverList');
  97. let serverElems = serverList.children();
  98. serverElems.sort(function(a, b) {
  99. let an = +$(a).find('.server-ping').text();
  100. let bn = +$(b).find('.server-ping').text();
  101. if (an === 0) {
  102. an = 1000;
  103. }
  104. if (bn === 0) {
  105. bn = 1000;
  106. }
  107. return an > bn? 1:(an < bn? -1:0);
  108. });
  109. serverElems.detach().appendTo(serverList);
  110. $('.server-input').val(serverElems.first().find('.server-name').text());
  111. }).catch(function(err) {
  112. $('[id="' + server.ip + '"]').remove();
  113. return false;
  114. });
  115. promises.push(promise);
  116. });
  117. sidebar.append(connectForm);
  118. sidebar.append(serverList);
  119. $('body').append(HUD);
  120. $('body').append(sidebar);
  121. $('head').append(styleSheet);
  122.  
  123. $('#HUD').hide();
  124.  
  125. $(document).on('click', '#connectForm > .connect-button', function(e) {
  126. selectServer($('.server-input').val());
  127. });
  128.  
  129. $(document).on('click', '#serverList > .server-listing', function(e) {
  130. selectServer($(e.currentTarget).find('.server-name').text());
  131. });
  132.  
  133. setInterval(function() {
  134. if (!window.playing) {
  135. $('#sidebar').show();
  136. $('#HUD').hide();
  137. }
  138. else {
  139. $('#sidebar').hide();
  140. $('#HUD').show();
  141. }
  142. window.want_quality = 0;
  143. window.ggbg = false;
  144. window.gla = false;
  145.  
  146. window.gsc = currentZoom;
  147.  
  148. if (window.snake) {
  149. $('#HUD').find('.server').text('Server: ' + window.bso.ip + ':' + window.bso.po);
  150. $('#HUD').find('.coordinates').text('Coordinates: ' + Math.round(window.snake.xx / 100) + ', ' + Math.round(window.snake.yy / 100));
  151. $('#HUD').find('.section').text('Section: ' + Math.round((window.snake.xx - 22000) / 1000) + ', ' + Math.round((window.snake.yy - 22000)/1000));
  152. }
  153.  
  154. if (window.bso && window.bso.ip) {
  155. document.title = 'slither.io - ' + window.bso.ip + ':' + window.bso.po;
  156. }
  157. else {
  158. document.title = 'slither.io - disconnected'
  159. }
  160. }, 15);
  161.  
  162. $(document).bind('DOMMouseScroll mousewheel', zoom);
  163.  
  164. $(window).keydown(function(e) {
  165. console.log('keydown: ' + e.keyCode);
  166.  
  167. if (e.keyCode === 27) {
  168. quit();
  169. }
  170.  
  171. if (e.keyCode === 90) {
  172. currentZoom = 0.9;
  173. }
  174. });
  175. });
  176.  
  177. console.log(servers);
  178.  
  179. function quit() {
  180. if (window.playing && window.resetGame) {
  181. window.want_close_socket = true;
  182. window.dead_mtm = 0;
  183. if (window.play_btn) {
  184. window.play_btn.setEnabled(true);
  185. }
  186. window.resetGame();
  187. }
  188. }
  189.  
  190. function zoom(e) {
  191. console.log(window.gsc);
  192. if (!window.gsc) {
  193. return;
  194. }
  195. currentZoom *= Math.pow(0.9, e.originalEvent.wheelDelta / -120 || e.originalEvent.detail / 2 || 0);
  196. }
  197.  
  198. function selectServer(servername) {
  199. let ip;
  200. let port;
  201. [ip, port] = servername.split(':');
  202. console.log(ip, +port);
  203. window.forceServer(ip, +port);
  204. let serverElem = $('[id="' + ip + '"]');
  205. serverElem.addClass('selected');
  206. serverElem.siblings().removeClass('selected');
  207. $('.server-input').val(servername);
  208. }
  209.  
  210.  
  211. function loadSos(chars) {
  212. /** @type {Array} */
  213. sos = [];
  214. /** @type {Array} */
  215. clus = [];
  216. chars.charAt(0);
  217. /** @type {number} */
  218. var i = 1;
  219. var d = {};
  220. /** @type {number} */
  221. var index = 0;
  222. /** @type {number} */
  223. d = index = 0;
  224. var c;
  225. /** @type {number} */
  226. var data = 0;
  227. /** @type {number} */
  228. var handle = 0;
  229. /** @type {Array} */
  230. var split = [];
  231. /** @type {Array} */
  232. var m = [];
  233. /** @type {Array} */
  234. var messages = [];
  235. /** @type {Array} */
  236. var received = [];
  237. for (;i < chars.length;) {
  238. if (c = (chars.charCodeAt(i++) - 97 - handle) % 26, 0 > c && (c += 26), data *= 16, data += c, handle += 7, 1 == d) {
  239. if (0 == index) {
  240. split.push(data);
  241. if (4 == split.length) {
  242. index++;
  243. }
  244. } else {
  245. if (1 == index) {
  246. m.push(data);
  247. if (3 == m.length) {
  248. index++;
  249. }
  250. } else {
  251. if (2 == index) {
  252. messages.push(data);
  253. if (3 == messages.length) {
  254. index++;
  255. }
  256. } else {
  257. if (3 == index && (received.push(data), 1 == received.length)) {
  258. d = {};
  259. /** @type {number} */
  260. index = c = 0;
  261. for (;index < m.length;index++) {
  262. c *= 256;
  263. c += m[index];
  264. }
  265. /** @type {number} */
  266. index = m = 0;
  267. for (;index < messages.length;index++) {
  268. m *= 256;
  269. m += messages[index];
  270. }
  271. /** @type {string} */
  272. d.ip = split.join(".");
  273. d.po = c;
  274. d.ac = m;
  275. d.wg = m + 5;
  276. d.clu = received[0];
  277. /** @type {Array} */
  278. sos.push(d);
  279. /** @type {Array} */
  280. split = [];
  281. /** @type {Array} */
  282. m = [];
  283. /** @type {Array} */
  284. messages = [];
  285. /** @type {Array} */
  286. received = [];
  287. /** @type {number} */
  288. index = 0;
  289. }
  290. }
  291. }
  292. }
  293. /** @type {number} */
  294. d = data = 0;
  295. } else {
  296. d++;
  297. }
  298. }
  299. return sos;
  300. }
  301.  
  302. function pingServer(ip) {
  303. return new Promise(function(resolve, reject) {
  304. let handle = null;
  305. let ping = Date.now();
  306. try {
  307. handle = new WebSocket('ws://' + ip + ':80/ptc');
  308. }
  309. catch (e) {
  310. handle = null;
  311. reject(e);
  312. }
  313. if (handle) {
  314. handle.binaryType = "arraybuffer";
  315. handle.onerror = function(err) {
  316. reject(err);
  317. };
  318. handle.onmessage = function(data) {
  319. let pong = Date.now();
  320. if (testing) {
  321. console.log(ip, ping, pong, pong - ping, data);
  322. }
  323. resolve(pong - ping);
  324. };
  325. handle.onopen = function(body) {
  326. console.log(body);
  327. ping = Date.now();
  328. let data = new Uint8Array(1);
  329. data[0] = 112;
  330. this.send(data);
  331. };
  332. }
  333. });
  334. }
  335. })();