Gartic.io Anonim Menu

Press F2 to open and close the menu

// ==UserScript==
// @name         Gartic.io Anonim Menu
// @namespace    https://greasyfork.org/
// @version      2024-01-18
// @description  Press F2 to open and close the menu
// @author       anonimbiri
// @match        https://gartic.io/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=gartic.io
// @require https://update.greasyfork.org/scripts/482771/1321969/Malayala%20Kit.js
// @grant        none
// ==/UserScript==
 
const AnonimbiriAPI = {
    ws: null,
    isGame: false,
    playerId: null,
    unlimitedKick: false,
    autoSkip: false,
    antiAfk: false,
    noCooldown: false,
    autoGuessing: false,
    hint: null,
    wordListURL: null,
    wordList: [],
    hotkey: new KeyboardEvent('keyup', {
        key: "F2",
        keyCode: 113,
        ctrlKey: false,
        altKey: false,
        shiftKey: false
    }),
    debug: false,
};
 
var toastManager = new MalayalaKit.ToastManager();
 
const kit = new MalayalaKit.CreateMenu({
    title: "Anonim Menu",
    icon: "",
    size: { width: 500, height: 400 },
    position: { top: 50, left: 50 },
    hotkey: AnonimbiriAPI.hotkey,
});
 
const general = new MalayalaKit.Tab("General");
general.addSwitch({
    label: "Unlimited Kick",
    value: false,
    onchange: (value) => {
        AnonimbiriAPI.unlimitedKick = value;
        toastManager.showToast({ message: 'Unlimited Kick is ' + (value ? 'ON' : 'OFF'), type: 'info' });
    },
});
general.addSwitch({
    label: "Auto Skip",
    value: false,
    onchange: (value) => {
        AnonimbiriAPI.autoSkip = value;
        toastManager.showToast({ message: 'Auto Skip is ' + (value ? 'ON' : 'OFF'), type: 'info' });
    },
});
general.addSwitch({
    label: "Anti Afk",
    value: false,
    onchange: (value) => {
        AnonimbiriAPI.antiAfk = value;
        toastManager.showToast({ message: 'Anti Afk is ' + (value ? 'ON' : 'OFF'), type: 'info' });
    },
});
general.addSwitch({
    label: "No Cooldown For Room Change",
    value: false,
    onchange: (value) => {
        AnonimbiriAPI.noCooldown = value;
        toastManager.showToast({ message: 'No Cooldown For Room Change is ' + (value ? 'ON' : 'OFF'), type: 'info' });
    },
});
general.addHotkey({
    label: "Menu Hotkey",
    style: "border",
    value: AnonimbiriAPI.hotkey,
    onlistener: function (event) {
        AnonimbiriAPI.hotkey = event;
        toastManager.showToast({ message: 'Menu Opening Hotkey Set To ' + event.key, type: 'info' });
    }
});
kit.addTab(general);
 
const guess = new MalayalaKit.Tab("Guess");
guess.addSwitch({
    label: "Auto Guessing",
    value: false,
    onchange: (value) => {
        AnonimbiriAPI.autoGuessing = value;
        toastManager.showToast({ message: 'Auto Guessing is ' + (value ? 'ON' : 'OFF'), type: 'info' });
    },
});
guess.addInput({
    label: "Word List",
    placeholder: "wordList.txt",
    type: "text",
    value: AnonimbiriAPI.wordListURL,
    onchange: (value) => {
        AnonimbiriAPI.wordListURL = value;
        fetch(AnonimbiriAPI.wordListURL)
            .then(response => response.text())
            .then(data => {
            AnonimbiriAPI.wordList = data.split('\n').map(word => word.trim().toLowerCase());
        }).catch(error => AnonimbiriAPI.debug && console.error('Error:', error));
    },
});
kit.addTab(guess);
 
let fakeWinText = "anonimbiri";
const local = new MalayalaKit.Tab("Local");
local.addInput({
    label: "Fake Win text",
    placeholder: "Enter Fake Win text",
    type: "text",
    value: fakeWinText,
    onchange: (value) => {
        fakeWinText = value;
    },
});
local.addButton({
    label: "Send Fake Win",
    style: "border",
    buttonLabel: "Send Fake Win",
    onclick: () => {
        const event = new MessageEvent("message", {
            data: `42["26","${fakeWinText}",10,11,10000]`,
        });
        AnonimbiriAPI.ws.dispatchEvent(event);
    },
});
kit.addTab(local);
 
