Moomoo.io 1.8.0 AutoGG & Interactive Menu

Press 'Esc' to open the menu and customize the AutoGG message, delay, and toggle keycode. Your settings will be saved even if you reload the page.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Moomoo.io 1.8.0 AutoGG & Interactive Menu
// @description  Press 'Esc' to open the menu and customize the AutoGG message, delay, and toggle keycode. Your settings will be saved even if you reload the page.
// @author       Seryo
// @version      1
// @namespace    https://greasyfork.org/users/1190411
// @match        *://*.moomoo.io/*
// @grant        none
// @license      MIT
// @icon         https://cdn.glitch.com/82ae8945-dcc6-4276-98a9-665381b4cd2b/cursor12.png
// @require      https://greasyfork.org/scripts/423602-msgpack/code/msgpack.js?version=1005014
// ==/UserScript==

const msgpack5 = window.msgpack;

let ws, autoGGEnabled = true;
let menuVisible = false;
let messageSpeed = parseInt(localStorage.getItem("autogg-message-speed"), 10) || 1400;
let toggleKeyCode = parseInt(localStorage.getItem("autogg-toggle-keycode"), 10) || 219;
let editedMessage = localStorage.getItem("autogg-edited-message") || "";
let lastKillCount = 0;
let originalMessageSpeed = messageSpeed;
let originalToggleKeyCode = toggleKeyCode;

function loadSettings() {
  const savedMessageSpeed = localStorage.getItem("autogg-message-speed");
  if (savedMessageSpeed !== null) {
    messageSpeed = parseInt(savedMessageSpeed, 10);
  } else {
    messageSpeed = 1400;
  }

  const savedToggleKeyCode = localStorage.getItem("autogg-toggle-keycode");
  if (savedToggleKeyCode !== null) {
    toggleKeyCode = parseInt(savedToggleKeyCode, 10);
  } else {
    toggleKeyCode = 219;
  }

  const savedEditedMessage = localStorage.getItem("autogg-edited-message");
  if (savedEditedMessage !== null) {
    editedMessage = savedEditedMessage || "";
  }
}

WebSocket.prototype.oldSend = WebSocket.prototype.send;

WebSocket.prototype.send = function (e) {
  if (!ws) {
    [document.ws, ws] = [this, this];
    attachWebSocketListener(this);
  }
  this.oldSend(e);
};

const attachWebSocketListener = (e) => {
  e.addEventListener("message", hookWS);
};

const hookWS = (e) => {};

const sendPacket = (e) => {
  if (ws) {
    ws.send(msgpack5.encode(e));
  }
};

const sendMessageToChat = (e) => {
  setTimeout(() => {
  sendPacket(["6", [e]]);
  }, messageSpeed);
};

function isChatOpen() {
  return document.activeElement.id.toLowerCase() === "chatbox";
}

function isAllianceInputActive() {
  return document.activeElement.id.toLowerCase() === "allianceinput";
}

function shouldHandleHotkeys() {
  return !isChatOpen() && !isAllianceInputActive();
}

const handleMutations = (mutationsList) => {
  for (const mutation of mutationsList) {
    if (mutation.target.id === "killCounter") {
      const count = parseInt(mutation.target.innerText, 10) || 0;

      if (count === 0) {
        lastKillCount = 0;
      }

      if (count > lastKillCount) {
        lastKillCount = count;
        if (autoGGEnabled) {
          sendMessageToChat(editedMessage);
        }
      }
    }
  }
};

const observer = new MutationObserver(handleMutations);
observer.observe(document, {
  subtree: true,
  childList: true,
});

const gradientColorStyle = document.createElement("style");
gradientColorStyle.textContent = `
  #autogg-character-count {
    transition: color 1s;
    color: #909090;
  }
`;
document.head.appendChild(gradientColorStyle);

