Global Anti-Inactivity

Attempts to prevent inactivity detection and overrides visibility API on all websites. Use responsibly and with caution.

// ==UserScript==
// @name         Global Anti-Inactivity
// @namespace    Violentmonkey Scripts
// @license MIT 
// @match        *://*/*
// @grant        none
// @version      1.2 // Incremented version number
// @author       SU2H1
// @description  Attempts to prevent inactivity detection and overrides visibility API on all websites. Use responsibly and with caution.
// ==/UserScript==
(function() {
    'use strict';

    // -- Configuration --
    const simulateActivityInterval = 60 * 1000; // Simulate activity every 60 seconds
    // -- End Configuration --

    // No need for the targetWebsites array or the shouldRun check because @match handles injection

    console.log("Global Anti-inactivity script running on this website.");

    // -- Prevent Blur Events --
    // Note: This might interfere with legitimate website functions that rely on blur.
    try { // Added try-catch for robustness on potentially sensitive browser/extension pages
        window.onblur = null;
        window.addEventListener('blur', (event) => {
            event.stopImmediatePropagation(); // Using stopImmediatePropagation can be more forceful
        }, true); // Use capture phase
        document.addEventListener('blur', (event) => {
            event.stopImmediatePropagation();
        }, true); // Use capture phase
    } catch (e) {
        console.warn("Anti-inactivity: Could not modify blur handlers.", e);
    }


    // -- Override Page Visibility API --
    // Note: This is invasive and might break sites relying heavily on the visibility API.
    try {
        let originalVisibilityStateDescriptor = Object.getOwnPropertyDescriptor(Document.prototype, 'visibilityState'); // Check prototype
        if (!originalVisibilityStateDescriptor && document) { // Fallback to instance if not on prototype
             originalVisibilityStateDescriptor = Object.getOwnPropertyDescriptor(document, 'visibilityState');
        }

        if (originalVisibilityStateDescriptor && originalVisibilityStateDescriptor.configurable) {
            Object.defineProperty(document, 'visibilityState', {
                get: function() { return 'visible'; },
                configurable: true,
                enumerable: true // Match original enumerability if possible
            });
        } else if (!originalVisibilityStateDescriptor) {
             // Define it if it doesn't exist at all (less likely, but for completeness)
             Object.defineProperty(document, 'visibilityState', {
                get: function() { return 'visible'; },
                configurable: true,
                enumerable: true
            });
        } else {
            console.warn("Anti-inactivity: visibilityState is not configurable.");
        }

        // Override addEventListener specifically on document and window for visibilitychange
        const originalAddEventListener = EventTarget.prototype.addEventListener;
        document.addEventListener = function(type, listener, options) {
            if (type === 'visibilitychange') {
                 console.log("Anti-inactivity: Blocked 'visibilitychange' listener registration on document.");
                 return; // Ignore
            }
            return originalAddEventListener.call(this, type, listener, options);
        };
        window.addEventListener = function(type, listener, options) {
            if (type === 'visibilitychange') {
                 console.log("Anti-inactivity: Blocked 'visibilitychange' listener registration on window.");
                 return; // Ignore
            }
            return originalAddEventListener.call(this, type, listener, options);
        };
        // Attempt to remove any existing listeners (might not always work reliably)
        // This is complex and often impractical, blocking new ones is the main effect here.

    } catch (e) {
        console.warn("Anti-inactivity: Could not fully override Visibility API.", e);
    }


    // -- Simulate Activity --
    let lastActivityTime = Date.now();

    function simulateMouseMove() {
        try {
            const event = new MouseEvent('mousemove', {
                clientX: Math.random() * window.innerWidth,
                clientY: Math.random() * window.innerHeight,
                bubbles: true,
                cancelable: false, // Typically false for mousemove
                view: window // Ensure view is set
            });
            document.dispatchEvent(event);
            lastActivityTime = Date.now();
        } catch(e) {
             console.warn("Anti-inactivity: Error simulating mouse move.", e);
        }
    }

    function simulateKeyPress() {
         try {
            // Keypress is deprecated, keydown/keyup are preferred, but keypress might still work for older scripts
            // Focusing an element first might be necessary on some pages for key events to be processed
            const event = new KeyboardEvent('keypress', {
                key: String.fromCharCode(Math.floor(Math.random() * 26) + 97), // Random lowercase letter
                code: 'Key' + String.fromCharCode(Math.floor(Math.random() * 26) + 65), // Corresponding KeyCode (approx)
                keyCode: Math.floor(Math.random() * 26) + 97, // keyCode is deprecated but sometimes checked
                which: Math.floor(Math.random() * 26) + 97,   // which is also deprecated
                bubbles: true,
                cancelable: true // Key events are often cancelable
            });
            // Dispatch on document or a potentially focused element if identifiable
            document.dispatchEvent(event);
            lastActivityTime = Date.now();
         } catch(e) {
             console.warn("Anti-inactivity: Error simulating key press.", e);
         }
    }

    const activityIntervalId = setInterval(() => {
        // Only simulate activity if no real activity has been detected recently
        const timeSinceLastActivity = Date.now() - lastActivityTime;
        if (timeSinceLastActivity > simulateActivityInterval * 0.8) { // Start simulating a bit before the interval
            if (Math.random() > 0.5) {
                simulateMouseMove();
            } else {
                simulateKeyPress();
            }
            console.log("Simulating user activity.");
        }
    }, simulateActivityInterval);

    // Keep track of actual user activity
    ['mousemove', 'mousedown', 'mouseup', 'keydown', 'keyup', 'wheel', 'scroll', 'touchstart', 'touchend'].forEach(eventType => {
        document.addEventListener(eventType, () => {
            lastActivityTime = Date.now();
        }, { passive: true, capture: true }); // Capture phase and passive for broader coverage & performance
    });

    console.log("Global Anti-inactivity measures applied.");

    // Optional: Add a way to clean up if the script were ever stopped manually (rare for UserScripts)
    // window.addEventListener('unload', () => {
    //    clearInterval(activityIntervalId);
       // Restore original methods if possible (complex and often omitted)
    // });

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址