Roo Web Master

Bypass Roo

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Roo Web Master
// @description  Bypass Roo
// @match        http://*/*
// @match        https://*/*
// @run-at       document-start
// @version 0.0.1.20260610050048
// @namespace https://greasyfork.org/users/1611219
// ==/UserScript==

(() => {
 "use strict";

 const code = `
   (() => {
     "use strict";

     const DEBUG = true;

     const HEADERS_TO_SET = {
       "x-roo-client": "consumer-app",
   "x-roo-platform": "ios"
     };

     const TARGET_METHODS = ["*"];

     const TARGET_URL_PATTERN = /.*/;

     function log(...args) {
       if (DEBUG) {
         console.log("[Roo headers]", ...args);
       }
     }

     function normaliseUrl(url) {
       try {
         return new URL(String(url), location.href).href;
       } catch {
         return String(url);
       }
     }

     function shouldModify(url, method) {
       const fullUrl = normaliseUrl(url);
       const upperMethod = String(method || "GET").toUpperCase();

       const methodMatches =
         TARGET_METHODS.includes("*") ||
         TARGET_METHODS.map(m => m.toUpperCase()).includes(upperMethod);

       return methodMatches && TARGET_URL_PATTERN.test(fullUrl);
     }

     function editHeaders(headersLike) {
       const headers = new Headers(headersLike || {});

       for (const [name, value] of Object.entries(HEADERS_TO_SET)) {
         headers.set(name, value);
       }

       return headers;
     }

     function isManagedHeader(name) {
       const lowerName = String(name).toLowerCase();

       return Object.keys(HEADERS_TO_SET).some(
         headerName => headerName.toLowerCase() === lowerName
       );
     }

     /*
       Patch fetch()
     */
     const originalFetch = window.fetch;

     window.fetch = function patchedFetch(input, init = {}) {
       let url;
       let method;
       let originalHeaders;

       if (input instanceof Request) {
         url = input.url;
         method = init.method || input.method || "GET";
         originalHeaders = init.headers || input.headers;
       } else {
         url = input;
         method = init.method || "GET";
         originalHeaders = init.headers;
       }

       if (!shouldModify(url, method)) {
         return originalFetch.call(this, input, init);
       }

       log("patching fetch", method, normaliseUrl(url), HEADERS_TO_SET);

       const newInit = {
         ...init,
         method,
         headers: editHeaders(originalHeaders)
       };

       if (input instanceof Request) {
         return originalFetch.call(this, new Request(input, newInit));
       }

       return originalFetch.call(this, input, newInit);
     };

     /*
       Patch XMLHttpRequest
     */
     const originalOpen = XMLHttpRequest.prototype.open;
     const originalSend = XMLHttpRequest.prototype.send;
     const originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;

     XMLHttpRequest.prototype.open = function patchedOpen(method, url, ...rest) {
       this.__rooHeaderUrl = url;
       this.__rooHeaderMethod = method;
       this.__rooHeaderShouldModify = shouldModify(url, method);

       return originalOpen.call(this, method, url, ...rest);
     };

     XMLHttpRequest.prototype.setRequestHeader = function patchedSetRequestHeader(name, value) {
       if (this.__rooHeaderShouldModify && isManagedHeader(name)) {
         return;
       }

       return originalSetRequestHeader.call(this, name, value);
     };

     XMLHttpRequest.prototype.send = function patchedSend(body) {
       if (this.__rooHeaderShouldModify) {
         log("patching xhr", this.__rooHeaderMethod, normaliseUrl(this.__rooHeaderUrl), HEADERS_TO_SET);

         for (const [name, value] of Object.entries(HEADERS_TO_SET)) {
           originalSetRequestHeader.call(this, name, value);
         }
       }

       return originalSend.call(this, body);
     };

     log("installed");
   })();
 `;

 const script = document.createElement("script");
 script.textContent = code;

 const target = document.documentElement || document.head || document.body;

 if (target) {
   target.appendChild(script);
   script.remove();
 } else {
   document.addEventListener("DOMContentLoaded", () => {
     document.documentElement.appendChild(script);
     script.remove();
   }, { once: true });
 }
})();