ServerSelector

Select servers from different gamemodes and regions.

2022-01-09 기준 버전입니다. 최신 버전을 확인하세요.

// ==UserScript==
// @name         ServerSelector
// @namespace    http://tampermonkey.net/
// @version      1.1.2
// @description  Select servers from different gamemodes and regions.
// @author       Altanis + Bismuth
// @match        *://diep.io/*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        unsafeWindow
// @license      MIT
// ==/UserScript==

// Special credits to Diep7444 for paving the way to an effective region changer.

const textShadow = 'text-shadow:black 0.18vh 0, black -0.18vh 0, black 0 -0.18vh, black 0 0.18vh, black 0.18vh 0.18vh, black -0.18vh 0.18vh, black 0.18vh -0.18vh, black -0.18vh -0.18vh, black 0.09vh 0.18vh, black -0.09vh 0.18vh, black 0.09vh -0.18vh, black -0.09vh -0.18vh, black 0.18vh 0.09vh, black -0.18vh 0.09vh, black 0.18vh -0.09vh, black -0.18vh -0.09vh'
const regions = ["do-sfo","do-nyc","do-fra","do-sgp"];
const modes = ["ffa", "teams", "4teams", "maze"];
const colors = ["#00b2e1","#bf7ff5","#00e16e","#f14e54","#FDD023"];
const modeHTML = document.createElement("div");
document.body.appendChild(modeHTML);
modeHTML.innerHTML = `
<div class='parent' id='mode' style='user-select:none; position:fixed; bottom:43%; right:0.5%; text-align:center; width:20vw; font-family:Ubuntu; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>    <div class='child' style='line-height:2vh; opacity:75%'>
        If no servers are showing, be patient.
        TAB to hide menu.
        WARNING! Do not repeatedly press buttons, as you may be ratelimited and will be unable to access diep for 15 minutes.
        <br>
        <p style="font-size:12px">Created by Altanis and Bismuth</p>
        <p style="font-size:12px">Credits to Diep7444</p>
        <hr>
    </div>
    <button class='child' type='button' id='ffa' value='mode' style='width:3.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:${colors[0]}; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>FFA</button>
    <button class='child' type='button' id='teams' value='mode' style='width:3.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:${colors[1]}; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>2TDM</button>
    <button class='child' type='button' id='4teams' value='mode' style='width:3.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:${colors[2]}; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>4TDM</button>
    <button class='child' type='button' id='maze' value='mode' style='width:3.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:${colors[3]}; color:#FFFFFF; font-style:normal; font-size:0.9vw;${textShadow}'>MAZE</button>
    <button class='child' type='button' id='sandbox' value='mode' style='width:3.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:${colors[4]}; color:#FFFFFF; font-style:normal; font-size:0.9vw;${textShadow}'>SBX</button>
    <button class='child' type='button' id='do-sfo' value='region' style='width:3.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:${colors[0]}; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>SFO</button>
    <button class='child' type='button' id='do-nyc' value='region' style='width:3.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:${colors[1]}; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>NYC</button>
    <button class='child' type='button' id='do-fra' value='region' style='width:3.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:${colors[2]}; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>FRA</button>
    <button class='child' type='button' id='do-sgp' value='region' style='width:3.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:${colors[3]}; color:#FFFFFF; font-style:normal; font-size:0.9vw;${textShadow}'>SGP</button>
    <div class='parent' id='choice' style='user-select:none; position:fixed; bottom:34%; right:0.5%; text-align:center; width:15vw; font-family:Ubuntu; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>
</div>
</div>
`
document.getElementById('mode').style.display = 'block';
addButtonListener('ffa');
addButtonListener('teams');
addButtonListener('4teams');
addButtonListener('maze');
addButtonListener('sandbox');
addButtonListener('do-sfo');
addButtonListener('do-nyc');
addButtonListener('do-fra');
addButtonListener('do-sgp');
function refreshHTML() {
    let json = "<div class='parent' id='choice' style='user-select:none; position:fixed; bottom:37%; right:0.5%; text-align:center; width:15vw; font-family:Ubuntu; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>" + choices.mode + " - " + choices.region + " <hr></div>";
    for (let n = 0; n < serverWithoutCSS[choices.mode][choices.region].length; n++) {
        json += "<button class='child' type='button' id='choice" + n + "' value='"+ n + "' style='width:5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:" + colors[n % 7] + "; color:#FFFFFF; font-style:normal; font-size:0.9vw;" + textShadow + "}'>" + serverWithoutCSS[choices.mode][choices.region][n].slice(0,8) + "</button>";
    }
    json += "</div>"
    document.getElementById('choice').innerHTML = `${json}`;
    for (let n = 0; n < serverWithoutCSS[choices.mode][choices.region].length; n++) {
        addButtonListener('choice'+n);
    }
}
function buttonAction(id) {
    let button = document.getElementById(id);
    if (button.value === 'mode') {
        choices.mode = id;
        fetchServer(choices.mode, choices.region, 3);
    }
    else if (button.value === 'region') {
        choices.region = id;
        fetchServer(choices.mode, choices.region, 3);
    }
    else {
        (connectTo(choices.mode, choices.region, button.value));
    }
    refreshHTML();
}
function addButtonListener(id) {
    document.getElementById(id).addEventListener("click", function() {buttonAction(id)});
    document.getElementById(id).addEventListener("mouseenter", function() {lightenColor(id)});
    document.getElementById(id).addEventListener("mouseleave", function() {resetColor(id)});
}
function lightenColor(id) {
    document.getElementById(id).style.opacity = '100%'
}

