Embedded diep lobby selector

Embed diep lobby selector into diep.io page

  1. // ==UserScript==
  2. // @name Embedded diep lobby selector
  3. // @namespace http://tampermonkey.net/
  4. // @version 2
  5. // @description Embed diep lobby selector into diep.io page
  6. // @author discord@celestial_raccoon_80621
  7. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  8. // @match diep.io/*
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. /*
  14. This script (unless in TypeScript form) is the result of
  15. transpiling TypeScript into JavaScript, hence why this
  16. code looks so messy. This is because i want types with
  17. TypeScript, but tampermonkey doesn't support TypeScript
  18. so i have to transpile my TypeScript code with the `tsc`
  19. compiler, then put it here, if you want the TypeScript
  20. source, DM on discord and i'll likely respond
  21. in a few hours or less, discord username is in the
  22. author field above or in any gui of the script
  23. */
  24.  
  25. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  26. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  27. return new (P || (P = Promise))(function (resolve, reject) {
  28. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  29. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  30. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  31. step((generator = generator.apply(thisArg, _arguments || [])).next());
  32. });
  33. };
  34.  
  35. (() => {
  36. 'use strict';
  37. // Top level variables, change TOGGLE_KEYBIND to whatever you want (to change display visibility)
  38. const TOGGLE_KEYBIND = 'q';
  39. const UPDATE_DELAY = 1000; // miliseconds
  40. const storageKey = "diepioLobbyselect_";
  41. const API = "https://lb.diep.io/api/lb/pc"; // or you can change this to /mobile
  42. // todo: add these in accurately
  43. let colors = {
  44. fra: "rgba(255, 0, 0, 0.5)",
  45. atl: "rgba(255, 255, 0, 0.5)",
  46. sgp: "rgba(50, 50, 200, 0.5)",
  47. syd: "rgba(0, 255, 0, 0.5)"
  48. };
  49. let intToTeam = {
  50. 0: "blue",
  51. 1: "red",
  52. 2: "purple",
  53. 3: "green"
  54. };
  55. let intToColor = {
  56. 0: "rgb(33, 143, 221)",
  57. 1: "rgb(232, 27, 27)",
  58. 2: "rgb(184, 13, 207)",
  59. 3: "rgb(81, 220, 34)",
  60. };
  61. let data = [];
  62. // local storage management
  63. const storage = {
  64. get(key, defaultValue) {
  65. return localStorage.getItem(storageKey + key) || defaultValue;
  66. },
  67. set(key, value) {
  68. return __awaiter(this, void 0, void 0, function* () {
  69. localStorage.setItem(storageKey + key, value);
  70. });
  71. },
  72. getBool(key, defaultValue) {
  73. let value = this.get(key, null);
  74. return value === null ? defaultValue : value === "true";
  75. },
  76. getNumber(key, defaultValue) {
  77. let value = this.get(key, null);
  78. return value === null ? defaultValue : parseFloat(value);
  79. },
  80. };
  81. let showUI = storage.getBool('showUI', false);
  82. // inject CSS into the head element
  83. // https://stackoverflow.com/questions/79614720/how-do-i-add-hover-and-active-events-to-my-tampermonkey-injected-script
  84. const styleElem = document.createElement('style');
  85. styleElem.textContent = `
  86. .lobby-button {
  87. padding: 5px;
  88. border: 1px solid black;
  89. background-color: rgba(255, 255, 255, 0.5);
  90. cursor: pointer;
  91. transition: background-color 0.2s ease;
  92. }
  93. .lobby-button:hover {
  94. background-color: rgba(200, 200, 200, 0.7);
  95. }
  96. .lobby-button:active {
  97. background-color: rgba(150, 150, 150, 0.9);
  98. }
  99. `;
  100. document.head.appendChild(styleElem);
  101. function getTextForNumPlayers(numPlayers) {
  102. // this function was vibe coded
  103. if (numPlayers < 850)
  104. return "Very Low";
  105. if (numPlayers < 900)
  106. return "Low";
  107. if (numPlayers < 950)
  108. return "Below Average";
  109. if (numPlayers < 1050)
  110. return "Average";
  111. if (numPlayers < 1100)
  112. return "Above Average";
  113. if (numPlayers < 1200)
  114. return "High";
  115. return "Very High";
  116. }
  117. // update the values in the UI every second
  118. function update() {
  119. return __awaiter(this, void 0, void 0, function* () {
  120. let response = yield fetch(API);
  121. let value = yield response.json();
  122. data = value.regions;
  123. let count = 0;
  124. for (let region of data) {
  125. count += region.numPlayers;
  126. }
  127. numPlayers.textContent = `Players Active: ${count} (${getTextForNumPlayers(count)})`;
  128. // https://stackoverflow.com/questions/3955229/remove-all-child-elements-of-a-dom-node-in-javascript
  129. buttons.textContent = "";
  130. for (let region of data) {
  131. let playerCount = document.createElement('p');
  132. playerCount.textContent = `${region.regionName} ${region.numPlayers} Players`;
  133. playerCount.style.marginRight = "0px";
  134. buttons.appendChild(playerCount);
  135. for (let index = 0; index < region.lobbies.length; index++) {
  136. // put every sixth lobby on a new row
  137. if (index % 6 === 0 && index > 5) {
  138. buttons.appendChild(document.createElement('br'));
  139. }
  140. const lobby = region.lobbies[index];
  141. const button = document.createElement('button');
  142. button.textContent = `${lobby.gamemode} ${lobby.numPlayers}p`;
  143. button.className = 'lobby-button';
  144. button.addEventListener('click', () => {
  145. let teamIndex = buttonIndex;
  146. if (lobby.gamemode === "teams"
  147. && teamIndex > 1
  148. || !lobby.gamemode.includes("teams")) {
  149. teamIndex = 0;
  150. }
  151. window.open(`https://diep.io/?ip=${lobby.ip}&g=${lobby.gamemode}&l=0x${teamIndex}`);
  152. });
  153. button.style.padding = "5px";
  154. button.style.border = "1px solid black";
  155. button.style.backgroundColor = colors[region.region] || "rgba(255, 255, 255, 0.5)";
  156. button.style.marginLeft = "5px";
  157. button.style.marginBottom = "2px";
  158. buttons.appendChild(button);
  159. }
  160. buttons.appendChild(document.createElement('br'));
  161. }
  162. });
  163. }
  164. update();
  165. let IntervalID = setInterval(update, UPDATE_DELAY);
  166. // toggle display visibility
  167. function toggle() {
  168. return __awaiter(this, void 0, void 0, function* () {
  169. let display = container.style.display;
  170. container.style.display = display === 'block' ? 'none' : 'block';
  171. showUI = !showUI;
  172. storage.set('showUI', showUI);
  173. console.log("ShowUI is: ", showUI);
  174. if (showUI) {
  175. update();
  176. IntervalID = setInterval(update, UPDATE_DELAY);
  177. }
  178. else {
  179. clearInterval(IntervalID);
  180. }
  181. });
  182. }
  183. // handle display visibility update
  184. document.addEventListener('keydown', (ev) => {
  185. if (ev.key === TOGGLE_KEYBIND) {
  186. toggle();
  187. }
  188. });
  189. const container = document.createElement('div');
  190. let style = container.style;
  191. style.position = 'absolute';
  192. style.left = '0%';
  193. style.top = '0';
  194. style.zIndex = '999999';
  195. style.backgroundColor = 'rgba(255, 255, 255, 0.5)';
  196. style.padding = '5px';
  197. style.border = '1px solid black';
  198. style.borderRadius = '5px';
  199. style.display = 'block';
  200. document.body.append(container);
  201. const title = document.createElement('p');
  202. title.textContent = 'Diep lobby selector by EclipSyS';
  203. title.style.position = 'relative';
  204. title.style.zIndex = '999999';
  205. title.style.padding = '0px';
  206. title.style.margin = '0px';
  207. container.appendChild(title);
  208. const numPlayers = document.createElement('p');
  209. numPlayers.textContent = "Players Active: ?";
  210. numPlayers.style.position = 'relative';
  211. numPlayers.style.zIndex = '999999';
  212. numPlayers.style.padding = '0px';
  213. numPlayers.style.margin = '0px';
  214. numPlayers.style.marginBottom = "3px";
  215. container.appendChild(numPlayers);
  216. const teamDiv = document.createElement('div');
  217. teamDiv.style.zIndex = '999999';
  218. teamDiv.style.backgroundColor = 'rgb(25, 160, 205)';
  219. teamDiv.style.border = '1px solid black';
  220. teamDiv.style.borderRadius = '5px';
  221. teamDiv.style.display = 'flex';
  222. teamDiv.style.height = "20px";
  223. const teamTitle = document.createElement('p');
  224. teamTitle.textContent = "Switch target team:";
  225. teamTitle.style.marginTop = "0px";
  226. teamDiv.appendChild(teamTitle);
  227. let buttonIndex = storage.getNumber('teamIndex', 0);
  228. const teamButton = document.createElement('button');
  229. teamButton.style.marginLeft = "5px";
  230. teamButton.textContent = intToTeam[buttonIndex];
  231. teamButton.style.backgroundColor = intToColor[buttonIndex];
  232. teamButton.addEventListener('click', () => {
  233. buttonIndex++;
  234. if (buttonIndex >= Object.keys(intToTeam).length) {
  235. buttonIndex = 0;
  236. }
  237. teamButton.textContent = intToTeam[buttonIndex];
  238. teamButton.style.backgroundColor = intToColor[buttonIndex];
  239. storage.set('teamIndex', buttonIndex);
  240. });
  241. teamDiv.appendChild(teamButton);
  242. container.appendChild(teamDiv);
  243. const buttons = document.createElement('div');
  244. let btnStyle = buttons.style;
  245. btnStyle.right = '0%';
  246. btnStyle.top = '0';
  247. btnStyle.zIndex = '999999';
  248. btnStyle.backgroundColor = 'rgb(141, 24, 187)';
  249. btnStyle.padding = '5px';
  250. btnStyle.border = '1px solid black';
  251. btnStyle.borderRadius = '5px';
  252. btnStyle.display = 'block';
  253. container.appendChild(buttons);
  254. console.log("Initial showUi is", showUI);
  255. if (!showUI) {
  256. // by default the div is visible, we set this here to synchronize the values
  257. showUI = true;
  258. toggle();
  259. }
  260. })();