Sploop++

simple visuals

目前為 2024-02-25 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Sploop++
// @version      0.6
// @description  simple visuals
// @author       nyannez
// @match        *://sploop.io/*
// @run-at       document-start
// @icon         https://sploop.io/img/ui/favicon.png
// @grant        none
// @namespace https://greasyfork.org/users/960747
// ==/UserScript==

const defaultSettings = {
    HP: true,
    chestsHP: true,
    rainbHP: true,
    automill: true,
    LBF: false,
    rainbBar: false
};
window.defaultSettings = defaultSettings;
const getEl = (id) => document.getElementById(id);
const serverInfo = document.createElement("span");
const pingCount = document.createElement("span");
const bossInfo = document.createElement("span");
const servers = {
    SFRA: "EU#1 Sand",
    SFRA2: "EU#2",
    SFRA2BIS: "EU#2 Sand",
    SCA: "USA#1 Sand",
    SCA2: "USA#2 Sand",
    SGP: 'AS#1 Sand',
    SGP2: 'AS#2 Sand',
    SGP3BIS: "AS#3 Sand",
    FRA1FFA: "EU Classic",
    CA1FFA: "USA Classic",
    SGP1FFA: "AS Classic",
};
window.addEventListener('DOMContentLoaded', event => {
    const Comfortaa = document.createElement('style');
    Comfortaa.innerHTML = `@import "https://fonts.googleapis.com/css2?family=Comfortaa&display=swap";`;
    document.head.appendChild(Comfortaa);
    serverInfo.style = `position: absolute;font-size: 120%;z-index: 888;top: 15px;color: white;left: 1%;font-weight: 100;pointer-events: none;font-family: Comfortaa;text-shadow: 1px 1px 5px black, 3px 3px 5px black;`;
    pingCount.id = "pingCount";
    pingCount.style = "position: absolute;z-index: 10;left: 1%;font-family: Comfortaa;pointer-events:none;top: 50px;font-size: 120%;color: white;font-weight: 100;text-shadow: 1px 1px 5px black, 3px 3px 5px black;"
    bossInfo.id = "bossInfo";
    bossInfo.style = "position: absolute;z-index: 10;left: 1%;font-family: Comfortaa;pointer-events:none;top: 85px;font-size: 120%;color: white;font-weight: 100;text-shadow: 1px 1px 5px black, 3px 3px 5px black;"
    pingCount.textContent = "Ping: unknown";
    serverInfo.textContent = "Loading...";
    bossInfo.textContent = "Boss: unknown";
    serverInfo.style.display = "none";
    pingCount.style.display = "none";
    bossInfo.style.display = "none";
    const menu = document.createElement("div");
    menu.id = "menu";
    menu.style = `
    position: absolute;
    top: 50%;
    background: #00000042;
    left: 50%;
    height: 500px;
    width: 400px;
    transform: translate(-50%, -50%);
    display: none;
    `;
    menu.innerHTML = `
    <div>
    <span class="checkbox-text">Health point</span>
    <label class="checkbox">
      <input type="checkbox" id="HP">
      <span class="checkmark"></span>
    </label>
    </div>
    <div>
    <span class="checkbox-text">Rainbow HP</span>
    <label class="checkbox">
      <input type="checkbox" id="rainbHP">
      <span class="checkmark"></span>
    </label>
    </div>
    <div>
    <span class="checkbox-text">Rainbow age bar</span>
    <label class="checkbox">
      <input type="checkbox" id="rainbBar">
      <span class="checkmark"></span>
    </label>
    </div>
    <div>
    <span class="checkbox-text">Rainbow speed: </span>
    <input class="inpu" value="35">
    </div>
    <div>
    <span class="checkbox-text">Chests HP</span>
    <label class="checkbox">
      <input type="checkbox" id="chestsHP">
      <span class="checkmark"></span>
    </label>
    </div>
    <div>
    <div>
    <span class="checkbox-text">Automills</span>
    <label class="checkbox">
      <input type="checkbox" id="automill">
      <span class="checkmark"></span>
    </label>
    </div>
    <div>
    <span class="checkbox-text">Leader board full gold</span>
    <label class="checkbox">
      <input type="checkbox" id="LBF">
      <span class="checkmark"></span>
    </label>
    </div>
    `;
    document.body.append(serverInfo, pingCount, bossInfo, menu);
    setInterval(() => {
        getSploopServers();
        if (!currentServerUrl) return;
        const serverName = currentServerUrl.toUpperCase();
        const server = sploopServers.find(i => i.r === serverName);
        serverInfo.textContent = `${servers[serverName]}: ${server.d[1]}`;
    }, 2000);
    try {
        document.querySelector("#hat-menu > div.pop-top.select").remove();
        [...document.getElementsByClassName("green-button")].forEach(event => {
            event.style.pointerEvents = "all";
        });
        ["logo", "bottom-wrap", "shop-io-games", "right-content", "game-bottom-content", "game-right-content-main", "game-left-content-main", "cross-promo", "landscape"].forEach(e => getEl(e).remove());
        [...document.getElementsByClassName("description")].forEach(e => {
            e.remove();
        });
        document.querySelector("#skin-message > a > div").remove();
        document.querySelector("#left-content > div:nth-child(3)").remove();
        getEl("shop-message").style.opacity = 0;
        getEl("skin-message").style.opacity = 0;
    } catch(err) {}
    const styleItem = `
    .inpu {
       width: auto;
       max-width: 50px;
       outline: none;
       text-align: center;
    }

    .checkbox {
      position: relative;
      display: inline-block;
      cursor: pointer;
    }

    .checkbox input {
      position: absolute;
      opacity: 0;
      cursor: pointer;
    }

    .checkbox .checkmark {
      position: relative;
      display: inline-block;
      vertical-align: middle;
      width: 20px;
      height: 20px;
      border: 2px solid #333;
      border-radius: 5px;
      background-color: #222;
    }

    .checkbox input:checked + .checkmark {
      background-color: #222;
    }

    .checkbox input:checked + .checkmark:after {
      content: "";
      background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e");
      background-size: cover;
      background-position: center;
      position: absolute;
      width: 100%;
      height: 100%;
    }

    .checkbox span {
      pointer-events: none;
    }

    .checkbox-text {
      font-family: Comfortaa;
      color: white;
    }

    .subcontent-bg {
        box-shadow: none;
        border: none;
    }

    #ranking-rank-container {
      height: 360px;
    }

    #ranking2-middle-main {
      height: auto;
    }

    #left-content {
      height: 40px;
      position: unset;
      width: 100px;
      display: flex;
      flex-direction: row;
      justify-content: space-around;
    }

    #hat-menu {
      height: 330px;
    }

    .green-button {
      background-color: #ffffff5c;
      box-shadow: none;
    }

    .green-button:hover {
      box-shadow: none;
      background-color: #ffffff87;
    }

    .green-button:active {
      box-shadow: none;
      background-color: #ffffff5c;
    }

    .menu .content .menu-item .menu-pricing .action {
      border-radius: 0;
      text-shadow: none;
      border: 3px solid #ffffff;
    }

    .scrollbar::-webkit-scrollbar {
      border: none;
      border-radius: 0;
    }

    .scrollbar::-webkit-scrollbar-thumb {
      border-radius: 0;
      box-shadow: none;
    }

    .pop-box {
      box-shadow: none;
      border-radius: 0;
      background: none !important;
    }

    .menu .content .menu-item {
      border-bottom: none;
      text-shadow: none;
    }

    #game-middle-main {
      left: 50%;
      transform: translate(-50%);
    }

    #main-content {
      background: none;
    }

    #hat_menu_content {
      pointer-events: none;
      padding: 0;
      border: none;
      background: none;
      box-shadow: none;
      margin: 0px;
      overflow: hidden;
    }

    .profile-scores {
      width: 600px;
      height: 76px;
      color: white;
    }

    #profile-next-rank-text {
      height: 100%;
      color: white;
      width: auto;
      max-width: none;
    }

    #profile-next-rank-icons {
      height: 100%;
      width: 250px;
      padding: 5px;
      margin-right: 10px;
    }
    `;
    const styleElement = document.createElement("style");
    styleElement.innerHTML = styleItem;
    document.head.appendChild(styleElement);
    const kd = document.createElement("div");
    let kdCount = (Number(document.querySelector("#total-kill").textContent) / Number(document.querySelector("#total-death").textContent)).toFixed(2);
    kd.innerHTML = `<div><div class="text-shadowed-3 profile-score">Kills/Deaths</div><div class="text-shadowed-3 profile-score yellow-text">${kdCount}</div></div>`;
    document.querySelector("#profile-container > div.middle-main.profile-scores").appendChild(kd);
    document.querySelectorAll('input[type="checkbox"]').forEach(el => {
        const id = el.id;
        if (["chestsHP", "LBF", "HP", "rainbHP", "rainbBar", "automill"].includes(id)) {
            el.checked = defaultSettings[id];
            el.addEventListener("click", event => {
                defaultSettings[id] = !defaultSettings[id];
            });
        };
    });
    window.hue = 0;
    const updateColors = () => {
        if (defaultSettings.rainbBar) {
            window.barColor = `hsl(${window.hue}, 80%, 50%)`;
        } else {
            window.barColor = "#ffffff";
        }
        if (defaultSettings.rainbHP) {
            window.myHPColor = `hsl(${window.hue}, 80%, 50%)`;
        } else {
            window.myHPColor = "#a4cc4f";
        }
        window.hue += 0.3;
        window.hue >= 360 && (window.hue = 0);
    };
    const setNewInterval = () => {
        const speed = document.querySelector("#menu > div:nth-child(4) > input").value;
        const colorInterval = setInterval(() => {
            if (speed !== document.querySelector("#menu > div:nth-child(4) > input").value) {
                console.debug("new interval");
                setNewInterval();
                clearInterval(colorInterval);
            };
            updateColors();
        }, document.querySelector("#menu > div:nth-child(4) > input").value);
    };
    setNewInterval();
});

