UNPKG

@xmcl/client

Version:

Minecraft socket pipeline utilities. Support Minecraft lan server discovery.

8 lines (7 loc) 43.2 kB
{ "version": 3, "sources": ["../coders.ts", "../packet.ts", "../channel.ts", "../status.ts", "../lan.ts"], "sourcesContent": ["import { deserializeSync, serializeSync } from '@xmcl/nbt'\nimport { ByteBuffer } from '@xmcl/bytebuffer'\nimport '@xmcl/bytebuffer/varint32'\nimport '@xmcl/bytebuffer/varint64'\nimport type { PacketRegistry } from './channel'\n\nexport interface SlotData {\n blockId: number\n itemCount?: number\n itemDamage?: number\n nbt?: any\n}\n\n/**\n * The packet encode/decode algorithm\n */\nexport interface Coder<T> {\n readonly encode: (buffer: ByteBuffer, data: T, context?: PacketRegistry) => void\n readonly decode: (buffer: ByteBuffer, context?: PacketRegistry) => T\n}\n\nexport const VarInt: Coder<number> = {\n decode: (buffer, inst) => buffer.readVarint32(),\n encode: (buffer, inst) => { buffer.writeVarint32(inst) },\n}\n\nexport const Int: Coder<number> = {\n decode: (buffer, inst) => buffer.readInt(),\n encode: (buffer, inst) => { buffer.writeInt(inst) },\n}\n\nexport const Byte: Coder<number> = {\n decode: (buffer, inst) => buffer.readByte(),\n encode: (buffer, inst) => { buffer.writeByte(inst) },\n}\n\nexport const UByte: Coder<number> = {\n decode: (buffer, inst) => buffer.readUint8(),\n encode: (buffer, inst) => { buffer.writeUint8(inst) },\n}\n\nexport const Bool: Coder<boolean> = {\n decode: (buffer, inst) => buffer.readByte() === 1,\n encode: (buffer, inst) => { buffer.writeByte(inst ? 1 : 0) },\n}\n\nexport const Float: Coder<number> = {\n decode: (buffer, inst) => buffer.readFloat(),\n encode: (buffer, inst) => { buffer.writeFloat(inst) },\n}\n\nexport const Double: Coder<number> = {\n decode: (buffer, inst) => buffer.readDouble(),\n encode: (buffer, inst) => { buffer.writeDouble(inst) },\n}\n\nexport const UUID: Coder<string> = {\n decode: (buffer, inst) => {\n const makeDigit = (hex: string, digit: number) => {\n if (hex.length < digit) {\n let d = ''\n for (let i = 0; i < digit - hex.length; i += 1) {\n d += '0'\n }\n return `${d}${hex}`\n }\n return hex\n }\n const hi = buffer.readUint64()\n const lo = buffer.readUint64()\n\n let a = makeDigit(Number(hi >> 32n).toString(16), 8)\n const b = makeDigit(((hi >> 16n) & 0xFFFFn).toString(16), 4)\n const c = makeDigit((hi & 0xFFFFn).toString(16), 4)\n const d = makeDigit(((lo >> 48n) & 0xFFFFn).toString(16), 4)\n const e = makeDigit((lo & 0xFFFFFFFFFFFFn).toString(16), 12)\n\n if (a.length === 16) {\n a = a.substring(8, 16)\n }\n\n return `${a}-${b}-${c}-${d}-${e}`\n },\n encode: (buffer, inst) => {\n const components = inst.split('-')\n if (components.length !== 5) { throw new Error('Invalid UUID') }\n let hi = BigInt(`0x${components[0]}`)\n hi = hi << (16n)\n hi = hi | (BigInt(`0x${components[1]}`))\n hi = hi << (16n)\n hi = hi | (BigInt(`0x${components[2]}`))\n\n let lo = BigInt(`0x${components[3]}`)\n lo = lo << 48n\n lo = lo | (BigInt(`0x${components[4]}`))\n\n buffer.writeUint64(hi)\n buffer.writeUint64(lo)\n },\n}\n\nexport const Short: Coder<number> = {\n decode: (buffer, inst) => buffer.readShort(),\n encode: (buffer, inst) => { buffer.writeShort(inst) },\n}\n\nexport const UShort: Coder<number> = {\n decode: (buffer, inst) => buffer.readUint16(),\n encode: (buffer, inst) => { buffer.writeUint16(inst) },\n}\n\nexport const Long: Coder<bigint> = {\n decode: (buffer, inst) => buffer.readLong(),\n encode: (buffer, inst) => { buffer.writeInt64(inst) },\n}\n\nexport const VarLong: Coder<bigint> = {\n decode: (buffer, inst) => buffer.readVarint64(),\n encode: (buffer, inst) => { buffer.writeVarint64(inst) },\n}\n\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport const String: Coder<string> = {\n decode: (buffer) => {\n const length = buffer.readVarint32()\n return Buffer.from(buffer.readBytes(length).toBuffer()).toString('utf-8')\n },\n encode: (buffer, inst) => {\n const byte = Buffer.from(inst)\n buffer.writeVarint32(byte.byteLength)\n buffer.writeBytes(Buffer.from(inst))\n },\n}\n\nexport const Json: Coder<any> = {\n decode: (buffer, inst) => {\n return JSON.parse(String.decode(buffer, inst))\n },\n encode: (buffer, inst, ctx) => {\n String.encode(buffer, JSON.stringify(inst), ctx)\n },\n}\n\nexport const Slot: Coder<SlotData> = {\n decode: (buffer, ctx) => {\n const blockId = Short.decode(buffer, ctx)\n if (blockId === -1) { return { blockId } }\n const itemCount = Byte.decode(buffer) || undefined\n const itemDamage = Short.decode(buffer) || undefined\n if (Byte.decode(buffer, ctx) === 0) {\n return {\n blockId,\n itemCount,\n itemDamage,\n }\n }\n return {\n blockId,\n itemCount,\n itemDamage,\n nbt: deserializeSync(Buffer.from(buffer.buffer)),\n }\n },\n encode: (buffer, inst) => {\n Short.encode(buffer, inst.blockId)\n Byte.encode(buffer, inst.itemCount || 0)\n Byte.encode(buffer, inst.itemDamage || 0)\n if (inst.nbt) {\n Byte.encode(buffer, 1)\n buffer.writeBytes(serializeSync(inst.nbt))\n } else {\n Byte.encode(buffer, 0)\n }\n },\n}\n\nexport const ByteArray: Coder<Int8Array> = {\n decode: (buffer, inst) => {\n const len = buffer.readVarint32()\n const arr = new Int8Array(len)\n for (let i = 0; i < len; i += 1) {\n arr[i] = buffer.readByte()\n }\n return arr\n },\n encode: (buffer, inst) => {\n const len = inst.length\n buffer.writeVarint32(len)\n for (let i = 0; i < len; i += 1) {\n buffer.writeByte(inst[i])\n }\n },\n}\n", "import type { State } from './channel'\nimport { Coder } from './coders'\n\ninterface FieldRecord { name: string; type: Coder<any> }\n\nexport type Side = 'server' | 'client'\n\nexport interface PacketRegistryEntry {\n readonly id: number\n readonly name: string\n readonly state: State\n readonly side: Side\n readonly coder: Coder<any>\n}\n\nexport type FieldType<T> = (type: Coder<T>) => (target: any, key: string) => void\nexport type PacketType = (side: Side, id: number, state: State) => (constructor: (...args: any[]) => any) => void\n\nexport const PacketMetadata = Symbol('PacketMetadata')\nexport const PacketFieldsMetadata = Symbol('PacketFieldsMetadata')\n\n/**\n * Get a packet registry entry for a class\n * @param clazz The class object\n */\nexport function getPacketRegistryEntry(clazz: new (...args: any) => any): PacketRegistryEntry {\n return clazz.prototype[PacketMetadata]\n}\n\n/**\n * Annotate the field type in your packet. Assign a coder for serialization/deserialization.\n * This will generate a list of `FieldType` in your class prototype.\n *\n * @param type The coder to serialize/deserialize the field.\n * @see \"coders.ts\"\n */\nexport function Field<T>(type: Coder<T>) {\n return (target: any, key: string) => {\n const container = target\n if (!container[PacketFieldsMetadata]) {\n container[PacketFieldsMetadata] = []\n }\n container[PacketFieldsMetadata].push({ name: key, type })\n }\n}\n/**\n * Decoarte for you packet class.\n * This will generate a `PacketRegistryEntry` in your class prototype.\n *\n * @param side The side of your packet\n * @param id The id of your packet\n * @param state The state of you packet should be\n */\nexport function Packet(side: Side, id: number, state: State, name = '') {\n return (constructor: new (...args: any[]) => any) => {\n const container = constructor.prototype\n const fields: FieldRecord[] = container[PacketFieldsMetadata] || []\n container[PacketMetadata] = {\n id,\n name: name || constructor.name,\n side,\n state,\n coder: {\n encode(buffer, value) {\n fields.forEach((cod) => {\n cod.type.encode(buffer, value[cod.name])\n })\n },\n decode(buffer) {\n const value = newCall(constructor)\n fields.forEach((cod) => {\n try {\n value[cod.name] = cod.type.decode(buffer)\n } catch (e) {\n console.error(new Error(`Exception during reciving packet [${id}]${constructor.name}`))\n console.error(e)\n }\n })\n return value\n },\n },\n } as PacketRegistryEntry\n }\n}\n\n// https://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible\nfunction newCall(Cls: any) {\n // tslint:disable-next-line: new-parens\n // eslint-disable-next-line prefer-rest-params\n return new (Function.prototype.bind.apply(Cls, arguments as any))()\n}\n", "import { ByteBuffer } from '@xmcl/bytebuffer'\nimport { EventEmitter } from 'events'\nimport { NetConnectOpts, Socket } from 'net'\nimport { Transform, TransformCallback, TransformOptions, Writable } from 'stream'\nimport { unzip } from 'zlib'\nimport { Coder } from './coders'\nimport { PacketRegistryEntry, Side, PacketMetadata } from './packet'\n\nexport type State = keyof States\ninterface States {\n handshake: PacketCoders\n login: PacketCoders\n status: PacketCoders\n play: PacketCoders\n}\n\n/**\n * The channel for send and listen the Minecraft packet.\n */\nexport class Channel extends EventEmitter {\n state: State = 'handshake'\n\n private readonly states = {\n client: {\n handshake: new PacketCoders(),\n login: new PacketCoders(),\n status: new PacketCoders(),\n play: new PacketCoders(),\n },\n server: {\n handshake: new PacketCoders(),\n login: new PacketCoders(),\n status: new PacketCoders(),\n play: new PacketCoders(),\n },\n }\n\n private connection: Socket = new Socket({ allowHalfOpen: false })\n\n private outbound: Writable\n private inbound: Writable\n private listened = false\n\n private enableCompression = false\n private compressionThreshold = -1\n\n constructor() {\n super()\n this.outbound = new MinecraftPacketEncoder(this)\n this.outbound.pipe(new MinecraftPacketOutbound()).pipe(this.connection)\n\n this.inbound = new MinecraftPacketInBound()\n this.inbound\n .pipe(new PacketDecompress({\n get enableCompression() {\n return false\n },\n get compressionThreshold() {\n return -1\n },\n }))\n .pipe(new MinecraftPacketDecoder(this))\n .pipe(new PacketEmitter(this))\n\n this.connection.pipe(this.inbound)\n }\n\n /**\n * Is the connection ready to read and write\n */\n get ready() {\n return this.connection.readable && this.connection.writable && this.listened\n }\n\n findCoderById(packetId: number, side: Side): Coder<any> {\n const all = this.states[side][this.state]\n return all.packetIdCoders[packetId]\n }\n\n getPacketId(packetInst: any, side: Side): number {\n const packetName = Object.getPrototypeOf(packetInst).constructor.name\n const all = this.states[side][this.state]\n return all.packetNameToId[packetName]\n }\n\n registerPacketType(clazz: new (...args: any) => any) {\n const entry: PacketRegistryEntry = clazz.prototype[PacketMetadata]\n const { state, side, id, name, coder } = entry\n const coders = this.states[side][state]\n coders.packetIdCoders[id] = coder\n coders.packetNameToId[name] = id\n }\n\n registerPacket(entry: PacketRegistryEntry) {\n const { state, side, id, name, coder } = entry\n const coders = this.states[side][state]\n coders.packetIdCoders[id] = coder\n coders.packetNameToId[name] = id\n }\n\n /**\n * Open the connection and start to listen the port.\n */\n async listen(option: NetConnectOpts & { keepalive?: boolean | number }) {\n await new Promise<void>((resolve, reject) => {\n this.connection.connect(option, () => {\n resolve()\n })\n if (option.timeout) {\n this.connection.setTimeout(option.timeout)\n }\n if (option.keepalive) {\n this.connection.setKeepAlive(true, typeof option.keepalive === 'boolean' ? 3500 : option.keepalive)\n }\n this.connection.once('error', (e) => { reject(e) })\n this.connection.once('timeout', () => { reject(new Error('Connection timeout.')) })\n })\n this.connection.on('error', (e) => { this.emit('error', e) })\n\n this.emit('listen')\n this.listened = true\n }\n\n disconnect() {\n if (!this.listened || !this.ready) {\n return Promise.resolve()\n }\n this.listened = false\n return new Promise<void>((resolve, reject) => {\n this.connection.once('close', (err) => {\n if (err) {\n reject(err)\n } else {\n resolve()\n }\n })\n this.connection.end()\n })\n }\n\n /**\n * Sent a packet to server.\n */\n send<T>(message: T, skeleton?: Partial<T>) {\n if (!this.connection.writable) { throw new Error(\"Cannot write if the connection isn't writable!\") }\n if (skeleton) { Object.assign((message as any), skeleton) }\n return new Promise<void>((resolve, reject) => {\n this.outbound.write(message, (err) => {\n if (err) {\n reject(err)\n } else {\n this.emit('send', message)\n resolve()\n }\n })\n })\n }\n\n /**\n * Listen for sepcific packet by its class name.\n */\n onPacket<T>(packet: new (...args: any[]) => T, listener: (event: T) => void): this {\n return this.on(`packet:${packet.name}`, listener)\n }\n\n oncePacket<T>(packet: new (...args: any[]) => T, listener: (event: T) => void): this {\n return this.once(`packet:${packet.name}`, listener)\n }\n}\n\nexport interface Channel extends EventEmitter {\n on<T>(channel: string, listener: (event: T) => void): this\n once<T>(channel: string, listener: (event: T) => void): this\n}\n\nexport abstract class PacketInBound extends Transform {\n private buffer: ByteBuffer = ByteBuffer.allocate(1024)\n\n protected abstract readPacketLength(bb: ByteBuffer): number\n\n _transform(chunk: Buffer, encoding: string, callback: TransformCallback) {\n this.buffer.ensureCapacity(chunk.length + this.buffer.offset)\n this.buffer.append(chunk)\n this.buffer.flip()\n\n let unresolvedBytes\n do {\n const packetLength = this.readPacketLength(this.buffer)\n unresolvedBytes = this.buffer.remaining()\n\n if (packetLength <= unresolvedBytes) {\n const result = Buffer.alloc(packetLength)\n // TODO: check if this src refactor is correct\n const src = Buffer.from(this.buffer.buffer)\n src.copy(result, 0, this.buffer.offset, this.buffer.offset + packetLength)\n this.push(result)\n\n src.copyWithin(0, packetLength) // clear emitted bytes\n this.buffer.offset = 0 // reset read offset to the front\n this.buffer.limit -= packetLength // reduce the limit by emitted bytes\n\n unresolvedBytes -= packetLength\n } else {\n this.buffer.offset = this.buffer.limit\n this.buffer.limit = this.buffer.capacity()\n break\n }\n } while (unresolvedBytes > 0)\n callback()\n }\n}\n\nclass MinecraftPacketInBound extends PacketInBound {\n protected readPacketLength(bb: ByteBuffer): number {\n return bb.readVarint32()\n }\n}\n\nclass PacketDecompress extends Transform {\n constructor(private option: { readonly enableCompression: boolean; readonly compressionThreshold: number }) {\n super()\n }\n\n _transform(chunk: Buffer, encoding: string, callback: TransformCallback) {\n if (!this.option.enableCompression) {\n this.push(chunk)\n callback()\n return\n }\n const message = ByteBuffer.wrap(chunk)\n const dataLength = message.readVarint32()\n if (dataLength === 0 || dataLength < this.option.compressionThreshold) {\n this.push(message.buffer.slice(message.offset))\n callback()\n } else {\n const compressedContent = message.buffer.slice(message.offset)\n unzip(compressedContent, (err, result) => {\n if (err) {\n callback(err)\n } else {\n this.push(result)\n callback()\n }\n })\n }\n }\n}\n\nexport interface PacketRegistry {\n findCoderById(packetId: number, side: 'client' | 'server'): Coder<any>\n getPacketId(message: any, side: 'client' | 'server'): number\n}\n\nexport abstract class PacketDecoder extends Transform {\n constructor(private client: PacketRegistry) {\n super({ writableObjectMode: true, readableObjectMode: true })\n }\n\n abstract readPacketId(message: ByteBuffer): number\n\n _transform(chunk: Buffer, encoding: string, callback: TransformCallback) {\n const message = ByteBuffer.wrap(chunk)\n const packetId = this.readPacketId(message)\n const packetContent = message.slice()\n const coder = this.client.findCoderById(packetId, 'server')\n if (coder) {\n this.push(coder.decode(packetContent))\n } else {\n console.error(`Unknown packet ${packetId} : ${packetContent.buffer}.`)\n }\n callback()\n }\n}\n\nclass MinecraftPacketDecoder extends PacketDecoder {\n readPacketId(message: ByteBuffer): number {\n return message.readVarint32()\n }\n}\n\nexport class PacketEmitter extends Writable {\n constructor(private eventBus: EventEmitter) {\n super({ objectMode: true })\n }\n\n _write(inst: any, encoding: string, callback: (error?: Error | null) => void): void {\n this.eventBus.emit(`packet:${Object.getPrototypeOf(inst).constructor.name}`, inst)\n callback()\n }\n}\n\nexport abstract class PacketEncoder extends Transform {\n constructor(private client: PacketRegistry) {\n super({ writableObjectMode: true, readableObjectMode: true })\n }\n\n protected abstract writePacketId(bb: ByteBuffer, id: number): void\n\n _transform(message: any, encoding: string, callback: TransformCallback) {\n const id = this.client.getPacketId(message, 'client')\n const coder = this.client.findCoderById(id, 'client')\n if (coder && coder.encode) {\n const buf = new ByteBuffer()\n this.writePacketId(buf, id)\n coder.encode(buf, message, this.client)\n buf.flip()\n const arr = buf.buffer.slice(0, buf.limit)\n this.push(Buffer.from(arr))\n callback()\n } else {\n callback(new Error(`Cannot find coder for message. ${JSON.stringify(message)}`))\n }\n }\n}\n\nclass MinecraftPacketEncoder extends PacketEncoder {\n protected writePacketId(bb: ByteBuffer, id: number): void {\n bb.writeByte(id)\n }\n}\n\nexport abstract class PacketOutbound extends Transform {\n protected abstract writePacketLength(bb: ByteBuffer, len: number): void\n\n constructor(private channelWidth = Number.MAX_SAFE_INTEGER, opts?: TransformOptions) {\n super(opts)\n }\n\n _transform(packet: Buffer, encoding: string, callback: TransformCallback) {\n const buffer = new ByteBuffer()\n\n this.writePacketLength(buffer, packet.length)\n buffer.append(packet)\n buffer.flip()\n\n let bytesToSend = buffer.remaining()\n while (bytesToSend > 0) {\n const toSend = Math.min(bytesToSend, this.channelWidth)\n const chunk = buffer.readBytes(toSend)\n this.push(Buffer.from(chunk.toBuffer()))\n bytesToSend -= toSend\n }\n\n callback()\n }\n}\n\nclass MinecraftPacketOutbound extends PacketOutbound {\n protected writePacketLength(bb: ByteBuffer, len: number): void {\n bb.writeVarint32(len)\n }\n}\n\nclass PacketCoders {\n packetIdCoders: { [packetId: number]: Coder<any> } = {}\n packetNameToId: { [name: string]: number } = {}\n}\n", "/* eslint-disable @typescript-eslint/no-redeclare */\nimport { TextComponent } from '@xmcl/text-component'\nimport { Channel } from './channel'\nimport { VarInt, String, Long as CLong, Short, Json } from './coders'\nimport { Packet, Field } from './packet'\n\n@Packet('client', 0x00, 'handshake')\nexport class Handshake {\n @Field(VarInt) protocolVersion!: number\n\n @Field(String) serverAddress!: string\n\n @Field(Short) serverPort!: number\n\n @Field(VarInt) nextState!: number\n}\n\n@Packet('client', 0x00, 'status')\nexport class ServerQuery { }\n\n@Packet('server', 0x00, 'status')\nexport class ServerStatus { @Field(Json) status!: Status }\n\n@Packet('client', 0x01, 'status')\nexport class Ping { @Field(CLong) time = BigInt(Date.now()) }\n\n@Packet('server', 0x01, 'status')\nexport class Pong { @Field(CLong) ping!: bigint }\n\n/**\n * The json format for Minecraft server handshake status query response\n */\nexport interface Status {\n /**\n * The version info of the server\n */\n version: {\n /**\n * The name of the version, might be standard version, like 1.14.4.\n * Or it can be modified content, just be any string the server hoster like.\n */\n name: string\n /**\n * The protocol version\n */\n protocol: number\n }\n /**\n * The player info in server\n */\n players: {\n /**\n * The server max player capacity\n */\n max: number\n /**\n * The current online player number\n */\n online: number\n /**\n * The online player info\n */\n sample?: Array<GameProfile>\n }\n /**\n * The motd of server, which might be the raw TextComponent string or structurelized TextComponent JSON\n */\n description: TextComponent | string\n /**\n * The base 64 favicon data\n */\n favicon: string | ''\n modinfo?: {\n type: string | 'FML'\n modList: Array<ForgeModIdentity>\n }\n /**\n * The ping from server\n */\n ping: number\n}\ninterface GameProfile {\n name: string\n id: string\n}\ninterface ForgeModIdentity {\n readonly modid: string\n readonly version: string\n}\n\nexport interface QueryOptions {\n /**\n * see http://wiki.vg/Protocol_version_numbers\n */\n protocol?: number\n /**\n * timeout milliseconds\n */\n timeout?: number\n retryTimes?: number\n}\n\n/**\n * Create a channel with Handleshake, ServerQuery, ServerStatus, Ping, Pong packets are registered.\n *\n * This is a lower level function for the case that you want to use channel directly\n *\n * @see {@link Channel}\n */\nexport function createChannel() {\n const channel: Channel = new Channel()\n channel.registerPacketType(Handshake)\n channel.registerPacketType(ServerQuery)\n channel.registerPacketType(ServerStatus)\n channel.registerPacketType(Ping)\n channel.registerPacketType(Pong)\n return channel\n}\n\n/**\n * Query the server status in raw JSON format in one shot.\n *\n * @param server The server information\n * @param options The query options\n */\nexport async function queryStatus(server: { host: string; port?: number }, options: QueryOptions = {}): Promise<Status> {\n const host = server.host\n const port = server.port || 25565\n const timeout = options.timeout || 4000\n const protocol = options.protocol || 498\n const retry = typeof options.retryTimes === 'number' ? options.retryTimes : 0\n\n let result: Status | undefined\n let error: Error | undefined\n\n const channel: Channel = createChannel()\n\n for (let retryTimes = retry + 1; retryTimes > 0; retryTimes--) {\n try {\n result = await query(channel, host, port, timeout, protocol)\n break\n } catch (e) {\n error = e as Error\n }\n }\n if (result) {\n return result\n }\n throw error\n}\n\n/**\n * Create a query client for certain protocol and timeout setting.\n * @param protocol The protocol number\n * @param timeout The timeout millisecond\n */\nexport function createClient(protocol: number, timeout?: number) {\n const channel: Channel = createChannel()\n return {\n get channel() { return channel },\n set protocol(v: number) { protocol = v },\n get protocol() { return protocol },\n query(host: string, port = 25565) {\n return query(channel, host, port, timeout || 4000, protocol)\n },\n }\n}\n\nasync function query(channel: Channel, host: string, port: number, timeout: number, protocol: number) {\n await channel.listen({\n host,\n port,\n timeout,\n })\n const { status } = await new Promise<ServerStatus>((resolve, reject) => {\n channel.oncePacket(ServerStatus, (e) => {\n resolve(e)\n })\n channel.once('error', reject)\n try {\n channel.send(new Handshake(), {\n protocolVersion: protocol,\n serverAddress: host,\n serverPort: port,\n nextState: 1,\n })\n channel.state = 'status'\n channel.send(new ServerQuery())\n setTimeout(() => {\n reject(new Error('Timeout'))\n }, timeout * 10)\n } catch (e) {\n reject(e)\n }\n })\n\n const { ping } = await new Promise<Pong>((resolve, reject) => {\n channel.once<Pong>('packet:Pong', (e) => {\n resolve(e)\n })\n channel.once('error', reject)\n try {\n channel.send(new Ping())\n } catch (e) {\n reject(e)\n }\n })\n status.ping = Number(BigInt(Date.now()) - ping)\n\n await channel.disconnect()\n\n return status\n}\n", "import { Socket, createSocket, RemoteInfo } from 'dgram'\nimport { EventEmitter } from 'events'\n\nexport const LAN_MULTICAST_ADDR = '224.0.2.60'\nexport const LAN_MULTICAST_ADDR_V6 = 'FF75:230::60'\nexport const LAN_MULTICAST_PORT = 4445\n\nexport interface MinecraftLanDiscover {\n on(channel: 'discover', listener: (event: LanServerInfo & { remote: RemoteInfo }) => void): this\n once(channel: 'discover', listener: (event: LanServerInfo & { remote: RemoteInfo }) => void): this\n addListener(channel: 'discover', listener: (event: LanServerInfo & { remote: RemoteInfo }) => void): this\n removeListener(channel: 'discover', listener: (event: LanServerInfo & { remote: RemoteInfo }) => void): this\n}\n\nexport class MinecraftLanDiscover extends EventEmitter {\n readonly socket: Socket\n\n #ready = false\n #group: string\n\n get isReady() {\n return this.#ready\n }\n\n constructor(type: 'udp4' | 'udp6' = 'udp4') {\n super()\n const sock = createSocket({ type, reuseAddr: true })\n\n this.#group = type === 'udp4' ? LAN_MULTICAST_ADDR : LAN_MULTICAST_ADDR_V6\n\n sock.on('listening', () => {\n const address = sock.address()\n sock.addMembership(this.#group, type === 'udp4' ? address.address : undefined)\n sock.setMulticastTTL(128)\n sock.setBroadcast(true)\n this.#ready = true\n })\n\n sock.on('message', (buf, remote) => {\n const content = buf.toString('utf-8')\n\n const motdRegx = /\\[MOTD\\](.+)\\[\\/MOTD\\]/g\n const portRegx = /\\[AD\\](.+)\\[\\/AD\\]/g\n\n const portResult = portRegx.exec(content)\n if (!portResult || !portResult[1]) {\n // emit error\n } else {\n const motd = motdRegx.exec(content)?.[1] ?? ''\n const port = Number.parseInt(portResult[1])\n this.emit('discover', { motd, port, remote })\n }\n })\n\n this.socket = sock\n }\n\n broadcast(inf: LanServerInfo) {\n return new Promise<number>((resolve, reject) => {\n this.socket.send(`[MOTD]${inf.motd}[/MOTD][AD]${inf.port}[/AD]`, LAN_MULTICAST_PORT, this.#group, (err, bytes) => {\n if (err) reject(err)\n else resolve(bytes)\n })\n })\n }\n\n bind(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.socket.bind(LAN_MULTICAST_PORT, () => {\n resolve()\n }).once('error', (e) => {\n reject(e)\n })\n })\n }\n\n destroy(): Promise<void> {\n return new Promise((resolve) => {\n this.socket.close(resolve)\n })\n }\n}\n\nexport interface LanServerInfo {\n motd: string\n port: number\n}\n"], "mappings": "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", "names": ["d", "EventEmitter"] }