let intervalId = null;
let spamText = "anonimbiri";
const spam = new MalayalaKit.Tab("Spam");
spam.addSwitch({
    label: "Spam",
    value: false,
    onchange: (value) => {
        if (value) {
            intervalId = setInterval(() => {
                const randomIndex = Math.floor(Math.random() * (spamText.length + 1));
                const newText = spamText.replace(/(‎{${randomIndex}})/, '$1.');
                AnonimbiriAPI.ws.send(`42[11,${AnonimbiriAPI.playerId},"${newText}"]`);
            }, 800);
        } else {
            clearInterval(intervalId);
        }
        toastManager.showToast({ message: 'Spam Has ' + (value ? 'Started' : 'Heen Stopped'), type: 'info' });
    },
});
spam.addInput({
    label: "Spam text",
    placeholder: "Enter Spam text",
    type: "text",
    value: spamText,
    onchange: (value) => {
        spamText = value;
    },
});
kit.addTab(spam);
 
let intervalHint = null;
let index = 0;
window.WebSocket = class extends WebSocket {
    constructor(...args) {
        super(...args);
        AnonimbiriAPI.ws = this;
        this.addEventListener("message", (e) => {
            AnonimbiriAPI.debug && console.log("%c<--- Received data:", "color: pink", e.data);
            const messageData = JSON.parse(e.data.slice(2));
            if (messageData[0] === "45" && AnonimbiriAPI.unlimitedKick) {
                const OriginalDate = window.Date;
                window.Date = class extends Date {
                    static now() {
                        return super.now() * 2123;
                    }
                };
                setTimeout(() => {
                    window.Date = OriginalDate;
                }, 2000);
                return;
            } else if (messageData[0] === "5") {
                AnonimbiriAPI.isGame = true;
                AnonimbiriAPI.playerId = messageData[2];
            } else if (messageData[0] === "16" && AnonimbiriAPI.autoSkip) {
                AnonimbiriAPI.ws.send(`42[25,${AnonimbiriAPI.playerId}]`);
            } else if (messageData[0] === "34") {
                AnonimbiriAPI.ws.send(`42[30,${AnonimbiriAPI.playerId}]`);
                AnonimbiriAPI.ws.send(`42[30,${AnonimbiriAPI.playerId}]`);
                AnonimbiriAPI.ws.send(`42[30,${AnonimbiriAPI.playerId}]`);
            } else if (messageData[0] === "19" && AnonimbiriAPI.antiAfk) {
                window.Date = class extends Date {
                    static now() {
                        return super.now() / 2123;
                    }
                };
            } else if (messageData[0] === "23") {
                !AnonimbiriAPI.debug && console.clear();
                const nickElements = document.querySelectorAll('.nick');
                nickElements.forEach((nickElement) => {
                    const nickName = nickElement.innerText;
                    if (
                        nickName.startsWith('‎') &&
                        !nickElement.parentElement.querySelector('.cheater') &&
                        !nickElement.parentElement.parentElement.classList.contains('you')
                    ) {
                        const newElement = document.createElement('span');
                        newElement.classList.add('cheater');
                        newElement.style = 'color:pink; font-weight: bold; font-family: "Lucida Console", "Courier New", monospace;';
                        newElement.innerText = `🎮 Cheater`;
                        nickElement.parentElement.appendChild(newElement);
                    }
                });
            } else if (messageData[0] ==="30") {
                AnonimbiriAPI.hint = messageData[1].join('');
                if(!AnonimbiriAPI.autoGuessing && !AnonimbiriAPI.hint && intervalHint) return;
                setInterval(() => {
                    const hints = guessWord(AnonimbiriAPI.hint);
                    if (index < hints.length) AnonimbiriAPI.ws.send(`42[13,${AnonimbiriAPI.playerId},"${hints[index++]}"]`), AnonimbiriAPI.wordList.splice(AnonimbiriAPI.wordList.indexOf(hints[index++]), 1);
                    else clearInterval(intervalHint);
                }, 1000);
 
            } else if (messageData[0] ==="19" && intervalHint) {
                AnonimbiriAPI.hint = null;
                clearInterval(intervalHint);
                fetch(AnonimbiriAPI.wordListURL)
                    .then(response => response.text())
                    .then(data => {
                    AnonimbiriAPI.wordList = data.split('\n').map(word => word.trim().toLowerCase());
                }).catch(error => AnonimbiriAPI.debug && console.error('Error:', error));
            } else if (messageData[0] ==="13" && AnonimbiriAPI.wordList.length !== 0) {
                const index = AnonimbiriAPI.wordList.indexOf(messageData[1].toLowerCase());
                index !== -1 && AnonimbiriAPI.wordList.splice(index, 1)
            }
        });
    }
 
    send(data) {
        AnonimbiriAPI.debug && console.log("%c---> Sent data:", "color: pink", data);
        const newData = JSON.parse(data.slice(2));
        if (newData[1] && newData[1].nick) {
            newData[1].nick = `‎${newData[1].nick}`;
            data = data.slice(0, 2) + JSON.stringify(newData);
            super.send(data);
        } else if (newData[0] === "46") {
        } else {
            super.send(data);
        }
    }
};
 