let sploopServers, currentServerUrl, ws;
const getSploopServers = async () => {
    await fetch("https://sploop.io/servers").then(e => e.text()).then(e => (sploopServers = JSON.parse(e)));
};

const entities = {
    0: { health: 100 },
    14: { health: 380 },
    23: { health: 380 },
    24: { health: 380 },
    25: { health: 1000 },
    27: { health: 5000 },
    28: { health: 5000 },
    36: { health: 380 },
};

const packetsID = {
    item: 0,
    move: 1,
    hat: 5,
    chat: 7,
    place: 8,
    joinGame: 11,
    angle: 13,
    upgrade: 14,
    stopMove: 15,
    clanAcc: 17,
    stopAttack: 18,
    hit: 19,
    joinClan: 21,
    clan: 22,
    EAttack: 23,
    clanLeave: 24
};

let myID, placing = true, copyMove = 0, onHand = 0, placed = false, isAlive = false;
const sendPacket = (packetID, ...values) => ws.send(new Uint8Array([packetID, ...values]));

const getAngle = (angle) => {
    const vec = {
        x: 0,
        y: 0
    };
    if (angle & 1) vec.y--;
    if (angle & 2) vec.y++;
    if (angle & 4) vec.x--;
    if (angle & 8) vec.x++;
    vec.x *= -1;
    vec.y *= -1;
    return Math.atan2(vec.y, vec.x);
};

