Your auto chat...

Create your own personal automated chat. To open the menu, click on the new button next to the chat button. To create a message, enter it in the input field where the timer is shown, then click on the "Create" button. To delete a message, click on the "Delete" button. You can change existing messages, just click on the text in them and change.

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

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

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name         Your auto chat...
// @namespace    -
// @version      0.2
// @description  Create your own personal automated chat. To open the menu, click on the new button next to the chat button. To create a message, enter it in the input field where the timer is shown, then click on the "Create" button. To delete a message, click on the "Delete" button. You can change existing messages, just click on the text in them and change.
// @author       Nudo#7346
// @match        *://moomoo.io/*
// @match        *://*.moomoo.io/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=moomoo.io
// @grant        none
// @license      MIT
// @run-at       document-start
// ==/UserScript==

// Shit code is our everything!

(function() {
    const Config = {}

    Config.random = function(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min
    }

    Config.stopStupidProcesses = function(event) {
        if (!this.hasOwnProperty("socket")) {
            return void 0
        }

        if (event.data.toLowerCase() === "e") {
            this.socket.send(new Uint8Array(Array.from(Config.msgpack.encode(["7", [1]]))))
        }

        this.socket.send(new Uint8Array(Array.from(Config.msgpack.encode(["33", [null]]))))
    }

    class Message {
        constructor(id, message, position) {
            this.id = id
            this.text = message
            this.position = position
        }

        send() {
            if (!Config.hasOwnProperty("socket")) {
                return void 0
            }

            const message = document.querySelector(`#storageInvInput[data-iid="${this.id}"]`).value

            this.text = message

            Config.messageManager.messages[this.id].text = this.text

            window.localStorage.setItem("__srg", JSON.stringify(Config.messageManager.messages))

            Config.socket.send(new Uint8Array(Array.from(Config.msgpack.encode(["ch", [message]]))))
        }
    }

    class MessageManager {
        constructor() {
            this.messages = {}
            this.savedMessages = {}
            this.limit = 99
            this.lastMessage = Date.now()
            this.updateSpeed = 3000
            this.currentMessage = 0
        }

        get newID() {
            return Config.random(1e9, 10e9)
        }

        addSavedMessage() {
            this.savedMessages = window.localStorage.__srg

            if (typeof this.savedMessages === 'undefined') {
                return void 0
            }

            let messages = Object.values(JSON.parse(this.savedMessages))
            messages = messages.sort((a, b) => a.position - b.position)

            for (const i in messages) {
                const message = messages[i]

                this.add(message.text, message.id)
            }
        }

        add(message, oldID) {
            const messages = Object.values(this.messages)

            if (messages.length >= this.limit || message.match(/[а-яА-Я]/)) {
                return void 0
            }

            const id = typeof oldID === 'undefined' ? this.newID : oldID
            const position = messages.length + 1

            this.messages[id] = new Message(id, message, position)

            Config.createMessageItem(id, message, position)

            this.savedMessages = window.localStorage.__srg

            window.localStorage.setItem("__srg", JSON.stringify(this.messages))

            return this.messages[id]
        }

        remove(id) {
            const position = this.messages[id].position - 1
            let messages = Object.values(this.messages)

            for (let i = position; i < messages.length; i++) {
                messages = messages.sort((a, b) => a.position - b.position)

                this.messages[messages[i].id].position -= 1

                document.getElementById(`position-${messages[i].id}`).textContent = `${this.messages[messages[i].id].position}.`
            }

            Config.removeMessageItem(id)

            delete this.messages[id]

            this.savedMessages = window.localStorage.__srg

            window.localStorage.setItem("__srg", JSON.stringify(this.messages))

            return this.messages
        }

        clear(clearStorage) {
            this.messages = {}

            const storageHolder = document.getElementById("storageHolder")

            storageHolder.innerHTML = `
            <div class="storageItem">No Auto Message Yet</div>
            `

            if (clearStorage) {
                window.localStorage.removeItem("__srg")
            }

            return this.messages
        }

        setUpdateSpeed(speed) {
            speed = speed[1]

            if (!speed.length) {
                return void 0
            }

            speed = parseInt(speed)

            if (speed < 0) {
                speed = 0
            }

            this.updateSpeed = speed

            return this.updateSpeed
        }

        init() {
            setInterval(() => {
                try {
                    const storageInput = document.getElementById("storageInput")
                    const storageButtonM = document.querySelector(".storageButtonM")

                    if (storageInput.value === "__srg:clear" || storageInput.value.startsWith("__srg:speed=") || storageInput.value.startsWith("__srg:sp=")) {
                        storageButtonM.textContent = "Execute"
                    } else {
                        storageButtonM.textContent = "Create"
                    }

                    if (!this.lastMessage || Date.now() - this.lastMessage >= this.updateSpeed) {
                        let messages = Object.values(this.messages)

                        messages = messages.sort((a, b) => a.position - b.position)

                        this.lastMessage = Date.now()

                        if (!messages.length) {
                            return void 0
                        }

                        if (this.currentMessage >= messages.length) {
                            this.currentMessage = 0
                        }

                        messages[this.currentMessage].send()

                        this.currentMessage += 1
                    } else {
                        const storageInput = document.getElementById("storageInput")

                        storageInput.placeholder = `${this.updateSpeed - (Date.now() - this.lastMessage)}ms`
                    }
                } catch {}
            })
        }
    }

    Config.messageManager = new MessageManager()

    Config.messageManager.init()

    window.cfg = Config

    window.addEventListener("load", () => {
        const gameUI = document.getElementById("gameUI")
        const html = `
        <div id="storageButton" class="uiElement gameButton">
		  <i class="material-icons" style="font-size:40px;vertical-align:middle">post_add</i>
        </div>

        <div id="storageMenu" style="display: none;">
		  <div id="storageHolder">
            <div class="storageItem">No Auto Message Yet</div>
          </div>
		  <div id="storageManager">
            <input type="text" id="storageInput" maxlength="30" placeholder="unique message">
            <div class="storageButtonM" style="width: 140px;">Create</div>
          </div>
	    </div>

        <style>
        .removeMsgBtn {
          float: right;
          font-size: 24px;
          text-align: right;
          cursor: pointer;
          color: #80eefc;
        }

        .removeMsgBtn:hover {
          color: #72d3e0;
        }

        .storageItem {
          font-size: 24px;
          color: #fff;
          padding: 5px;
        }

        .storageButtonM {
          pointer-events: all;
          cursor: pointer;
          margin-top: 10px;
          font-size: 24px;
          color: #fff;
          padding: 5px;
          background-color: rgba(0, 0, 0, 0.25);
          -webkit-border-radius: 4px;
          -moz-border-radius: 4px;
          border-radius: 4px;
          text-align: center;
          display: inline-block;
        }

        #storageInput {
          pointer-events: all;
          font-size: 24px;
          color: #fff;
          background-color: rgba(0, 0, 0, 0.25);
          -webkit-border-radius: 4px;
          -moz-border-radius: 4px;
          border-radius: 4px;
          padding: 5px;
          display: inline-block;
          outline: none;
          border-color: none;
          border: 0;
          -webkit-box-shadow: none;
          box-shadow: none;
          width: 200px;
          margin-right: 7px;
        }

        #storageInvInput {
          pointer-events: all;
          font-size: 24px;
          color: rgba(255, 255, 255, 0.6);
          background-color: rgba(0, 0, 0, 0);
          outline: none;
          border-color: none;
          border: 0;
          -webkit-box-shadow: none;
          box-shadow: none;
          width: 184px;
        }

        #storageHolder {
          pointer-events: all;
          height: 200px;
          max-height: calc(100vh - 260px);
          overflow-y: scroll;
          -webkit-overflow-scrolling: touch;
          width: 350px;
          display: inline-block;
          text-align: left;
          padding: 10px;
          background-color: rgba(0, 0, 0, 0.25);
          -webkit-border-radius: 4px;
          -moz-border-radius: 4px;
          border-radius: 4px;
        }

        #storageMenu {
          display: none;
          width: 100%;
          position: absolute;
          text-align: center;
          top: 50%;
          transform: translateY(-50%);
          -ms-transform: translateY(-50%);
          -moz-transform: translateY(-50%);
          -webkit-transform: translateY(-50%);
          -o-transform: translateY(-50%);
        }

        #storageButton {
          right: 450px;
        }

        @media only screen and (max-width: 768px) {
          #storageButton {
            top: inherit;
            left: 60px;
          }

          .storageItem, #storageInput, .storageButtonM, .removeMsgBtn, #storageInvInput {
            font-size: 18px;
          }
        }
        </style>
        `

        gameUI.insertAdjacentHTML("beforeend", html)

        const storageButton = document.getElementById("storageButton")
        const storageMenu = document.getElementById("storageMenu")
        const storageInput = document.getElementById("storageInput")
        const storageHolder = document.getElementById("storageHolder")
        const storageButtonM = document.querySelector(".storageButtonM")
        const gameActionBtns = ["allianceButton", "storeButton", "chatButton"]
        const gameActionMenus = ["chatHolder", "allianceMenu", "storeMenu"]

        storageButton.addEventListener("click", () => {
            const action = {
                "block": "none",
                "none": "block"
            }

            for (const menu of gameActionMenus) {
                document.getElementById(menu).style.display = "none"
            }

            storageMenu.style.display = action[storageMenu.style.display]
        })

        Config.removeMessageItem = function(id) {
            const removeMsgBtns = document.querySelectorAll(".removeMsgBtn")

            for (const btn of removeMsgBtns) {
                if (btn.dataset.id === id.toString()) {
                    btn.parentNode.remove()
                }
            }

            if (removeMsgBtns.length === 1) {
                storageHolder.innerHTML = `
                <div class="storageItem">No Auto Message Yet</div>
                `
            }
        }

        Config.createMessageItem = function(id, message, position) {
            const removeMsgBtns = document.querySelectorAll(".removeMsgBtn")

            if (!removeMsgBtns.length) {
                storageHolder.innerHTML = ""
            }

            const messagePosition = position

            storageHolder.innerHTML += `
              <div class="storageItem" data-siid="${id}">
                <span id="position-${id}" style="color: rgba(255, 255, 255, 0.6)">${messagePosition}.</span>
                <input type="text" id="storageInvInput" value="${message}" maxlength="30" placeholder="3000ms" data-iid="${id}">
                <div class="removeMsgBtn" data-id="${id}">Remove</div>
              </div>
            `

            const storageInvInputs = document.querySelectorAll("#storageInvInput")

            for (const input of storageInvInputs) {
                input.addEventListener("input", (event) => {
                    Config.stopStupidProcesses(event)
                })
            }
        }

        storageButtonM.addEventListener("click", (event) => {
            let value = storageInput.value

            if (value === "__srg:clear") {
                storageHolder.innerHTML = ""
                storageInput.value = ""

                return Config.messageManager.clear(true)
            }

            if (value.startsWith("__srg:speed=")) {
                const speed = value.split("=")

                storageInput.value = ""

                return Config.messageManager.setUpdateSpeed(speed)
            }

            if (!value.length) {
                return void 0
            }

            if (value.length >= Config.messageManager.limit) {
                value = value.slice(0, 30)
            }

            storageInput.value = ""

            Config.messageManager.add(value)
        })

        storageHolder.addEventListener("click", (event) => {
            const target = event.target

            if (target.className === "removeMsgBtn") {
                Config.messageManager.remove(target.dataset.id)
            }
        })

        storageInput.addEventListener("input", (event) => {
            Config.stopStupidProcesses(event)
        })

        document.addEventListener("keydown", (event) => {
            if (event.code === "Enter" || event.code === "Escape") {
                storageMenu.style.display = "none"
            }
        })

        for (const btn of gameActionBtns) {
            document.getElementById(btn).addEventListener("click", (event) => {
                storageMenu.style.display = "none"
            })
        }

        Config.messageManager.addSavedMessage()
    })

    Config.msgpack = {}

    Function.prototype.call = new Proxy(Function.prototype.call, {
        apply(target, _this, args) {
            const data = target.apply(_this, args)

            if (args[1] && args[1].i) {
                const i = args[1].i

                if (i === 9) {
                    Config.msgpack.encode = args[0].encode
                }

                if (i === 15) {
                    Config.msgpack.decode = args[0].decode
                    Function.prototype.call = target
                }
            }

            return data
        }
    })

    const set = Object.getOwnPropertyDescriptor(WebSocket.prototype, "onmessage").set;
    Object.defineProperty(WebSocket.prototype, "onmessage", {
        set(callback) {
            return set.call(this, new Proxy(callback, {
                apply(target, _this, args) {
                    Config.socket = _this

                    return target.apply(_this, args)
                }
            }))
        }
    })
})()