Relay proxy fixes, handle disconnect
This commit is contained in:
parent
565ae4583d
commit
3f5c4ad12e
4 changed files with 20 additions and 26 deletions
|
|
@ -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
|
||||
})
|
||||
|
|
|
|||
36
src/relay.js
36
src/relay.js
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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--
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue