Kour.io Zeph Menu

Speed Hack, Set KP (Work In Progress) Invisibility

当前为 2025-04-04 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Kour.io Zeph Menu
// @match        *://kour.io/*
// @version      1.0.4
// @author       Happyjeffery
// @icon         https://i.imgur.com/11sYWVM.png
// @description  Speed Hack, Set KP (Work In Progress) Invisibility
// @run-at       document-start
// @grant        unsafeWindow
// @namespace    https://greasyfork.org/users/1369586
// ==/UserScript==

(function() {
    'use strict';

    /***************************************
     * Performance.now Speed Hack
     ***************************************/
    const originalPerfNow = performance.now.bind(performance);
    function updatePerformanceNow(multiplier) {
        if (multiplier === 1) {
            performance.now = originalPerfNow;
        } else {
            performance.now = new Proxy(originalPerfNow, {
                apply: function(target, thisArg, argArray) {
                    try {
                        throw new Error();
                    } catch (e) {
                        if (!e.stack.includes("invoke_")) {
                            return target.apply(thisArg, argArray) * multiplier;
                        }
                    }
                    return target.apply(thisArg, argArray);
                }
            });
        }
    }
    updatePerformanceNow(1);

    /***************************************
     * Invisibility WebSocket Hook
     ***************************************/
    const wsInstances = [];  // Store all open WebSocket instances.
    const OriginalWebSocket = unsafeWindow.WebSocket;
    function hookOnMessage(ws) {
        const originalAddEventListener = ws.addEventListener;
        ws.addEventListener = function(type, listener, options) {
            if (type === "message") {
                const wrappedListener = function(event) {
                    try {
                        if (event.data && typeof event.data !== "string") {
                            const data = new Uint8Array(event.data);
                            const hexString = Array.from(data)
                                .map(b => b.toString(16).padStart(2, '0'))
                                .join(" ");
                            const damageSignature = "f3 04 c8 02 f5 15 04";
                            if (hexString.startsWith(damageSignature) && kourInstance.config.Invisible) {
                                return; // Block this damage packet.
                            }
                        }
                    } catch (e) { }
                    listener.call(this, event);
                };
                return originalAddEventListener.call(this, type, wrappedListener, options);
            } else {
                return originalAddEventListener.call(this, type, listener, options);
            }
        };

        const descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(ws), 'onmessage');
        Object.defineProperty(ws, 'onmessage', {
            set: function(fn) {
                const wrapped = function(event) {
                    try {
                        if (event.data && typeof event.data !== "string") {
                            const data = new Uint8Array(event.data);
                            const hexString = Array.from(data)
                                .map(b => b.toString(16).padStart(2, '0'))
                                .join(" ");
                            const damageSignature = "f3 04 c8 02 f5 15 04";
                            if (hexString.startsWith(damageSignature) && kourInstance.config.Invisible) {
                                return;
                            }
                        }
                    } catch (e) { }
                    fn(event);
                };
                descriptor.set.call(this, wrapped);
            },
            get: function() {
                return descriptor.get.call(this);
            }
        });
    }
    unsafeWindow.WebSocket = function(...args) {
        const ws = new OriginalWebSocket(...args);
        wsInstances.push(ws);
        hookOnMessage(ws);
        return ws;
    };
    unsafeWindow.WebSocket.prototype = OriginalWebSocket.prototype;


    class Kour {
        constructor() {
            this.config = {
                Invisible: true  
            };
        }
    }
    const kourInstance = new Kour();
    unsafeWindow.kourInstance = kourInstance;

    function setKP() {
        let kpValue = prompt("Enter KP value:", "35");
        if (!kpValue) return;
        const numKP = Number(kpValue);
        if (isNaN(numKP)) {
            console.error("Invalid KP value entered.");
            return;
        }
        if (typeof unityInstance !== 'undefined' && typeof unityInstance.SendMessage === 'function') {
            try {
                unityInstance.SendMessage('MainManager', 'OnReceivedIsAdmin', numKP);
                console.log(`[Zeph Menu] Sent KP value ${numKP} via SendMessage.`);
            } catch (e) {
                console.error("[Zeph Menu] SendMessage failed:", e);
            }
        } else {
            console.error("[Zeph Menu] unityInstance not found.");
        }
        unsafeWindow.kpValue = numKP;
    }

    function refreshWebSocketHandlers() {
        wsInstances.forEach(ws => {
            try {
                let current = ws.onmessage;
                ws.onmessage = current; 
            } catch (e) { /* ignore errors */ }
        });
    }

    function createUI() {
        const menu = document.createElement('div');
        menu.id = "zephMenu";
        Object.assign(menu.style, {
            position: "fixed",
            top: "50px",
            right: "50px",
            width: "250px",
            backgroundColor: "#5a2d72", 
            color: "#fff",
            padding: "15px",
            zIndex: "10000",
            fontFamily: "Arial, sans-serif",
            fontSize: "16px",
            borderRadius: "8px",
            boxShadow: "0 4px 8px rgba(0,0,0,0.2)",
            display: "none",
            transition: "all 0.3s ease-in-out"
        });

        const header = document.createElement("div");
        header.textContent = "Zeph Menu";
        header.style.textAlign = "center";
        header.style.fontWeight = "bold";
        header.style.fontSize = "20px";
        header.style.marginBottom = "15px";
        menu.appendChild(header);

        const adminBtn = document.createElement("button");
        adminBtn.textContent = "Set KP (Work in progress)";
        Object.assign(adminBtn.style, {
            width: "100%",
            margin: "8px 0",
            padding: "8px",
            cursor: "pointer",
            backgroundColor: "#9b3e9f",
            border: "none",
            borderRadius: "5px",
            fontSize: "14px",
            color: "#fff",
            transition: "background-color 0.3s",
        });
        adminBtn.addEventListener("click", setKP);
        adminBtn.addEventListener("mouseover", () => adminBtn.style.backgroundColor = "#a74cbf");
        adminBtn.addEventListener("mouseout", () => adminBtn.style.backgroundColor = "#9b3e9f");
        menu.appendChild(adminBtn);

        const speedContainer = document.createElement("div");
        speedContainer.style.margin = "15px 0";
        const speedLabel = document.createElement("label");
        speedLabel.textContent = "Speed Hack Multiplier: ";
        speedContainer.appendChild(speedLabel);
        const speedValue = document.createElement("span");
        speedValue.textContent = "1x";
        speedContainer.appendChild(speedValue);
        const speedSlider = document.createElement("input");
        speedSlider.type = "range";
        speedSlider.min = "1";
        speedSlider.max = "6"; // Maximum 6×
        speedSlider.step = "0.5";
        speedSlider.value = "1";
        speedSlider.style.width = "100%";
        speedSlider.addEventListener("input", function() {
            let multiplier = parseFloat(speedSlider.value);
            speedValue.textContent = multiplier.toFixed(1) + "x";
            updatePerformanceNow(multiplier);
        });
        speedContainer.appendChild(speedSlider);
        menu.appendChild(speedContainer);

        const invisContainer = document.createElement("div");
        const invisCheckbox = document.createElement("input");
        invisCheckbox.type = "checkbox";
        invisCheckbox.id = "invisToggle";
        invisCheckbox.checked = kourInstance.config.Invisible;
        invisCheckbox.addEventListener("change", function() {
            kourInstance.config.Invisible = this.checked;
            console.log("Invisibility set to " + this.checked);
            refreshWebSocketHandlers();
        });
        const invisLabel = document.createElement("label");
        invisLabel.htmlFor = "invisToggle";
        invisLabel.textContent = " Invisible";
        invisContainer.appendChild(invisCheckbox);
        invisContainer.appendChild(invisLabel);
        menu.appendChild(invisContainer);

        document.body.appendChild(menu);
    }

    document.addEventListener("keydown", function(e) {
        if (e.key === "o" && !e.target.matches("input, textarea")) {
            const menu = document.getElementById("zephMenu");
            if (menu) {
                menu.style.display = (menu.style.display === "none" ? "block" : "none");
            }
        }
    });

    window.addEventListener("load", createUI);
})();