Universal Speed Hack

A powerful Universal Speed Hack supporting setTimeout,setInterval,requestAnimationFrame,Date.now(), and performance.now()

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Greasemonkey lub Violentmonkey.

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

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana będzie instalacja rozszerzenia Tampermonkey lub Userscripts.

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

Aby zainstalować ten skrypt, musisz zainstalować rozszerzenie menedżera skryptów użytkownika.

(Mam już menedżera skryptów użytkownika, pozwól mi to zainstalować!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Musisz zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

(Mam już menedżera stylów użytkownika, pozwól mi to zainstalować!)

// ==UserScript==
// @name         Universal Speed Hack
// @namespace    http://tampermonkey.net/
// @version      1
// @description  A powerful Universal Speed Hack supporting setTimeout,setInterval,requestAnimationFrame,Date.now(), and performance.now()
// @author       OpenSource (https://www.youtube.com/@OpenSource-w4j)
// @match        *://*/*
// @run-at       document-start
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function enableSpeedHackEngine() {
        if (window.__universal_sh_engine_active) return;
        window.__universal_sh_engine_active = true;

        let globalSpeed = 1.0;
        let speedhackActive = false;

        window.__sh_setSpeed = (val) => { globalSpeed = val; };
        window.__sh_setActive = (act) => { speedhackActive = act; };

        const realPerfNow = performance.now.bind(performance);
        const origRAF = window.requestAnimationFrame.bind(window);

        let lastTime = realPerfNow();
        let simTime = lastTime;

        performance.now = function() {
            if (!speedhackActive || globalSpeed === 1.0) return realPerfNow();
            const now = realPerfNow();
            simTime += (now - lastTime) * globalSpeed;
            lastTime = now;
            return simTime;
        };

        window.requestAnimationFrame = function(cb) {
            return origRAF(function(timestamp) {
                lastTime = timestamp;
                if (!speedhackActive || globalSpeed === 1.0) return cb(timestamp);
                return cb(simTime);
            });
        };

        const origSetInterval = window.setInterval;
        const origSetTimeout = window.setTimeout;

        window.setInterval = function(callback, delay, ...args) {
            if (speedhackActive && globalSpeed > 0) {
                delay = delay / globalSpeed;
            }
            return origSetInterval(callback, delay, ...args);
        };

        window.setTimeout = function(callback, delay, ...args) {
            if (speedhackActive && globalSpeed > 0) {
                delay = delay / globalSpeed;
            }
            return origSetTimeout(callback, delay, ...args);
        };

        const realDateNow = Date.now.bind(Date);
        let simDateNow = realDateNow();
        let lastDateCheck = realDateNow();

        Date.now = function() {
            if (!speedhackActive || globalSpeed === 1.0) return realDateNow();
            const now = realDateNow();
            simDateNow += (now - lastDateCheck) * globalSpeed;
            lastDateCheck = now;
            return Math.floor(simDateNow);
        };
    }

    enableSpeedHackEngine();

    function initWhenCanvasReady() {
        if (document.getElementById('universal-speed-hack-host')) return;

        const checkInterval = setInterval(() => {
            const gameCanvas = document.querySelector('canvas');
            if (gameCanvas && (gameCanvas.width > 100 || gameCanvas.height > 100 || gameCanvas.style.display !== 'none')) {
                clearInterval(checkInterval);
                createGUI();
            }
        }, 300);
    }

    function createGUI() {
        if (document.getElementById('universal-speed-hack-host')) return;

        let globalSpeed = 1.0;
        let speedhackActive = false;
        let toggleKey = 'h';

        const host = document.createElement('div');
        host.id = 'universal-speed-hack-host';
        host.style.cssText = 'position: fixed; top: 0; left: 0; z-index: 2147483647; pointer-events: none;';
        const shadow = host.attachShadow({ mode: 'open' });

        const container = document.createElement('div');
        container.id = 'universal-speed-hack-gui';
        container.style.cssText = `
            position: fixed;
            top: 15px;
            right: 15px;
            pointer-events: auto;
            background: #141414;
            color: #e0e0e0;
            padding: 12px;
            border-radius: 8px;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            font-size: 12px;
            box-shadow: 0 8px 24px rgba(0,0,0,0.6);
            user-select: none;
            display: flex;
            flex-direction: column;
            gap: 10px;
            width: 200px;
            border: 1px solid #2a2a2a;
        `;
        shadow.appendChild(container);

        const header = document.createElement('div');
        header.style.cssText = 'font-weight: 600; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #262626; padding-bottom: 6px; cursor: move; color: #fff; letter-spacing: 0.3px;';
        header.innerHTML = '<span>Universal Speed Hack</span> <span style="cursor:pointer; color:#777; font-size:14px;" id="sh-min">−</span>';
        container.appendChild(header);

        const body = document.createElement('div');
        body.id = 'sh-content';
        body.style.cssText = 'display: flex; flex-direction: column; gap: 8px;';
        container.appendChild(body);

        const toggleBtn = document.createElement('button');
        toggleBtn.innerText = 'OFF';
        toggleBtn.style.cssText = `
            background: #2a2a2a;
            color: #ef4444;
            border: 1px solid #3f3f46;
            padding: 6px;
            border-radius: 5px;
            cursor: pointer;
            font-weight: 700;
            font-size: 11px;
            transition: all 0.2s;
        `;

        function updateToggleUI() {
            toggleBtn.style.background = speedhackActive ? '#166534' : '#2a2a2a';
            toggleBtn.style.color = speedhackActive ? '#4ade80' : '#ef4444';
            toggleBtn.style.borderColor = speedhackActive ? '#22c55e' : '#3f3f46';
            toggleBtn.innerText = speedhackActive ? 'ACTIVE' : 'OFF';
            if (window.__sh_setActive) window.__sh_setActive(speedhackActive);
        }

        toggleBtn.onclick = () => {
            speedhackActive = !speedhackActive;
            updateToggleUI();
        };
        body.appendChild(toggleBtn);

        const controlWrap = document.createElement('div');
        controlWrap.style.cssText = 'display: flex; flex-direction: column; gap: 6px; background: #1a1a1a; padding: 8px; border-radius: 6px; border: 1px solid #222;';

        const labelRow = document.createElement('div');
        labelRow.style.cssText = 'display: flex; justify-content: space-between; color: #a1a1aa; font-size: 11px; align-items: center;';
        labelRow.innerHTML = `<span>Speed</span>`;

        const inputControls = document.createElement('div');
        inputControls.style.cssText = 'display: flex; align-items: center; gap: 4px;';

        const minusBtn = document.createElement('button');
        minusBtn.innerText = '-';
        minusBtn.style.cssText = 'background: #222; color: #38bdf8; border: 1px solid #333; width: 22px; height: 22px; border-radius: 3px; cursor: pointer; font-weight: bold; font-size: 12px;';

        const numberInput = document.createElement('input');
        numberInput.type = 'text';
        numberInput.value = '1';
        numberInput.style.cssText = `
            width: 40px;
            background: #111;
            color: #38bdf8;
            border: 1px solid #333;
            text-align: center;
            font-family: monospace;
            font-size: 11px;
            border-radius: 4px;
            height: 20px;
            outline: none;
        `;

        const plusBtn = document.createElement('button');
        plusBtn.innerText = '+';
        plusBtn.style.cssText = 'background: #222; color: #38bdf8; border: 1px solid #333; width: 22px; height: 22px; border-radius: 3px; cursor: pointer; font-weight: bold; font-size: 12px;';

        function applySpeed(val) {
            let num = parseFloat(val);
            if (isNaN(num) || num < 1) num = 1;
            if (num > 9999) num = 9999;
            globalSpeed = num;
            numberInput.value = num;
            sliderInput.value = num > sliderInput.max ? sliderInput.max : num;
            if (window.__sh_setSpeed) window.__sh_setSpeed(globalSpeed);
        }

        // CONTINUOUS HOLD-TO-INCREMENT LOGIC (PC & MOBILE TOUCH)
        let holdInterval = null;
        let holdTimeout = null;

        function startHold(stepValue) {
            stopHold();
            applySpeed(globalSpeed + stepValue);

            holdTimeout = setTimeout(() => {
                holdInterval = setInterval(() => {
                    applySpeed(globalSpeed + stepValue);
                }, 75);
            }, 400);
        }

        function stopHold() {
            if (holdTimeout) { clearTimeout(holdTimeout); holdTimeout = null; }
            if (holdInterval) { clearInterval(holdInterval); holdInterval = null; }
        }

        minusBtn.addEventListener('mousedown', (e) => { e.preventDefault(); startHold(-1); });
        minusBtn.addEventListener('mouseup', stopHold);
        minusBtn.addEventListener('mouseleave', stopHold);
        minusBtn.addEventListener('touchstart', (e) => { e.preventDefault(); startHold(-1); }, {passive: false});
        minusBtn.addEventListener('touchend', stopHold);

        plusBtn.addEventListener('mousedown', (e) => { e.preventDefault(); startHold(1); });
        plusBtn.addEventListener('mouseup', stopHold);
        plusBtn.addEventListener('mouseleave', stopHold);
        plusBtn.addEventListener('touchstart', (e) => { e.preventDefault(); startHold(1); }, {passive: false});
        plusBtn.addEventListener('touchend', stopHold);

        numberInput.addEventListener('input', (e) => {
            let clean = e.target.value.replace(/[^0-9.]/g, '');
            if (clean !== '') applySpeed(clean);
        });

        numberInput.addEventListener('keydown', (e) => {
            e.stopPropagation();
            if (e.key === 'Enter') {
                e.preventDefault();
                numberInput.blur();
            }
        });

        inputControls.appendChild(minusBtn);
        inputControls.appendChild(numberInput);
        inputControls.appendChild(plusBtn);
        labelRow.appendChild(inputControls);
        controlWrap.appendChild(labelRow);

        const sliderInput = document.createElement('input');
        sliderInput.type = 'range';
        sliderInput.min = '1';
        sliderInput.max = '9999';
        sliderInput.step = '1';
        sliderInput.value = '1';
        sliderInput.style.cssText = 'width: 100%; cursor: pointer; accent-color: #38bdf8;';

        sliderInput.oninput = (e) => {
            applySpeed(e.target.value);
        };

        controlWrap.appendChild(sliderInput);
        body.appendChild(controlWrap);

        const footer = document.createElement('div');
        footer.style.cssText = 'font-size: 8px; color: #52525b; text-align: center; border-top: 1px solid #262626; padding-top: 4px;';
        footer.innerHTML = '<a href="https://www.youtube.com/@OpenSource-w4j" target="_blank" style="color: #38bdf8; text-decoration: none;">Made by OpenSource</a>';
        container.appendChild(footer);

        let minimized = false;
        header.querySelector('#sh-min').onclick = () => {
            minimized = !minimized;
            body.style.display = minimized ? 'none' : 'flex';
            header.querySelector('#sh-min').innerText = minimized ? '+' : '−';
        };

        window.addEventListener('keydown', (e) => {
            if (shadow.activeElement === numberInput) return;
            if (e.key.toLowerCase() === toggleKey) {
                container.style.display = container.style.display === 'none' ? 'flex' : 'none';
            }
        });

        // PC Drag-and-Drop
        let isDragging = false;
        let startX, startY, initialX, initialY;

        header.onmousedown = (e) => {
            if (e.target.id === 'sh-min') return;
            isDragging = true;
            startX = e.clientX;
            startY = e.clientY;
            initialX = container.offsetLeft;
            initialY = container.offsetTop;
            document.addEventListener('mousemove', onMouseMove);
            document.addEventListener('mouseup', onMouseUp);
        };

        function onMouseMove(e) {
            if (!isDragging) return;
            container.style.left = (initialX + (e.clientX - startX)) + 'px';
            container.style.top = (initialY + (e.clientY - startY)) + 'px';
            container.style.right = 'auto';
        }

        function onMouseUp() {
            isDragging = false;
            document.removeEventListener('mousemove', onMouseMove);
            document.removeEventListener('mouseup', onMouseUp);
        }

        // Mobile Touch Support for Dragging
        header.ontouchstart = (e) => {
            if (e.target.id === 'sh-min') return;
            const touch = e.touches[0];
            isDragging = true;
            startX = touch.clientX;
            startY = touch.clientY;
            initialX = container.offsetLeft;
            initialY = container.offsetTop;
            document.addEventListener('touchmove', onTouchMove);
            document.addEventListener('touchend', onTouchEnd);
        };

        function onTouchMove(e) {
            if (!isDragging) return;
            const touch = e.touches[0];
            container.style.left = (initialX + (touch.clientX - startX)) + 'px';
            container.style.top = (initialY + (touch.clientY - startY)) + 'px';
            container.style.right = 'auto';
        }

        function onTouchEnd() {
            isDragging = false;
            document.removeEventListener('touchmove', onTouchMove);
            document.removeEventListener('touchend', onTouchEnd);
        }

        if (document.body) {
            document.body.appendChild(host);
            showNotification(shadow);
        } else {
            window.addEventListener('DOMContentLoaded', () => {
                document.body.appendChild(host);
                showNotification(shadow);
            });
        }
    }

    function showNotification(shadowRoot) {
        const notif = document.createElement('div');
        notif.style.cssText = `
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            z-index: 2147483647;
            background: #18181b;
            color: #f4f4f5;
            padding: 8px 16px;
            border-radius: 6px;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            font-size: 11px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.5);
            border: 1px solid #27272a;
            transition: opacity 0.5s ease;
            opacity: 1;
            pointer-events: auto;
            letter-spacing: 0.3px;
        `;
        notif.innerHTML = '<a href="https://www.youtube.com/@OpenSource-w4j" target="_blank" style="color: #38bdf8; text-decoration: none;">Made by OpenSource</a>';
        shadowRoot.appendChild(notif);

        // Disappears automatically after 2 seconds
        setTimeout(() => {
            notif.style.opacity = '0';
            setTimeout(() => notif.remove(), 500);
        }, 2000);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initWhenCanvasReady);
    } else {
        initWhenCanvasReady();
    }
})();