Fix relay, cleanup
This commit is contained in:
parent
1538c3fc03
commit
5ea8056e04
5 changed files with 25 additions and 62 deletions
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
|
||||
|
|
|
|||
44
src/relay.js
44
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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue