kour.io mod menu

Kour.io mod menu

Nainštalovať tento skript?
Autor skriptu navrhuje

Tiež sa vám môže páčiť Kour.rip.

Nainštalovať tento skript

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==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();
        }
    });
});