Bypass Roo
// ==UserScript==
// @name Roo Web Method
// @description Bypass Roo
// @match http://*/*
// @match https://*/*
// @run-at document-start
// @version 0.0.1.20260609221425
// @namespace https://greasyfork.org/users/1611219
// ==/UserScript==
(() => {
"use strict";
const HEADER_NAME = "x-roo-client";
const HEADER_VALUE = "consumer-app";
const TARGET_METHODS = ["*"];
const TARGET_URL_PATTERN = /.*/;
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 || {});
headers.set(HEADER_NAME, HEADER_VALUE);
headers.set("x-roo-device", "ios");
headers.set("x-roo-app-version", "3.0.0");
return headers;
}
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);
}
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);
};
const originalOpen = XMLHttpRequest.prototype.open;
const originalSend = XMLHttpRequest.prototype.send;
const originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
XMLHttpRequest.prototype.open = function patchedOpen(method, url, ...rest) {
this.__headerEditorUrl = url;
this.__headerEditorMethod = method;
this.__headerEditorShouldModify = shouldModify(url, method);
return originalOpen.call(this, method, url, ...rest);
};
XMLHttpRequest.prototype.setRequestHeader = function patchedSetRequestHeader(name, value) {
if (
this.__headerEditorShouldModify &&
String(name).toLowerCase() === HEADER_NAME.toLowerCase()
) {
return;
}
return originalSetRequestHeader.call(this, name, value);
};
XMLHttpRequest.prototype.send = function patchedSend(body) {
if (this.__headerEditorShouldModify) {
originalSetRequestHeader.call(this, HEADER_NAME, HEADER_VALUE);
originalSetRequestHeader.call(this, "x-roo-device", "ios");
originalSetRequestHeader.call(this, "x-roo-app-version", "3.0.0");
}
return originalSend.call(this, body);
};
})();