Keeps sites blind to tab switches and window blur. Fully blocks all focus and visibility checks, now with requestAnimationFrame capped below 10fps.
当前为
// ==UserScript==
// @name Undetectorized – Limited RAF
// @namespace bypass.focus.fixed
// @version 5.5
// @author Gaze
// @icon https://i.imgur.com/l8qT82q.jpeg
// @description Keeps sites blind to tab switches and window blur. Fully blocks all focus and visibility checks, now with requestAnimationFrame capped below 10fps.
// @include *
// @run-at document-start
// ==/UserScript==
(function() {
const uw = unsafeWindow;
// --- Patch document & window focus/visibility ---
const patch = () => {
try {
uw.document.hasFocus = () => true;
uw.hasFocus = () => true;
Object.defineProperty(document, "visibilityState", { get: () => "visible" });
["hidden","mozHidden","msHidden","webkitHidden"].forEach(p =>
Object.defineProperty(document, p, { value: false })
);
window.onblur = null;
window.onfocus = null;
document.onblur = null;
document.onfocus = null;
window.focus = () => true;
document.focus = () => true;
window.onbeforeunload = null;
document.onbeforeunload = null;
Object.defineProperty(window, "onbeforeunload", { set: () => true, get: () => null });
} catch(e){}
};
// --- Block all focus/blur/visibility events ---
const blockEvents = () => {
try {
const evs = [
"visibilitychange","webkitvisibilitychange","mozvisibilitychange","msvisibilitychange",
"blur","focus","focusin","focusout",
"mouseleave","mouseout","mouseenter","mouseover",
"pageshow","pagehide","resume","freeze"
];
const handler = e => {
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
};
evs.forEach(ev => {
window.addEventListener(ev, handler, true);
document.addEventListener(ev, handler, true);
});
} catch(e){}
};
// --- Hook addEventListener to ignore critical events ---
const hookAddEvent = () => {
try {
const blocked = [
"visibilitychange","webkitvisibilitychange","mozvisibilitychange","msvisibilitychange",
"blur","focus","focusin","focusout",
"mouseleave","mouseout","mouseenter","mouseover",
"beforeunload",
"pageshow","pagehide","resume","freeze"
];
const orig = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(type, listener, opts) {
if (blocked.includes(type)) return;
return orig.call(this, type, listener, opts);
};
} catch(e){}
};
// --- Patch timing & limit requestAnimationFrame ---
const patchTiming = () => {
try {
const base = performance.now();
performance.now = () => base + Math.random() * 0.01;
const oRAF = uw.requestAnimationFrame;
let lastCall = 0;
const minInterval = 111; // ~9 FPS
uw.requestAnimationFrame = cb => {
const now = performance.now();
const delay = Math.max(0, minInterval - (now - lastCall));
lastCall = now + delay;
return setTimeout(() => cb(performance.now()), delay);
};
const oTO = uw.setTimeout;
uw.setTimeout = (fn, t) => oTO(fn, 0);
} catch(e){}
};
// --- Initial patching ---
patch();
blockEvents();
hookAddEvent();
patchTiming();
// --- Keep patches alive ---
setInterval(() => {
patch();
hookAddEvent();
patchTiming();
}, 100);
})();