const checkChat = () => getEl("chat-wrapper").style.display === "" || getEl("chat-wrapper").style.display === "none";

window.addEventListener("keydown", event => {
    const pressedKey = event.code;
    if (pressedKey === "Escape") window.openMenu();
    if (pressedKey === "Digit1") {
        onHand = 0;
    } else if (pressedKey === "Digit2") onHand = 1;
    if (checkChat() && ["KeyW", "KeyA", "KeyS", "KeyD"].includes(pressedKey)) {
        if (pressedKey === "KeyW") copyMove |= 1;
        if (pressedKey === "KeyA") copyMove |= 4;
        if (pressedKey === "KeyS") copyMove |= 2;
        if (pressedKey === "KeyD") copyMove |= 8;
    }
});

window.addEventListener("keyup", event => {
    const pressedKey = event.code;
    if (checkChat() && ["KeyW", "KeyA", "KeyS", "KeyD"].includes(pressedKey)) {
        if (pressedKey === "KeyW") copyMove &= -2;
        if (pressedKey === "KeyA") copyMove &= -5;
        if (pressedKey === "KeyS") copyMove &= -3;
        if (pressedKey === "KeyD") copyMove &= -9;
    }
});

const sound = new Audio("https://cdn.discordapp.com/attachments/911689086903918602/1203401888792318023/uK3Ujie.mp3?ex=65d0f658&is=65be8158&hm=35e255836bc58ddc434aedc81ddbb149a1cde594ed6ae13a197212b865ef581e&");
window.seconds = undefined;

window.getKill = (data) => {
};
window.getBoss = (ID) => {
    clearInterval(window.seconds);
    console.debug(ID);
    const whichBoss = ID === 0 ? "cow" : ID === 1 ? "dragon" : ID === 2 ? "mammoth" : "unknown";
    bossInfo.textContent = `Boss: ${whichBoss}`;
};

