Relay proxy fixes, handle disconnect

This commit is contained in:
extremeheat 2021-06-18 14:49:06 -04:00
commit 3f5c4ad12e
4 changed files with 20 additions and 26 deletions

View file

@ -38,13 +38,15 @@ Want to contribute on something important for PrismarineJS ? go to https://githu
### Client example
Example to connect to a server in offline mode, and relay chat messages back:
```js
const bedrock = require('bedrock-protocol')
const client = bedrock.createClient({
host: 'localhost', // optional
port: 19132, // optional, default 19132
username: 'Notch', // the username you want to join as, optional if online mode
offline: true // optional, default false. if true, do not login with Xbox Live. You will not be asked to sign-in if set to true.
offline: true, // optional, default false. if true, do not login with Xbox Live. You will not be asked to sign-in if set to true.
// Optional for some servers which verify the title ID:
// authTitle: bedrock.title.MinecraftNintendoSwitch
})

View file

@ -37,13 +37,15 @@ class RelayPlayer extends Player {
// Called when we get a packet from backend server (Backend -> PROXY -> Client)
readUpstream (packet) {
if (!this.startRelaying) {
this.upInLog('Client not ready, queueing packet until join')
this.downQ.push(packet)
return
}
this.upInLog('->', packet)
const des = this.server.deserializer.parsePacketBuffer(packet)
const name = des.data.name
const params = des.data.params
this.upInLog('->', name, params)
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
@ -51,31 +53,12 @@ class RelayPlayer extends Player {
}
this.emit('clientbound', des.data)
// If we're sending a chunk, but player isn't yet initialized, wait until it is.
// This is wrong and should not be an issue to send chunks before the client
// is in the world; need to investigate further, but for now it's fine.
if (this.status !== 3) {
if (name === 'level_chunk') {
this.chunkSendCache.push([name, params])
return
}
if (name === 'respawn') this.respawnPacket.push([name, params])
} else if (this.status === 3 && this.chunkSendCache.length) {
for (const chunk of this.chunkSendCache) {
this.queue(...chunk)
}
for (const rp of this.respawnPacket) {
this.queue(...rp)
}
this.chunkSendCache = []
this.respawnPacket = []
}
this.queue(name, params)
}
// Send queued packets to the connected client
flushDownQueue () {
this.downOutLog('Flushing downstream queue')
for (const packet of this.downQ) {
const des = this.server.deserializer.parsePacketBuffer(packet)
this.write(des.data.name, des.data.params)
@ -85,10 +68,11 @@ class RelayPlayer extends Player {
// Send queued packets to the backend upstream server from the client
flushUpQueue () {
this.upOutLog('Flushing upstream queue')
for (const e of this.upQ) { // Send the queue
const des = this.server.deserializer.parsePacketBuffer(e)
if (des.data.name === 'client_cache_status') { // Currently broken, force off the chunk cache
this.upstream.write('client_cache_status', { enabled: false })
// this.upstream.write('client_cache_status', { enabled: false })
} else {
this.upstream.write(des.data.name, des.data.params)
}
@ -127,7 +111,7 @@ class RelayPlayer extends Player {
break
case 'set_local_player_as_initialized':
this.status = 3
break
// falls through
default:
// Emit the packet as-is back to the upstream server
this.downInLog('Relaying', des.data)
@ -137,6 +121,11 @@ class RelayPlayer extends Player {
super.readPacket(packet)
}
}
close (reason) {
this.upstream.close(reason)
super.close(reason)
}
}
class Relay extends Server {
@ -196,6 +185,7 @@ class Relay extends Server {
this.conLog('dropping connection as single client relay', conn)
conn.close()
} else {
this.clientCount++
const player = new this.RelayPlayer(this, conn)
this.conLog('New connection from', conn.address)
this.clients[conn.address] = player

View file

@ -46,7 +46,7 @@ class Server extends EventEmitter {
onCloseConnection = (inetAddr, reason) => {
this.conLog('close connection', inetAddr?.address, reason)
delete this.clients[inetAddr]?.connection // Prevent close loop
this.clients[inetAddr]?.close()
this.clients[inetAddr?.address ?? inetAddr]?.close()
delete this.clients[inetAddr]
this.clientCount--
}

View file

@ -2,6 +2,7 @@ const { ClientStatus, Connection } = require('./connection')
const fs = require('fs')
const Options = require('./options')
const debug = require('debug')('minecraft-protocol')
// const { serialize } = require('./datatypes/util')
const { KeyExchange } = require('./handshake/keyExchange')
const Login = require('./handshake/login')
@ -110,7 +111,7 @@ class Player extends Connection {
close (reason) {
if (this.status !== ClientStatus.Disconnected) {
this.emit('close') // Emit close once
if (!reason) console.trace('Client closed connection', this.connection?.address)
if (!reason) this.inLog('Client closed connection', this.connection?.address)
}
this.q = []
this.q2 = []
@ -130,6 +131,7 @@ class Player extends Connection {
return
}
// this.inLog(des.data.name, serialize(des.data.params).slice(0, 200))
switch (des.data.name) {
case 'login':
this.onLogin(des)