您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Select servers from different gamemodes and regions for Diep. Also restores player count for Diep.io.
当前为
// ==UserScript== // @name Diep.io Server Selector + Restore Player Count // @namespace http://tampermonkey.net/ // @version 2.1.0 // @description Select servers from different gamemodes and regions for Diep. Also restores player count for Diep.io. // @author Altanis + Bismuth // @match *://diep.io/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant unsafeWindow // @grant GM_setClipboard // @license MIT // ==/UserScript== (async function() { // 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", "survival","teams", "4teams", "dom","tag","maze","sandbox"]; const colors = ["#E8B18A", "#E666EA", "#9566EA", "#6690EA", "#E7D063", "#EA6666", "#92EA66", "#66EAE6"]; var PLAYER_COUNT = 0; var _resp = await fetch(`https://api-game.rivet.gg/v1/matchmaker/lobbies/list`); var lists = await _resp.json(); if (!localStorage.lists) { localStorage.lists = JSON.stringify({ timestamp: Date.now(), list: lists, }); } setInterval(async function() { if (!localStorage.lists) { localStorage.lists = JSON.stringify({ timestamp: Date.now(), list: lists, }); } if (Date.now() - JSON.parse(localStorage.lists)?.timestamp > 3e5) { var _resp = await fetch(`https://api-game.rivet.gg/v1/matchmaker/lobbies/list`); var lists = await _resp.json(); localStorage.lists = JSON.stringify({ timestamp: Date.now(), list: lists, }); console.log('Refreshed server list.'); } }, 5000); const modeHTML = document.createElement("div"); document.body.appendChild(modeHTML); modeHTML.innerHTML = ` <div class='parent' id='ServerSelector' style='user-select:none; position:fixed; top:25%; right:0.5%; text-align:center; width:15vw; font-family:Ubuntu; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'><div class='child' style='line-height:2vh; opacity:75%'> TAB to show server selector <br> <p style="font-size:12px">Created by Altanis and Bismuth</p> <hr> </div> <p style="font-size:10px">Game Mode</p> <button class='child' type='button' id='ffa' value='mode' style='width:3.5vw; height:3vh; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[7]}; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>FFA</button> <button class='child' type='button' id='survival' value='mode' style='width:3.5vw; height:3vh; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[6]}; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>SURV</button> <button class='child' type='button' id='teams' value='mode' style='width:3.5vw; height:3vh; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[5]}; 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; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[4]}; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>4TDM</button> <button class='child' type='button' id='dom' value='mode' style='width:3.5vw; height:3vh; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[3]}; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>DOM</button> <button class='child' type='button' id='tag' value='mode' style='width:3.5vw; height:3vh; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[2]}; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'>TAG</button> <button class='child' type='button' id='maze' value='mode' style='width:3.5vw; height:3vh; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[1]}; 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; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[0]}; color:#FFFFFF; font-style:normal; font-size:0.9vw;${textShadow}'>SBX</button> <p style="font-size:10px">Region</p> <button class='child' type='button' id='do-sfo' value='region' style='width:3.5vw; height:3vh; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[3]}; 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; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[2]}; 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; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[6]}; 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; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[5]}; color:#FFFFFF; font-style:normal; font-size:0.9vw;${textShadow}'>SGP</button> <div class='parent' id='choice' style='user-select:none; position:relative; top:65%; left:0.5%; text-align:center; width:15vw; font-family:Ubuntu; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'> <br> </div> </div> ` document.getElementById('ServerSelector').style.display = 'block'; for (let mode of modes) { addButtonListener(mode); } for (let region of regions) { addButtonListener(region); } function refreshHTML() { let json = `<div class='parent' id='choice' style='user-select:none; position:relative; top:65%; left:0.5%; text-align:center; width:15vw; font-family:Ubuntu; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'><p style="font-size:12px"> </p><div class='child' style='line-height:2vh; opacity:75%'> Servers for ${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:6vw; height:3vh; border-radius: 0.5vw; font-family:Ubuntu; opacity:60%; background:${colors[n % 8]}; color:#FFFFFF; font-style:normal; font-size:0.9vw; ${textShadow}'> ${currentServer.includes(serverWithoutCSS[choices.mode][choices.region][n].slice(0,8))? '>': ''}${serverWithoutCSS[choices.mode][choices.region][n].slice(0,8)}</button>`; } 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 if (button.value === 'copy') { GM_setClipboard("diep.io/#" + getServerLink(currentServer.split("://")[1].split("-80.lobby")[0]).toUpperCase()); } 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 = '60%' } const choices = { mode: 'ffa', region: 'do-sfo' } const serverWithoutCSS = { "ffa": { "do-sfo": [], "do-nyc": [], "do-fra": [], "do-sgp": [] }, "survival": { "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": [] }, "dom": { "do-sfo": [], "do-nyc": [], "do-fra": [], "do-sgp": [] }, "tag": { "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 GAMEMODES_MAP = ['survival', 'tag', '4teams', 'sandbox', 'maze', 'dom', 'ffa', 'teams']; const REGIONS_MAP = ['do-fra', 'do-sgp', 'do-sfo', 'do-nyc']; var do_connect = false; var currentServer = ''; var override = false; async function fetchServer(mode, region) { const body = JSON.parse(localStorage.lists)?.list; if (!body.hasOwnProperty('game_modes') && !body.hasOwnProperty('message')) return alert('API of Rivet is down!'); if (body.message === 'too many requests') return alert('Ratelimit reached! Wait 15 minutes.'); PLAYER_COUNT = 0; body.game_modes.forEach(function(g) { g.regions.forEach(function(r) { r.lobbies.forEach(function(l) { PLAYER_COUNT += l.total_player_count }); }); }); const lobbies = body.game_modes[GAMEMODES_MAP.indexOf(mode)]?.regions[REGIONS_MAP.indexOf(region)]?.lobbies; if (!lobbies) return alert('Very strange... no lobbies exist...'); lobbies.forEach(function({ lobby_id }) { lobby_id = `${lobby_id}-80.lobby.${region}.hiss.io:443`; if (!serverWithoutCSS[mode][region].some(function(host) { return host === lobby_id })) { serverWithoutCSS[mode][region].push(lobby_id); } }); refreshHTML(); } function appendServers(mode, region) { fetchServer(mode, region); } 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; currentServer = args[0]; unsafeWindow.serverURL = args[0]; do_connect = false; override = true; return Reflect.construct(t, args)} }); var _fetch = unsafeWindow.fetch; unsafeWindow.fetch = function(endpoint, opts) { return _fetch(endpoint, opts) .then(function(response) { return new Promise(function(res) { response.clone().json() .then(function(body) { if (!override) return res(response); body.lobby.lobby_id = currentServer.split('wss://')[1].split('-80.lobby')[0]; body.lobby.region.region_id = choices.region; const blob = new Blob([JSON.stringify(body)], { type: 'application/json' }); return res(new Response(blob)); override = false; }) .catch(function(er) { return res(response); }); }); }); } document.body.onkeydown = function(e) { if (String.fromCharCode(e.keyCode) === '\t') { if (document.getElementById('ServerSelector').style.display === "none") { document.getElementById('ServerSelector').style.display = "block"; document.getElementById('choice').style.display = "block"; } else { document.getElementById('ServerSelector').style.display = "none"; document.getElementById('choice').style.display = "none"; } } } function getServerLink(server) { let link = ''; for (const char of server) { const code = char.charCodeAt(0); const value = (`00${code.toString(16)}`).slice(-2); link += value.split("").reverse().join(""); } return link; } async function calcPlayerCount() { const body = JSON.parse(localStorage.lists)?.list; if (!body.hasOwnProperty('game_modes') && !body.hasOwnProperty('message')) return alert('API of Rivet is down!'); if (body.message === 'too many requests') return alert('Ratelimit reached! Wait 15 minutes.'); PLAYER_COUNT = 0; body.game_modes.forEach(function(g) { g.regions.forEach(function(r) { r.lobbies.forEach(function(l) { PLAYER_COUNT += l.total_player_count }); }); }); } calcPlayerCount(); setInterval(calcPlayerCount, 60000); const crx = CanvasRenderingContext2D.prototype; crx.fillText = new Proxy(crx.fillText, { apply(f, _this, args) { if (args[0].includes('ms do')) args[0] += ` ‖ ${PLAYER_COUNT} players`; return f.apply(_this, args); } }); crx.strokeText = new Proxy(crx.strokeText, { apply(f, _this, args) { if (args[0].includes('ms do')) args[0] += ` ‖ ${PLAYER_COUNT} players`; return f.apply(_this, args); } }); crx.measureText = new Proxy(crx.measureText, { apply(f, _this, args) { if (args[0].includes('ms do')) args[0] += ` ‖ ${PLAYER_COUNT} players`; return f.apply(_this, args); } }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址