From 1ee16fe201ec19d9fcebaf656568c5d6d0fd40d4 Mon Sep 17 00:00:00 2001 From: AChompSitsIn <114684575+AChompSitsIn@users.noreply.github.com> Date: Sat, 27 Jun 2026 01:19:01 -0700 Subject: [PATCH 1/2] Send client settings during configuration phase (fixes mineflayer#3623) --- src/client/play.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/client/play.js b/src/client/play.js index 71ad739f..56c14f42 100644 --- a/src/client/play.js +++ b/src/client/play.js @@ -53,6 +53,20 @@ module.exports = function (client, options) { client.write('configuration_acknowledged', {}) } client.state = states.CONFIGURATION + // Mirror the vanilla client, which sends Client Information during the + // configuration phase. Some servers (e.g. Hypixel) wait for it before + // sending finish_configuration and close the socket otherwise. Must be + // after the CONFIGURATION state flip so it serializes correctly. (#3623) + client.write('settings', { + locale: 'en_us', + viewDistance: 10, + chatFlags: 0, + chatColors: true, + skinParts: 127, + mainHand: 1, + enableTextFiltering: false, + enableServerListing: true + }) client.once('select_known_packs', () => { client.write('select_known_packs', { packs: [] }) }) From 94ac4c31f901b43ebd8b7e0e089c63377f04a181 Mon Sep 17 00:00:00 2001 From: AChompSitsIn <114684575+AChompSitsIn@users.noreply.github.com> Date: Sat, 27 Jun 2026 14:53:54 -0700 Subject: [PATCH 2/2] Make configuration-phase client settings configurable via clientSettings option --- docs/API.md | 9 +++++++++ src/client/play.js | 24 ++++++++++++++---------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/docs/API.md b/docs/API.md index 88067bca..79b3ab1f 100644 --- a/docs/API.md +++ b/docs/API.md @@ -147,6 +147,15 @@ Returns a `Client` instance and perform login. * id : a numeric client id used for referring to multiple clients in a server * validateChannelProtocol (optional) : whether or not to enable protocol validation for custom protocols using plugin channels. Defaults to true * disableChatSigning (optional) : Don't try obtaining chat signing keys from Mojang (1.19+) + * clientSettings (optional) : Client Information (settings) sent to the server during the configuration phase (1.20.2+). All fields are optional and default to vanilla-safe values: + * locale : language/locale string, default `'en_us'` + * viewDistance : view distance in chunks, default `10` + * chatFlags : chat mode, `0` = enabled, `1` = commands only, `2` = hidden, default `0` + * chatColors : whether chat colors are enabled, default `true` + * skinParts : displayed skin parts bitmask, default `127` + * mainHand : `0` = left, `1` = right, default `1` + * enableTextFiltering : default `false` + * enableServerListing : whether the player appears in server status player samples, default `true` * realms : An object which should contain one of the following properties: `realmId` or `pickRealm`. When defined will attempt to join a Realm without needing to specify host/port. **The authenticated account must either own the Realm or have been invited to it** * realmId : The id of the Realm to join. * pickRealm(realms) : A function which will have an array of the user Realms (joined/owned) passed to it. The function should return a Realm. diff --git a/src/client/play.js b/src/client/play.js index 56c14f42..bcb72411 100644 --- a/src/client/play.js +++ b/src/client/play.js @@ -55,17 +55,21 @@ module.exports = function (client, options) { client.state = states.CONFIGURATION // Mirror the vanilla client, which sends Client Information during the // configuration phase. Some servers (e.g. Hypixel) wait for it before - // sending finish_configuration and close the socket otherwise. Must be - // after the CONFIGURATION state flip so it serializes correctly. (#3623) + // sending finish_configuration and will close the socket otherwise. + // Defaults are vanilla-safe and can be overridden per-field via the + // `clientSettings` option. A client that also sends Client Information in + // the play state (e.g. mineflayer on its 'login' event) still takes + // precedence there, exactly as the vanilla client re-sends settings. (#3623) + const clientSettings = options.clientSettings || {} client.write('settings', { - locale: 'en_us', - viewDistance: 10, - chatFlags: 0, - chatColors: true, - skinParts: 127, - mainHand: 1, - enableTextFiltering: false, - enableServerListing: true + locale: clientSettings.locale ?? 'en_us', + viewDistance: clientSettings.viewDistance ?? 10, + chatFlags: clientSettings.chatFlags ?? 0, + chatColors: clientSettings.chatColors ?? true, + skinParts: clientSettings.skinParts ?? 127, + mainHand: clientSettings.mainHand ?? 1, + enableTextFiltering: clientSettings.enableTextFiltering ?? false, + enableServerListing: clientSettings.enableServerListing ?? true }) client.once('select_known_packs', () => { client.write('select_known_packs', { packs: [] })