您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Draws markers on items
// ==UserScript== // @name Moomoo.io Item markers // @author Murka // @description Draws markers on items // @icon https://moomoo.io/img/favicon.png?v=1 // @version 0.2 // @match *://moomoo.io/* // @match *://*.moomoo.io/* // @run-at document-start // @grant none // @license MIT // @namespace https://greasyfork.org/users/919633 // ==/UserScript== /* jshint esversion:6 */ /* Author: Murka Github: https://github.com/Murka007 Discord: https://discord.gg/sG9cyfGPj5 Greasyfork: https://greasyfork.org/en/users/919633 MooMooForge: https://github.com/MooMooForge */ (function() { "use strict"; // render - false/true, used to toggle rendering of marker // color - hex/rgb color, used to change marker color const MARKER_COLOR = { MY_PLAYER: { render: true, color: "#a7f060" }, TEAMMATE: { render: true, color: "#fceb65" }, ENEMY: { render: true, color: "#f76363" } }; const MARKER_SIZE = 10; const log = console.log; const createRecursiveHook = (target, prop, condition, callback) => { (function recursiveHook() { Object.defineProperty(target, prop, { set(value) { delete target[prop]; this[prop] = value; if ( condition(this, value) && callback(this, value) ) return; recursiveHook(); }, configurable: true }) })(); } function createHook(target, prop, setter, getter) { const symbol = Symbol(prop); Object.defineProperty(target, prop, { get() { getter(this, this[symbol]); return this[symbol]; }, set(value) { setter(this, symbol, value); }, configurable: true }) } let item = null; createHook(Object.prototype, "isItem", function(that, symbol, value) { that[symbol] = value; }, function(that, value) { if (value === true) { item = that; } }); const myPlayer = { id: null }; const teammates = []; // myPlayer spawned function setupPlayer(temp) { myPlayer.id = temp[1]; } function createDeleteClan(temp) { if (!temp[1]) { teammates.splice(0, teammates.length); } } function updateClanList(temp) { teammates.splice(0, teammates.length); for (let i=0;i<temp[1].length;i+=2) { const [ id, name ] = temp[1].slice(i, i+2); teammates.push(id); } } function getItemColor(id) { if (id === myPlayer.id) return MARKER_COLOR.MY_PLAYER; if (teammates.includes(id)) return MARKER_COLOR.TEAMMATE; return MARKER_COLOR.ENEMY; } function drawMarker(ctx) { if (!item || !item.owner || myPlayer.id === null) return; const type = getItemColor(item.owner.sid); if (!type.render) return; ctx.fillStyle = type.color; ctx.beginPath(); ctx.arc(0, 0, MARKER_SIZE, 0, 2 * Math.PI); ctx.fill(); item = null; } // This method is called when item was drawn CanvasRenderingContext2D.prototype.restore = new Proxy(CanvasRenderingContext2D.prototype.restore, { apply(target, _this, args) { drawMarker(_this); return target.apply(_this, args); } }); document.msgpack = { Encoder: null, Decoder: null }; // Intercept msgpack encoder createRecursiveHook( Object.prototype, "initialBufferSize", (_this) => ( typeof _this === "object" && typeof _this.encode === "function" && _this.encode.length === 1 ), (_this) => { document.msgpack.Encoder = _this; return true; } ); // Intercept msgpack decoder createRecursiveHook( Object.prototype, "maxExtLength", (_this) => ( typeof _this === "object" && typeof _this.decode === "function" && _this.decode.length === 1 ), (_this) => { document.msgpack.Decoder = _this; return true; } ); // previous way to get msgpack encoder and decoder. // Get msgpack's encode and decode methods /*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) msgpack.encode = args[0].encode; if (i === 15) { msgpack.decode = args[0].decode; Function.prototype.call = target; } } return data; } })*/ const PACKETS = { 1: setupPlayer, st: createDeleteClan, sa: updateClanList, }; // Handle WebSocket data function message(event) { try { const data = document.msgpack.Decoder.decode(new Uint8Array(event.data)); const temp = [data[0], ...data[1]]; PACKETS[temp[0]](temp); } catch(err){} } // Intercept WebSocket window.WebSocket = new Proxy(WebSocket, { construct(target, args) { const socket = new target(...args); socket.addEventListener("message", message); return socket; } }); // old intercept ws method /*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) { message(args[0]); return target.apply(_this, args); } })) } })*/ })();