Pings available servers and lets you pick the one you want. This is a good plugin for playing with friends.
// ==UserScript==
// @name Slither.io Server Picker
// @namespace http://tampermonkey.net/
// @version 0.1.11
// @description Pings available servers and lets you pick the one you want. This is a good plugin for playing with friends.
// @author SystemDisc
// @match http://slither.io/
// @grant none
// @run-at document-start
// @require https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js
// ==/UserScript==
(function() {
'use strict';
let serverData = $.ajax({
type: 'GET',
url: 'http://slither.io/i33628.txt',
async: false
}).responseText;
let currentZoom = 0.9;
$(function() {
let css = `
iframe[src="/social-box/"] {
display: none !important;
}
#HUD, #sidebar {
position: fixed;
top: 0;
left: 0;
z-index: 20;
padding: 15px;
background-color: rgba(0,0,0,0.5);
color: #fff;
}
#sidebar {
height: 100vh;
overflow: auto;
}
#connectForm {
margin-bottom: 15px;
}
#serverList > .server-listing {
margin-bottom: 5px;
cursor: pointer;
}
#serverList > .server-listing > .server-name, #serverList > .server-listing > .server-ping {
display: inline-block;
}
#serverList > .server-listing > .server-ping {
margin-left: 10px;
color: green;
}
#serverList > .server-listing > .server-ping.bad {
color: red;
}
`;
let styleSheet = $('<style type="text/css">');
styleSheet.html(css);
let HUD = $('<div id="HUD">');
let server = $('<div class="server">');
let coordinates = $('<div class="coordinates">');
let section = $('<div class="section">');
HUD.append(server);
HUD.append(coordinates);
HUD.append(section);
let sidebar = $('<div id="sidebar">');
let connectForm = $('<div id="connectForm">');
let serverInput = $('<input class="server-input" type="test" name="serverHostname" placeholder="ip:port">');
let serverConnect = $('<button class="connect-button" type="button">Connect</button>');
connectForm.append(serverInput);
connectForm.append(serverConnect);
let serverList = $('<div id="serverList">');
sidebar.append(connectForm);
sidebar.append(serverList);
$('body').append(HUD);
$('body').append(sidebar);
$('head').append(styleSheet);
$('#HUD').hide();
$(document).on('click', '#connectForm > .connect-button', function(e) {
selectServer($('.server-input').val());
});
$(document).on('click', '#serverList > .server-listing', function(e) {
selectServer($(e.currentTarget).find('.server-name').text());
});
let start = true;
setInterval(function() {
if (!window.playing) {
$('#sidebar').show();
$('#HUD').hide();
if (!$('#nick').hasClass('loaded')) {
$('#nick').val(localStorage.getItem('savedNick'));
$('#nick').addClass('loaded');
}
if (start) {
loadServers();
start = false;
}
}
else {
$('#sidebar').hide();
$('#HUD').show();
start = true;
}
window.want_quality = 1;
window.render_mode = 1;
window.high_quality = true;
window.gla = false;
window.ggbg = false;
if (window.gbgi) {
window.gbgi.src = '';
window.gbgi.onload = null;
window.gbgi = null;
if (window.gbgmc) {
window.gbgmc = null;
}
}
window.gsc = currentZoom;
if (window.snake) {
$('#HUD').find('.server').text('Server: ' + window.bso.ip + ':' + window.bso.po);
$('#HUD').find('.coordinates').text('Coordinates: ' + Math.round(window.snake.xx / 100) + ', ' + Math.round(window.snake.yy / 100));
$('#HUD').find('.section').text('Section: ' + Math.round((window.snake.xx - 22000) / 1000) + ', ' + Math.round((window.snake.yy - 22000)/1000));
localStorage.setItem('savedNick', snake.nk);
}
if (window.bso && window.bso.ip) {
document.title = 'slither.io - ' + window.bso.ip + ':' + window.bso.po;
}
else {
document.title = 'slither.io - disconnected'
}
}, 15);
$(document).bind('DOMMouseScroll mousewheel', zoom);
$(window).keydown(function(e) {
console.log('keydown: ' + e.keyCode);
if (e.keyCode === 27) {
quit();
}
if (e.keyCode === 90) {
currentZoom = 0.9;
}
});
});
function loadServers() {
let serverList = $('#serverList');
serverList.children().remove();
let servers = loadSos(serverData);
let savedServers = window.localStorage.getItem('servers');
if (!savedServers) {
savedServers = {};
}
else {
savedServers = JSON.parse(savedServers);
}
for (let servername in savedServers) {
let ip;
let port;
[ip, port] = servername.split(':');
servers.push({ip: ip, po: port});
}
let promises = [];
servers.forEach(function(server) {
let serverElem = $('[id="' + server.ip + '"]');
let serverNameElem;
let serverPingElem;
if (serverElem.length === 0) {
serverElem = $('<div id="' + server.ip + '" class="server-listing">');
serverNameElem = $('<div class="server-name">');
serverPingElem = $('<div class="server-ping">');
serverNameElem.text(server.ip + ':' + server.po);
serverElem.append(serverNameElem);
serverElem.append(serverPingElem);
serverList.append(serverElem);
}
else {
serverNameElem = serverElem.find('.server-name');
serverPingElem = serverElem.find('.server-ping');
}
let promise = pingServer(server.ip).then(function(ping) {
if (savedServers[server.ip + ':' + server.po]) {
ping = Math.round((savedServers[server.ip + ':' + server.po] + ping) / 2);
}
let pingElem = $('[id="' + server.ip + '"]').find('.server-ping');
pingElem.text(ping);
if (ping > 75) {
pingElem.addClass('bad');
}
else {
savedServers[server.ip + ':' + server.po] = ping;
pingElem.removeClass('bad');
}
let serverList = $('#serverList');
let serverElems = serverList.children();
serverElems.sort(function(a, b) {
let an = +$(a).find('.server-ping').text();
let bn = +$(b).find('.server-ping').text();
if (an === 0) {
an = 1000;
}
if (bn === 0) {
bn = 1000;
}
return an > bn? 1:(an < bn? -1:0);
});
serverElems.detach().appendTo(serverList);
if (!window.bso || !window.bso.ip) {
$('.server-input').val(serverElems.first().find('.server-name').text());
}
}).catch(function(err) {
$('[id="' + server.ip + '"]').remove();
delete savedServers[server.ip + ':' + server.po];
return false;
});
promises.push(promise);
});
Promise.all(promises).then(function() {
localStorage.setItem('servers', JSON.stringify(savedServers));
selectServer($('.server-input').val());
});
}
function quit() {
if (window.playing && window.resetGame) {
window.want_close_socket = true;
window.dead_mtm = 0;
if (window.play_btn) {
window.play_btn.setEnabled(true);
}
window.resetGame();
}
}
function zoom(e) {
console.log(window.gsc);
if (!window.gsc) {
return;
}
currentZoom *= Math.pow(0.9, e.originalEvent.wheelDelta / -120 || e.originalEvent.detail / 2 || 0);
}
function selectServer(servername) {
let ip;
let port;
[ip, port] = servername.split(':');
console.log(ip, +port);
window.forceServer(ip, +port);
let serverElem = $('[id="' + ip + '"]');
serverElem.addClass('selected');
serverElem.siblings().removeClass('selected');
$('.server-input').val(servername);
}
function loadSos(chars) {
/** @type {Array} */
sos = [];
/** @type {Array} */
clus = [];
chars.charAt(0);
/** @type {number} */
var i = 1;
var d = {};
/** @type {number} */
var index = 0;
/** @type {number} */
d = index = 0;
var c;
/** @type {number} */
var data = 0;
/** @type {number} */
var handle = 0;
/** @type {Array} */
var split = [];
/** @type {Array} */
var m = [];
/** @type {Array} */
var messages = [];
/** @type {Array} */
var received = [];
for (;i < chars.length;) {
if (c = (chars.charCodeAt(i++) - 97 - handle) % 26, 0 > c && (c += 26), data *= 16, data += c, handle += 7, 1 == d) {
if (0 == index) {
split.push(data);
if (4 == split.length) {
index++;
}
} else {
if (1 == index) {
m.push(data);
if (3 == m.length) {
index++;
}
} else {
if (2 == index) {
messages.push(data);
if (3 == messages.length) {
index++;
}
} else {
if (3 == index && (received.push(data), 1 == received.length)) {
d = {};
/** @type {number} */
index = c = 0;
for (;index < m.length;index++) {
c *= 256;
c += m[index];
}
/** @type {number} */
index = m = 0;
for (;index < messages.length;index++) {
m *= 256;
m += messages[index];
}
/** @type {string} */
d.ip = split.join(".");
d.po = c;
d.ac = m;
d.wg = m + 5;
d.clu = received[0];
/** @type {Array} */
sos.push(d);
/** @type {Array} */
split = [];
/** @type {Array} */
m = [];
/** @type {Array} */
messages = [];
/** @type {Array} */
received = [];
/** @type {number} */
index = 0;
}
}
}
}
/** @type {number} */
d = data = 0;
} else {
d++;
}
}
return sos;
}
function pingServer(ip) {
return new Promise(function(resolve, reject) {
let handle = null;
let ping = Date.now();
try {
handle = new WebSocket('ws://' + ip + ':80/ptc');
}
catch (e) {
handle = null;
reject(e);
}
if (handle) {
handle.binaryType = "arraybuffer";
handle.onerror = function(err) {
reject(err);
};
handle.onmessage = function(data) {
let pong = Date.now();
if (testing) {
console.log(ip, ping, pong, pong - ping, data);
}
resolve(pong - ping);
};
handle.onopen = function(body) {
console.log(body);
ping = Date.now();
let data = new Uint8Array(1);
data[0] = 112;
this.send(data);
};
}
});
}
})();