UNPKG

moomooio-client

Version:

MooMooIO-Client is a client-side wrapper API designed for the game MooMoo.io. This package aims to provide a simple yet powerful API for creating clones, mods, or plugins for MooMoo.io.

240 lines (212 loc) 8.11 kB
import { encode } from "msgpack-lite"; import MooMooIOConnection from "./MooMooIOConnection"; type Packet = readonly [string, unknown]; export default class ClientPacketOrganizer { #requestStack: Packet[] = []; constructor(readonly connection: MooMooIOConnection) {} destroy() { this.#requestStack = []; } /** * Generator function that reads and yields items from the request stack. * @returns An iterator for the items in the request stack. */ protected *readRequestStack() { for (let item of this.#requestStack) { yield item; } // Reset the request stack after yielding all items this.#requestStack = []; } /** * Pushes a new request to the request stack. * @param {Packet} input - The request to be added to the stack. */ protected requestStackPush(input: Packet): void { this.#requestStack.push(input); } protected async parse(packet: Packet): Promise<boolean> { return this.connection.send(encode(packet)); } public async parseLast(): Promise<boolean> { const packet = this.#requestStack.pop(); return !!packet && (await this.parse(packet)); } public async parseRequestStack() { for (let packet of this.readRequestStack()) { await this.parse(packet); } } /** * * @description This packet is used to respond to a join request you received as the team owner. You can either `Accept` or `Deny` the request. * @ignored If you don't own the team, this packet will be ignored. * @param answer Either `Accept` or `Deny`. * * @note The response is based on the order in which the requests were received, with the oldest request being answered first. */ answerJoinRequest(answer: "Accept" | "Deny") { this.requestStackPush(["11", [answer == "Accept" ? 1 : 0]]); return this; } /** * @description This packet is used to purchase/buy an `Accessory` or `Hat` in the game. * @ignored if you already own the item or if you don't have enough gold to make the purchase. The packet will be ignored. * @param itemID is the unique number that identifies the item (ID). * @param itemType can be either `Accessory` or `Hat`. * @note If you haven't spawned in the game yet, this packet will be ignored */ buy(itemID: number, itemType: "Accessory" | "Hat") { this.requestStackPush(["13c", [1, itemID, itemType == "Accessory" ? 1 : 0]]); return this; } /** * * @description this packet is used to create a team in the game. * @ignored If you are already in a team or if the title you provide is already being used by another team. this packet will be ignored * @param teamTitle unique title for the team. * * @note you can have one team at the same time. */ createTeam(teamTitle: string) { this.requestStackPush(["8", [teamTitle]]); return this; } /** * @description This packet is used to **equip** an `Accessory` or `Hat` in the game. * @ignored if you don't have that item yet. the packet will be ignored. * @param itemID is the identification number for that item (ID). * @param itemType can be either `Accessory` or `Hat`. * @note If you haven't spawned in the game yet, this packet will be ignored. */ equip(itemID: number, itemType: "Accessory" | "Hat") { this.requestStackPush(["13c", [0, itemID, itemType == "Accessory" ? 1 : 0]]); return this; } /** * @description This packet is used to change the item held by your player. * @param itemID A unique code that identifies the item. * @param isWeapon A method to categorize the type of item. */ holdItem(itemID: number, isWeapon: boolean) { this.requestStackPush(["5", [itemID, isWeapon]]); return this; } /** * * @description This packet is used to ask to join a team in the game. * @ignored If you are already in a team, this packet will be ignored. * @param teamTitle The name of the team you want to join. * @note If the team cannot be found, this packet will be ignored. */ joinRequest(teamTitle: string) { this.requestStackPush(["10", [teamTitle]]); return this; } /** * * @description This packet is for removing someone from your team * @ignored If you are not the team owner. this packet will be ignored * @param playerID The ID of the player you want to kick from your team. */ kickFromTeam(playerID: number) { this.requestStackPush(["12", [playerID]]); return this; } /** * * @description this packet is used to **leave your current team. * @ignored If you are not in a team. this packet will be ignored. */ leaveTeam() { this.requestStackPush(["9", []]); return this; } /** * @description this packet is used to ping the game * @param target either `MiniMap` or `Connection` * @note * > if the `target` is `MiniMap` then the server gonna responses with `UpdateMiniMap`....... * > if the `target` is `Connection` then the server gonna responses with `Pong` */ ping(target: "MiniMap" | "Connection") { this.requestStackPush(target == "MiniMap" ? ["14", [1]] : ["pp", []]); return this; } /** * @description this packet is used to update your character direction in the game. * @param direction the direction your character is facing (in radian) * * @note this direction may be overwritten by `setPunchState` */ setDirection(direction: number) { this.requestStackPush(["2", [direction]]); return this; } /** * @description This packet is used to update your punch status in the game. * @param state is an indicator of whether your player should start punching or not. * @param direction is the direction the player should face before updating the status (in radian). * @depth I think I need to explain this further. * The `state` refers to whether your player is currently punching or not. * You can make your player perform an punch by following these steps: * > First, enable the punch by setting the `state` parameter to `true`. * > Second, disable the punch by setting the `state` parameter to `false`. */ setPunchState(state: boolean, direction: number) { this.requestStackPush(["c", [state, direction]]); return this; } /** * @description This packet is used to send a message for nearby players * @param content the message content you want to send */ chat(message: string) { this.requestStackPush(["ch", [message.slice(0, 30)]]); return this; } /** * @description This packet is used to create your character in the game. * @param name The name of your character. * @param skinID The skin ID of your character. * @param haveStartPackage Determines whether your character should start with a fast start-up package (having 100 resources for each resource). */ spawn(name: string, skinID: number, haveStartPackage: boolean = true) { this.requestStackPush([ "sp", [ { moofoll: haveStartPackage, skin: skinID, name, }, ], ]); return this; } /** * @description this packet is used to toggle auto-punch * @notSafe true */ toggleAutoPunchState() { this.requestStackPush(["7", [1]]); return this; } /** * @description This packet is used to toggle the lock of your player facing direction. * @note Not recommended to use. avoid use this as much as possible */ toggleLockDir() { this.requestStackPush(["7", [0]]); return this; } /** * @description This packet is used to upgrade your chosen items in the game. * @param itemID A special code that identify the item. * @note If you do not meet the necessary conditions for the upgrade, this packet will be ignored. */ upgrade(itemID: number) { this.requestStackPush(["6", [itemID]]); return this; } }