您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
gives you magical ping!
- // ==UserScript==
- // @name server changer
- // @version 0.1
- // @description gives you magical ping!
- // @author wealthydev
- // @match *://*.tankionline.com/*
- // @grant none
- // @run-at document-start
- // @namespace https://greasyfork.org/users/1347888
- // ==/UserScript==
- (function() {
- const ws = WebSocket;
- window.WebSocket = class extends ws {
- constructor(url) {
- let data = window.target_server?.split(":"),
- target = data ? `wss://${data[0]}.tankionline.com:${data[1]}/` : null;
- super(target || url);
- console.log("server", this.url);
- }
- };
- const server_changer = (JSON.parse(localStorage.getItem("server_changer")) || {});
- window.target_server = server_changer.target;
- server_changer.target = null;
- if(window.target_server) {
- localStorage.setItem("server_changer", JSON.stringify(server_changer));
- return alert(`targeting server [${window.target_server}]`)
- }
- let shadow = { host: document.createElement("div") }
- document.body.appendChild(shadow.host);
- shadow.root = shadow.host.attachShadow({ mode: 'open' });
- shadow.root.innerHTML = `<style>.mini-box{z-index:999999;position:absolute;top:100px;left:100px;width:140px;background-color:#f9f9f9;border:1px solid #ccc;border-radius:6px;padding:10px;box-shadow:0 2px 10px rgba(0,0,0,.1);cursor:move;user-select:none}.mini-box label,.mini-box select{font-size:12px}.mini-box select{width:100%;padding:4px;margin-top:5px}</style><script></script><div class=mini-box id=box><div style=display:flex;justify-content:space-between;align-items:center;margin-bottom:6px><label style=font-size:large>servers</label> <button id=connect_server style="font-size:10px;padding:4px 8px">connect</button></div></div>`;
- const box = shadow.root.querySelector("#box")
- let hue = 0;
- function animate() {
- hue = (hue + 1) % 360;
- box.style["background-color"] = `hsl(${hue}, 100%, 60%)`;
- }
- setInterval(animate, 50);
- function update_list(servers) {
- const select = document.createElement("select");
- select.name = "servers";
- select.id = "server";
- select.style.marginTop = "8px";
- let option = document.createElement("option");
- option.value = option.text = `default`;
- select.appendChild(option);
- const sorted = Object.entries(servers).sort((a, b) => a[1] - b[1]);
- sorted.forEach(([name, ping]) => {
- option = document.createElement("option");
- option.value = name;
- option.text = `${name.split(":")[0]} / ${ping} ms`;
- select.appendChild(option);
- });
- box.appendChild(select);
- select.value = `default`;
- const button = shadow.root.querySelector("#connect_server");
- button.addEventListener("click", () => {
- if(select.value === "default") return box.remove();
- server_changer.target = select.value;
- localStorage.setItem("server_changer", JSON.stringify(server_changer));
- return window.location.reload();
- });
- }
- const scan = (url, callback) => {
- const ws = new WebSocket(url);
- let start, pause;
- ws.onopen = () => {
- start = Date.now();
- ws.close();
- }
- ws.onclose = () => {
- const responseTime = Date.now() - start;
- callback(Math.round(responseTime / 2));
- clearTimeout(pause);
- }
- ws.onerror = () => {
- callback();
- ws.close();
- clearTimeout(pause);
- }
- pause = setTimeout(() => {
- callback();
- ws.close();
- }, 500);
- }
- let servers;
- function update() {
- fetch("https://tankionline.com/s/status.js").then(async res => {
- const data = await res.json();
- servers = {};
- for (const [, value] of Object.entries(data.nodes)) {
- let server = value.endpoint,
- key = server.host.split(".tanki")[0];
- if(server.status !== "NORMAL") continue;
- scan(`wss://${server.host}:${server.wsPorts[0]}`, function(ping) {
- if(!ping) return null;
- servers[`${key}:${server.wsPorts[0]}`] = ping;
- });
- }
- setTimeout(() => update_list(servers), 1e3)
- });
- }
- update();
- })();