import { options } from './optionsStorage' //@ts-check const { EventEmitter } = require('events') const debug = require('debug')('minecraft-protocol') const states = require('minecraft-protocol/src/states') window.serverDataChannel ??= {} export const customCommunication = { sendData (data) { setTimeout(() => { window.serverDataChannel[this.isServer ? 'emitClient' : 'emitServer'](data) }) }, receiverSetup (processData) { window.serverDataChannel[this.isServer ? 'emitServer' : 'emitClient'] = (data) => { processData(data) } } } class CustomChannelClient extends EventEmitter { constructor (isServer, version) { super() this.version = version this.isServer = !!isServer this.state = states.HANDSHAKING } get state () { return this.protocolState } setSerializer (state) { customCommunication.receiverSetup.call(this, (/** @type {{name, params, state?}} */parsed) => { if (!options.excludeCommunicationDebugEvents.includes(parsed.name)) { debug(`receive in ${this.isServer ? 'server' : 'client'}: ${parsed.name}`) } this.emit(parsed.name, parsed.params, parsed) this.emit('packet_name', parsed.name, parsed.params, parsed) }) } // eslint-disable-next-line @typescript-eslint/adjacent-overload-signatures, grouped-accessor-pairs set state (newProperty) { const oldProperty = this.protocolState this.protocolState = newProperty this.setSerializer(this.protocolState) this.emit('state', newProperty, oldProperty) } end (reason) { this._endReason = reason this.emit('end', this._endReason) // still emits on server side only, doesn't send anything to our client } write (name, params) { if(!options.excludeCommunicationDebugEvents.includes(name)) { debug(`[${this.state}] from ${this.isServer ? 'server' : 'client'}: ` + name) debug(params) } this.emit('writePacket', name, params) customCommunication.sendData.call(this, { name, params, state: this.state }) } writeBundle (packets) { // no-op } writeRaw (buffer) { // no-op } } export default CustomChannelClient