kour.io mod menu

Kour.io mod menu

Установить этот скрипт?
Рекомендуемый автором скрипт

Вам также может понравится Kour.rip.

Установить этот скрипт

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         kour.io mod menu 
// @match        *://kour.io/*
// @version      1.7.0
// @author       rexmine-code
// @description  Kour.io mod menu
// @run-at       document-start
// @grant        unsafeWindow
// @namespace https://greasyfork.org/users/1369586
// @license MIT
// ==/UserScript==

const Signatures = {
    ping:              "f3 07 01 00 00", // Filter
    pong:              "f3 06 01 01 01", // Filter
    anotherPing:       "f3 04 e2 03 e3", // Filter

    createGame:        "f3 02 e3 03 ff 07 06", // Create Game / Party (Can be used to change partyId)
    updateState:       "f3 02 fd 02 f4 03 c8", // Insta-kill
    damageTaken:       "f3 04 c8 02 f5 15 04", // Invisibility

    connectStarts:     "f3 02 e", // Connect (start)
    connectEnds:       "f1 1c e8 1c bf 0b 23" // Connect (end)
}

class Kour {
    constructor() {
        this.sockets = [];
        this.config = {
            Invisible: true,
            InstantKill: false
        }
        this.packets = 0;
        unsafeWindow.WebSocket = class extends WebSocket {
            constructor() {
                super(...arguments);
                this.addEventListener("open", event => {
                    kourInstance.sockets.push(this);
                    kourInstance.hook(this);
                });
            }
        }
    }

    hexArrayToString(hexArray) {
        let str = '';
        for (let i = 0; i < hexArray.length; i++) {
            let hex = hexArray[i];
            let decimalValue = parseInt(hex, 16);
            str += String.fromCharCode(decimalValue);
        }
        return str;
    }

    hook(socket) {
        console.debug("%c !! ", "background:#7aadff;color:#000", `Intercepted WebSocket (${socket.url})`);
        const send = socket.send;
        const onmessage = socket.onmessage;

        socket.onmessage = (event) => {
            if (event.data == null) {
                return onmessage.call(socket, event);
            }

            let hexArray = Array.from(new Uint8Array(event.data)).map(byte => byte.toString(16).padStart(2, '0'));
            let stringHexArray = hexArray.join(" ");

            if (stringHexArray.startsWith(Signatures.damageTaken) && this.config.Invisible) {
                return;
            }

            return onmessage.call(socket, event);
        };

        socket.send = (data) => {
            let hexArray = Array.from(new Uint8Array(data)).map(byte => byte.toString(16).padStart(2, '0'));
            let stringHexArray = hexArray.join(" ");

            if (stringHexArray.startsWith(Signatures.createGame)) {
                let partyId = this.hexArrayToString(hexArray.slice(7, 13));
                console.debug("%c => ", "background:#7F7;color:#000", "Creating game:", partyId);
                return send.call(socket, data);
            } else if (stringHexArray.startsWith(Signatures.updateState) && this.config.InstantKill) {
                for (let i = 0; i < 40; i++) {
                    send.call(socket, data);
                }
                return send.call(socket, data);
            }
            return send.call(socket, data);
        };
    }

