From 7057ad979b416192ada235f2f4e3b5eb26af5fa1 Mon Sep 17 00:00:00 2001 From: extremeheat Date: Sat, 13 Jul 2024 17:03:33 -0400 Subject: [PATCH] Fix realms loading issue due to createClient plugin init order (#1303) * Fix realms loading issue due to createClient plugin init order * remove exception on bad parse of disconnect * Update index.d.ts * Improve serverTest check logic try and debug flaky tests --- src/client/versionChecking.js | 1 - src/createClient.js | 25 +++++++---- src/index.d.ts | 15 ++++++- test/serverTest.js | 83 ++++++++++++++++++++++++----------- 4 files changed, 87 insertions(+), 37 deletions(-) diff --git a/src/client/versionChecking.js b/src/client/versionChecking.js index ab9833fd..41854420 100644 --- a/src/client/versionChecking.js +++ b/src/client/versionChecking.js @@ -10,7 +10,6 @@ module.exports = function (client, options) { try { parsed = JSON.parse(message.reason) } catch (error) { - client.emit('error', error) return } let text = parsed.text ? parsed.text : parsed diff --git a/src/createClient.js b/src/createClient.js index 10cacc07..912e331e 100644 --- a/src/createClient.js +++ b/src/createClient.js @@ -39,17 +39,20 @@ function createClient (options) { tcpDns(client, options) if (options.auth instanceof Function) { options.auth(client, options) + onReady() } else { switch (options.auth) { case 'mojang': console.warn('[deprecated] mojang auth servers no longer accept mojang accounts to login. convert your account.\nhttps://help.minecraft.net/hc/en-us/articles/4403181904525-How-to-Migrate-Your-Mojang-Account-to-a-Microsoft-Account') auth(client, options) + onReady() break case 'microsoft': if (options.realms) { - microsoftAuth.realmAuthenticate(client, options).then(() => microsoftAuth.authenticate(client, options)).catch((err) => client.emit('error', err)) + microsoftAuth.realmAuthenticate(client, options).then(() => microsoftAuth.authenticate(client, options)).catch((err) => client.emit('error', err)).then(onReady) } else { microsoftAuth.authenticate(client, options).catch((err) => client.emit('error', err)) + onReady() } break case 'offline': @@ -58,17 +61,21 @@ function createClient (options) { client.uuid = uuid.nameToMcOfflineUUID(client.username) options.auth = 'offline' options.connect(client) + onReady() break } } - if (options.version === false) autoVersion(client, options) - setProtocol(client, options) - keepalive(client, options) - encrypt(client, options) - play(client, options) - compress(client, options) - pluginChannels(client, options) - versionChecking(client, options) + + function onReady () { + if (options.version === false) autoVersion(client, options) + setProtocol(client, options) + keepalive(client, options) + encrypt(client, options) + play(client, options) + compress(client, options) + pluginChannels(client, options) + versionChecking(client, options) + } return client } diff --git a/src/index.d.ts b/src/index.d.ts index 70b86cc4..42308525 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -49,7 +49,20 @@ declare module 'minecraft-protocol' { on(event: 'connect', handler: () => PromiseLike): this on(event: string, handler: (data: any, packetMeta: PacketMeta) => PromiseLike): this on(event: `raw.${string}`, handler: (buffer: Buffer, packetMeta: PacketMeta) => PromiseLike): this - on(event: 'playerChat', handler: (data: { formattedMessage: string, plainMessage: string, type: string, sender: string, senderName: string, senderTeam: string, verified?: boolean }) => PromiseLike): this + on(event: 'playerChat', handler: (data: { + // (JSON string) The chat message preformatted, if done on server side + formattedMessage: string, + // (Plaintext) The chat message without formatting (for example no ` message` ; instead `message`), on version 1.19+ + plainMessage: string, + // (JSON string) Unsigned formatted chat contents. Should only be present when the message is modified and server has chat previews disabled. Only on versions 1.19.0, 1.19.1 and 1.19.2 + unsignedContent?: string, + type: string, + sender: string, + senderName: string, + senderTeam: string, + targetName: string, + verified?: boolean + }) => PromiseLike): this on(event: 'systemChat', handler: (data: { positionId: number, formattedMessage: string }) => PromiseLike): this // Emitted after the player enters the PLAY state and can send and recieve game packets on(event: 'playerJoin', handler: () => void): this diff --git a/test/serverTest.js b/test/serverTest.js index b2f67105..f4105975 100644 --- a/test/serverTest.js +++ b/test/serverTest.js @@ -126,23 +126,30 @@ for (const supportedVersion of mc.supportedVersions) { version: version.minecraftVersion, port: PORT }) - let count = 2 + let serverClosed, clientClosed server.on('connection', function (client) { client.on('end', function (reason) { assert.strictEqual(reason, 'LoginTimeout') server.close() }) }) - server.on('close', resolve) + server.on('close', () => { + serverClosed = true + console.log('Server closed') + checkFinish() + }) server.on('listening', function () { const client = new mc.Client(false, version.minecraftVersion) - client.on('end', resolve) + client.on('end', () => { + clientClosed = true + console.log('Client closed') + checkFinish() + }) client.connect(PORT, '127.0.0.1') }) - function resolve () { - count -= 1 - if (count <= 0) done() + function checkFinish () { + if (serverClosed && clientClosed) done() } }) @@ -154,14 +161,19 @@ for (const supportedVersion of mc.supportedVersions) { version: version.minecraftVersion, port: PORT }) - let count = 2 + let serverClosed, clientClosed server.on('connection', function (client) { client.on('end', function (reason) { assert.strictEqual(reason, 'KeepAliveTimeout') + console.log('Server client disconnected') server.close() }) }) - server.on('close', resolve) + server.on('close', () => { + serverClosed = true + console.log('Server closed') + checkFinish() + }) server.on('listening', function () { const client = mc.createClient({ username: 'superpants', @@ -170,11 +182,14 @@ for (const supportedVersion of mc.supportedVersions) { keepAlive: false, version: version.minecraftVersion }) - client.on('end', resolve) + client.on('end', () => { + clientClosed = true + console.log('Client closed') + checkFinish() + }) }) - function resolve () { - count -= 1 - if (count <= 0) done() + function checkFinish () { + if (serverClosed && clientClosed) done() } }) @@ -363,27 +378,36 @@ for (const supportedVersion of mc.supportedVersions) { version: version.minecraftVersion, port: PORT }) - let count = 4 + let serverPlayerDisconnected, serverClosed, clientClosed server.on('connection', function (client) { client.on('end', function (reason) { - resolve() + serverPlayerDisconnected = true + console.log('Server player disconnected') + checkFinish() server.close() }) }) - server.on('close', resolve) + server.on('close', () => { + serverClosed = true + console.log('Server closed') + checkFinish() + }) server.on('listening', function () { - resolve() + console.log('Server is listening') const client = mc.createClient({ username: 'lalalal', host: '127.0.0.1', version: version.minecraftVersion, port: PORT }) - client.on('end', resolve) + client.on('end', () => { + clientClosed = true + console.log('Client closed') + checkFinish() + }) }) - function resolve () { - count -= 1 - if (count <= 0) done() + function checkFinish () { + if (serverPlayerDisconnected && clientClosed && serverClosed) done() } }) @@ -393,15 +417,22 @@ for (const supportedVersion of mc.supportedVersions) { version: version.minecraftVersion, port: PORT }) - let count = 2 + let serverPlayerDisconnected, serverClosed server.on('playerJoin', function (client) { + console.log('Server got player join') client.on('end', function (reason) { assert.strictEqual(reason, 'ServerShutdown') - resolve() + serverPlayerDisconnected = true + console.log('Server player disconnected') + checkFinish() }) client.write('login', loginPacket(client, server)) }) - server.on('close', resolve) + server.on('close', () => { + serverClosed = true + console.log('Server closed') + checkFinish() + }) server.on('listening', function () { const client = mc.createClient({ username: 'lalalal', @@ -410,12 +441,12 @@ for (const supportedVersion of mc.supportedVersions) { port: PORT }) client.on('playerJoin', function () { + console.log('Client joined') server.close() }) }) - function resolve () { - count -= 1 - if (count <= 0) done() + function checkFinish () { + if (serverPlayerDisconnected && serverClosed) done() } })