window.receiveMsg = (msg) => {
    const data = msg.data;
    const decoded = typeof data === "string" ? JSON.parse(data) : new Uint8Array(data);
    if (!ws) {
        currentServerUrl = msg.target.url.split('//')[1].split('.')[0];
        ws = msg.target;
        ws.onclose = () => (ws = undefined);
    };
    switch (decoded[0]) {
        case 20: {
            if (defaultSettings.automill && copyMove !== 0 && isAlive && serverInfo.textContent.includes("Sand") && !placed && window.stats[Sploop.objCount][5] < 8 && placing) {
                placing = false;
                sendPacket(packetsID.item, 0);
                sendPacket(packetsID.item, 5);
                const angle = getAngle(copyMove);
                const transformedAngle = 65535 * (angle + Math.PI) / (2 * Math.PI);
                sendPacket(packetsID.hit, 255 & transformedAngle, transformedAngle >> 8 & 255);
                sendPacket(packetsID.stopAttack);
                sendPacket(packetsID.item, onHand);
                setTimeout(() => {
                    placing = true;
                }, 100)
            } else if (window.stats[Sploop.objCount][5] === 8) placed = true;
            break;
        }
        case 15:
            getEl("pingCount").textContent = `Ping: ${decoded[1]}`;
            break;
        case 21: {
            console.debug("event done!");
            let count = 59;
            window.seconds = setInterval(() => {
                bossInfo.textContent = `Next boss: ${count}s`;
                count--;
            }, 1000)
            break;
        }
        case 35:
            isAlive = true;
            serverInfo.style.display = "block";
            pingCount.style.display = "block";
            bossInfo.style.display = "block";
            break;
        case 19:
            onHand = 0;
            isAlive = false;
            placed = false;
            serverInfo.style.display = "none";
            pingCount.style.display = "none";
            bossInfo.style.display = "none";
            break;
        case 33: (myID = decoded[1]);
    };
};

let gameEntity;
let chests = [], queue = [];
window.attackAnimation = (type, id, weapon, isObject, entity) => {
    if (entity.type === 30 && chests.some(chest => chest[Sploop.id2] === id)) {
        queue.push(id);
    } else if (entity.type === 0) {
        const chests = queue.map(id => gameEntity.get(id));
        queue = [];
        if (!chests.length) return;
        const hatAdditional = entity[Sploop.hat] === 11 ? 1.4 : (entity[Sploop.hat] === 2 ? 1.25 : 1);
        const damage = (window.weapons[weapon][Sploop.weaponDamage2] || window.weapons[weapon][Sploop.weaponDamage]) * hatAdditional;
        chests.forEach(entity => {
            entity.health = ((entity.health -= damage) % 1 === 0) ? entity.health.toFixed(0) : entity.health.toFixed(1);
        });
    };
};

window.drawChestHP = (target, id, ctx, step) => {
    if (target.type === 30 && target.health === undefined) target.health = 380;
    if (!chests.some(chest => chest[Sploop.id2] === target[Sploop.id2]) && target.type === 30) chests.push(target);
};
window.removeEntity = (entity) => {
    //second
    if (!entity.health) return;
    if ([12].includes(entity.type)) {
        const player = [...gameEntity].filter(([key, value]) => Sploop.id in value && value[Sploop.id] === entity[Sploop.id] && value.type === 0)[0][1];
        const spike = queue.map(id => gameEntity.get(id));
        queue = [];
        spike.forEach(obj => {
            obj.health -= player[Sploop.currentWeapon]; // 27 : 30; ih, Kh, Lh
        });
    };
    delete entity.health;
    const index = chests.findIndex(chest => chest[Sploop.id2] === entity[Sploop.id2]);
    if (index !== -1) {
        chests.splice(index, 1);
    };
};

window.getEntityData = async (entity, ctx, isTeammate, map) => {
    gameEntity = map;
    const entityX = entity[Sploop.x],
          entityY = entity[Sploop.y];

    const maxHealth = entities[entity.type].health;
    const entityHealth = ((entity[Sploop.health] * maxHealth / 100) / 255 * 100).toFixed(0);
    if (defaultSettings.HP) {
        ctx.font = "100 20px MV Boli";
        ctx.shadowOffsetX = 2;
        ctx.shadowOffsetY = 2;
        ctx.shadowColor = "#000000";
        ctx.shadowBlur = 5;
        ctx.fillStyle = (entity[Sploop.id] === myID || isTeammate) ? window.myHPColor : "#802641";
        ctx.fillText(`${entityHealth}/${maxHealth}`, entityX - 50, entityY + window.sprites[entity.type][Sploop.size] + 70);
        ctx.shadowBlur = 0;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 0;
    };
    if (defaultSettings.chestsHP && chests.length) {
        chests.forEach(target => {
            ctx.save();
            ctx.beginPath();
            ctx.textAlign = "center";
            ctx.font = "600 20px Comfortaa";
            ctx.fillStyle = "#fff";
            ctx.strokeStyle = "#000";
            ctx.lineWidth = 3;
            ctx.strokeText(target.health, target[Sploop.x], target[Sploop.y] + 5);
            ctx.fillText(target.health, target[Sploop.x], target[Sploop.y] + 5);
            ctx.fillRect
            ctx.closePath();
            ctx.restore();
        });
    };
};

