From a1698d712fe7083e31ffd9e5f8ecc03dece50ddb Mon Sep 17 00:00:00 2001 From: extremeheat Date: Fri, 31 Dec 2021 15:18:46 +0000 Subject: [PATCH] relay: fix empty chunk loading issues, make chunk caching optional --- index.d.ts | 6 +++++- src/relay.js | 32 ++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/index.d.ts b/index.d.ts index 5b0c8c2..a14500d 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,7 +1,7 @@ import EventEmitter from "events" declare module "bedrock-protocol" { - type Version = '1.18.1' | '1.18.0' | '1.17.41' | '1.17.40' | '1.17.34' | '1.17.30' | '1.17.11' | '1.17.10' | '1.17.0' | '1.16.220' | '1.16.210' | '1.16.201' + type Version = '1.18.2' | '1.18.1' | '1.18.0' | '1.17.41' | '1.17.40' | '1.17.34' | '1.17.30' | '1.17.11' | '1.17.10' | '1.17.0' | '1.16.220' | '1.16.210' | '1.16.201' enum title { MinecraftNintendoSwitch, MinecraftJava } @@ -34,6 +34,8 @@ declare module "bedrock-protocol" { connectTimeout?: number // whether to skip initial ping and immediately connect skipPing?: boolean + // where to log connection information to (default to console.log) + conLog? } export interface ServerOptions extends Options { @@ -149,6 +151,8 @@ declare module "bedrock-protocol" { // Skip authentication connecting to the remote server? offline: false, } + // Whether to enable chunk caching (default: false) + enableChunkCaching?: boolean } export class Relay extends Server { diff --git a/src/relay.js b/src/relay.js index b78662f..6aac5a3 100644 --- a/src/relay.js +++ b/src/relay.js @@ -31,6 +31,7 @@ class RelayPlayer extends Player { this.outLog = this.downOutLog this.inLog = this.downInLog this.chunkSendCache = [] + this.sentStartGame = false this.respawnPacket = [] } @@ -52,8 +53,25 @@ class RelayPlayer extends Player { this.server.deserializer.verify(des, this.server.serializer) } - this.emit('clientbound', des.data) - this.queue(name, params) + this.emit('clientbound', des.data, des) + + if (!des.canceled) { + if (name === 'start_game') { + this.sentStartGame = true + } else if (name === 'level_chunk' && !this.sentStartGame) { + this.chunkSendCache.push(params) + return + } + + this.queue(name, params) + } + + if (this.chunkSendCache.length > 0 && this.sentStartGame) { + for (const entry of this.chunkSendCache) { + this.queue('level_chunk', entry) + } + this.chunkSendCache = [] + } } // Send queued packets to the connected client @@ -102,16 +120,17 @@ class RelayPlayer extends Player { this.server.deserializer.verify(des, this.server.serializer) } - this.emit('serverbound', des.data) + this.emit('serverbound', des.data, des) + if (des.canceled) return switch (des.data.name) { case 'client_cache_status': // Force the chunk cache off. - this.upstream.queue('client_cache_status', { enabled: false }) + this.upstream.queue('client_cache_status', { enabled: this.enableChunkCaching }) break case 'set_local_player_as_initialized': this.status = 3 - // falls through + // falls through default: // Emit the packet as-is back to the upstream server this.downInLog('Relaying', des.data) @@ -139,6 +158,7 @@ class Relay extends Server { this.forceSingle = true this.upstreams = new Map() this.conLog = debug + this.enableChunkCaching = options.enableChunkCaching } // Called after a new player joins our proxy. We first create a new Client to connect to @@ -167,7 +187,7 @@ class Relay extends Server { // Tell the server to disable chunk cache for this connection as a client. // Wait a bit for the server to ack and process, the continue with proxying // otherwise the player can get stuck in an empty world. - client.write('client_cache_status', { enabled: false }) + client.write('client_cache_status', { enabled: this.enableChunkCaching }) ds.upstream = client ds.flushUpQueue() this.conLog('Connected to upstream server')