Skip to content

Commit

Permalink
Fix server_data payload for 1.19+, fix kicks messages on 1.20.3+ (#1364)
Browse files Browse the repository at this point in the history
* Fix server_data payload sent to clients for versions 1.19+

Fixes #1362

Add missing fields to `server_data` payload for versions 1.19+.

* Add `motd` and `icon` fields to `server_data` payload for version 1.19.
* Add `motd`, `icon`, and `enforcesSecureChat` fields to `server_data` payload for version 1.19.2.
* Add `motd`, `icon`, and `enforcesSecureChat` fields to `server_data` payload for version 1.19.3.
* Add `motd`, `iconBytes`, and `enforcesSecureChat` fields to `server_data` payload for versions 1.19.4, 1.20, and 1.20.2.
* Add `motd`, `iconBytes`, and `enforcesSecureChat` fields to `server_data` payload for version 1.20.3.
* Add `motd` and `iconBytes` fields to `server_data` payload for version 1.20.5+.
* Use NBT components for `motd` if `chatPacketsUseNbtComponents` feature is supported.
* Convert `favicon` to buffer for `iconBytes` field if available.

---

For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/PrismarineJS/node-minecraft-protocol/issues/1362?shareId=XXXX-XXXX-XXXX-XXXX).

* add --retries 2

* lint, debug close event emit twice

* bail tests

* fix

* flaky test fix

* remove debug

* Update serverTest.js

* Fix NBT chat not being used for 1.20.3+ kicks

* Update createClient.js

* fix client.._supportFeature not being defined

* only nbt on the play state disconnect
  • Loading branch information
extremeheat authored Jan 6, 2025
1 parent f258c76 commit 8e131c3
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Client extends EventEmitter {
this.hideErrors = hideErrors
this.closeTimer = null
const mcData = require('minecraft-data')(version)
this._supportFeature = mcData.supportFeature
this.state = states.HANDSHAKING
this._hasBundlePacket = mcData.supportFeature('hasBundlePacket')
}
Expand Down
1 change: 1 addition & 0 deletions src/createServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ function createServer (options = {}) {
server.onlineModeExceptions = Object.create(null)
server.favicon = favicon
server.options = options
server._supportFeature = mcData.supportFeature
options.registryCodec = options.registryCodec || mcData.registryCodec || mcData.loginPacket?.dimensionCodec

// The RSA keypair can take some time to generate
Expand Down
8 changes: 6 additions & 2 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const net = require('net')
const EventEmitter = require('events').EventEmitter
const Client = require('./client')
const states = require('./states')
const nbt = require('prismarine-nbt')
const { createSerializer } = require('./transforms/serializer')

class Server extends EventEmitter {
Expand All @@ -26,11 +27,14 @@ class Server extends EventEmitter {
self.socketServer.on('connection', socket => {
const client = new Client(true, this.version, this.customPackets, this.hideErrors)
client._end = client.end
client.end = function end (endReason, fullReason = JSON.stringify({ text: endReason })) {
client.end = function end (endReason, fullReason) {
if (client.state === states.PLAY) {
fullReason ||= this._supportFeature('chatPacketsUseNbtComponents')
? nbt.comp({ text: nbt.string(endReason) })
: JSON.stringify({ text: endReason })
client.write('kick_disconnect', { reason: fullReason })
} else if (client.state === states.LOGIN) {
client.write('disconnect', { reason: fullReason })
client.write('disconnect', { reason: fullReason || endReason })
}
client._end(endReason)
}
Expand Down
6 changes: 6 additions & 0 deletions src/server/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const chatPlugin = require('./chat')
const { concat } = require('../transforms/binaryStream')
const { mojangPublicKeyPem } = require('./constants')
const debug = require('debug')('minecraft-protocol')
const nbt = require('prismarine-nbt')

/**
* @param {import('../index').Client} client
Expand Down Expand Up @@ -196,7 +197,12 @@ module.exports = function (client, server, options) {
client.settings = {}

if (client.supportFeature('chainedChatWithHashing')) { // 1.19.1+
const jsonMotd = JSON.stringify(server.motdMsg ?? { text: server.motd })
const nbtMotd = nbt.comp({ text: nbt.string(server.motd) })
client.write('server_data', {
motd: client.supportFeature('chatPacketsUseNbtComponents') ? nbtMotd : jsonMotd,
icon: server.favicon, // b64
iconBytes: server.favicon ? Buffer.from(server.favicon, 'base64') : undefined,
previewsChat: options.enableChatPreview,
// Note: in 1.20.5+ user must send this with `login`
enforcesSecureChat: options.enforceSecureProfile
Expand Down
15 changes: 13 additions & 2 deletions test/serverTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ for (const supportedVersion of mc.supportedVersions) {
describe('mc-server ' + supportedVersion + 'v', function () {
this.timeout(5000)
this.beforeEach(async function () {
console.log('🔻 Starting test', this.currentTest.title)
PORT = await getPort()
console.log(`Using port for tests: ${PORT}`)
})
Expand Down Expand Up @@ -411,9 +412,12 @@ for (const supportedVersion of mc.supportedVersions) {
})
})
function checkFinish () {
if (serverPlayerDisconnected && clientClosed && serverClosed) done()
if (serverPlayerDisconnected && clientClosed && serverClosed) {
console.log('Kick test is done')
callOnce(done)
}
}
})
}).retries(2)

it('gives correct reason for kicking clients when shutting down', function (done) {
const server = mc.createServer({
Expand Down Expand Up @@ -532,3 +536,10 @@ for (const supportedVersion of mc.supportedVersions) {
})
})
}

function callOnce (fn, ...args) {
console.log('Call Fn', fn.called)
if (fn.called) return
fn(...args)
fn.called = true
}

0 comments on commit 8e131c3

Please sign in to comment.