window.requestAnimationFrame = (t) => setTimeout(t, 0);
const TYPEOF = value => Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
const NumberSystem = [
    { radix: 2, prefix: "0b0*" },
    { radix: 8, prefix: "0+" },
    { radix: 10, prefix: "" },
    { radix: 16, prefix: "0x0*" }
];
class Regex {
    constructor(code, unicode) {
        this.code = this.COPY_CODE = code;
        this.unicode = unicode || false;
        this.hooks = {};
    }

    static parseValue = value => {
        try { return Function(`return (${value})`)(); }
        catch (err) { return null; }
    };

    isRegexp = value => TYPEOF(value) === "regexp";

    generateNumberSystem = int => `(?:${NumberSystem.map(({ prefix, radix }) => prefix + int.toString(radix)).join("|")})`;

    parseVariables = regex => regex.replace(/\{VAR\}/g, "(?:let|var|const)")
    .replace(/\{QUOTE\}/g, "['\"`]")
    .replace(/ARGS\{(\d+)\}/g, (_, count) => (Array(Number(count)).fill("\\w+")).join("\\s*,\\s*"))
    .replace(/NUMBER\{(\d+)\}/g, (_, int) => this.generateNumberSystem(Number(int)));

    format = (name, inputRegex, flags) => {
        const regex = Array.isArray(inputRegex) ? inputRegex.map(exp => this.isRegexp(exp) ? exp.source : exp).join("\\s*") : this.isRegexp(inputRegex) ? inputRegex.source : "";
        let parsedRegex = this.parseVariables(regex);

        if (this.unicode) {
            parsedRegex = parsedRegex.replace(/\\w/g, "(?:[^\\x00-\\x7F-]|\\$|\\w)");
        }

        const expression = new RegExp(parsedRegex.replace(/\{INSERT\}/, ""), flags);
        return parsedRegex.includes("{INSERT}") ? new RegExp(parsedRegex, flags) : expression;
    };

    template = (type, name, regex, substr) => {
        const expression = new RegExp(`(${this.format(name, regex).source})`);
        const match = this.code.match(expression) || [];
        this.code = this.code.replace(expression, type === 0 ? "$1" + substr : substr + "$1");
        return match;
    };

    match = (name, regex, flags, debug = false) => {
        const expression = this.format(name, regex, flags);
        const match = this.code.match(expression) || [];
        this.hooks[name] = { expression, match };
        return match;
    };

    matchAll = (name, regex, debug = false) => {
        const expression = this.format(name, regex, "g");
        const matches = [...this.code.matchAll(expression)];
        this.hooks[name] = { expression, match: matches };
        return matches;
    };

    replace = (name, regex, substr, flags) => {
        const expression = this.format(name, regex, flags);
        this.code = this.code.replace(expression, substr);
        return this.code.match(expression) || [];
    };

    replaceAll = (name, regex, substr, flags) => {
        const expression = this.format(name, regex, "g");
        this.code = this.code.replaceAll(expression, substr);
        return this.code.match(expression) || [];
    };

    append = (name, regex, substr) => this.template(0, name, regex, substr);

    prepend = (name, regex, substr) => this.template(1, name, regex, substr);

