1
// ==UserScript==
// @name Force n_frames and size for /backend/nf/create (sora.chatgpt.com only)
// @namespace http://tampermonkey.net/
// @version 1.3
// @description Перехватывает POST на /backend/nf/create и ставит n_frames=N и size="large" (работает только на sora.chatgpt.com)
// @author You
// @match https://sora.chatgpt.com/*
// @grant none
// @run-at document-start
// ==/UserScript==
(function () {
'use strict';
const N = 450;
const TARGET_PATH = "/backend/nf/create";
const DEBUG = false;
function dlog(...args) { if (DEBUG) console.debug('[patch-fetch]', ...args); }
function mutateBody(b) {
if (b == null) return b;
if (typeof b === "string") {
try {
const j = JSON.parse(b);
j.n_frames = N;
j.size = "large";
return JSON.stringify(j);
} catch {
try {
let out = b.replace(/"n_frames"\s*:\s*\d+/g, `"n_frames": ${N}`);
out = out.replace(/"size"\s*:\s*"[^"]*"/g, `"size": "large"`);
if (!/\"n_frames\"\s*:/.test(out) && /^\s*\{/.test(out)) {
out = out.replace(/^\s*\{/, `{"n_frames": ${N}, `);
}
return out;
} catch { return b; }
}
}
if (typeof FormData !== "undefined" && b instanceof FormData) {
if (b.has("n_frames")) b.set("n_frames", String(N)); else b.append("n_frames", String(N));
if (b.has("size")) b.set("size", "large"); else b.append("size", "large");
return b;
}
if (typeof URLSearchParams !== "undefined" && b instanceof URLSearchParams) {
b.set("n_frames", String(N));
b.set("size", "large");
return b;
}
if (typeof b === "object") {
try {
const copy = JSON.parse(JSON.stringify(b));
copy.n_frames = N;
copy.size = "large";
return copy;
} catch { return b; }
}
return b;
}
const origFetch = window.fetch.bind(window);
window.fetch = async function(input, init) {
try {
const url = (typeof input === "string") ? input : (input && input.url) || "";
const method = (init && init.method) || (typeof input === "object" && input.method) || "GET";
if (url.includes(TARGET_PATH) && String(method).toUpperCase() === "POST") {
if (init && 'body' in init) {
init = Object.assign({}, init, { body: mutateBody(init.body) });
} else if (typeof input === "object" && input instanceof Request) {
const origReq = input;
const reqClone = origReq.clone();
let newBody;
try {
const txt = await reqClone.text();
newBody = mutateBody(txt);
} catch {}
if (newBody !== undefined) {
const reqInit = {
method: origReq.method,
headers: new Headers(origReq.headers),
mode: origReq.mode,
credentials: origReq.credentials,
cache: origReq.cache,
redirect: origReq.redirect,
referrer: origReq.referrer,
referrerPolicy: origReq.referrerPolicy,
integrity: origReq.integrity,
keepalive: origReq.keepalive,
signal: origReq.signal,
body: newBody
};
input = new Request(origReq.url, reqInit);
}
}
}
} catch (e) { console.warn('patch-fetch: outer error', e); }
return origFetch(input, init);
};
(function () {
const openOrig = XMLHttpRequest.prototype.open;
const sendOrig = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function(method, url) {
this.__patched_method = method;
this.__patched_url = url;
return openOrig.apply(this, arguments);
};
XMLHttpRequest.prototype.send = function(body) {
try {
const url = this.__patched_url || '';
const method = this.__patched_method || '';
if (url.includes(TARGET_PATH) && String(method).toUpperCase() === 'POST') {
body = mutateBody(body);
}
} catch (e) { console.warn('patch-xhr outer error', e); }
return sendOrig.call(this, body);
};
})();
dlog('patch-fetch initialized for', TARGET_PATH, 'n_frames=', N);
})();
For immediate assistance, please email our customer support: [email protected]