HackTimer V2

Uses a Web Worker to ensure high-precision timing for setInterval and setTimeout, minimizing throttling.

Versione datata 21/10/2025. Vedi la nuova versione l'ultima versione.

Questo script non dovrebbe essere installato direttamente. È una libreria per altri script da includere con la chiave // @require https://update.greasyfork.org/scripts/552983/1681317/HackTimer%20V2.js

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

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

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @license      MIT
// @name         HackTimer V2
// @namespace    HackTimer
// @version      1.1.2 (Gemini version)
// @description  Uses a Web Worker to ensure high-precision timing for setInterval and setTimeout, minimizing throttling.
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function () {
    const logPrefix = 'HackTimer V2: ';
    let workerScriptUrl = null;

    // --- 1. Generate Worker Script Blob URL ---
    try {
        const workerCode = `
            var fakeIdToId = {};
            onmessage = function (event) {
                var data = event.data;
                var name = data.name;
                var fakeId = data.fakeId;
                // Ensure time is treated as a number, defaulting to 0
                var time = data.time || 0; 

                switch (name) {
                    case 'setInterval':
                        fakeIdToId[fakeId] = setInterval(function () {
                            postMessage({ fakeId: fakeId });
                        }, time);
                        break;
                    case 'clearInterval':
                        if (fakeIdToId[fakeId]) {
                            clearInterval(fakeIdToId[fakeId]);
                            delete fakeIdToId[fakeId];
                        }
                        break;
                    case 'setTimeout':
                        fakeIdToId[fakeId] = setTimeout(function () {
                            postMessage({ fakeId: fakeId });
                            // Timeouts clear themselves after firing
                            delete fakeIdToId[fakeId]; 
                        }, time);
                        break;
                    case 'clearTimeout':
                        if (fakeIdToId[fakeId]) {
                            clearTimeout(fakeIdToId[fakeId]);
                            delete fakeIdToId[fakeId];
                        }
                        break;
                }
            };
        `;
        const blob = new Blob([workerCode], { type: 'application/javascript' });
        workerScriptUrl = window.URL.createObjectURL(blob);
    } catch (error) {
        console.warn(logPrefix + 'Blob creation failed. Web Worker replacement disabled.', error);
        return; // Cannot proceed without Blob support
    }

    if (typeof Worker === 'undefined') {
        console.warn(logPrefix + 'Web Workers not supported. Replacement disabled.');
        if (workerScriptUrl) window.URL.revokeObjectURL(workerScriptUrl);
        return;
    }

    let worker;
    const fakeIdToCallback = new Map();
    let lastFakeId = 1;

    // --- 2. ID Generation ---
    function getFakeId() {
        // Simple incrementing ID, wrapping safely (using a large limit)
        lastFakeId = (lastFakeId % 0xFFFFFFF) + 1; 
        while (fakeIdToCallback.has(lastFakeId)) {
            lastFakeId++;
        }
        return lastFakeId;
    }

    // --- 3. Callback Execution Logic ---
    function executeCallback(fakeId) {
        const request = fakeIdToCallback.get(fakeId);
        if (!request) return;

        const { callback, parameters, isTimeout } = request;
        
        if (isTimeout) {
            fakeIdToCallback.delete(fakeId);
        }

        let callbackFunc = callback;
        
        // Handle string callbacks (legacy support)
        if (typeof callback === 'string') {
            try {
                // eslint-disable-next-line no-new-func
                callbackFunc = new Function(callback);
            } catch (error) {
                console.error(logPrefix + 'Error parsing string callback:', error);
                return;
            }
        }

        if (typeof callbackFunc === 'function') {
            try {
                // Execute in the global scope
                callbackFunc.apply(window, parameters);
            } catch (error) {
                console.error(logPrefix + 'Error executing callback:', error);
            }
        }
    }

    // --- 4. Worker Initialization and Overrides ---
    try {
        worker = new Worker(workerScriptUrl);
        
        // Store originals (useful if users mix native and hacked timers)
        const originalClearInterval = window.clearInterval;
        const originalClearTimeout = window.clearTimeout;

        // Override setInterval
        window.setInterval = function (callback, time, ...parameters) {
            const fakeId = getFakeId();
            fakeIdToCallback.set(fakeId, {
                callback: callback,
                parameters: parameters,
                isTimeout: false
            });
            worker.postMessage({
                name: 'setInterval',
                fakeId: fakeId,
                time: Math.max(0, time || 0)
            });
            return fakeId;
        };

        // Override clearInterval
        window.clearInterval = function (fakeId) {
            if (fakeIdToCallback.has(fakeId)) {
                fakeIdToCallback.delete(fakeId);
                worker.postMessage({
                    name: 'clearInterval',
                    fakeId: fakeId
                });
            } else if (typeof fakeId === 'number' && fakeId > 0) {
                // Allow clearing native timers if the ID wasn't tracked by us
                originalClearInterval(fakeId);
            }
        };

        // Override setTimeout
        window.setTimeout = function (callback, time, ...parameters) {
            const fakeId = getFakeId();
            fakeIdToCallback.set(fakeId, {
                callback: callback,
                parameters: parameters,
                isTimeout: true
            });
            worker.postMessage({
                name: 'setTimeout',
                fakeId: fakeId,
                time: Math.max(0, time || 0)
            });
            return fakeId;
        };

        // Override clearTimeout
        window.clearTimeout = function (fakeId) {
            if (fakeIdToCallback.has(fakeId)) {
                fakeIdToCallback.delete(fakeId);
                worker.postMessage({
                    name: 'clearTimeout',
                    fakeId: fakeId
                });
            } else if (typeof fakeId === 'number' && fakeId > 0) {
                // Allow clearing native timers
                originalClearTimeout(fakeId);
            }
        };

        // Worker Message Handlers
        worker.onmessage = function (event) {
            const { fakeId } = event.data;
            executeCallback(fakeId);
        };

        worker.onerror = function (event) {
            console.error(logPrefix + 'Worker runtime error:', event);
        };
        
        // Clean up the temporary Blob URL
        window.URL.revokeObjectURL(workerScriptUrl);
        
    } catch (error) {
        console.error(logPrefix + 'Initialisation failed. Using standard timers.', error);
        if (workerScriptUrl) window.URL.revokeObjectURL(workerScriptUrl);
    }
})();