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