您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Chat with your friends privately
// ==UserScript== // @name MooMoo.io Private Chat Room // @description Chat with your friends privately // @author KOOKY WARRIOR // @match *://*.moomoo.io/* // @icon https://moomoo.io/img/favicon.png?v=1 // @require https://cdnjs.cloudflare.com/ajax/libs/peerjs/1.4.7/peerjs.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js // @license MIT // @version 0.1 // @namespace https://gf.qytechs.cn/users/999838 // ==/UserScript== /* 1) To get started, press "Shift" + "Enter" 2) Now you should be able to see 4 buttons: - Join Room (Join a room via room ID) - Create Room (Create a room) - Show/Hide (Show or hide the chat container) - Open/Close Editor (Edit the position of the chat container by dragging it around / Change the size of the chat container at the bottom right of the chat container) 3) After you have joined or created a room, press "Shift" + "Enter" to activate the private chat input message holder. 4) Once you have finished typing your message, press "Enter" to send the message to the chat room 5) If you want to clear the chat, type "/clear" and then press "Enter" */ ;(() => { let myID = null let conn = null let peer = null let connected = false let editing = false const gameUI = document.getElementById("gameUI") const gameCanvas = document.getElementById("gameCanvas") const style = document.createElement("style") style.innerHTML = /*css*/ ` #chatContainer { background-color: rgba(0, 0, 0, 0.1); position: absolute; padding: 10px; pointer-events: all; word-break: break-word; overflow-x: hidden; } #chatContainer::-webkit-scrollbar { width: 0.6em; } #chatContainer::-webkit-scrollbar-thumb { background-color: white; } #chatContainer::-webkit-scrollbar-track { background-color: none !important; } #roomChatSettingsContainer { width: 100%; position: fixed; text-align: center; top: 50%; transform: translateY(-50%); -ms-transform: translateY(-50%); -moz-transform: translateY(-50%); -webkit-transform: translateY(-50%); -o-transform: translateY(-50%); } .roomChatSettingButton { margin: 10px; } #roomChatBoxInput { padding: 6px; font-size: 20px; color: #fff; background-color: rgba(0, 0, 0, 0.25); -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; pointer-events: all; border: 0; } #roomChatBoxInput:focus { outline: none; } #popupContainer { width: 100%; position: fixed; text-align: center; top: 50%; transform: translateY(-50%); -ms-transform: translateY(-50%); -moz-transform: translateY(-50%); -webkit-transform: translateY(-50%); -o-transform: translateY(-50%); } #popupContainerInput { padding: 10px; font-size: 26px; color: #fff; background-color: rgba(0, 0, 0, 0.25); -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; pointer-events: all; border: 0; } #popupContainerInput:focus { outline: none; } .chatmsgholder { width: 100%; color: white; font-size: 22px; } .systemmsgholder { width: 100%; color: #fadadc; font-size: 22px; } ` document.head.appendChild(style) const style2 = document.createElement("link") style2.rel = "stylesheet" style2.href = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/themes/le-frog/jquery-ui.min.css" document.head.appendChild(style2) const chatContainer = document.createElement("div") chatContainer.id = "chatContainer" chatContainer.style.overflowY = "auto" chatContainer.style.width = localStorage.getItem("room_chat_width") ? localStorage.getItem("room_chat_width") : "15%" chatContainer.style.height = localStorage.getItem("room_chat_height") ? localStorage.getItem("room_chat_height") : "30%" chatContainer.style.top = localStorage.getItem("room_chat_top") ? localStorage.getItem("room_chat_top") : "0%" chatContainer.style.left = localStorage.getItem("room_chat_left") ? localStorage.getItem("room_chat_left") : "0%" chatContainer.style.display = "none" gameUI.appendChild(chatContainer) const roomChatSettingsContainer = document.createElement("div") roomChatSettingsContainer.style.display = "none" roomChatSettingsContainer.id = "roomChatSettingsContainer" const joinRoomButton = document.createElement("div") joinRoomButton.className = "roomChatSettingButton storeTab" joinRoomButton.textContent = "Join Room" roomChatSettingsContainer.appendChild(joinRoomButton) const createRoomButton = document.createElement("div") createRoomButton.className = "roomChatSettingButton storeTab" createRoomButton.textContent = "Create Room" roomChatSettingsContainer.appendChild(createRoomButton) const copyRoomIDButton = document.createElement("div") copyRoomIDButton.className = "roomChatSettingButton storeTab" copyRoomIDButton.textContent = "Copy Room ID" copyRoomIDButton.style.display = "none" roomChatSettingsContainer.appendChild(copyRoomIDButton) const leaveRoomButton = document.createElement("div") leaveRoomButton.className = "roomChatSettingButton storeTab" leaveRoomButton.textContent = "Leave Room" leaveRoomButton.style.display = "none" roomChatSettingsContainer.appendChild(leaveRoomButton) const deleteRoomButton = document.createElement("div") deleteRoomButton.className = "roomChatSettingButton storeTab" deleteRoomButton.textContent = "Delete Room" deleteRoomButton.style.display = "none" roomChatSettingsContainer.appendChild(deleteRoomButton) const toggleHideButton = document.createElement("div") toggleHideButton.className = "roomChatSettingButton storeTab" toggleHideButton.textContent = "Show" roomChatSettingsContainer.appendChild(toggleHideButton) const editStyleButton = document.createElement("div") editStyleButton.className = "roomChatSettingButton storeTab" editStyleButton.textContent = "Open Editor" roomChatSettingsContainer.appendChild(editStyleButton) function mousedown(event) { gameCanvas.dispatchEvent( new MouseEvent("mousedown", { button: event.button }) ) } function mouseup(event) { gameCanvas.dispatchEvent( new MouseEvent("mouseup", { button: event.button }) ) } function mousemove(event) { gameCanvas.dispatchEvent( new MouseEvent("mousemove", { clientX: event.clientX, clientY: event.clientY }) ) } chatContainer.onmousedown = mousedown chatContainer.onmouseup = mouseup chatContainer.onmousemove = mousemove editStyleButton.onclick = function () { if (editing) { editing = false editStyleButton.textContent = "Open Editor" chatContainer.style.overflowY = "auto" $("#chatContainer").resizable("destroy") $("#chatContainer").draggable("destroy") chatContainer.onmousedown = mousedown chatContainer.onmouseup = mouseup chatContainer.onmousemove = mousemove gameCanvas.style.pointerEvents = "auto" } else { editing = true editStyleButton.textContent = "Close Editor" chatContainer.style.overflowY = "hidden" if (chatContainer.style.display == "none") { chatContainer.style.display = "block" toggleHideButton.textContent = "Hide" } chatContainer.onmousedown = null chatContainer.onmouseup = null chatContainer.onmousemove = null gameCanvas.style.pointerEvents = "none" $("#chatContainer").resizable({ containment: "#gameUI", stop: function (event, ui) { const width = (ui.size.width / window.innerWidth) * 100 + "%" const height = (ui.size.height / window.innerHeight) * 100 + "%" localStorage.setItem("room_chat_width", width) localStorage.setItem("room_chat_height", height) chatContainer.style.width = width chatContainer.style.height = height } }) $("#chatContainer").draggable({ containment: "#gameUI", stop: function (event, ui) { const top = (ui.position.top / window.innerHeight) * 100 + "%" const left = (ui.position.left / window.innerWidth) * 100 + "%" localStorage.setItem("room_chat_top", top) localStorage.setItem("room_chat_left", left) chatContainer.style.top = top chatContainer.style.left = left } }) } } toggleHideButton.onclick = function () { if (chatContainer.style.display == "none") { chatContainer.style.display = "block" toggleHideButton.textContent = "Hide" } else { chatContainer.style.display = "none" toggleHideButton.textContent = "Show" if (editing) { editing = false editStyleButton.textContent = "Open Editor" chatContainer.style.overflowY = "auto" $("#chatContainer").resizable("destroy") $("#chatContainer").draggable("destroy") chatContainer.onmousedown = mousedown chatContainer.onmouseup = mouseup chatContainer.onmousemove = mousemove gameCanvas.style.pointerEvents = "auto" } } } document.getElementById("chatHolder").appendChild(roomChatSettingsContainer) const roomChatBoxInput = document.createElement("input") roomChatBoxInput.setAttribute("autocomplete", "off") roomChatBoxInput.setAttribute("aria-autocomplete", "none") roomChatBoxInput.id = "roomChatBoxInput" roomChatBoxInput.type = "text" roomChatBoxInput.placeholder = "Enter Private Message" roomChatBoxInput.maxLength = 50 roomChatBoxInput.style.display = "none" document.getElementById("chatHolder").appendChild(roomChatBoxInput) const popupContainer = document.createElement("div") popupContainer.id = "popupContainer" popupContainer.style.display = "none" const popupContainerInput = document.createElement("input") popupContainerInput.setAttribute("autocomplete", "off") popupContainerInput.setAttribute("aria-autocomplete", "none") popupContainerInput.id = "popupContainerInput" popupContainerInput.className = "roomChatSettingButton" popupContainerInput.type = "text" popupContainerInput.placeholder = "Enter username" popupContainer.appendChild(popupContainerInput) const popupContainerokButton = document.createElement("div") popupContainerokButton.className = "roomChatSettingButton storeTab" popupContainerokButton.textContent = "OK" popupContainer.appendChild(popupContainerokButton) const popupContainercancelButton = document.createElement("div") popupContainercancelButton.className = "roomChatSettingButton storeTab" popupContainercancelButton.textContent = "Cancel" popupContainercancelButton.onclick = function () { popupContainer.style.display = "none" if (document.getElementById("chatHolder").style.display != "none") { roomChatSettingsContainer.style.display = "block" } } popupContainer.appendChild(popupContainercancelButton) document.getElementById("chatHolder").appendChild(popupContainer) new MutationObserver((mutations) => { mutations.forEach((mutationRecord) => { if (document.getElementById("chatHolder").style.display != "block") { popupContainer.style.display = "none" document.getElementById("chatBox").hidden = false roomChatBoxInput.style.display = "none" roomChatBoxInput.value = "" if (editing) { editing = false editStyleButton.textContent = "Open Editor" chatContainer.style.overflowY = "auto" $("#chatContainer").resizable("destroy") $("#chatContainer").draggable("destroy") chatContainer.onmousedown = mousedown chatContainer.onmouseup = mouseup chatContainer.onmousemove = mousemove gameCanvas.style.pointerEvents = "auto" } } }) }).observe(document.getElementById("chatHolder"), { attributes: true, attributeFilter: ["style"] }) let sendMessage = () => {} window.addEventListener("keydown", (event) => { if (event.code != "Enter") return if (event.shiftKey) { roomChatSettingsContainer.style.display = "block" document.getElementById("chatBox").hidden = true if (connected) { roomChatBoxInput.style.display = "inline-block" const interval = setInterval(() => { roomChatBoxInput.focus() if (document.activeElement == roomChatBoxInput) { clearInterval(interval) } }, 10) } } else { roomChatSettingsContainer.style.display = "none" if (document.getElementById("chatBox").hidden && roomChatBoxInput.value != "") { if (connected) { sendMessage(roomChatBoxInput.value) } roomChatBoxInput.value = "" document.getElementById("chatBox").hidden = false roomChatBoxInput.style.display = "none" } } }) function copy(text) { var input = document.createElement("textarea") input.innerHTML = text document.body.appendChild(input) input.select() var result = document.execCommand("copy") document.body.removeChild(input) return result } function showSystemMessage(msg) { const needToScroll = chatContainer.scrollTop + chatContainer.clientHeight >= chatContainer.scrollHeight - 5 const container = document.createElement("div") container.className = "systemmsgholder" const systemmsgholder = document.createElement("span") systemmsgholder.innerText = "* " + msg container.appendChild(systemmsgholder) chatContainer.appendChild(container) if (chatContainer.childElementCount > 250) { chatContainer.removeChild(chatContainer.firstChild) } if (needToScroll) { chatContainer.scrollTop = chatContainer.scrollHeight } } function showChatMessage(owner, msg) { const needToScroll = chatContainer.scrollTop + chatContainer.clientHeight >= chatContainer.scrollHeight - 5 const container = document.createElement("div") container.className = "chatmsgholder" const nameholder = document.createElement("span") nameholder.innerText = owner + ": " container.appendChild(nameholder) const chatmsgholder = document.createElement("span") chatmsgholder.innerText = msg.substring(0, 50) chatmsgholder.style.color = "rgba(255, 255, 255, 0.6)" container.appendChild(chatmsgholder) chatContainer.appendChild(container) if (chatContainer.childElementCount > 250) { chatContainer.removeChild(chatContainer.firstChild) } if (needToScroll) { chatContainer.scrollTop = chatContainer.scrollHeight } } let myselfLeft = false joinRoomButton.addEventListener("click", () => { peer = new Peer() peer.on("open", async (id) => { myID = id if (myID == null) return popupContainerInput.value = "" popupContainerInput.placeholder = "Enter Room ID" popupContainer.style.display = "block" roomChatSettingsContainer.style.display = "none" popupContainerInput.focus() popupContainerokButton.onclick = function () { const roomID = popupContainerInput.value if (roomID == null || roomID == "") { document.getElementById("chatButton").click() return } popupContainerInput.value = "" popupContainerInput.placeholder = "Enter Username" popupContainer.style.display = "block" roomChatSettingsContainer.style.display = "none" popupContainerInput.focus() popupContainerokButton.onclick = function () { document.getElementById("chatButton").click() const name = popupContainerInput.value if (name == null || name == "") return conn = peer.connect(roomID) conn.on("open", () => { connected = true chatContainer.innerHTML = "" chatContainer.style.display = "block" toggleHideButton.textContent = "Hide" conn.on("data", (data) => { if (data.type === 0) { conn.send({ name: name, peerID: myID, type: 0 }) } else if (data.type === 1) { // SYSTEM MESSAGE showSystemMessage(data.msg) } else if (data.type === 2) { // SOMEONE SEND MESSAGE showChatMessage(data.owner, data.msg) } }) }) myselfLeft = false conn.on("close", () => { document.getElementById("chatButton").click() connected = false joinRoomButton.style.display = "inline-block" createRoomButton.style.display = "inline-block" copyRoomIDButton.style.display = "none" leaveRoomButton.style.display = "none" if (!myselfLeft) { showSystemMessage("You left the chat room due to either a lost connection or the chat room being closed") } }) sendMessage = (msg) => { if (msg == "/clear") { chatContainer.innerHTML = "" return } conn.send({ type: 1, peerID: myID, msg: msg }) } joinRoomButton.style.display = "none" createRoomButton.style.display = "none" copyRoomIDButton.onclick = function () { copy(roomID) } copyRoomIDButton.style.display = "inline-block" leaveRoomButton.style.display = "inline-block" leaveRoomButton.onclick = function () { document.getElementById("chatButton").click() myselfLeft = true conn.close() peer.destroy() connected = false joinRoomButton.style.display = "inline-block" createRoomButton.style.display = "inline-block" copyRoomIDButton.style.display = "none" leaveRoomButton.style.display = "none" showSystemMessage("You left the chat room") } } } }) }) createRoomButton.addEventListener("click", () => { peer = new Peer() peer.on("open", (id) => { myID = id if (myID == null) return popupContainerInput.value = "" popupContainerInput.placeholder = "Enter Username" popupContainer.style.display = "block" roomChatSettingsContainer.style.display = "none" popupContainerInput.focus() popupContainerokButton.onclick = function () { document.getElementById("chatButton").click() const name = popupContainerInput.value if (name == null || name == "") return connected = true chatContainer.innerHTML = "" chatContainer.style.display = "block" toggleHideButton.textContent = "Hide" let allConnections = [ { name: name + "[1]", peerID: myID, conn: null } ] let usernameCounter = 1 showSystemMessage("Room created") copy(myID) showSystemMessage("Room ID copied") peer.on("connection", (connection) => { connection.on("open", () => { connection.on("data", (data) => { if (data.type === 0) { // RECEIVED JOIN DATA (peerID, name, type) usernameCounter++ allConnections.push({ name: `${data.name}[${usernameCounter}]`, peerID: data.peerID, conn: connection }) allConnections.forEach((e) => { if (e.conn == null) return e.conn.send({ type: 1, peerID: data.peerID, msg: `${data.name}[${usernameCounter}] has joined the chat room` }) }) showSystemMessage(`${data.name}[${usernameCounter}] has joined the chat room`) } else if (data.type === 1) { // RECEIVE SEND MESSAGE (peerID, type, msg) for (let index = 0; index < allConnections.length; index++) { if (allConnections[index].peerID == data.peerID) { allConnections.forEach((e) => { if (e.conn == null) return e.conn.send({ type: 2, owner: allConnections[index].name, msg: data.msg }) }) showChatMessage(allConnections[index].name, data.msg) break } } } }) connection.send({ type: 0 }) }) const otherpeerID = connection.peer connection.on("close", () => { for (let index = 0; index < allConnections.length; index++) { if (allConnections[index].peerID == otherpeerID) { const name = allConnections[index].name allConnections.splice(index, 1) allConnections.forEach((e) => { if (e.conn == null) return e.conn.send({ type: 1, peerID: otherpeerID, msg: `${name} has left the chat room` }) }) showSystemMessage(`${name} has left the chat room`) break } } }) }) sendMessage = (msg) => { if (msg == "/clear") { chatContainer.innerHTML = "" return } allConnections.forEach((e) => { if (e.conn == null) return e.conn.send({ type: 2, owner: name + "[1]", msg: msg }) }) showChatMessage(name + "[1]", msg) } joinRoomButton.style.display = "none" createRoomButton.style.display = "none" copyRoomIDButton.onclick = function () { copy(myID) showSystemMessage("Room ID copied") } copyRoomIDButton.style.display = "inline-block" deleteRoomButton.style.display = "inline-block" deleteRoomButton.onclick = function () { document.getElementById("chatButton").click() peer.destroy() connected = false joinRoomButton.style.display = "inline-block" createRoomButton.style.display = "inline-block" copyRoomIDButton.style.display = "none" deleteRoomButton.style.display = "none" } } }) }) })()
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址