MooMoo.io Move Camera

Move the x-offset and y-offset of your canvas to match a player's position

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         MooMoo.io Move Camera
// @description  Move the x-offset and y-offset of your canvas to match a player's position
// @author       KOOKY WARRIOR
// @match        *://*.moomoo.io/*
// @icon         https://moomoo.io/img/favicon.png?v=1
// @require      https://cdnjs.cloudflare.com/ajax/libs/msgpack-lite/0.1.26/msgpack.min.js
// @require 	 https://greasyfork.org/scripts/478839-moomoo-io-packet-code/code/MooMooio%20Packet%20Code.js
// @run-at       document-start
// @grant        unsafeWindow
// @license      MIT
// @version      0.3.2
// @namespace    https://greasyfork.org/users/999838
// ==/UserScript==

/*
In the chatbox:
- Type "/moveto sid" to move the x-offset and y-offset of your canvas to the position of a player
- To show players' sid, type "/showsid"
- To hide players' sid, type "/hidesid"
- If you wish to return to the normal x-offset and y-offset of your canvas, type "/stop"
*/

;(async () => {
	unsafeWindow.movecamera = true

	let mySID = null
	let showSID = false
	let camera = false
	let follow = {
		exist: false,
		sid: null,
		x: null,
		y: null,
		x1: null,
		x2: null,
		y1: null,
		y2: null,
		dt: 0
	}

	let now, delta, lastUpdate
	function update() {
		now = Date.now()
		if (lastUpdate == null) {
			lastUpdate = now
		}
		delta = now - lastUpdate
		lastUpdate = now

		if (camera && follow.sid != null && follow.exist === true) {
			follow.dt += delta
			let tmpRate = Math.min(1.7, follow.dt / 170)
			let xdiff = follow.x2 - follow.x1
			let ydiff = follow.y2 - follow.y1
			follow.x = follow.x1 + xdiff * tmpRate
			follow.y = follow.y1 + ydiff * tmpRate
		}
		unsafeWindow.requestAnimationFrame(update)
	}
	update()

	let init = false
	await new Promise(async (resolve) => {
		let { send } = WebSocket.prototype

		WebSocket.prototype.send = function (...x) {
			send.apply(this, x)
			this.send = send
			if (!init) {
				init = true
				this.addEventListener("message", (e) => {
					if (!e.origin.includes("moomoo.io") && !unsafeWindow.privateServer) return
					const [packet, data] = msgpack.decode(new Uint8Array(e.data))
					switch (packet) {
						case PACKETCODE.RECEIVE.setupGame:
							mySID = data[0]
							break
						case PACKETCODE.RECEIVE.updatePlayers:
							if (follow.sid != null && camera) {
								follow.exist = false
								for (let i = 0; i < data[0].length; i += 13) {
									if (data[0][i] === follow.sid) {
										follow.exist = true
										follow.x1 = follow.x || data[0][i + 1]
										follow.y1 = follow.y || data[0][i + 2]
										follow.x2 = data[0][i + 1]
										follow.y2 = data[0][i + 2]
										follow.dt = 0
										break
									}
								}
							}
							break
						case PACKETCODE.RECEIVE.receiveChat:
							if (data[0] === mySID) {
								if (data[1] == "/showsid") {
									showSID = true
								} else if (data[1] == "/hidesid") {
									showSID = false
								} else if (data[1].startsWith("/moveto")) {
									let e = data[1].split(" ")
									if (e[1] != null && Number(e[1]) != NaN) {
										follow.sid = Number(e[1])
									}
									camera = true
								} else if (data[1] == "/stop") {
									camera = false
									follow = {
										exist: false,
										sid: null,
										x: null,
										y: null,
										x1: null,
										x2: null,
										y1: null,
										y2: null,
										dt: 0
									}
								}
							}
							break
					}
				})
			}
			resolve(this)
		}
	})

	const symbol = Symbol("PositionX")
	Object.defineProperty(Object.prototype, "x", {
		get() {
			if (this.isPlayer === true && this.sid === mySID && camera && follow.sid != null && follow.exist === true) {
				return follow.x
			}
			return this[symbol]
		},
		set(value) {
			this[symbol] = value
		},
		configurable: true
	})

	const symbol2 = Symbol("PositionY")
	Object.defineProperty(Object.prototype, "y", {
		get() {
			if (this.isPlayer === true && this.sid === mySID && camera && follow.sid != null && follow.exist === true) {
				this.visible = false
				return follow.y
			}
			return this[symbol2]
		},
		set(value) {
			this[symbol2] = value
		},
		configurable: true
	})

	const symbol3 = Symbol("MooMooName")
	Object.defineProperty(Object.prototype, "name", {
		get() {
			if (this.isPlayer === true && showSID) {
				return this[symbol3] + ` [${this.sid}]`
			} else {
				return this[symbol3]
			}
		},
		set(value) {
			this[symbol3] = value
		},
		configurable: true
	})
})()