Greasy Fork

DigDig.IO Server Selector

Server selector for digdig.io

目前为 2021-07-07 提交的版本。查看 最新版本

// ==UserScript==
// @name         DigDig.IO Server Selector
// @namespace    http://tampermonkey.net/
// @version      0.1.4
// @description  Server selector for digdig.io
// @author       Zertalious (Zert)
// @match        *://digdig.io/*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        unsafeWindow
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

GM_addStyle(`
.btn, .container {
	font-family: 'Ubuntu';
	font-weight: bolder;
	background: #aeaeae;
	color: #fff;
	font-size: 14px;
	font-family: Ubuntu;
	border: 4px solid #8f8f8f;
	border-radius: 6px;
	text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
	transition: 0.2s;
}

.btn {
	position: absolute;
	right: 10px;
	bottom: 10px;
	padding: 5px 15px;
	cursor: pointer;
}

.btn:hover {
	background: #c1c1c1;
}

.active .btn {
	background: #999999;
}

.container {
	position: absolute;
	bottom: 55px;
	right: 6px;
	padding: 10px;
	width: 300px;
	transition: 0.2s;
	transform: translate(0, calc(100% + 55px));
}

.active .container {
	transform: unset;
}

.close-btn {
	position: absolute;
	top: 10px;
	right: 10px;
	width: 20px;
	height: 20px;
	border-radius: 4px;
	background: #bb5555;
	border: 4px solid #974545;
	cursor: pointer;
	outline: 0;
}

.close-btn:hover {
	background: #c76161;
}

.close-btn:after, .close-btn:before {
	content: "";
	position: absolute;
	left: 51%;
	top: 52.5%;
	width: 3px;
	height: 100%;
	background: #cccccc;
	border-radius: 4px;
}

.close-btn:after {
	transform: translate(-50%, -50%) rotate(45deg);
}

.close-btn:before {
	transform: translate(-50%, -50%) rotate(-45deg);
}

.title {
	font-size: 1.6em;
	text-align: center;
	margin-bottom: 0.5em;
}

.item {
	background: rgba(0, 0, 0, 0.2);
	padding: 10px;
	border-radius: 5px;
	margin-bottom: 5px;
	cursor: pointer;
}

.item-active {
	box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.2);
}

.preloader {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 10px;
}

.spinner {
	width: 40px;
	height: 40px;
	border: 10px solid rgba(0, 0, 0, 0.5);
	border-top-color: rgba(0, 0, 0, 0.8);
	border-radius: 50%;
	animation: spin 0.5s infinite;
}

.preloader-text {
	margin-top: 5px;
	font-size: 1.25em;
}

@keyframes spin {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(360deg);
	}
}
`);

(async function () {
	const KEY = 'digdig-server-id';
	let currentServerId;
	let serverIds;
	const sockets = [];
	unsafeWindow.WebSocket = new Proxy(unsafeWindow.WebSocket, {
		construct(target, args) {
			logMessage('In WebSocket proxy. Attempting connection to ' + args[0]);
			if (serverIds) {
				let items = args[0].split('//');
				const protocol = items[0] + '//';
				items = items[1].split(':');
				const x = items[0].split('.')
				const id = x.shift();
				const port = items[1];
				if (serverIds[id]) {
					args[0] = protocol + currentServerId + '.' + x.join('.') + ':' + port;
					logMessage('Game server found! Overriding...', {url: args[0], currentServerId});
				}
			}
			const socket = Reflect.construct(...arguments);
			sockets.push(socket);
			return socket;
		}
	});

	const wrapper = document.body;

	wrapper.innerHTML += `
	<div class="btn">Servers</div>
	<div class="container">
		<div class="title">Servers</div>
		<div class="close-btn"></div>
		<div class="preloader">
			<div class="spinner"></div>
			<div class="preloader-text">Fetching...</div>
		</div>
	</div>
	`;

	const btn = document.querySelector('.btn');
	const closeBtn = document.querySelector('.close-btn');
	const container = document.querySelector('.container');

	btn.onclick = function () {
		if (wrapper.classList.contains('active')) {
			wrapper.classList.remove('active');
		} else {
			wrapper.classList.add('active');
		}
	}

	closeBtn.onclick = function () {
		wrapper.classList.remove('active');
	}

	document.querySelector('canvas').onclick = function () {
		wrapper.classList.remove('active');
	}

	const servers = await fetchServers();
	serverIds = {};

	let first = true;

	for (let key in servers) {
		const item = document.createElement('div');
		const server = servers[key];
		item.classList.add('item');
		item.innerText = key;
		item.setAttribute('data-id', server.id);
		container.appendChild(item);
		if (!currentServerId) {
			item.classList.add('item-active');
			currentServerId = server.id;
		}
		item.onclick = function () {
			const active = document.querySelector('.item-active');
			active.classList.remove('item-active');
			item.classList.add('item-active');
			currentServerId = server.id;
			reconnect();
		}
		serverIds[server.id] = true;
	}

	logMessage({serverIds, servers});

	document.querySelector('.preloader').style.display = 'none';

	async function fetchServers() {
		let response = await fetch('https://api.n.m28.io/endpoint/digdig-ffa/findEach/');
		let json = await response.json();
		const servers = {};
		for (let key in json.servers) {
			servers['ffa_' + key] = json.servers[key];
		}

		response = await fetch('https://api.n.m28.io/endpoint/digdig-teams/findEach/');
		json = await response.json();
		
		for (let key in json.servers) {
			servers['teams_' + key] = json.servers[key];
		}
		return servers;
	}

	function reconnect() {
		logMessage('Reconnecting...');
		for (let i = 0; i < sockets.length; i++) {
			sockets[i].close();
		}
	}

	function logMessage() {
		console.log('[DSS]', ...arguments);
	}
})();