diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7b5f89fd..a94f373e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,10 +13,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Use Node.js 22.x + - name: Use Node.js 24.x uses: actions/setup-node@v1.4.4 with: - node-version: 22.x + node-version: 24.x - run: npm i && npm run lint PrepareSupportedVersions: runs-on: ubuntu-latest @@ -25,10 +25,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Use Node.js 22.x + - name: Use Node.js 24.x uses: actions/setup-node@v1.4.4 with: - node-version: 22.x + node-version: 24.x - id: set-matrix run: | node -e " @@ -44,10 +44,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Use Node.js 22.x + - name: Use Node.js 24.x uses: actions/setup-node@v1 with: - node-version: 22.x + node-version: 24.x - name: Setup Java JDK uses: actions/setup-java@v1.4.3 with: diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index f5e18ab9..e694d60c 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -3,6 +3,9 @@ on: push: branches: - master # Change this to your default branch +permissions: + id-token: write + contents: write jobs: npm-publish: name: npm-publish @@ -13,13 +16,12 @@ jobs: - name: Set up Node.js uses: actions/setup-node@master with: - node-version: 22.0.0 + node-version: 24 + registry-url: 'https://registry.npmjs.org' - id: publish - uses: JS-DevTools/npm-publish@v1 - with: - token: ${{ secrets.NPM_AUTH_TOKEN }} + uses: JS-DevTools/npm-publish@v4 - name: Create Release - if: steps.publish.outputs.type != 'none' + if: ${{ steps.publish.outputs.type }} id: create_release uses: actions/create-release@v1 env: diff --git a/docs/HISTORY.md b/docs/HISTORY.md index 6bb8a1fa..151647c3 100644 --- a/docs/HISTORY.md +++ b/docs/HISTORY.md @@ -1,5 +1,13 @@ # History +## 1.65.0 +* [Update CI to Node 24 (#1473)](https://github.com/PrismarineJS/node-minecraft-protocol/commit/8008fe065787d50c7ab490cb0a503cb9200043fe) (thanks @rom1504) +* [Fix publish condition for npm-publish v4 (#1472)](https://github.com/PrismarineJS/node-minecraft-protocol/commit/9bc871da00a82058ad68f7fb6fd661c268f6a7a9) (thanks @rom1504) +* [Switch to trusted publishing via OIDC (#1471)](https://github.com/PrismarineJS/node-minecraft-protocol/commit/f87f9d5b35888be3bccece3edf5761183cf916a4) (thanks @rom1504) + +## 1.64.1 +* [Backport velocity field changes from 1.21.9+ to older versions (#1467)](https://github.com/PrismarineJS/node-minecraft-protocol/commit/b66c9aa08052859fb2e3075a3d6c6f84a84e77f1) (thanks @SuperGamerTron) + ## 1.64.0 * [🎈 1.21.11 (#1457)](https://github.com/PrismarineJS/node-minecraft-protocol/commit/77f4167d93a70322f2963c3c81586c8fe0c6c299) (thanks @rom1504bot) diff --git a/package.json b/package.json index f93c3183..5a00ce54 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "minecraft-protocol", - "version": "1.64.0", + "version": "1.65.0", "description": "Parse and serialize minecraft packets, plus authentication and encryption.", "main": "src/index.js", "types": "src/index.d.ts", @@ -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']) + }) + +}) diff --git a/test/packetTest.js b/test/packetTest.js index d4074f66..a5d7e918 100644 --- a/test/packetTest.js +++ b/test/packetTest.js @@ -232,6 +232,9 @@ const values = { vec3i: { x: 0, y: 0, z: 0 }, + vec3i16: { + x: 0, y: 0, z: 0 + }, count: 1, // TODO : might want to set this to a correct value bool: true, f64: 99999.2222,