function updateCharacterCount() {
  const messageInput = document.getElementById("autogg-message-input");
  const characterCount = document.getElementById("autogg-character-count");
  const newCharacterCount = 30 - messageInput.value.length;

  characterCount.style.transition = "color 1s";

  if (newCharacterCount >= 1) {
    characterCount.style.color = "#909090";
  } else if (newCharacterCount >= 1) {

      const redValue = 255 - (newCharacterCount - 10) * 12;
    const color = `rgb(255, ${redValue}, ${redValue})`;
    characterCount.style.color = color;
  } else {
    characterCount.style.color = "red";
  }

  characterCount.textContent = newCharacterCount;
}

document.addEventListener("keydown", (e) => {
  if (e.keyCode === toggleKeyCode && shouldHandleHotkeys()) {
    if (shouldHandleHotkeys()) {
      autoGGEnabled = !autoGGEnabled;
      document.title = autoGGEnabled ? "𝙲𝚑𝚊𝚝 𝙾𝙽" : "𝙲𝚑𝚊𝚝 𝙾𝙵𝙵";
      console.log("AutoGG is now " + (autoGGEnabled ? "ON" : "OFF"));
      updateAutoGGStatus();
      updateCharacterCount();
    } else if (isChatOpen() && autoGGEnabled) {
      sendMessageToChat(editedMessage);
    }
  }

  if (e.keyCode === 27 && shouldHandleHotkeys() && storeMenu.style.display !== 'block') {
    toggleMenu();
  }
});

function updateAutoGGStatus() {
  const statusText = document.getElementById("autogg-status");
  statusText.textContent = autoGGEnabled ? "On" : "Off";
}

function saveMessage() {
  const messageInput = document.getElementById("autogg-message-input");
  editedMessage = messageInput.value;
  saveSettings();
  updateCharacterCount();
}

function saveSpeed() {
  const speedInput = document.getElementById("autogg-speed-input");
  const newSpeed = parseInt(speedInput.value, 10);

  if (!isNaN(newSpeed) && newSpeed > 0) {
    messageSpeed = newSpeed;
    saveSettings();
  } else {
    alert("Speed must be greater than 0");
  }
}

function saveToggleKey() {
  const toggleKeyInput = document.getElementById("autogg-toggle-key-input");
  const newToggleKey = toggleKeyInput.value;
  if (newToggleKey === "") {
    return;
  }
  if (!isNaN(newToggleKey) && newToggleKey >= 0 && newToggleKey <= 255) {
    toggleKeyCode = parseInt(newToggleKey, 10);
    saveSettings();
    updateToggleKeyText();
  } else {
    alert("Key must be between 0 and 255");
  }
}

function saveSettings() {
  localStorage.setItem("autogg-message-speed", messageSpeed);
  localStorage.setItem("autogg-toggle-keycode", toggleKeyCode);
  localStorage.setItem("autogg-edited-message", editedMessage);
}

loadSettings();

function updateToggleKeyText() {
  const toggleKeyLabel = document.getElementById("autogg-toggle-key-label");
  toggleKeyLabel.textContent = `Toggle Key: ${toggleKeyCode}`;
}

function toggleMenu() {
  const menu = document.getElementById("autogg-menu");
  menuVisible = !menuVisible;
  if (menuVisible) {
    const messageInput = document.getElementById("autogg-message-input");
    messageInput.value = editedMessage;
    const speedInput = document.getElementById("autogg-speed-input");
    speedInput.value = messageSpeed.toString();
    const toggleKeyInput = document.getElementById("autogg-toggle-key-input");
    toggleKeyInput.value = toggleKeyCode.toString();
    updateCharacterCount();
  } else {
  }
  menu.style.display = menuVisible ? "block" : "none";
}

const menu = document.createElement("div");
menu.id = "autogg-menu";
menu.style.display = "none";
menu.style.background = 'rgba(0, 0, 0, 0.8)';
menu.style.fontFamily = 'Hammersmith One, sans-serif';
menu.style.position = 'fixed';
menu.style.top = '20px';
menu.style.left = '20px';
menu.style.border = '1px solid #000';
menu.style.borderRadius = '8px';
menu.style.boxShadow = '0px 0px 10px rgba(0, 0, 0, 0.25)';
menu.style.boxShadow = '5px 5px 10px rgba(0, 0, 0, 0.4)';
menu.style.width = '240px';
menu.style.color = '#fff';
menu.style.fontSize = '17px';
menu.style.zIndex = '9999';
menu.style.overflowY = 'auto';
menu.style.padding = '10px';
menu.style.textAlign = 'center';