    watermark() {
        let overlayCanvas = document.createElement("canvas");
        let unityContainer = document.getElementById("unity-container");
        overlayCanvas.width = unityContainer.clientWidth;
        overlayCanvas.height = unityContainer.clientHeight;
        overlayCanvas.style.position = "absolute";
        overlayCanvas.style.top = "50%";
        overlayCanvas.style.left = "50%";
        overlayCanvas.style.transform = "translate(-50%, -50%)";
        overlayCanvas.style.pointerEvents = "none";
        unityContainer.appendChild(overlayCanvas);

        let ctx = overlayCanvas.getContext("2d");
        ctx.font = "15px monospace";
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";

        function animate() {
            let lines = [`kour.rip (${kourInstance.packets})`];
            lines.push(kourInstance.config.Invisible ? "<c>✔ Invisible" : "<c>✖ Invisible");
            lines.push(kourInstance.config.InstantKill ? "<c>✔ Instant-Kill" : "<c>✖ Instant-Kill");

            let lineHeight = 20;
            let startY = overlayCanvas.height / 2 - ((lines.length - 1) * lineHeight) / 2 + 60;
            let centerX = overlayCanvas.width / 2;

            ctx.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);
            ctx.globalAlpha = 1;

            lines.forEach((line, index) => {
                ctx.fillStyle = line.includes("<c>") ? "#F8CEFF" : "white";
                ctx.fillText(line.replace("<c>", ""), centerX, startY + index * lineHeight);
            });

            requestAnimationFrame(animate);
        }

        animate();
    }

    toggleInvisible() {
        this.config.Invisible = !this.config.Invisible;
    }

    toggleInstantKill() {
        this.config.InstantKill = !this.config.InstantKill;
    }

    openModMenu() {
        let menu = document.createElement('div');
        menu.style.position = 'fixed';
        menu.style.top = '10px';
        menu.style.left = '10px';
        menu.style.backgroundColor = 'rgba(0, 0, 0, 0.9)';  // Increase opacity
        menu.style.color = 'white';
        menu.style.padding = '20px';  // Increase padding for better visibility
        menu.style.borderRadius = '5px';
        menu.style.zIndex = '9999';
        menu.style.boxShadow = '0 0 20px rgba(0, 0, 0, 0.7)';  // Add more shadow for better contrast

        let invBtn = this.createStyledButton('Invisible', () => {
            this.toggleInvisible();
            invBtn.innerText = this.config.Invisible ? 'Disable Invisible' : 'Enable Invisible';
        });

        let killBtn = this.createStyledButton('Instant Kill', () => {
            this.toggleInstantKill();
            killBtn.innerText = this.config.InstantKill ? 'Disable Instant-Kill' : 'Enable Instant-Kill';
        });

        menu.appendChild(invBtn);
        menu.appendChild(document.createElement('br'));
        menu.appendChild(killBtn);

        // RGB border effect using CSS animation
        menu.style.border = '5px solid';
        menu.style.borderImage = 'linear-gradient(45deg, red, orange, yellow, green, blue, indigo, violet)';
        menu.style.borderImageSlice = 1;

        // Ensure the menu is always visible for debugging
        document.body.appendChild(menu);
        this.menu = menu;
    }

    createStyledButton(text, onClick) {
        let button = document.createElement('button');
        button.innerText = text;
        button.style.backgroundColor = 'transparent';
        button.style.color = 'white';
        button.style.border = '3px solid transparent';
        button.style.padding = '10px';
        button.style.margin = '5px';
        button.style.borderRadius = '5px';
        button.style.fontSize = '14px';
        button.style.cursor = 'pointer';
        button.style.transition = 'all 0.3s ease';

        // RGB border effect for buttons
        button.style.borderImage = 'linear-gradient(45deg, red, orange, yellow, green, blue, indigo, violet)';
        button.style.borderImageSlice = 1;

        // Add hover effect
        button.onmouseover = () => {
            button.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';
        };
        button.onmouseout = () => {
            button.style.backgroundColor = 'transparent';
        };

        button.onclick = onClick;
        return button;
    }

    toggleMenu() {
        if (this.menu.style.display === 'none') {
            this.menu.style.display = 'block';
        } else {
            this.menu.style.display = 'none';
        }
    }
}

const kourInstance = new Kour();

unsafeWindow.kourInstance = kourInstance;

window.addEventListener("load", () => {
    kourInstance.openModMenu();
    window.addEventListener("keydown", (e) => {
        if (e.key === 'm') {  // Press 'm' to toggle the mod menu
            kourInstance.toggleMenu();
        }
    });
});