Greasy Fork

MooMoo.io Anti-Kick

An Anti-Kick script for MooMoo.io using msgpack.js

目前为 2023-09-10 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.greasyfork.cloud/scripts/474034/1248163/MooMooio%20Anti-Kick.js

// ==UserScript==
// @name         MooMoo.io Anti-Kick
// @namespace    https://greasyfork.org/users/1064285-vcrazy-gaming
// @version      1
// @description  An Anti-Kick script for MooMoo.io using msgpack.js
// @author       _VcrazY_
// @match        *://*.moomoo.io/*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @require      https://greasyfork.org/scripts/423602-msgpack/code/msgpack.js
// @grant        none
// @license      MIT
// ==/UserScript==
/* jshint esversion:6 */

(function () {
  'use strict';

  const packetLimitPerMinute = 125;
  const packetLimitPerSecond = 10;
  const ignoredPacketTypes = ["pp", "rmd"];
  const rateLimitedPacketTypes = ["5", "c", "33", "2", "7", "13c"];
  const packetHistory = new Map();
  const packetQueue = [];
  let resetTime = Date.now();
  const msgpackLibrary = window.msgpack;

  const packetHandler = new (class {
    constructor() {
      this.resetRateLimit();
    }

    resetRateLimit() {
      this.packetLimitPerMinute = packetLimitPerMinute;
      this.packetLimitPerSecond = packetLimitPerSecond;
      this.packetHistory = new Map();
      this.packetQueue = [];
      this.resetTime = Date.now();
    }

    isRateLimited(packet) {
      const binary = new Uint8Array(packet);
      const decodedPacket = msgpackLibrary.decode(binary);

      if (Date.now() - this.resetTime > this.packetLimitPerMinute) {
        this.resetRateLimit();
      }

      if (!ignoredPacketTypes.includes(decodedPacket[0])) {
        if (this.packetHistory.has(decodedPacket[0])) {
          const lastPacket = this.packetHistory.get(decodedPacket[0]);

          switch (decodedPacket[0]) {
            case "2":
            case "33":
              if (lastPacket[0] === decodedPacket[1][0]) return true;
              break;
          }
        }

        if (this.packetQueue.length > this.packetLimitPerSecond) {
          return rateLimitedPacketTypes.includes(decodedPacket[0]) || this.packetQueue.push(packet);
        }

        this.packetQueue.push({
          type: decodedPacket[0],
          data: decodedPacket[1],
        });

        this.packetHistory.set(decodedPacket[0], decodedPacket[1]);
      }

      return false;
    }
  })();

  let isFirstSend = false;

  WebSocket.prototype.send = new Proxy(WebSocket.prototype.send, {
    apply: function (target, thisArg, argumentsList) {
      if (
        (!isFirstSend ||
          (thisArg.addEventListener("message", (event) => {
            if (packetHandler.packetQueue.length) {
              const data = new Uint8Array(event.data);
              if (msgpackLibrary.decode(data)[0] === "33") {
                thisArg.send(packetHandler.packetQueue[0]);
                packetHandler.packetQueue.shift();
              }
            }
          }),
          (isFirstSend = true)),
        !packetHandler.isRateLimited(argumentsList[0]))
      ) {
        return Reflect.apply(target, thisArg, argumentsList);
      }
    },
  });
})();