function guessWord(guessedPattern) {
    if (!guessedPattern) return;
    const wordList = AnonimbiriAPI.wordList.map(word => word.toLowerCase());
    const length = guessedPattern.length;
    const possibleWords = [];
 
    for (let i = 0; i < wordList.length; i++) {
        const word = wordList[i];
        if (word.length === length) {
            let match = true;
 
            for (let j = 0; j < length; j++) {
                if (guessedPattern[j] !== '_' && guessedPattern[j] !== word[j]) {
                    match = false;
                    break;
                }
            }
 
            if (match) {
                possibleWords.push(word);
            }
        }
    }
 
    return possibleWords;
}
 
// I'll just leave it here that such a method exists and works
/*function requestText (url) {
    return fetch(url).then((d) => {return d.text()})
}
function requestBuffer (url) {
    return fetch(url).then((d) => {return d.arrayBuffer()})
}
 
Node.prototype.appendChild = new Proxy(Node.prototype.appendChild, {
    apply: async function (target, thisArg, [element]) {
        if (element.tagName === "SCRIPT" && element.src.includes('room')) {
            let text = await requestText(element.src);
            text = text.replace(/this\._lang\.violatingRules/g, '"dememe"'); // this is the wrong code lol
            let blob = new Blob([text]);
            element.src = URL.createObjectURL(blob);
        }
        return Reflect.apply(target, thisArg, [element]);
    }
});*/
 
const observer = new MutationObserver(() => {
    const input = document.querySelector('input[name="chat"]');
    input?.disabled && input.querySelector('input[name="chat"]').replaceWith(
        Object.assign(document.createElement('input'), {
            type: 'text',
            name: 'chat',
            className: 'mousetrap',
            placeholder: '🔓 Chat Unlocked',
            autocomplete: 'off',
            autocorrect: 'off',
            autocapitalize: 'off',
            maxLength: 100,
            value: '',
        })
    );
    if (document.querySelector('#popUp') && AnonimbiriAPI.noCooldown) {
        const OriginalDate = window.Date;
        window.Date = class extends Date {
            static now() {
                return super.now() * 2123;
            }
        };
        setTimeout(() => {
            window.Date = class extends Date {
                static now() {
                    return super.now() / 2123;
                }
            };
        }, 500);
        document.querySelector('.ic-playHome').click();
    }
});
 
observer.observe(document.body, { childList: true, subtree: false });
 
const keyupEvent = (e) => {
    if (e.keyCode === 13) {
        const chatInput = document.querySelector('input[name="chat"]');
        AnonimbiriAPI.ws.send(`42[11,${AnonimbiriAPI.playerId},"${chatInput.value}"]`);
        chatInput.value = '';
    }
};
 
window.addEventListener('keyup', keyupEvent);
window.AnonimbiriAPI = AnonimbiriAPI;
kit.render();