    insert = (name, regex, substr) => {
        const { source } = this.format(name, regex);
        if (!source.includes("{INSERT}")) throw new Error("Your regexp must contain {INSERT} keyword");
        const findExpression = new RegExp(source.replace(/^(.*)\{INSERT\}(.*)$/, "($1)($2)"));
        this.code = this.code.replace(findExpression, `$1${substr}$2`);
        return this.code.match(findExpression);
    };
};
window.openMenu = () => {
    let dis = getEl("menu").style.display;
    getEl("menu").style.display = dis === "block" ? dis = "none" : dis = "block";
};
window.convertToEmoji = (text) => {
    const emojiRegex = /:(\w+):/g;

    const convertedText = text.replace(emojiRegex, (match, p1) => {
        const emojiMap = {
            smile: '😊',
            grin: '😁',
            joy: '😂',
            laughing: '😆',
            sweat_smile: '😅',
            wink: '😉',
            blush: '😊',
            yum: '😋',
            sunglasses: '😎',
            heart_eyes: '😍',
            kissing_heart: '😘',
            kissing_closed_eyes: '😚',
            stuck_out_tongue_winking_eye: '😜',
            stuck_out_tongue_closed_eyes: '😝',
            flushed: '😳',
            relieved: '😌',
            unamused: '😒',
            sweat: '😓',
            pensive: '😔',
            sleep: '😴',
            mask: '😷',
            thermometer_face: '🤒',
            head_bandage: '🤕',
            sleeping: '😴',
            zzz: '💤',
            poop: '💩',
            clap: '👏',
            thumbs_up: '👍',
            thumbs_down: '👎',
            heart: '❤️',
            broken_heart: '💔',
            sparkling_heart: '💖',
            star: '⭐',
            fire: '🔥',
            rainbow: '🌈',
            rocket: '🚀',
            hourglass: '⌛',
            gift: '🎁',
            tada: '🎉',
            umbrella: '☔',
            snowflake: '❄️',
            sun: '☀️',
            moon: '🌙',
            beer: '🍺',
            coffee: '☕',
            cake: '🍰',
            money_bag: '💰',
            bomb: '💣',
            airplane: '✈️',
            anchor: '⚓',
            guitar: '🎸',
            alien: '👽',
            skull: '💀',
            ghost: '👻',
            pumpkin: '🎃',
            christmas_tree: '🎄',
            santa: '🎅',
            gift_box: '🎁',
            bell: '🔔',
            crossed_swords: '⚔️',
            wizard: '🧙',
            clinking_glasses: '🥂',
            thinking_face: '🤔',
            detective: '🕵️‍♂️',
            scientist: '👨‍🔬',
            astronaut: '👨‍🚀',
            artist: '👩‍🎨',
            pilot: '👨‍✈️',
            bride_with_veil: '👰',
            angel: '👼',
            baby: '👶',
            family: '👪',
            thumbs_up: '👍',
            thumbs_down: '👎',
        };

        return emojiMap[p1] || match;
    });

    return convertedText;
}

document.addEventListener("wheel", (event) => {
    getEl("hat_menu_content").scrollBy(0, event.deltaY < 0 ? -900 : 900);
});

