UNPKG

@hazae41/kcp

Version:

Zero-copy KCP protocol for the web

1 lines 6.95 kB
{"version":3,"file":"reader.mjs","sources":["../../../../src/mods/kcp/reader.ts"],"sourcesContent":["import { Empty, Opaque, Readable } from \"@hazae41/binary\";\nimport { Cursor } from \"@hazae41/cursor\";\nimport { Console } from \"mods/console/index.js\";\nimport { KcpSegment } from \"./segment.js\";\nimport { SecretKcpDuplex } from \"./stream.js\";\n\nexport type KcpReadError =\n | ExpectedKcpSegmentError\n | UnknownKcpCommandError\n\nexport class ExpectedKcpSegmentError extends Error {\n readonly #class = ExpectedKcpSegmentError\n readonly name = this.#class.name\n\n constructor() {\n super(`Expected a KCP segment`)\n }\n\n}\n\nexport class UnknownKcpCommandError extends Error {\n readonly #class = UnknownKcpCommandError\n readonly name = this.#class.name\n\n constructor() {\n super(`Unknown KCP command`)\n }\n\n}\n\nexport type SecretKcpReaderEvents = {\n ack: (segment: KcpSegment<Opaque>) => void\n}\n\nexport class SecretKcpReader {\n\n readonly #buffer = new Map<number, KcpSegment<Opaque>>()\n\n constructor(\n readonly parent: SecretKcpDuplex\n ) { }\n\n async onWrite(chunk: Opaque) {\n const cursor = new Cursor(chunk.bytes)\n\n while (cursor.remaining)\n await this.#onSegment(Readable.readOrRollbackAndThrow(KcpSegment, cursor))\n\n return\n }\n\n async #onSegment(segment: KcpSegment<Opaque>) {\n if (segment.conversation !== this.parent.conversation)\n return\n\n if (segment.command === KcpSegment.commands.push)\n return await this.#onPushSegment(segment)\n if (segment.command === KcpSegment.commands.ack)\n return await this.#onAckSegment(segment)\n if (segment.command === KcpSegment.commands.wask)\n return await this.#onWaskSegment(segment)\n\n throw new UnknownKcpCommandError()\n }\n\n async #onPushSegment(segment: KcpSegment<Opaque>) {\n const conversation = this.parent.conversation\n const command = KcpSegment.commands.ack\n const timestamp = segment.timestamp\n const serial = segment.serial\n const unackSerial = this.parent.recvCounter\n const fragment = new Empty()\n\n const ack = KcpSegment.empty({ conversation, command, timestamp, serial, unackSerial, fragment })\n\n this.parent.output.enqueue(ack)\n\n if (segment.serial < this.parent.recvCounter) {\n Console.debug(`Received previous KCP segment`)\n return\n }\n\n if (segment.serial > this.parent.recvCounter) {\n Console.debug(`Received next KCP segment`)\n this.#buffer.set(segment.serial, segment)\n return\n }\n\n this.parent.input.enqueue(segment.fragment)\n\n this.parent.recvCounter++\n\n let next: KcpSegment<Opaque> | undefined\n\n while (next = this.#buffer.get(this.parent.recvCounter)) {\n Console.debug(`Unblocked next KCP segment`)\n\n this.parent.input.enqueue(next.fragment)\n this.#buffer.delete(this.parent.recvCounter)\n\n this.parent.recvCounter++\n }\n }\n\n async #onAckSegment(segment: KcpSegment<Opaque>) {\n const future = this.parent.resolveOnAckBySerial.get(segment.serial)\n\n if (future == null)\n return\n this.parent.resolveOnAckBySerial.delete(segment.serial)\n\n future.resolve()\n }\n\n async #onWaskSegment(segment: KcpSegment<Opaque>) {\n const conversation = this.parent.conversation\n const command = KcpSegment.commands.wins\n const serial = 0\n const unackSerial = this.parent.recvCounter\n const fragment = new Empty()\n\n const wins = KcpSegment.empty({ conversation, command, serial, unackSerial, fragment })\n\n this.parent.output.enqueue(wins)\n }\n\n}"],"names":[],"mappings":"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"}