Digdig.IO Server Selector

try to take over the world!

当前为 2021-07-06 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Digdig.IO Server Selector
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1.1
  5. // @description try to take over the world!
  6. // @author Zertalious (Zert)
  7. // @match *://digdig.io/*
  8. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  9. // @grant unsafeWindow
  10. // @grant GM_addStyle
  11. // @grant GM_setValue
  12. // @grant GM_getValue
  13. // ==/UserScript==
  14.  
  15. GM_addStyle(`
  16. .container {
  17. width: 100%;
  18. height: 100%;
  19. position: fixed;
  20. top: 0;
  21. left: 0;
  22. pointer-events: none;
  23. user-select: none;
  24. }
  25.  
  26. .active {
  27. pointer-events: auto;
  28. }
  29.  
  30. .btn,
  31. .modalUI {
  32. background: #aeaeae;
  33. color: #fff;
  34. font-size: 14px;
  35. font-family: Ubuntu;
  36. border: 4px solid #8f8f8f;
  37. border-radius: 6px;
  38. pointer-events: auto;
  39. text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
  40. }
  41.  
  42. .btn {
  43. position: absolute;
  44. right: 10px;
  45. bottom: 10px;
  46. padding: 5px 15px;
  47. cursor: pointer;
  48. outline: 0;
  49. transition: 0.2s;
  50. }
  51.  
  52. .btn-active {
  53. transform: translate(0, 0);
  54. }
  55.  
  56. .container:not(.active) .btn:hover {
  57. background: #c7c7c7;
  58. }
  59.  
  60. .active .btn {
  61. background: #c7c7c7;
  62. }
  63.  
  64. .modalUI {
  65. position: absolute;
  66. bottom: 55px;
  67. right: 6px;
  68. padding: 10px;
  69. width: 300px;
  70. max-height: 400px;
  71. transition: 0.2s;
  72. transform: translate(0, calc(100% + 55px));
  73. overflow: auto;
  74. }
  75.  
  76. .active .modalUI {
  77. transform: translate(0, 0);
  78. }
  79.  
  80. .modalUI-title {
  81. font-size: 1.6em;
  82. text-align: center;
  83. margin-top: 0;
  84. }
  85.  
  86. .modalUI-close-btn {
  87. position: absolute;
  88. right: 5px;
  89. top: 7px;
  90. width: 24px;
  91. height: 24px;
  92. border-radius: 4px;
  93. background: #bb5555;
  94. border: 4px solid #974545;
  95. cursor: pointer;
  96. outline: 0;
  97. }
  98.  
  99. .modalUI-close-btn:hover {
  100. background: #da6868;
  101. }
  102.  
  103. .modalUI-close-btn:after,
  104. .modalUI-close-btn:before {
  105. content: "";
  106. position: absolute;
  107. left: 51%;
  108. top: 52.5%;
  109. width: 3px;
  110. height: 100%;
  111. background: #cccccc;
  112. border-radius: 4px;
  113. }
  114.  
  115. .modalUI-close-btn:after {
  116. transform: translate(-50%, -50%) rotate(45deg);
  117. }
  118.  
  119. .modalUI-close-btn:before {
  120. transform: translate(-50%, -50%) rotate(-45deg);
  121. }
  122.  
  123. .modalUI-element {
  124. background: rgba(0, 0, 0, 0.2);
  125. padding: 10px;
  126. border-radius: 5px;
  127. margin-bottom: 5px;
  128. cursor: pointer;
  129. }
  130.  
  131. .modalUI-element:last-child {
  132. margin-bottom: 0;
  133. }
  134.  
  135. .modalUI-element-active {
  136. box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.2);
  137. }
  138.  
  139. .modalUI-loader {
  140. display: flex;
  141. flex-direction: column;
  142. align-items: center;
  143. padding: 10px;
  144. }
  145.  
  146. .spinner {
  147. width: 40px;
  148. height: 40px;
  149. border: 10px solid rgba(0, 0, 0, 0.5);
  150. border-top-color: rgba(0, 0, 0, 0.8);
  151. border-radius: 50%;
  152. animation: spin 0.5s infinite;
  153. }
  154.  
  155. .spinner-text {
  156. margin-top: 5px;
  157. font-size: 1.25em;
  158. }
  159.  
  160. .modalUI-info {
  161. position: absolute;
  162. right: 30px;
  163. top: 6px;
  164. font-size: 1.20em;
  165. padding: 4px 5px;
  166. }
  167.  
  168. .modalUI-info:hover .modalUI-info-content {
  169. opacity: 1;
  170. pointer-events: inherit;
  171. }
  172.  
  173. .modalUI-info-content {
  174. position: absolute;
  175. bottom: 170%;
  176. right: 0;
  177. background: rgba(0, 0, 0, 0.4);
  178. border-radius: 4px;
  179. opacity: 0;
  180. padding: 8px;
  181. font-size: 0.85rem;
  182. width: 450px;
  183. transition: 0.2s;
  184. pointer-events: none;
  185. display: flex;
  186. flex-direction: row;
  187. }
  188.  
  189. .modalUI-info-title {
  190. margin: 0;
  191. margin-bottom: 5px;
  192. font-size: 1.40rem;
  193. }
  194.  
  195. .version-label {
  196. font-size: 0.75em;
  197. text-align: right;
  198. }
  199.  
  200. .divider {
  201. width: 3px;
  202. background: rgba(0, 0, 0, 0.3);
  203. border-radius: 5px;
  204. margin: 0 10px;
  205. }
  206.  
  207. .modalUI-info-content > div:not(.divider) {
  208. flex: 1;
  209. }
  210.  
  211. @keyframes spin {
  212. from {
  213. transform: rotate(0deg);
  214. }
  215. to {
  216. transform: rotate(360deg);
  217. }
  218. }
  219. `);
  220.  
  221. (async function() {
  222. const html = `
  223. <button class="btn">Servers</button>
  224. <div class="modalUI">
  225. <h1 class="modalUI-title">Servers</h1>
  226. <button class="modalUI-close-btn"></button>
  227. <div class="modalUI-element modalUI-loader">
  228. <div class="spinner"></div>
  229. <div class="spinner-text">Fetching...</div>
  230. </div>
  231. </div>
  232. `;
  233. const container = document.createElement("div");
  234. container.classList.add('container');
  235. container.innerHTML = html;
  236. document.body.appendChild(container);
  237. const modalUIEl = document.querySelector(".modalUI");
  238. const btnEl = document.querySelector(".btn");
  239. const closeBtnEl = document.querySelector(".modalUI-close-btn");
  240. const loaderEl = document.querySelector(".modalUI-loader");
  241. btnEl.onclick = () => {
  242. container.classList.toggle("active");
  243. }
  244. closeBtnEl.onclick = () => {
  245. closeModal();
  246. }
  247. const closeModal = () => {
  248. container.classList.remove("active");
  249. }
  250. window.addEventListener('click', (evt) => {
  251. if (evt.target === container) {
  252. closeModal();
  253. }
  254. });
  255. function removeActiveClass() {
  256. let activeEl = document.querySelector(".modalUI-element-active");
  257. if (activeEl) {
  258. activeEl.classList.remove("modalUI-element-active");
  259. }
  260. }
  261.  
  262. const sockets = [];
  263. let gameSocket = null;
  264. const KEY = 'digdig-selected-server';
  265. unsafeWindow.WebSocket = new Proxy(unsafeWindow.WebSocket, {
  266. construct(target, args) {
  267. let isGameSocket;
  268. if (servers) {
  269. for (let key in servers) {
  270. if (args[0].indexOf(servers[key].ipv4) > -1) { // is a game socket
  271. // disconnect socket and connect to selected server
  272. isGameSocket = true;
  273. console.log('game server found!');
  274. if (args[0].indexOf(GM_getValue(KEY)) == -1) {
  275. let old = args[0];
  276. args[0] = args[0].split('//')[0] + '//' + GM_getValue(KEY) + ':443';
  277. console.log('Was connecting to ' + old + ', overriding to ' + GM_getValue(KEY) + '...');
  278. } else {
  279. GM_setValue(KEY, args[0].split('//')[1].split(':')[0]);
  280. console.log('No saved server found! Saving current server...');
  281. const el = document.querySelector('[data-server="' + GM_getValue(KEY) + '"]');
  282. if (el) {
  283. el.classList.add('modalUI-element-active');
  284. }
  285. }
  286. break;
  287. }
  288. }
  289. }
  290. const socket = Reflect.construct(...arguments);
  291. if (isGameSocket) {
  292. gameSocket = socket;
  293. }
  294. sockets.push(socket);
  295. return socket;
  296. }
  297. });
  298. const response = await fetch('https://api.n.m28.io/endpoint/digdig/findEach/');
  299. const json = await response.json();
  300. const servers = json.servers;
  301. for (let i = 0; i < sockets.length; i++) {
  302. const socket = sockets[i];
  303. for (let key in servers) {
  304. if (socket.url.indexOf(servers[key].ipv4) > -1) {
  305. gameSocket = socket;
  306. reconnect();
  307. }
  308. }
  309. }
  310. for (let key in servers) {
  311. const server = servers[key];
  312. let el = document.createElement("div");
  313. el.classList.add("modalUI-element");
  314. el.innerHTML = key;
  315. el.setAttribute('data-server', server.ipv4);
  316. el.onclick = function() {
  317. removeActiveClass();
  318. el.classList.add("modalUI-element-active");
  319. GM_setValue(KEY, server.ipv4);
  320. reconnect();
  321. }
  322. if (server.ipv4 == GM_getValue(KEY)) {
  323. el.classList.add('modalUI-element-active');
  324. }
  325. modalUIEl.appendChild(el);
  326. }
  327. loaderEl.style.display = 'none';
  328. function reconnect() {
  329. while (sockets.length > 0) {
  330. try {
  331. sockets.shift().close();
  332. } catch (e) {}
  333. }
  334. }
  335. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址