Fix relay, cleanup

This commit is contained in:
extremeheat 2021-04-20 09:50:12 -04:00
commit 5ea8056e04
5 changed files with 25 additions and 62 deletions

View file

@ -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)
})

View file

@ -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)

View file

@ -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

View file

@ -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))
})
}