function resetColor(id) {
    document.getElementById(id).style.opacity = '75%'
}
const choices = {
    mode: 'ffa',
    region: 'do-sfo'
}
const serverWithoutCSS = {
    "ffa": {
        "do-sfo": [],
        "do-nyc": [],
        "do-fra": [],
        "do-sgp": []
    },
    "teams": {
        "do-sfo": [],
        "do-nyc": [],
        "do-fra": [],
        "do-sgp": []
    },
    "4teams": {
        "do-sfo": [],
        "do-nyc": [],
        "do-fra": [],
        "do-sgp": []
    },
    "maze": {
        "do-sfo": [],
        "do-nyc": [],
        "do-fra": [],
        "do-sgp": []
    },
    "sandbox": {
        "do-sfo": [],
        "do-nyc": [],
        "do-fra": [],
        "do-sgp": []
    },
};
const servers = [];
var do_connect = false;
var currentServer = '';
async function fetchServer(mode, region, times, ids = []) {
    if (mode === 'sandbox') times = 1;
    const url = "https://api-game.rivet.gg";
    for (let i = 0; i < times; i++) {
        try {
            const response = await fetch(`${url}/v1/matchmaker/lobbies/find`, {method: 'post', body: `{"game_modes": ["${mode}"], "regions": ["${region}"]}`});
            const body = await response.json();
            if (body.hasOwnProperty("lobby")) {
                Object.entries(body.lobby.ports).forEach(([key, val]) => {
                    if (!serverWithoutCSS[mode][region].some((host) => {
                        return host === val.host;
                    })) {
                        serverWithoutCSS[mode][region].push(val.host);
                        servers.push(mode + " " + region + " " + serverWithoutCSS[mode][region].length + ": " + val.host.slice(0,8));
                        const txt = key;
                    }
                });
            }
        } catch (err) {
            console.error(err);
        }
    }
    refreshHTML();
}
function appendServers(mode, region) {
    fetchServer(mode, region, 3);
}
function connectTo(mode, region, number) {
    if (!serverWithoutCSS[mode][region][number]) return;
    currentServer = "wss://" + serverWithoutCSS[mode][region][number];
    do_connect = true;
    unsafeWindow.input.execute('lb_reconnect');
}
unsafeWindow.servers = serverWithoutCSS;
unsafeWindow.WebSocket = new Proxy(WebSocket, {construct(t, args) {
    if (do_connect) args[0] = currentServer;
    do_connect = false; return Reflect.construct(t, args)}});
document.body.onkeydown = function(e) {
    if (e.keyCode === 9) {
        if (document.getElementById('mode').style.display === "none") {
            document.getElementById('mode').style.display = "block";
            document.getElementById('choice').style.display = "block";
        } else {
            document.getElementById('mode').style.display = "none";
            document.getElementById('choice').style.display = "none";
        }
    }
}