From 4c79e964c65f6756fde9fb058e769ec1ad03a599 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 17:00:34 +0000 Subject: [PATCH 1/2] Update to version 26.1 --- .github/workflows/ci.yml | 3 +++ docs/README.md | 2 +- src/version.js | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 408636fc..7b5f89fd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,5 +55,8 @@ jobs: distribution: 'adopt' - name: Install dependencies run: npm install + - run: cd node_modules && cd minecraft-data && mv minecraft-data minecraft-data-old && git clone -b pc_26_1 https://github.com/PrismarineJS/minecraft-data --depth 1 && node bin/generate_data.js + - run: curl -o node_modules/protodef/src/serializer.js https://raw.githubusercontent.com/extremeheat/node-protodef/refs/heads/dlog/src/serializer.js && curl -o node_modules/protodef/src/compiler.js https://raw.githubusercontent.com/extremeheat/node-protodef/refs/heads/dlog/src/compiler.js + - name: Run tests run: npm run mochaTest -- -g ${{ matrix.mcVersion }}v diff --git a/docs/README.md b/docs/README.md index f1cddc60..51e02e8b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,7 +18,7 @@ Parse and serialize minecraft packets, plus authentication and encryption. 1.15 (1.15, 1.15.1, 1.15.2), 1.16 (20w13b, 20w14a, 1.16-rc1, 1.16, 1.16.1, 1.16.2, 1.16.3, 1.16.4, 1.16.5), 1.17 (21w07a, 1.17, 1.17.1), 1.18 (1.18, 1.18.1 and 1.18.2), 1.19 (1.19, 1.19.1, 1.19.2, 1.19.3, 1.19.4), 1.20 (1.20, 1.20.1, 1.20.2, 1.20.3, 1.20.4, 1.20.5, 1.20.6), - 1.21, 1.21.1, 1.21.3, 1.21.4, 1.21.5, 1.21.6, 1.21.8, 1.21.9, 1.21.11 + 1.21, 1.21.1, 1.21.3, 1.21.4, 1.21.5, 1.21.6, 1.21.8, 1.21.9, 1.21.11, 26.1 * Parses all packets and emits events with packet fields as JavaScript diff --git a/src/version.js b/src/version.js index 51312c21..3aff3da9 100644 --- a/src/version.js +++ b/src/version.js @@ -1,6 +1,6 @@ 'use strict' module.exports = { - defaultVersion: '1.21.11', - supportedVersions: ['1.7', '1.8.8', '1.9.4', '1.10.2', '1.11.2', '1.12.2', '1.13.2', '1.14.4', '1.15.2', '1.16.5', '1.17.1', '1.18.2', '1.19', '1.19.2', '1.19.3', '1.19.4', '1.20', '1.20.1', '1.20.2', '1.20.4', '1.20.6', '1.21.1', '1.21.3', '1.21.4', '1.21.5', '1.21.6', '1.21.8', '1.21.9', '1.21.11'] + defaultVersion: '26.1', + supportedVersions: ['1.7', '1.8.8', '1.9.4', '1.10.2', '1.11.2', '1.12.2', '1.13.2', '1.14.4', '1.15.2', '1.16.5', '1.17.1', '1.18.2', '1.19', '1.19.2', '1.19.3', '1.19.4', '1.20', '1.20.1', '1.20.2', '1.20.4', '1.20.6', '1.21.1', '1.21.3', '1.21.4', '1.21.5', '1.21.6', '1.21.8', '1.21.9', '1.21.11', '26.1'] } From 3a7498b1f4dadeac9507c0761740d427dece9208 Mon Sep 17 00:00:00 2001 From: Mik <29287456+Mikulasz12@users.noreply.github.com> Date: Mon, 4 May 2026 04:35:19 +0100 Subject: [PATCH 2/2] Update declare_commands handling for 26.1 (#1478) Co-authored-by: extremeheat --- package.json | 4 +-- src/client/chat.js | 32 +++++++++++++------- test/declareCommandsTest.js | 58 +++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 test/declareCommandsTest.js diff --git a/package.json b/package.json index acb2b5aa..5a00ce54 100644 --- a/package.json +++ b/package.json @@ -52,11 +52,11 @@ "debug": "^4.3.2", "endian-toggle": "^0.0.0", "lodash.merge": "^4.3.0", - "minecraft-data": "^3.78.0", + "minecraft-data": "^3.109.0", "minecraft-folder-path": "^1.2.0", "node-fetch": "^2.6.1", "node-rsa": "^0.4.2", - "prismarine-auth": "^2.2.0", + "prismarine-auth": "^3.1.1", "prismarine-chat": "^1.10.0", "prismarine-nbt": "^2.5.0", "prismarine-realms": "^1.2.0", diff --git a/src/client/chat.js b/src/client/chat.js index 00218709..9327f3ef 100644 --- a/src/client/chat.js +++ b/src/client/chat.js @@ -302,20 +302,30 @@ module.exports = function (client, options) { const sliceIndexForMessage = {} client.on('declare_commands', (packet) => { + // Defensive guard: command data comes from the network and may be malformed or partially decoded. + if (!Array.isArray(packet?.nodes) || !Array.isArray(packet.nodes[0]?.children)) { + return + } + const nodes = packet.nodes + function visit (node, commandName, depth = 0) { + if (!node || !node.extraNodeData) return + + const { name, parser } = node.extraNodeData + if (parser === 'minecraft:message') { + sliceIndexForMessage[commandName] = [name, depth] + } + + for (const childIndex of node.children || []) { + visit(nodes[childIndex], commandName, depth + 1) + } + } + for (const commandNode of nodes[0].children) { const node = nodes[commandNode] - const commandName = node.extraNodeData.name - function visit (node, depth = 0) { - const name = node.extraNodeData.name - if (node.extraNodeData.parser === 'minecraft:message') { - sliceIndexForMessage[commandName] = [name, depth] - } - for (const child of node.children) { - visit(nodes[child], depth + 1) - } - } - visit(node, 0) + const commandName = node?.extraNodeData?.name + if (!commandName) continue + visit(node, commandName, 0) } }) diff --git a/test/declareCommandsTest.js b/test/declareCommandsTest.js new file mode 100644 index 00000000..ddba6172 --- /dev/null +++ b/test/declareCommandsTest.js @@ -0,0 +1,58 @@ +/* eslint-env mocha */ + +const assert = require('assert') +const EventEmitter = require('events') +const minecraftDataPath = require.resolve('minecraft-data') +const injectChatPlugin = require('../src/client/chat') + +describe('declare_commands handling', () => { + let originalMinecraftData + + beforeEach(() => { + originalMinecraftData = require.cache[minecraftDataPath]?.exports + require.cache[minecraftDataPath] = { + exports: () => ({ + supportFeature (feature) { + return feature === 'useChatSessions' || feature === 'seperateSignedChatCommandPacket' + } + }) + } + }) + + afterEach(() => { + if (originalMinecraftData) { + require.cache[minecraftDataPath] = { exports: originalMinecraftData } + } else { + delete require.cache[minecraftDataPath] + } + }) + + it('tracks message arguments from structured declare_commands nodes', () => { + const client = new EventEmitter() + client.version = '26.1' + client.verifyMessage = () => true + client.profileKeys = true + client._session = { uuid: '00000000-0000-0000-0000-000000000000' } + + const writes = [] + client.write = (name, data) => writes.push({ name, data }) + + injectChatPlugin(client, {}) + client.signMessage = () => Buffer.from([1]) + + client.emit('declare_commands', { + nodes: [ + { children: [1] }, + { children: [2], extraNodeData: { name: 'msg' } }, + { children: [], extraNodeData: { name: 'message', parser: 'minecraft:message' } } + ] + }) + + client._signedChat('/msg hello there', { timestamp: 1n, salt: 1n }) + + assert.strictEqual(writes.length, 1) + assert.strictEqual(writes[0].name, 'chat_command_signed') + assert.deepStrictEqual(writes[0].data.argumentSignatures.map(sig => sig.argumentName), ['message']) + }) + +})