您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
(WORKING AS OF 4/15/23) The only working stream sniper script without using exploits
当前为
// ==UserScript== // @name RoSniper // @namespace http://tampermonkey.net/ // @version 0.1 // @description (WORKING AS OF 4/15/23) The only working stream sniper script without using exploits // @author Lukas Dobbles // @match https://www.roblox.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net // @grant none // ==/UserScript== (function () { "use strict"; const getJSON = (url, args = {}) => { args.headers = args.headers || {}; return fetch(url, args) .then((r) => r.json()) .catch((e) => console.log(e)); }; const search = async (placeId, name, setStatus, cb) => { const userId = await getUserId(name); const thumbUrl = await getThumb(userId); setStatus("thumb url: " + thumbUrl); let cursor = null; let searching = true; let allPlayerTokens = []; while (searching) { const servers = await getServer(placeId, cursor); cursor = servers.nextPageCursor; for (let i = 0; i < servers.data.length; i++) { const place = servers.data[i]; allPlayerTokens = allPlayerTokens.concat( place.playerTokens.map((token) => ({ token, place, })) ); } if (!cursor) break; setStatus("next server..."); } const chunkSize = 80; let i = 0; const nextThumbChunk = () => { i += chunkSize; const chunk = allPlayerTokens.slice(i, i + chunkSize); setStatus( `searching servers ${Math.floor((i / allPlayerTokens.length) * 100)}%` ); fetchThumbs(chunk.map(({ token }) => token)).then((serverThumbs) => { if (!serverThumbs || !serverThumbs["data"]) setStatus("error: " + serverThumbs); else { let found = false; for (let k = 0; k <= serverThumbs.data.length; k++) { const thumb = serverThumbs.data[k]; if (thumb && thumb.imageUrl === thumbUrl) { found = true; setStatus(thumb.imageUrl); console.log(chunk[k].place); setStatus("FOUND THEM!"); cb({ found: true, place: chunk[k].place, }); } } if (i + chunkSize > allPlayerTokens.length) cb({ found: false }); else if (!found) nextThumbChunk(); } }); }; nextThumbChunk(); }; const getUserId = (name) => fetch("https://www.roblox.com/users/profile?username=" + name).then((r) => { if (!r.ok) throw "User not found"; return r.url.match(/\d+/)[0]; }); const getThumb = (id) => getJSON( `https://thumbnails.roblox.com/v1/users/avatar-headshot?userIds=${id}&format=Png&size=150x150` ).then((d) => d.data[0].imageUrl); const getServer = (placeId, cursor) => { let url = `https://games.roblox.com/v1/games/${placeId}/servers/Public?limit=100`; if (cursor) url += "&cursor=" + cursor; return getJSON(url).catch(() => null); }; const fetchThumbs = (tokens) => { let body = []; tokens.forEach((token) => { body.push({ requestId: `0:${token}:AvatarHeadshot:150x150:png:regular`, type: "AvatarHeadShot", targetId: 0, token, format: "png", size: "150x150", }); }); return getJSON("https://thumbnails.roblox.com/v1/batch", { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json", }, body: JSON.stringify(body), }); }; const instancesContainer = document.getElementById( "running-game-instances-container" ); if (instancesContainer) { const containerHeader = document.createElement("div"); containerHeader.classList = "section"; const headerText = document.createElement("h2"); headerText.innerText = "RoSniper"; containerHeader.appendChild(headerText); const form = document.createElement("form"); const usernameInput = document.createElement("input"); usernameInput.classList = "input-field"; usernameInput.placeholder = "Username"; form.appendChild(usernameInput); const submitButton = document.createElement("button"); submitButton.classList = "btn-primary-md"; submitButton.innerText = "Search"; form.appendChild(submitButton); const statusText = document.createElement("p"); form.appendChild(statusText); const joinBtn = document.createElement("button"); joinBtn.style.display = "none"; joinBtn.innerText = "Join"; joinBtn.classList = "btn-control-xs rbx-game-server-join game-server-join-btn btn-primary-md btn-min-width"; const donateButton = document.createElement("a"); donateButton.href = "https://www.paypal.com/donate/?business=FAN54H88ETRKQ&no_recurring=0&item_name=This+money+gives+me+motivation+to+keep+maintaining+my+projects.+Anything+donated+is+appreciated.¤cy_code=USD"; donateButton.target = "blank"; donateButton.style.marginTop = "0.2rem"; donateButton.classList = "btn-secondary-md"; donateButton.innerText = "donate"; containerHeader.appendChild(form); containerHeader.appendChild(joinBtn); containerHeader.appendChild(donateButton); instancesContainer.insertBefore( containerHeader, instancesContainer.firstChild ); const placeId = location.href.match(/\d+/)[0]; form.addEventListener("submit", (evt) => { evt.preventDefault(); search( placeId, usernameInput.value, (txt) => { console.log(txt); statusText.innerText = txt; }, (place) => { if (!place.found) { statusText.innerText = "couldn't find them"; return; } joinBtn.style.display = ""; joinBtn.onclick = () => { window.Roblox.GameLauncher.joinGameInstance(placeId, place.id); }; } ); }); } })();