UNPKG

teeworlds

Version:

Library for (ingame) teeworlds bots.

114 lines (92 loc) 3.63 kB
import { EventEmitter } from "stream"; import { MsgPacker } from "../MsgPacker"; import { MsgUnpacker } from "../MsgUnpacker"; import { Client } from "../client"; import { NETMSG } from "../enums_types/protocol"; import { Chunk, RconCommand } from "../enums_types/types"; interface RconEvents { rcon_line: (line: string) => void; rcon_auth_status: (info: {AuthLevel: number, ReceiveCommands: number}) => void; rcon_cmd_add: (info: {command: string, description: string, params: string}) => void; rcon_cmd_rem: (info: {command: string}) => void; } export class Rcon extends EventEmitter { on<K extends keyof RconEvents>(event: K, listener: RconEvents[K]): this { return super.on(event, listener); } emit<K extends keyof RconEvents>(event: K, ...args: Parameters<RconEvents[K]>): boolean { return super.emit(event, ...args); } CommandList: RconCommand[] = []; private _client: Client; constructor(_client: Client) { super(); this._client = _client; } // SendMsgEx: (Msgs: MsgPacker[] | MsgPacker) => void; private send(packer: MsgPacker | MsgPacker[]) { if (!this._client.options?.lightweight) this._client.QueueChunkEx(packer); else this._client.SendMsgEx(packer); } public auth(username: string, password: string): void; public auth(password: string): void; /** Rcon auth, set the `username` to empty string for authentication w/o username **/ auth(usernameOrPassword: string, password?: string) { const rconAuthMsg = new MsgPacker(NETMSG.System.NETMSG_RCON_AUTH, true, 1); if (password == undefined) { rconAuthMsg.AddString(""); rconAuthMsg.AddString(usernameOrPassword); } else { rconAuthMsg.AddString(usernameOrPassword); rconAuthMsg.AddString(password); } rconAuthMsg.AddInt(1); this.send(rconAuthMsg); } /** Send rcon command **/ rcon(cmds: string[] | string) { let _cmds: string[]; if (cmds instanceof Array) _cmds = cmds else _cmds = [cmds]; const msgs: MsgPacker[] = []; _cmds.forEach((cmd) => { const rconCmdMsg = new MsgPacker(NETMSG.System.NETMSG_RCON_CMD, true, 1); rconCmdMsg.AddString(cmd); msgs.push(rconCmdMsg); }) this.send(msgs); } /** This method is called by the Client to handle the chunks. It should not be called directly. */ _checkChunks(chunk: Chunk): boolean { if (chunk.msgid == NETMSG.System.NETMSG_RCON_LINE) { const unpacker = new MsgUnpacker(chunk.raw); const msg = unpacker.unpackString(); this.emit('rcon_line', msg); } else if (chunk.msgid == NETMSG.System.NETMSG_RCON_AUTH_STATUS) { const unpacker = new MsgUnpacker(chunk.raw); const AuthLevel = unpacker.unpackInt(); const ReceiveCommands = unpacker.unpackInt(); this.emit('rcon_auth_status', {AuthLevel, ReceiveCommands}); } else if (chunk.msgid == NETMSG.System.NETMSG_RCON_CMD_ADD) { const unpacker = new MsgUnpacker(chunk.raw); const command = unpacker.unpackString(); const description = unpacker.unpackString(); const params = unpacker.unpackString(); this.CommandList.push({command, description, params}); this.emit('rcon_cmd_add', {command, description, params}); } else if (chunk.msgid == NETMSG.System.NETMSG_RCON_CMD_REM) { const unpacker = new MsgUnpacker(chunk.raw); const command = unpacker.unpackString(); this.emit('rcon_cmd_rem', {command}); let index = this.CommandList.findIndex(a => a.command == command); if (index -1 >= 0) this.CommandList.splice(index, 1); } else { return false; } return true; } }