window.abbreviateNumber = (number) => {
    const suffixes = {
        't': 1e12,
        'b': 1e9,
        'm': 1e6,
        'k': 1e3,
    };

    for (const [letter, value] of Object.entries(suffixes)) {
        if (number >= value) {
            const abbreviated = (number / value).toFixed(1).replace(/\.0$/, '');
            return `${abbreviated}${letter}`;
        }
    }

    return number.toString();
}
window.nameGold = false;
let Sploop;
const applyHooks = code => {
    const Hook = new Regex(code, true);
    window.COPY_CODE = (Hook.COPY_CODE.match(/^(\(function \w+\(\w+\)\{.+)\(.+?\);$/) || [])[1];
    Hook.append("EXTERNAL fix", /\(function (\w+)\(\w+\)\{/, "let $2 = eval(`(() => ${COPY_CODE})()`);delete window.COPY_CODE;");
    const ID = Hook.match('ID', /&&\w{2}===\w\.(\w{2})\){/)[1];
    const map = Hook.match("objects", /\(\);(\w).get\(\w{2}\)&&/)[1];
    const myData = Hook.match('myPlayer', /=(\w.get\(\w{2}\));\w&&\w\(\)/)[1];
    const X = Hook.match('playerX', /\{this\.(\w{2})=\w\|\|0/)[1];
    const Y = Hook.match('playerY', /,this\.(\w{2})=\w\|\|0\}/)[1];
    const ID2 = Hook.match('ID2', /-1!==\w+\.(\w+)&&/)[1];
    const currentWeapon = Hook.match("crntWeapon", /,\w.(\w{2})===/)[1];
    const angle = Hook.match("angle", /;\w.(\w{2})=\w\(\)/)[1];
    const weaponName = Hook.match("wpnName", /(\w{2}):"XX/)[1];
    const health = Hook.match("health", /(\w{2})<<8;/)[1];
    const weaponDamage = Hook.match("wpnDamage", /(\w{2}):32,reload:300/)[1];
    const weaponDamage2 = Hook.match("wpnDamage", /\w{2}:25,.{6}:300,(\w{2}):30/)[1];
    const teamID = Hook.match('test', /,\w=\w.(\w{2})\|.+?\<\<8/)[1];
    const radius = Hook.match("radius", /(\w{2}):220/)[1];
    const [, currentItem, hat] = Hook.match("hat", /\(\w+\.(\w+)\|\w+\.(\w+)<<NUMBER{8}\)/);
    const inWhichObject = Hook.match("iwo", /110\).+?,1===\w.(\w{2})&&!\w{2}/)[1];
    const weaponID = Hook.match('el', /(\w{2}):0,\w{2}:22,reload:150/)[1];
    const itemsID = Hook.match("IDs", />1\){.{3}(\w{2})/)[1];
    const objCount = Hook.match("objCount", /\),this.(\w{2})=\w\):/)[1];
    const size = Hook.match("size", /\(\)\[.{2}type\].(\w{2})\+50/)[1];
    const RweaponDMG = Hook.match("size", /\[0,0,10,0\](?:[^:]+:){4}[^,:]+,(\w{2})/)[1];
    Sploop = {
        x: X,
        y: Y,
        id: ID,
        map: map,
        id2: ID2,
        hat: hat,
        size: size,
        type: 'type',
        angle: angle,
        health: health,
        radius: radius,
        teamID: teamID,
        itemsID: itemsID,
        objCount: objCount,
        weaponID: weaponID,
        RweaponDMG: RweaponDMG,
        weaponName: weaponName,
        weaponDamage: weaponDamage,
        weaponDamage2: weaponDamage2,
        currentWeapon: currentWeapon,
        inWhichObject: inWhichObject
    }
    console.debug(Sploop);
    //console.debug(__MUTATEQOo.ic);
    Hook.append("test", /Di\(t,n,o\){/, `window.getBoss(t);`)
    Hook.replace("abrScore", /("ranking-score">.{3})(\w)/, `$1window.abbreviateNumber($2)`);
    let args = Hook.match("drawEntityInfo", /-NUMBER{50},.+?function \w+\((ARGS{3})\)\{/)[1];
    const weaponList = Hook.match("weaponList", /\?Math\.PI\/2.+?(\w\(\))/)[1];
    Hook.append("Kills", /=1}}function.+?function.{4}(\w).{2}/, `window.getKill($2);`);
    Hook.append('removeEntity', /(\w).{8}\w.delete\(\w\);/, `window.removeEntity($2);`);
    Hook.replace("renderItems", /(\(\w+\.\w+\+\w+,\w+\.\w+\+\w+\).+?\w+\(\).+?\w+\.\w+\.\w+\)([,;]))/, `$1window.drawChestHP(...arguments)$2`);
    Hook.replace("defaultData", /(\W\w+>NUMBER{1}\W.+?(\w+)\.(\w+).+?)function/, `$1window.stats=$2;window.sprites = tt();window.weapons=${weaponList};function`);
    Hook.append('drawEntityInfo', /\/255\*\(a-10\);.+?\]\)/, `;try {window.getEntityData(${args}, ${Sploop.map});} catch(err) {};`)
    Hook.append("getMsg", /0;fu.{10}(\w).{2}/, `window.receiveMsg($2);`);
    Hook.append("someFunction", /login\.hide\(\),\w{2}\(\)}/, `window.someFunction=lt;`);
    Hook.replace('customClan', /"\["/, `"«"`);
    Hook.replace('customClan', /"\]"/, `"»"`);
    Hook.replace("particles", /(0,\w{2}=!1,\w{2}=)!1,/, `$1true,`);
    Hook.replace("grid", /1,(\w{2})=!0/, `1, $1=false`);
    Hook.replace("millMarker", /=false,(\w{2})=!0/, `=false,$1=false`);
    Hook.replace("enablePing", /42.5\),(\w{2})=!1/, `42.5),$1=true`);
    Hook.replace("nativeRender", /(true,\w{2}=)!1/, `$1true`);
    Hook.replace("replaceOrigin", /("#8ecc51".{16}).{5}/, `$1let`);
    Hook.replace("betterAGEBar", /AGE "\+(\w),\d{2},.+?\)/, `" + "«" + $1 + "»",24,"#fff","#303030")`)
    Hook.replace("ColorMats", /\)\,24,\"\#\w{6}\"\)|\)\,24,\w\(\d{3}\)\)/, `),24,"#AE4D57", "#303030")`)
    Hook.replace("ColorMats", /\)\,24,\"\#\w{6}\"\)|\)\,24,\w\(\d{3}\)\)/, `),24,"#935F3B", "#303030")`)
    Hook.replace("ColorMats", /\)\,24,\"\#\w{6}\"\)|\)\,24,\w\(\d{3}\)\)/, `),24,"#7B7A91", "#303030")`)
    Hook.replace("ColorMats", /\"\",24\,\D{9}|\"\",24\,\w\(\d{3}\)/, `"",24,"#FFD700", "#303030"`)
    Hook.replace("ColorBioms", /"#ece5db"/, `"#A9A9A9"`);
    Hook.replace('customLoader', /Loading Sploop.io/, `Loading cringe...`)
    Hook.replace('customItemObvodka', /23,"#fff"/, `23,"#fff","#303030"`)
    Hook.replace('customItemObvodka', /eec39d"/, `eec39d", "#303030"`)
    Hook.replace('customItemInfo', /4f403c/, '4f403c80')
    Hook.replace('customBar', /10,"#5D3A37"|10,\w\(\d{3}\)/, `10,"#00000080"`)
    Hook.replace('customBar', /(00000080.+?fillStyle=).+?,/, `$1window.barColor,`)
    Hook.replace('customHP', /(,\.18.+?\:).+?\)}/, `$1window.myHPColor)}`)
    Hook.replace('customHP', /(\.5;.+?\?).+?",/, `$1window.myHPColor : "#802641",`)
    Hook.replace('customClan', /"#96C949","#404040"|"#96C949",\w\(\d{3}\)/, `"#0a80c9","#2e3336"`);
    Hook.append('showFullMats', /10},\w{2}\Dfunction\((\w)\){/, `return $2;`);
    Hook.append('attackAnim', /\+=NUMBER{5}.+?(\w+)=.+?(\w+)=.+?(\w+)=.+?(\w+)=.+?(\w+)=.+?;/, `window.attackAnimation($2, $3, $4, $5, $6);`);
    Hook.replace('showFullGold', /(\w)\>\d{7}.*?\+""/, `window.defaultSettings.LBF?$1:window.abbreviateNumber($1)`);
    Hook.append("blockPing", /\w.{40}\[2\]<<8;/, `return;`)
    const kawakaa = Hook.match("m", /var.{6}(\w{2})\((\w),(\w)\)&&\w{2}\(.{5}/).slice(1);
    Hook.append("newImg", /(\w).{9}(.{9})."clan_decline"\)\);/, `$2[$2.length] = $3("amoguduss"));$2[$2.length - 1].src = "https://cdn.glitch.global/80f01abb-e90c-4a7c-8f06-4aab31fdf28a/wasdad-02.png?v=1708708420340";`);
    Hook.append("newImg", /1.{4}(\w{2})\((\w).{9}38.5,42.5\)/, `,sbnoadnb=$2($3[$3.length - 1], 38.5, 42.5)`);
    Hook.append("newImg", /var.{6}(\w{2})\((\w),(\w)\)&&\w{2}\(.{5}/, `sbnoadnb.$2($3, $4) && window.openMenu(),`);
    Hook.append("newImg", /return \w{2}.\w{2}\(\w,\w\)&&\((\w)=!0\),/, `sbnoadnb.${kawakaa[0]}(${kawakaa[1]}, ${kawakaa[2]}) && ($2 = !0),`);
    Hook.append("newImg", /(\w{2}).(\w{2})=5,\w{2}.(\w{2}).{9}\[\w\(\d{3}\)\]-11;/ , `sbnoadnb.$3 = 5, sbnoadnb.$4 = $2.$4 - $2.width-11;`);
    Hook.append("newImg", /0,-50\)}}if\(\w{2}.\w{2}\(\w\),\w{2}.(\w{2})\((\w)\),/, `sbnoadnb.$2($3),`);
    Hook.append("goldNick", /=\[\w{2}\(\).\w{2}.\w{2},\w/, `+ (window.nameGold ? " " + window.abbreviateNumber(getEl("score-left-value").textContent) : "")`);
    return Hook.code;
};

window.eval = new Proxy(window.eval, {
    apply(target, _this, args) {
        const code = args[0];
        if (code.length > 100000) {
            args[0] = applyHooks(code);
            window.eval = target;
        }
        return target.apply(_this, args);
    }
});