document.body.appendChild(menu);

const title = document.createElement("h1");
title.style.fontSize = '28px';
title.style.marginTop = '15px';
const autoGGStatus = document.createElement("span");
autoGGStatus.id = "autogg-status";
autoGGStatus.style.fontSize = '28px';
autoGGStatus.style.marginLeft = '10px';
title.appendChild(document.createTextNode("AutoGG"));
title.appendChild(autoGGStatus);
menu.appendChild(title);

updateAutoGGStatus();

const hr1 = document.createElement("hr");
menu.appendChild(hr1);

const messageLabel = document.createElement("label");
messageLabel.textContent = "Edited Message";
const messageInputContainer = document.createElement("div");
messageInputContainer.style.display = "flex";

const messageInput = document.createElement("input");
messageInput.id = "autogg-message-input";
messageInput.name = "autogg-message";
messageInput.type = "text";
messageInput.value = editedMessage;
messageInput.maxLength = 30;
messageInput.setAttribute("autocomplete", "off");
messageInput.style.flex = "1";
messageInput.style.marginRight = "5px";
messageInput.addEventListener("input", updateCharacterCount);

messageInput.style.marginRight = "5px";

const characterCount = document.createElement("span");
characterCount.id = "autogg-character-count";
characterCount.style.fontSize = "12px";
characterCount.style.marginRight = "10px";
characterCount.style.alignSelf = "center";

characterCount.style.color = "#909090";

messageInputContainer.appendChild(messageInput);
messageInputContainer.appendChild(characterCount);

messageLabel.appendChild(messageInputContainer);
menu.appendChild(messageLabel);

const hr2 = document.createElement("hr");
menu.appendChild(hr2);

const speedLabel = document.createElement("label");
speedLabel.textContent = "Message Delay ";
const speedInput = document.createElement("input");
speedInput.id = "autogg-speed-input";
speedInput.name = "autogg-speed";
speedInput.type = "text";
speedInput.value = messageSpeed;
speedInput.maxLength = 4;
speedInput.style.width = "45px";
speedInput.setAttribute("autocomplete", "off");
speedLabel.appendChild(speedInput);
menu.appendChild(speedLabel);

speedInput.addEventListener("input", function () {
  if (this.value.length > 4) {
    this.value = this.value.slice(0, 4);
  }
speedInput.addEventListener("input", function () {
  this.value = this.value.replace(/[^0-9]/g, '');
});
});

const hr3 = document.createElement("hr");
menu.appendChild(hr3);

const toggleKeyLabel = document.createElement("label");
toggleKeyLabel.textContent = "Toggle Keycode ";
const tKeyInput = document.createElement("input");
tKeyInput.id = "autogg-toggle-key-input";
tKeyInput.name = "autogg-toggle-key";
tKeyInput.type = "text";
tKeyInput.value = toggleKeyCode;
tKeyInput.maxLength = 3;
tKeyInput.style.width = "39px";
tKeyInput.setAttribute("autocomplete", "off");
toggleKeyLabel.appendChild(tKeyInput);
menu.appendChild(toggleKeyLabel);

tKeyInput.addEventListener("input", function () {
  if (this.value.length > 3) {
    this.value = this.value.slice(0, 3);
  }
    tKeyInput.addEventListener("input", function () {
  this.value = this.value.replace(/[^0-9]/g, '');
});
});

const hr4 = document.createElement("hr");
menu.appendChild(hr4);

const saveButton = document.createElement("button");
saveButton.textContent = "Save";
saveButton.addEventListener("click", () => {
  saveMessage();
  saveSpeed();
  saveToggleKey();
});
loadSettings();
menu.appendChild(saveButton);