diff --git a/examples/createRelay.js b/examples/createRelay.js index d3b76ad..78eb4d3 100644 --- a/examples/createRelay.js +++ b/examples/createRelay.js @@ -2,36 +2,18 @@ const { Relay } = require('../src/relay') function createRelay () { console.log('Creating relay') - /** - * Example to create a non-transparent proxy (or 'Relay') connection to destination server - * In Relay we de-code and re-encode packets - */ + /* Example to create a non-transparent proxy (or 'Relay') connection to destination server */ const relay = new Relay({ /* Hostname and port for clients to listen to */ hostname: '0.0.0.0', port: 19130, - /** - * Who does the authentication - * If set to `client`, all connecting clients will be sent a message with a link to authenticate - * If set to `server`, the server will authenticate and only one client will be able to join - * (Default) If set to `none`, no authentication will be done - */ - auth: 'server', - - /** - * Sets if packets will automatically be forwarded. If set to false, you must listen for on('packet') - * events and - */ - auto: true, - /* Where to send upstream packets to */ destination: { hostname: '127.0.0.1', port: 19132 - // encryption: true } }) - + relay.conLog = console.debug relay.listen() } diff --git a/src/rak.js b/src/rak.js index 141dc71..930bc8a 100644 --- a/src/rak.js +++ b/src/rak.js @@ -80,8 +80,6 @@ class RakNativeServer extends EventEmitter { this.raknet.setOfflineMessage(server.getAdvertisement().toBuffer()) } - // TODO: periodically update the server name until we're closed - this.raknet.on('openConnection', (client) => { client.sendReliable = function (buffer, immediate) { const priority = immediate ? PacketPriority.IMMEDIATE_PRIORITY : PacketPriority.MEDIUM_PRIORITY @@ -91,8 +89,6 @@ class RakNativeServer extends EventEmitter { }) this.raknet.on('closeConnection', (client) => { - console.warn('! Client closed connection') - // TODO: need to handle this properly.. this.onCloseConnection(client) }) diff --git a/src/relay.js b/src/relay.js index 813ec05..70e0023 100644 --- a/src/relay.js +++ b/src/relay.js @@ -1,9 +1,7 @@ -// process.env.DEBUG = 'minecraft-protocol raknet' const { Client } = require('./client') const { Server } = require('./server') const { Player } = require('./serverPlayer') -const debug = globalThis.isElectron ? console.debug : require('debug')('minecraft-protocol relay') -// const { serialize } = require('./datatypes/util') +const debug = globalThis.isElectron ? console.debug : require('debug')('minecraft-protocol') /** @typedef {{ hostname: string, port: number, auth: 'client' | 'server' | null, destination?: { hostname: string, port: number } }} Options */ @@ -22,10 +20,10 @@ class RelayPlayer extends Player { }) this.downQ = [] this.upQ = [] - this.upInLog = (...msg) => console.debug('** Backend -> Proxy', ...msg) - this.upOutLog = (...msg) => console.debug('** Proxy -> Backend', ...msg) - this.downInLog = (...msg) => console.debug('** Client -> Proxy', ...msg) - this.downOutLog = (...msg) => console.debug('** Proxy -> Client', ...msg) + this.upInLog = (...msg) => console.debug('* Backend -> Proxy', ...msg) + this.upOutLog = (...msg) => console.debug('* Proxy -> Backend', ...msg) + this.downInLog = (...msg) => console.debug('* Client -> Proxy', ...msg) + this.downOutLog = (...msg) => console.debug('* Proxy -> Client', ...msg) if (!server.options.logging) { this.upInLog = () => { } @@ -34,13 +32,6 @@ class RelayPlayer extends Player { this.downOutLog = () => { } } - // this.upOutLog = (...msg) => { - // if (msg.includes('player_auth_input')) { - // // stream.write(msg) - // console.info('INPUT', msg) - // } - // } - this.outLog = this.downOutLog this.inLog = this.downInLog } @@ -48,21 +39,18 @@ class RelayPlayer extends Player { // Called when we get a packet from backend server (Backend -> PROXY -> Client) readUpstream (packet) { if (!this.startRelaying) { - console.warn('The downstream client is not ready yet !!') this.downQ.push(packet) return } - // this.upInLog('Recv packet', packet) + this.upInLog('->', packet) const des = this.server.deserializer.parsePacketBuffer(packet) const name = des.data.name const params = des.data.params - // this.upInLog('~ Bounce B->C', name, serialize(params).slice(0, 100)) - // this.upInLog('~ ', des.buffer) if (name === 'play_status' && params.status === 'login_success') return // We already sent this, this needs to be sent ASAP or client will disconnect if (debugging) { // some packet encode/decode testing stuff const rpacket = this.server.serializer.createPacketBuffer({ name, params }) - if (rpacket.toString('hex') !== packet.toString('hex')) { + if (!rpacket.equals(packet)) { console.warn('New', rpacket.toString('hex')) console.warn('Old', packet.toString('hex')) console.log('Failed to re-encode', name, params) @@ -71,8 +59,6 @@ class RelayPlayer extends Player { } this.queue(name, params) - // this.sendBuffer(packet) - this.emit('clientbound', des.data) } @@ -107,7 +93,7 @@ class RelayPlayer extends Player { return } this.flushUpQueue() // Send queued packets - // this.downInLog('Recv packet', packet) + this.downInLog('recv', packet) // TODO: If we fail to parse a packet, proxy it raw and log an error const des = this.server.deserializer.parsePacketBuffer(packet) @@ -127,7 +113,6 @@ class RelayPlayer extends Player { break default: // Emit the packet as-is back to the upstream server - // this.upstream.queue(des.data.name, des.data.params) this.downInLog('Relaying', des.data) this.upstream.sendBuffer(packet) } @@ -148,6 +133,7 @@ class Relay extends Server { this.RelayPlayer = options.relayPlayer || RelayPlayer this.forceSingle = true this.upstreams = new Map() + this.conLog = debug } openUpstreamConnection (ds, clientAddr) { @@ -157,13 +143,14 @@ class Relay extends Server { encrypt: this.options.encrypt, autoInitPlayer: false }) + client.connect() + console.log('CONNECTING TO', this.options.destination.hostname, this.options.destination.port) client.outLog = ds.upOutLog client.inLog = ds.upInLog - // console.log('Set upstream logs', client.outLog, client.inLog) client.once('join', () => { // Intercept once handshaking done ds.upstream = client ds.flushUpQueue() - console.log('Connected to upstream server') + this.conLog('Connected to upstream server') client.readPacket = (packet) => ds.readUpstream(packet) this.emit('join', /* client connected to proxy */ ds, /* backend server */ client) @@ -176,17 +163,16 @@ class Relay extends Server { if (!up) throw Error(`unable to close non-open connection ${clientAddr.hash}`) up.close() this.upstreams.delete(clientAddr.hash) - debug('relay closed connection', clientAddr) + this.conLog('closed upstream connection', clientAddr) } onOpenConnection = (conn) => { - debug('new connection', conn) if (this.forceSingle && this.clientCount > 0) { - debug('dropping connection as single client relay', conn) + this.conLog('dropping connection as single client relay', conn) conn.close() } else { const player = new this.RelayPlayer(this, conn) - console.debug('New connection from', conn.address) + this.conLog('New connection from', conn.address) this.clients[conn.address] = player this.emit('connect', player) this.openUpstreamConnection(player, conn.address) diff --git a/src/server.js b/src/server.js index 4c7551a..a953c39 100644 --- a/src/server.js +++ b/src/server.js @@ -21,11 +21,12 @@ class Server extends EventEmitter { this.clientCount = 0 this.inLog = (...args) => debug('S ->', ...args) this.outLog = (...args) => debug('S <-', ...args) + this.conLog = debug } validateOptions () { if (!Options.Versions[this.options.version]) { - console.warn('Supported versions: ', Options.Versions) + console.warn('Supported versions', Options.Versions) throw Error(`Unsupported version ${this.options.version}`) } this.options.protocolVersion = Options.Versions[this.options.version] @@ -35,7 +36,7 @@ class Server extends EventEmitter { } onOpenConnection = (conn) => { - console.debug('new connection', conn?.address) + this.conLog('new connection', conn?.address) const player = new Player(this, conn) this.clients[conn.address] = player this.clientCount++ @@ -43,7 +44,7 @@ class Server extends EventEmitter { } onCloseConnection = (inetAddr, reason) => { - console.debug('close connection', inetAddr?.address, reason) + this.conLog('close connection', inetAddr?.address, reason) delete this.clients[inetAddr]?.connection // Prevent close loop this.clients[inetAddr]?.close() delete this.clients[inetAddr] @@ -75,7 +76,7 @@ class Server extends EventEmitter { console.warn(`Failed to bind server on [${this.options.hostname}]/${this.options.port}, is the port free?`) throw e } - console.debug('Listening on', hostname, port, this.options.version) + this.conLog('Listening on', hostname, port, this.options.version) this.raknet.onOpenConnection = this.onOpenConnection this.raknet.onCloseConnection = this.onCloseConnection this.raknet.onEncapsulated = this.onEncapsulated diff --git a/src/transforms/framer.js b/src/transforms/framer.js index 7df557a..38d04c4 100644 --- a/src/transforms/framer.js +++ b/src/transforms/framer.js @@ -4,7 +4,7 @@ const zlib = require('zlib') // Concatenates packets into one batch packet, and adds length prefixs. class Framer { constructor () { - // Decoding + // Encoding this.packets = [] this.compressionLevel = 7 } @@ -15,10 +15,8 @@ class Framer { // Decode the payload zlib.inflateRaw(buf.slice(1), { chunkSize: 1024 * 1024 * 2 }, (err, inflated) => { - if (err) { - throw err - // console.error(err) - } else cb(Framer.getPackets(inflated)) + if (err) throw err + cb(Framer.getPackets(inflated)) }) }