HackTimer V1

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

נכון ליום 18-10-2025. ראה הגרסה האחרונה.

אין להתקין סקריפט זה ישירות. זוהי ספריה עבור סקריפטים אחרים // @require https://update.greasyfork.org/scripts/552983/1679776/HackTimer%20V1.js

// ==UserScript==
// @license      MIT
// @name         HackTimer V1
// @namespace    HackTimer
// @version      1.0.7
// @description  Uses a Web Worker to ensure high-precision timing for setInterval and setTimeout.
// @grant        none
// ==/UserScript==

(function (workerScript) {
    if (!/MSIE 10/i.test(navigator.userAgent)) {
        try {
            const workerCode = `
class TimerWorker {
    constructor() {
        this.timers = new Map();
        this.setupMessageHandler();
    }

    setupMessageHandler() {
        self.addEventListener('message', (event) => {
            const { name, fakeId, time } = event.data;
            this.handleMessage(name, fakeId, time);
        });
    }

    handleMessage(name, fakeId, time) {
        switch (name) {
            case 'setInterval':
                this.setInterval(fakeId, time);
                break;
            case 'clearInterval':
                this.clearInterval(fakeId);
                break;
            case 'setTimeout':
                this.setTimeout(fakeId, time);
                break;
            case 'clearTimeout':
                this.clearTimeout(fakeId);
                break;
        }
    }

    setInterval(fakeId, interval) {
        const timerId = setInterval(() => {
            postMessage({ fakeId });
        }, interval);
        this.timers.set(fakeId, { type: 'interval', id: timerId });
    }

    clearInterval(fakeId) {
        const timer = this.timers.get(fakeId);
        if (timer && timer.type === 'interval') {
            clearInterval(timer.id);
            this.timers.delete(fakeId);
        }
    }

    setTimeout(fakeId, timeout) {
        const timerId = setTimeout(() => {
            postMessage({ fakeId });
            this.timers.delete(fakeId);
        }, timeout);
        this.timers.set(fakeId, { type: 'timeout', id: timerId });
    }

    clearTimeout(fakeId) {
        const timer = this.timers.get(fakeId);
        if (timer && timer.type === 'timeout') {
            clearTimeout(timer.id);
            this.timers.delete(fakeId);
        }
    }
}

new TimerWorker();
`;
            const blob = new Blob([workerCode], { type: 'application/javascript' });
            workerScript = URL.createObjectURL(blob);
        } catch (error) {
            console.warn('HackTimer: Blob not supported, using external script');
        }
    }

    class HackTimer {
        constructor(workerScript) {
            this.worker = null;
            this.callbacks = new Map();
            this.lastId = 0;
            this.maxId = 0x7FFFFFFF;
            this.logPrefix = 'HackTimer: ';
            this.originalTimers = {
                setInterval: window.setInterval,
                clearInterval: window.clearInterval,
                setTimeout: window.setTimeout,
                clearTimeout: window.clearTimeout
            };
            
            this.init(workerScript);
        }

        init(workerScript) {
            if (typeof Worker === 'undefined') {
                console.warn(this.logPrefix + 'Web Workers not supported');
                return;
            }

            try {
                this.worker = new Worker(workerScript);
                this.setupWorkerHandlers();
                this.overrideTimers();
            } catch (error) {
                console.error(this.logPrefix + 'Initialisation failed:', error);
            }
        }

        setupWorkerHandlers() {
            this.worker.onmessage = (event) => {
                const { fakeId } = event.data;
                this.executeCallback(fakeId);
            };

            this.worker.onerror = (event) => {
                console.error(this.logPrefix + 'Worker error:', event);
            };
        }

        generateId() {
            do {
                this.lastId = (this.lastId >= this.maxId) ? 1 : this.lastId + 1;
            } while (this.callbacks.has(this.lastId));
            return this.lastId;
        }

        executeCallback(fakeId) {
            const callbackData = this.callbacks.get(fakeId);
            if (!callbackData) return;

            const { callback, parameters, isTimeout } = callbackData;
            
            if (isTimeout) {
                this.callbacks.delete(fakeId);
            }

            try {
                if (typeof callback === 'function') {
                    callback.apply(window, parameters);
                } else if (typeof callback === 'string') {
                    const func = new Function(callback);
                    func.apply(window, parameters);
                }
            } catch (error) {
                console.error(this.logPrefix + 'Callback execution error:', error);
            }
        }

        overrideTimers() {
            window.setInterval = (callback, time, ...parameters) => {
                const fakeId = this.generateId();
                this.callbacks.set(fakeId, {
                    callback,
                    parameters,
                    isTimeout: false
                });
                
                this.worker.postMessage({
                    name: 'setInterval',
                    fakeId: fakeId,
                    time: Math.max(0, time || 0)
                });
                
                return fakeId;
            };

            window.clearInterval = (fakeId) => {
                if (this.callbacks.has(fakeId)) {
                    this.callbacks.delete(fakeId);
                    this.worker.postMessage({
                        name: 'clearInterval',
                        fakeId: fakeId
                    });
                }
            };

            window.setTimeout = (callback, time, ...parameters) => {
                const fakeId = this.generateId();
                this.callbacks.set(fakeId, {
                    callback,
                    parameters,
                    isTimeout: true
                });
                
                this.worker.postMessage({
                    name: 'setTimeout',
                    fakeId: fakeId,
                    time: Math.max(0, time || 0)
                });
                
                return fakeId;
            };

            window.clearTimeout = (fakeId) => {
                if (this.callbacks.has(fakeId)) {
                    this.callbacks.delete(fakeId);
                    this.worker.postMessage({
                        name: 'clearTimeout',
                        fakeId: fakeId
                    });
                }
            };
        }

        destroy() {
            if (this.worker) {
                this.worker.terminate();
                this.callbacks.clear();
                
                // Restore original timer functions
                Object.assign(window, this.originalTimers);
            }
        }
    }

    // Initialize HackTimer
    new HackTimer(workerScript);

})('HackTimerWorker.js');