RoSearcher

Find empty Roblox servers at the click of a button.

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

  1. // ==UserScript==
  2. // @name RoSearcher
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.3
  5. // @description Find empty Roblox servers at the click of a button.
  6. // @author https://github.com/NotDSF
  7. // @match https://www.roblox.com/games/*
  8. // @icon https://www.google.com/s2/favicons?domain=tampermonkey.net
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. let GameID = document.URL.match(/games\/(\d+)\//)[1];
  16.  
  17. function GetServers(Index) {
  18. return new Promise((resolve, reject) => {
  19. fetch(`https://www.roblox.com/games/getgameinstancesjson?placeId=${GameID}&startIndex=${Index}&_=1`, {
  20. method: "GET",
  21. })
  22. .then(res => res.text())
  23. .then(json => resolve(JSON.parse(json)))
  24. .catch(er => reject(er));
  25. });
  26. }
  27.  
  28. fetch("https://raw.githubusercontent.com/NotDSF/RoSearcher/main/script-version")
  29. .then(res => res.text())
  30. .then(body => {
  31. if (body !== Version) {
  32. if (confirm("A new version of RoSearch is available, would you like to download it?")) {
  33. document.location.href = "https://greasyfork.org/en/scripts/430402-rosearcher";
  34. }
  35. }
  36. })
  37. .catch(er => {
  38. alert("RoSearcher Error:", er.toString());
  39. throw er;
  40. });
  41.  
  42. async function main() {
  43. if (!confirm("Are you sure you want to find an empty server?")) return;
  44.  
  45. let Status = document.getElementById("server-status");
  46. let MaxPingB = document.getElementById("ping-box");
  47. let IteratorB = document.getElementById("iterator-box");
  48. let MaxPlayersB = document.getElementById("player-box");
  49.  
  50. let MaxPing = MaxPingB.value.length ? parseInt(MaxPingB.value) : 300;
  51. let Iterator = IteratorB.value.length ? parseInt(IteratorB.value) : 30;
  52. let MaxPlayers = MaxPlayersB.value.length ? parseInt(MaxPlayersB.value) : 4;
  53.  
  54. let Index = 0;
  55. let LowestServer;
  56.  
  57. Status.innerHTML = "Looking for servers...";
  58.  
  59. while (true) {
  60. if (LowestServer && LowestServer.Len <= MaxPlayers && LowestServer.Ping <= MaxPing) {
  61. Status.innerHTML = `Found server! Players: ${LowestServer.Len} Ping: ${LowestServer.Ping}. Joining...`;
  62. eval(LowestServer.JoinScript);
  63. break;
  64. }
  65.  
  66. let Servers = await GetServers(Index)
  67. .catch(er => {
  68. throw er;
  69. });
  70.  
  71. if (!Servers.Collection.length) {
  72. if (LowestServer && Iterator === 10) {
  73. if (LowestServer.Len > MaxPlayers) alert(`We couldn't find a server with ${MaxPlayers} players or below! (Try editing your options)`);
  74. if (LowestServer.Ping > MaxPing) alert(`We couldn't find a server with ${MaxPing} ping or below! (Try editing your options)`);
  75.  
  76. Status.innerHTML = `Found server! Players: ${LowestServer.Len} Ping: ${LowestServer.Ping}. Joining...`;
  77. eval(LowestServer.JoinScript);
  78. break;
  79. }
  80.  
  81. if (LowestServer) {
  82. Iterator = 10;
  83. Index -= (Index > (Iterator * 2)) ? (Iterator * 2) : Iterator; // Just incase
  84. continue;
  85. }
  86.  
  87. alert("Sorry we couldn't find a server!");
  88. Status.innerHTML = "";
  89. break;
  90. }
  91. for (let Server of Servers.Collection) {
  92. let PlayerLen = Server.CurrentPlayers.length;
  93.  
  94. if (!LowestServer) {
  95. LowestServer = { Len: PlayerLen, Ping: Server.Ping, JoinLink: Server.JoinScript }
  96. continue;
  97. }
  98.  
  99. if (PlayerLen < LowestServer.Len) {
  100. LowestServer = { Len: PlayerLen, Ping: Server.Ping, JoinScript: Server.JoinScript }
  101. }
  102. }
  103.  
  104. Index += Iterator;
  105. Status.innerHTML = `Index: ${Index}, Lowest Server: ${LowestServer.Len}, Ping: ${LowestServer.Ping}...`;
  106. }
  107. }
  108.  
  109. let GameInstances = document.getElementById("game-instances");
  110. let ParentDiv = document.createElement("div");
  111. let ContainerHead = document.createElement("div");
  112.  
  113. ParentDiv.className = "stack";
  114. GameInstances.prepend(ParentDiv);
  115.  
  116. // container header
  117.  
  118. let Title = document.createElement("h3");
  119. Title.innerHTML = "RoSearch";
  120.  
  121. ContainerHead.className = "container-header";
  122. ContainerHead.prepend(Title);
  123.  
  124. // container children
  125.  
  126. let pingbox = document.createElement("textarea");
  127. pingbox.className = "dialog-input ng-valid ng-isolate-scope ng-touched ng-not-empty ng-dirty ng-valid-parse";
  128. pingbox.rows = 1;
  129. pingbox.style = "overflow: hidden; overflow-wrap: break-word; resize: none; height: 30px; margin-bottom: 5px; display: inherit; border-radius: 3px; width: 330px;";
  130. pingbox.placeholder = "Max Ping (Leave Blank For Default)";
  131. pingbox.id = "ping-box";
  132.  
  133. let maxPlayer = document.createElement("textarea");
  134. maxPlayer.className = "dialog-input ng-valid ng-isolate-scope ng-touched ng-not-empty ng-dirty ng-valid-parse";
  135. maxPlayer.rows = 1;
  136. maxPlayer.style = "overflow: hidden; overflow-wrap: break-word; resize: none; height: 30px; margin-bottom: 5px; display: inherit; border-radius: 3px; width: 330px;";
  137. maxPlayer.placeholder = "Max Players (Leave Blank For Default)";
  138. maxPlayer.id = "player-box";
  139.  
  140. let Iterator = document.createElement("textarea");
  141. Iterator.className = "dialog-input ng-valid ng-isolate-scope ng-touched ng-not-empty ng-dirty ng-valid-parse";
  142. Iterator.rows = 1;
  143. Iterator.style = "overflow: hidden; overflow-wrap: break-word; resize: none; height: 30px; margin-bottom: 5px; display: inherit; border-radius: 3px; width: 330px;";
  144. Iterator.placeholder = "Iterator (Leave Blank For Default)";
  145. Iterator.id = "iterator-box";
  146. let fakeButton = document.createElement("span");
  147. fakeButton.className = "btn-secondary-md btn-more";
  148. fakeButton.innerHTML = "Find Empty Server";
  149. fakeButton.onclick = main;
  150. fakeButton.style = "display: inherit; width: min-content; margin-bottom: 20px;";
  151.  
  152. let status = document.createElement("span");
  153. status.className = "section-content-off";
  154. status.id = "server-status";
  155. status.style = "display: inherit;";
  156.  
  157. ParentDiv.prepend(ContainerHead, maxPlayer, pingbox, Iterator, fakeButton, status);
  158. })();