From 924f0795ca13d7d09c352a47551104a8b74a69b9 Mon Sep 17 00:00:00 2001 From: Romain Beaumont Date: Sun, 27 Oct 2024 21:33:52 +0100 Subject: [PATCH 01/13] Support 1.21.3. --- .github/workflows/ci.yml | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e307beace..799ffb4fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,5 +56,6 @@ jobs: java-package: jre - name: Install Dependencies run: npm install + - run: cd node_modules && cd minecraft-data && mv minecraft-data minecraft-data-old && git clone -b pc1.21.3 https://github.com/GroobleDierne/minecraft-data.git --depth 1 && node bin/generate_data.js - name: Start Tests run: npm run mocha_test -- -g ${{ matrix.mcVersion }}v diff --git a/package.json b/package.json index 20bda92bb..d7595bd38 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "license": "MIT", "dependencies": { "minecraft-data": "^3.76.0", - "minecraft-protocol": "^1.50.0", + "minecraft-protocol": "github:PrismarineJS/node-minecraft-protocol#1.21.3", "prismarine-biome": "^1.1.1", "prismarine-block": "^1.17.0", "prismarine-chat": "^1.7.1", From c966b635daf357ac37d9fd4497002097059eb813 Mon Sep 17 00:00:00 2001 From: Romain Beaumont Date: Sun, 27 Oct 2024 21:59:06 +0100 Subject: [PATCH 02/13] Update version.js --- lib/version.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/version.js b/lib/version.js index 291917cb0..8623a4c59 100644 --- a/lib/version.js +++ b/lib/version.js @@ -1,4 +1,4 @@ -const testedVersions = ['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', '1.20.2', '1.20.4', '1.20.6', '1.21.1'] +const testedVersions = ['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', '1.20.2', '1.20.4', '1.20.6', '1.21.1', '1.21.3'] module.exports = { testedVersions, From 115939ff8013484dce02505c44e347ead4b0b25c Mon Sep 17 00:00:00 2001 From: extremeheat Date: Mon, 25 Nov 2024 10:53:21 -0500 Subject: [PATCH 03/13] Update entities.js --- lib/plugins/entities.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/plugins/entities.js b/lib/plugins/entities.js index 49a5b8696..db3841b6b 100644 --- a/lib/plugins/entities.js +++ b/lib/plugins/entities.js @@ -361,6 +361,11 @@ function inject (bot) { if (eventName) bot.emit(eventName, entity) }) + bot._client.on('damage_event', (packet) => { // 1.20+ + const entity = bot.entities[packet.entityId] + bot.emit('entityHurt', entity) + }) + bot._client.on('attach_entity', (packet) => { // attach entity const entity = fetchEntity(packet.entityId) From b529c5842774a5206f367cd658b749783044090a Mon Sep 17 00:00:00 2001 From: Romain Beaumont Date: Wed, 4 Dec 2024 21:25:10 +0100 Subject: [PATCH 04/13] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d7595bd38..a291f34d7 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "license": "MIT", "dependencies": { "minecraft-data": "^3.76.0", - "minecraft-protocol": "github:PrismarineJS/node-minecraft-protocol#1.21.3", + "minecraft-protocol": "^1.51.0", "prismarine-biome": "^1.1.1", "prismarine-block": "^1.17.0", "prismarine-chat": "^1.7.1", From 65be49277b5f7e9397b8d757d644d1433a034999 Mon Sep 17 00:00:00 2001 From: Romain Beaumont Date: Wed, 4 Dec 2024 21:26:07 +0100 Subject: [PATCH 05/13] Update ci.yml --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 799ffb4fe..e307beace 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,6 +56,5 @@ jobs: java-package: jre - name: Install Dependencies run: npm install - - run: cd node_modules && cd minecraft-data && mv minecraft-data minecraft-data-old && git clone -b pc1.21.3 https://github.com/GroobleDierne/minecraft-data.git --depth 1 && node bin/generate_data.js - name: Start Tests run: npm run mocha_test -- -g ${{ matrix.mcVersion }}v From 55f32ab3b04219300697c46bb5dfb5253342a3b5 Mon Sep 17 00:00:00 2001 From: IceTank <61137113+IceTank@users.noreply.github.com> Date: Wed, 11 Dec 2024 20:16:13 +0100 Subject: [PATCH 06/13] Fix gamemode test and implementation (#3508) * Fix gamemode test and implementation * Add gamemode test related comments * Fix gamemode tests Add test function to kill the bot * Add gamemode out of bounds checks * Simplify gameMode parsing and check against spawnRespawnWorldDataField feature --- lib/plugins/game.js | 14 ++++++++++-- test/externalTests/gamemode.js | 29 ++++++++++++++++++++---- test/externalTests/plugins/testCommon.js | 5 ++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/lib/plugins/game.js b/lib/plugins/game.js index c992d1f74..c47db6c6e 100644 --- a/lib/plugins/game.js +++ b/lib/plugins/game.js @@ -10,7 +10,12 @@ const dimensionNames = { 1: 'the_end' } -const parseGameMode = gameModeBits => gameModes[(gameModeBits & 0b11)] // lower two bits +const parseGameMode = gameModeBits => { + if (gameModeBits < 0 || gameModeBits > 0b11) { + return 'survival' + } + return gameModes[(gameModeBits & 0b11)] // lower two bits +} function inject (bot, options) { function getBrandCustomChannelName () { @@ -25,7 +30,12 @@ function inject (bot, options) { function handleRespawnPacketData (packet) { bot.game.levelType = packet.levelType ?? (packet.isFlat ? 'flat' : 'default') bot.game.hardcore = packet.isHardcore ?? Boolean(packet.gameMode & 0b100) - bot.game.gameMode = packet.gamemode || parseGameMode(packet.gameMode) + // Either a respawn packet or a login packet. Depending on the packet it can be "gamemode" or "gameMode" + if (bot.supportFeature('spawnRespawnWorldDataField')) { // 1.20.5 + bot.game.gameMode = packet.gamemode + } else { + bot.game.gameMode = parseGameMode(packet.gamemode ?? packet.gameMode) + } if (bot.supportFeature('segmentedRegistryCodecData')) { // 1.20.5 if (typeof packet.dimension === 'number') { bot.game.dimension = bot.registry.dimensionsArray[packet.dimension]?.name?.replace('minecraft:', '') diff --git a/test/externalTests/gamemode.js b/test/externalTests/gamemode.js index d4cc45a04..ebf2d1487 100644 --- a/test/externalTests/gamemode.js +++ b/test/externalTests/gamemode.js @@ -1,10 +1,29 @@ // test to see if bot retains creative gamemode in bot object on death const assert = require('assert') +const { onceWithCleanup } = require('../../lib/promise_utils') -module.exports = async (bot) => { - bot.test.becomeCreative() - bot.chat(`/kill ${bot.username}`) - await new Promise((resolve, reject) => setTimeout(resolve, 5000)) - assert.strictEqual(bot.game.gameMode, 'creative', 'Failed to parse respawn packet') +module.exports = () => { + const tests = [] + + function addTest (name, f) { + tests[name] = (bot) => f(bot) + } + + addTest('change', async (bot) => { + await bot.test.becomeSurvival() + assert.strictEqual(bot.game.gameMode, 'survival', 'Wrong gamemode after switching gamemode') + await bot.test.becomeCreative() + assert.strictEqual(bot.game.gameMode, 'creative', 'Wrong gamemode after switching gamemode') + }) + + addTest('after respawn', async (bot) => { + await bot.test.becomeCreative() + bot.test.selfKill() + await onceWithCleanup(bot, 'respawn', { timeout: 5000 }) + // Respawn packets send the gamemode. If the bot is in creative mode, it should respawn in creative mode. Tested <1.20 + assert.strictEqual(bot.game.gameMode, 'creative', 'Wrong gamemode after respawn') + }) + + return tests } diff --git a/test/externalTests/plugins/testCommon.js b/test/externalTests/plugins/testCommon.js index 0309fa4bf..0b25a918e 100644 --- a/test/externalTests/plugins/testCommon.js +++ b/test/externalTests/plugins/testCommon.js @@ -25,6 +25,7 @@ function inject (bot) { bot.test.placeBlock = placeBlock bot.test.runExample = runExample bot.test.tellAndListen = tellAndListen + bot.test.selfKill = selfKill bot.test.wait = function (ms) { return new Promise((resolve) => { setTimeout(resolve, ms) }) } @@ -232,4 +233,8 @@ function inject (bot) { } return closeExample() } + + function selfKill () { + bot.chat('/kill @p') + } } From 229ee1c2e4315c91d4528380c32dd5953bfbf09d Mon Sep 17 00:00:00 2001 From: extremeheat Date: Tue, 7 Jan 2025 08:44:43 +0000 Subject: [PATCH 07/13] 21.3 work --- lib/plugins/blocks.js | 11 ++- lib/plugins/entities.js | 109 ++++++++++++++++++++--- lib/plugins/generic_place.js | 4 +- lib/plugins/inventory.js | 5 +- lib/plugins/physics.js | 92 ++++++++++++++----- lib/plugins/settings.js | 3 +- package.json | 2 +- test/externalTests/plugins/testCommon.js | 4 + test/internalTest.js | 20 ++++- 9 files changed, 206 insertions(+), 44 deletions(-) diff --git a/lib/plugins/blocks.js b/lib/plugins/blocks.js index 6a9c1655a..e35e34a27 100644 --- a/lib/plugins/blocks.js +++ b/lib/plugins/blocks.js @@ -395,10 +395,13 @@ function inject (bot, { version, storageBuilder, hideErrors }) { bot._client.on('explosion', (packet) => { // explosion const p = new Vec3(packet.x, packet.y, packet.z) - packet.affectedBlockOffsets.forEach((offset) => { - const pt = p.offset(offset.x, offset.y, offset.z) - updateBlockState(pt, 0) - }) + if (packet.affectedBlockOffsets) { + // TODO: server no longer sends in 1.21.3. Is client supposed to compute this or is it sent via normal block updates? + packet.affectedBlockOffsets.forEach((offset) => { + const pt = p.offset(offset.x, offset.y, offset.z) + updateBlockState(pt, 0) + }) + } }) bot._client.on('spawn_entity_painting', (packet) => { diff --git a/lib/plugins/entities.js b/lib/plugins/entities.js index db3841b6b..0ec573f8b 100644 --- a/lib/plugins/entities.js +++ b/lib/plugins/entities.js @@ -341,6 +341,16 @@ function inject (bot) { bot.emit('entityMoved', entity) }) + // 1.21.3 - merges the packets above + bot._client.on('sync_entity_position', (packet) => { + const entity = fetchEntity(packet.entityId) + entity.position.set(packet.x, packet.y, packet.z) + entity.velocity.update(packet.dx, packet.dy, packet.dz) + entity.yaw = packet.yaw + entity.pitch = packet.pitch + bot.emit('entityMoved', entity) + }) + bot._client.on('entity_head_rotation', (packet) => { // entity head look const entity = fetchEntity(packet.entityId) @@ -588,8 +598,65 @@ function inject (bot) { }) bot._client.on('player_info', (packet) => { + console.log('Player Info', packet) // player list item(s) + if (bot.registry.version['>=']('1.21.3')) { + // the features checks below this will be un-needed with https://github.com/PrismarineJS/minecraft-data/pull/948 + for (const update of packet.data) { + let player = bot.uuidToUsername[update.uuid] ? bot.players[bot.uuidToUsername[update.uuid]] : null + let newPlayer = false + + const obj = { + uuid: update.uuid + } + + if (!player) newPlayer = true + + player ||= obj + + if (packet.action.add_player) { + obj.username = update.player.name + obj.displayName = player.displayName || new ChatMessage({ text: '', extra: [{ text: update.player.name }] }) + obj.skinData = extractSkinInformation(update.player.properties) + } + + if (packet.action.update_game_mode) { + obj.gamemode = update.gamemode + } + + if (packet.action.update_latency) { + obj.ping = update.latency + } + + if (update.displayName) { + obj.displayName = ChatMessage.fromNotch(update.displayName) + } + + if (newPlayer) { + if (!obj.username) continue // Should be unreachable + player = bot.players[obj.username] = obj + bot.uuidToUsername[obj.uuid] = obj.username + } else { + Object.assign(player, obj) + } + + const playerEntity = Object.values(bot.entities).find(e => e.type === 'player' && e.username === player.username) + player.entity = playerEntity + + if (playerEntity === bot.entity) { + bot.player = player + } + + if (newPlayer) { + bot.emit('playerJoined', player) + } else { + bot.emit('playerUpdated', player) + } + } + return + } + if (bot.supportFeature('playerInfoActionIsBitfield')) { for (const item of packet.data) { let player = bot.uuidToUsername[item.uuid] ? bot.players[bot.uuidToUsername[item.uuid]] : null @@ -800,20 +867,42 @@ function inject (bot) { } function moveVehicle (left, forward) { - bot._client.write('steer_vehicle', { - sideways: left, - forward, - jump: 0x01 - }) + if (bot.registry.version['>=']('1.21.3')) { + // docs: + // * left can take -1 or 1 : -1 means right, 1 means left + // * forward can take -1 or 1 : -1 means backward, 1 means forward + bot._client.write('player_input', { + inputs: { + forward: forward > 0, + backward: forward < 0, + left: left > 0, + right: left < 0 + } + }) + } else { + bot._client.write('steer_vehicle', { + sideways: left, + forward, + jump: 0x01 + }) + } } function dismount () { if (bot.vehicle) { - bot._client.write('steer_vehicle', { - sideways: 0.0, - forward: 0.0, - jump: 0x02 - }) + if (bot.registry.version['>=']('1.21.3')) { + bot._client.write('player_input', { + inputs: { + jump: true + } + }) + } else { + bot._client.write('steer_vehicle', { + sideways: 0.0, + forward: 0.0, + jump: 0x02 + }) + } } else { bot.emit('error', new Error('dismount: not mounted')) } diff --git a/lib/plugins/generic_place.js b/lib/plugins/generic_place.js index 8fddebacd..448dfc00d 100644 --- a/lib/plugins/generic_place.js +++ b/lib/plugins/generic_place.js @@ -79,7 +79,9 @@ function inject (bot) { cursorX: dx, cursorY: dy, cursorZ: dz, - insideBlock: false + insideBlock: false, + sequence: 0, // 1.19.0 + worldBorderHit: false // 1.21.3 }) } diff --git a/lib/plugins/inventory.js b/lib/plugins/inventory.js index d538711d3..1600da585 100644 --- a/lib/plugins/inventory.js +++ b/lib/plugins/inventory.js @@ -190,6 +190,7 @@ function inject (bot, { hideErrors }) { // TODO: tell the server that we are not sneaking while doing this await bot.lookAt(block.position.offset(0.5, 0.5, 0.5), false) // place block message + // TODO: logic below can likely be simplified if (bot.supportFeature('blockPlaceHasHeldItem')) { bot._client.write('block_place', { location: block.position, @@ -225,7 +226,9 @@ function inject (bot, { hideErrors }) { cursorX: cursorPos.x, cursorY: cursorPos.y, cursorZ: cursorPos.z, - insideBlock: false + insideBlock: false, + sequence: 0, // 1.19.0+ + worldBorderHit: false // 1.21.3+ }) } diff --git a/lib/plugins/physics.js b/lib/plugins/physics.js index 578e5a529..c9cf0bc7d 100644 --- a/lib/plugins/physics.js +++ b/lib/plugins/physics.js @@ -45,10 +45,14 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) { x: 0, y: 0, z: 0, + dx: 0, // 1.21.3 + dy: 0, + dz: 0, yaw: 0, pitch: 0, onGround: false, - time: 0 + time: 0, + flags: bot.registry.version['>=']('1.21.3') ? {} : 0 } // This function should be executed each tick (every 0.05 seconds) @@ -103,6 +107,7 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) { lastSent.y = position.y lastSent.z = position.z lastSent.onGround = onGround + lastSent.flags = { onGround, hasHorizontalCollision: undefined } // 1.21.3+ bot._client.write('position', lastSent) bot.emit('move', oldPos) } @@ -113,6 +118,7 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) { lastSent.yaw = yaw lastSent.pitch = pitch lastSent.onGround = onGround + lastSent.flags = { onGround, hasHorizontalCollision: undefined } // 1.21.3+ bot._client.write('look', lastSent) bot.emit('move', oldPos) } @@ -126,6 +132,7 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) { lastSent.yaw = yaw lastSent.pitch = pitch lastSent.onGround = onGround + lastSent.flags = { onGround, hasHorizontalCollision: undefined } // 1.21.3+ bot._client.write('position_look', lastSent) bot.emit('move', oldPos) } @@ -167,9 +174,9 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) { // Only send a position update if necessary, select the appropriate packet const positionUpdated = lastSent.x !== position.x || lastSent.y !== position.y || lastSent.z !== position.z || - // Send a position update every second, even if no other update was made - // This function rounds to the nearest 50ms (or PHYSICS_INTERVAL_MS) and checks if a second has passed. - (Math.round((now - lastSent.time) / PHYSICS_INTERVAL_MS) * PHYSICS_INTERVAL_MS) >= 1000 + // Send a position update every second, even if no other update was made + // This function rounds to the nearest 50ms (or PHYSICS_INTERVAL_MS) and checks if a second has passed. + (Math.round((now - lastSent.time) / PHYSICS_INTERVAL_MS) * PHYSICS_INTERVAL_MS) >= 1000 const lookUpdated = lastSent.yaw !== yaw || lastSent.pitch !== pitch if (positionUpdated && lookUpdated) { @@ -184,7 +191,10 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) { // For versions < 1.12, one player packet should be sent every tick // for the server to update health correctly // For versions >= 1.12, onGround !== lastSent.onGround should be used, but it doesn't ever trigger outside of login - bot._client.write('flying', { onGround: bot.entity.onGround }) + bot._client.write('flying', { + onGround: bot.entity.onGround, + flags: { onGround: bot.entity.onGround, hasHorizontalCollision: undefined } // 1.21.3+ + }) } lastSent.onGround = bot.entity.onGround // onGround is always set @@ -288,9 +298,14 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) { bot._client.on('explosion', explosion => { // TODO: emit an explosion event with more info if (bot.physicsEnabled && bot.game.gameMode !== 'creative') { - bot.entity.velocity.x += explosion.playerMotionX - bot.entity.velocity.y += explosion.playerMotionY - bot.entity.velocity.z += explosion.playerMotionZ + if (explosion.playerKnockback) { // 1.21.3+ + bot.entity.velocity.add(explosion.playerMotionX, explosion.playerMotionY, explosion.playerMotionZ) + } + if ('playerMotionX' in explosion) { + bot.entity.velocity.x += explosion.playerMotionX + bot.entity.velocity.y += explosion.playerMotionY + bot.entity.velocity.z += explosion.playerMotionZ + } } }) @@ -330,30 +345,59 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) { await bot.look(yaw, pitch, force) } + // 1.21.3+ + bot._client.on('player_rotation', (packet) => { + bot.entity.yaw = conv.fromNotchianYaw(packet.yaw) + bot.entity.pitch = conv.fromNotchianPitch(packet.pitch) + }) + // player position and look (clientbound) bot._client.on('position', (packet) => { // Is this necessary? Feels like it might wrongly overwrite hitbox size sometimes // e.g. when crouching/crawling/swimming. Can someone confirm? bot.entity.height = 1.8 - // Velocity is only set to 0 if the flag is not set, otherwise keep current velocity + // Velocity is reset if the x, y, z flags are not set const vel = bot.entity.velocity - vel.set( - packet.flags & 1 ? vel.x : 0, - packet.flags & 2 ? vel.y : 0, - packet.flags & 4 ? vel.z : 0 - ) - - // If flag is set, then the corresponding value is relative, else it is absolute + // If the x, y, z flags are not set, the position is absolute const pos = bot.entity.position - pos.set( - packet.flags & 1 ? (pos.x + packet.x) : packet.x, - packet.flags & 2 ? (pos.y + packet.y) : packet.y, - packet.flags & 4 ? (pos.z + packet.z) : packet.z - ) - - const newYaw = (packet.flags & 8 ? conv.toNotchianYaw(bot.entity.yaw) : 0) + packet.yaw - const newPitch = (packet.flags & 16 ? conv.toNotchianPitch(bot.entity.pitch) : 0) + packet.pitch + + // TODO: this current mineflayer logic maybe incorrect. New (maybe even older) versions of minecraft have flag values for + // dx/dy/dz but mineflayer is assuming that 0b111 applies for both velocity and position. + + let newYaw, newPitch + + if (bot.registry.version['>=']('1.21.3')) { + // flags is now an object with keys + // "flags": ["x", "y", "z", "yaw", "pitch", "dx", "dy", "dz", "yawDelta"] + const flags = packet.flags + vel.set( + flags.x ? vel.x : 0, + flags.y ? vel.y : 0, + flags.z ? vel.z : 0 + ) + pos.set( + flags.x ? (pos.x + packet.x) : packet.x, + flags.y ? (pos.y + packet.y) : packet.y, + flags.z ? (pos.z + packet.z) : packet.z + ) + newYaw = (flags.yaw ? conv.toNotchianYaw(bot.entity.yaw) : 0) + packet.yaw + newPitch = (flags.pitch ? conv.toNotchianPitch(bot.entity.pitch) : 0) + packet.pitch + } else { + vel.set( + packet.flags & 1 ? vel.x : 0, + packet.flags & 2 ? vel.y : 0, + packet.flags & 4 ? vel.z : 0 + ) + pos.set( + packet.flags & 1 ? (pos.x + packet.x) : packet.x, + packet.flags & 2 ? (pos.y + packet.y) : packet.y, + packet.flags & 4 ? (pos.z + packet.z) : packet.z + ) + newYaw = (packet.flags & 8 ? conv.toNotchianYaw(bot.entity.yaw) : 0) + packet.yaw + newPitch = (packet.flags & 16 ? conv.toNotchianPitch(bot.entity.pitch) : 0) + packet.pitch + } + bot.entity.yaw = conv.fromNotchianYaw(newYaw) bot.entity.pitch = conv.fromNotchianPitch(newPitch) bot.entity.onGround = false diff --git a/lib/plugins/settings.js b/lib/plugins/settings.js index a835e3851..a3bdd7cd9 100644 --- a/lib/plugins/settings.js +++ b/lib/plugins/settings.js @@ -87,7 +87,8 @@ function inject (bot, options) { : options.skinParts, mainHand: options.mainHand || 'right', enableTextFiltering: options.enableTextFiltering || false, - enableServerListing: options.enableServerListing || true + enableServerListing: options.enableServerListing || true, + particleStatus: 'all' } bot._client.on('login', () => { diff --git a/package.json b/package.json index a291f34d7..c2df60783 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "prismarine-registry": "^1.10.0", "prismarine-windows": "^2.9.0", "prismarine-world": "^3.6.0", - "protodef": "1.17.0", + "protodef": "^1.18.0", "typed-emitter": "^1.0.0", "vec3": "^0.1.7" }, diff --git a/test/externalTests/plugins/testCommon.js b/test/externalTests/plugins/testCommon.js index 0b25a918e..bfc068a00 100644 --- a/test/externalTests/plugins/testCommon.js +++ b/test/externalTests/plugins/testCommon.js @@ -144,6 +144,10 @@ function inject (bot) { // you need to be in creative mode for this to work async function setInventorySlot (targetSlot, item) { + // DEBUG + bot._client.on('packet', function (data, meta) { + console.log(meta.name, JSON.stringify(data).slice(0, 100)) + }) assert(item === null || item.name !== 'unknown', `item should not be unknown ${JSON.stringify(item)}`) return bot.creative.setInventorySlot(targetSlot, item) } diff --git a/test/internalTest.js b/test/internalTest.js index 2f74e03d1..ae28a1fda 100644 --- a/test/internalTest.js +++ b/test/internalTest.js @@ -254,9 +254,12 @@ for (const supportedVersion of mineflayer.testedVersions) { x: 1.5, y: 66, z: 1.5, + dx: 0, // 1.21.3 + dy: 0, // 1.21.3 + dz: 0, // 1.21.3 pitch: 0, yaw: 0, - flags: 0, + flags: bot.registry.version['>=']('1.21.3') ? {} : 0, teleportId: 0 } server.on('playerJoin', async (client) => { @@ -351,9 +354,22 @@ for (const supportedVersion of mineflayer.testedVersions) { x: 1, y: 0, z: 0, + dx: 0, // 1.21.3 + dy: 0, // 1.21.3 + dz: 0, // 1.21.3 pitch: 0, yaw: 0, - flags: 31, + flags: bot.registry.version['>=']('1.21.3') + ? { + // flags = ["x", "y", "z", "yaw", "pitch", "dx", "dy", "dz", "yawDelta"] + // 31 = 0b11111 + x: true, + y: true, + z: true, + yaw: true, + pitch: true + } + : 31, teleportId: 3 } absolute = false From 118424256154f9b0128445bccde5aa22375441ae Mon Sep 17 00:00:00 2001 From: extremeheat Date: Tue, 7 Jan 2025 08:48:41 +0000 Subject: [PATCH 08/13] fix --- test/externalTests/plugins/testCommon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/externalTests/plugins/testCommon.js b/test/externalTests/plugins/testCommon.js index bfc068a00..20ce5a592 100644 --- a/test/externalTests/plugins/testCommon.js +++ b/test/externalTests/plugins/testCommon.js @@ -146,7 +146,7 @@ function inject (bot) { async function setInventorySlot (targetSlot, item) { // DEBUG bot._client.on('packet', function (data, meta) { - console.log(meta.name, JSON.stringify(data).slice(0, 100)) + console.log(meta.name, JSON.stringify(data)?.slice(0, 100)) }) assert(item === null || item.name !== 'unknown', `item should not be unknown ${JSON.stringify(item)}`) return bot.creative.setInventorySlot(targetSlot, item) From 63654c5270efae1b4cf4905cf209e5f3ad82eb10 Mon Sep 17 00:00:00 2001 From: extremeheat Date: Tue, 7 Jan 2025 08:56:25 +0000 Subject: [PATCH 09/13] reduce debug logging --- test/externalTests/plugins/testCommon.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/externalTests/plugins/testCommon.js b/test/externalTests/plugins/testCommon.js index 20ce5a592..64912eade 100644 --- a/test/externalTests/plugins/testCommon.js +++ b/test/externalTests/plugins/testCommon.js @@ -142,12 +142,14 @@ function inject (bot) { } } + // DEBUG + bot._client.on('packet', function (data, meta) { + if (['chunk', 'time', 'light', 'alive'].some(e => meta.name.includes(e))) return + console.log('->', meta.name, JSON.stringify(data)?.slice(0, 100)) + }) + // you need to be in creative mode for this to work async function setInventorySlot (targetSlot, item) { - // DEBUG - bot._client.on('packet', function (data, meta) { - console.log(meta.name, JSON.stringify(data)?.slice(0, 100)) - }) assert(item === null || item.name !== 'unknown', `item should not be unknown ${JSON.stringify(item)}`) return bot.creative.setInventorySlot(targetSlot, item) } From 3158bd1eca797c0bfcaa5f848356798d518f1760 Mon Sep 17 00:00:00 2001 From: extremeheat Date: Tue, 7 Jan 2025 09:16:52 +0000 Subject: [PATCH 10/13] outbound logging --- test/externalTests/plugins/testCommon.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/externalTests/plugins/testCommon.js b/test/externalTests/plugins/testCommon.js index 64912eade..b3d7f3949 100644 --- a/test/externalTests/plugins/testCommon.js +++ b/test/externalTests/plugins/testCommon.js @@ -145,8 +145,14 @@ function inject (bot) { // DEBUG bot._client.on('packet', function (data, meta) { if (['chunk', 'time', 'light', 'alive'].some(e => meta.name.includes(e))) return - console.log('->', meta.name, JSON.stringify(data)?.slice(0, 100)) + console.log('->', meta.name, JSON.stringify(data)?.slice(0, 120)) }) + const oldWrite = bot._client.write + bot._client.write = function (name, data) { + if (['alive', 'pong', 'ping'].some(e => name.includes(e))) return + console.log('<-', name, JSON.stringify(data)?.slice(0, 120)) + oldWrite.apply(bot._client, arguments) + } // you need to be in creative mode for this to work async function setInventorySlot (targetSlot, item) { From e5292d1854902e12aae2fbb8a84930fa0da31290 Mon Sep 17 00:00:00 2001 From: extremeheat Date: Tue, 7 Jan 2025 10:25:08 +0000 Subject: [PATCH 11/13] fix logging --- test/externalTests/plugins/testCommon.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/externalTests/plugins/testCommon.js b/test/externalTests/plugins/testCommon.js index b3d7f3949..2876cef0c 100644 --- a/test/externalTests/plugins/testCommon.js +++ b/test/externalTests/plugins/testCommon.js @@ -145,17 +145,21 @@ function inject (bot) { // DEBUG bot._client.on('packet', function (data, meta) { if (['chunk', 'time', 'light', 'alive'].some(e => meta.name.includes(e))) return - console.log('->', meta.name, JSON.stringify(data)?.slice(0, 120)) + console.log('->', meta.name, JSON.stringify(data)?.slice(0, 250)) }) const oldWrite = bot._client.write bot._client.write = function (name, data) { if (['alive', 'pong', 'ping'].some(e => name.includes(e))) return - console.log('<-', name, JSON.stringify(data)?.slice(0, 120)) + console.log('<-', name, JSON.stringify(data)?.slice(0, 250)) oldWrite.apply(bot._client, arguments) } + BigInt.prototype.toJSON ??= function () { + return this.toString() + } // you need to be in creative mode for this to work async function setInventorySlot (targetSlot, item) { + console.trace('Setting inv slot to', targetSlot, JSON.stringify(item)) assert(item === null || item.name !== 'unknown', `item should not be unknown ${JSON.stringify(item)}`) return bot.creative.setInventorySlot(targetSlot, item) } From a93bb2c2dc48fcccd38b6cc9109fa2bd255a28ab Mon Sep 17 00:00:00 2001 From: extremeheat Date: Tue, 7 Jan 2025 12:01:18 +0000 Subject: [PATCH 12/13] disable logging and --bail --- lib/plugins/entities.js | 2 +- package.json | 2 +- test/externalTests/plugins/testCommon.js | 26 +++++++++++++----------- test/internalTest.js | 15 +++++++++----- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/lib/plugins/entities.js b/lib/plugins/entities.js index 0ec573f8b..740fcb742 100644 --- a/lib/plugins/entities.js +++ b/lib/plugins/entities.js @@ -601,7 +601,7 @@ function inject (bot) { console.log('Player Info', packet) // player list item(s) - if (bot.registry.version['>=']('1.21.3')) { + if (typeof packet.action === 'string') { // the features checks below this will be un-needed with https://github.com/PrismarineJS/minecraft-data/pull/948 for (const update of packet.data) { let player = bot.uuidToUsername[update.uuid] ? bot.players[bot.uuidToUsername[update.uuid]] : null diff --git a/package.json b/package.json index c2df60783..7b69e2f79 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "index.js", "types": "index.d.ts", "scripts": { - "mocha_test": "mocha --reporter spec --exit --bail", + "mocha_test": "mocha --reporter spec --exit", "test": "npm run mocha_test", "pretest": "npm run lint", "lint": "standard && standard-markdown", diff --git a/test/externalTests/plugins/testCommon.js b/test/externalTests/plugins/testCommon.js index 2876cef0c..78506ee2c 100644 --- a/test/externalTests/plugins/testCommon.js +++ b/test/externalTests/plugins/testCommon.js @@ -143,18 +143,20 @@ function inject (bot) { } // DEBUG - bot._client.on('packet', function (data, meta) { - if (['chunk', 'time', 'light', 'alive'].some(e => meta.name.includes(e))) return - console.log('->', meta.name, JSON.stringify(data)?.slice(0, 250)) - }) - const oldWrite = bot._client.write - bot._client.write = function (name, data) { - if (['alive', 'pong', 'ping'].some(e => name.includes(e))) return - console.log('<-', name, JSON.stringify(data)?.slice(0, 250)) - oldWrite.apply(bot._client, arguments) - } - BigInt.prototype.toJSON ??= function () { - return this.toString() + if (process.env.DEBUG) { + bot._client.on('packet', function (data, meta) { + if (['chunk', 'time', 'light', 'alive'].some(e => meta.name.includes(e))) return + console.log('->', meta.name, JSON.stringify(data)?.slice(0, 250)) + }) + const oldWrite = bot._client.write + bot._client.write = function (name, data) { + if (['alive', 'pong', 'ping'].some(e => name.includes(e))) return + console.log('<-', name, JSON.stringify(data)?.slice(0, 250)) + oldWrite.apply(bot._client, arguments) + } + BigInt.prototype.toJSON ??= function () { // eslint-disable-line + return this.toString() + } } // you need to be in creative mode for this to work diff --git a/test/internalTest.js b/test/internalTest.js index ae28a1fda..69b0535a9 100644 --- a/test/internalTest.js +++ b/test/internalTest.js @@ -11,8 +11,13 @@ for (const supportedVersion of mineflayer.testedVersions) { const registry = require('prismarine-registry')(supportedVersion) const version = registry.version const Chunk = require('prismarine-chunk')(supportedVersion) - const hasSignedChat = registry.supportFeature('signedChat') + const isNewPlayerInfoFormat = registry.version['>=']('1.20.3') + function wrapPlayerInfo (n) { + if (isNewPlayerInfoFormat) return { _value: n } + return n + } + const hasSignedChat = registry.supportFeature('signedChat') function chatText (text) { // TODO: move this to prismarine-chat in a new ChatMessage(text).toNotch(asNbt) method return registry.supportFeature('chatPacketsUseNbtComponents') @@ -580,7 +585,7 @@ for (const supportedVersion of mineflayer.testedVersions) { assert.strictEqual(entity.username, player.displayName.toString()) if (registry.supportFeature('playerInfoActionIsBitfield')) { client.write('player_info', { - action: 53, + action: wrapPlayerInfo(53), data: [{ uuid: '1-2-3-4', player: { @@ -616,7 +621,7 @@ for (const supportedVersion of mineflayer.testedVersions) { assert.strictEqual('wvffle', player.displayName.toString()) if (registry.supportFeature('playerInfoActionIsBitfield')) { client.write('player_info', { - action: 53, + action: wrapPlayerInfo(53), data: [{ uuid: '1-2-3-4', player: { @@ -653,7 +658,7 @@ for (const supportedVersion of mineflayer.testedVersions) { if (registry.supportFeature('playerInfoActionIsBitfield')) { client.write('player_info', { - action: 53, + action: wrapPlayerInfo(53), data: [{ uuid: '1-2-3-4', player: { @@ -736,7 +741,7 @@ for (const supportedVersion of mineflayer.testedVersions) { if (registry.supportFeature('playerInfoActionIsBitfield')) { client.write('player_info', { - action: 53, + action: wrapPlayerInfo(53), data: [{ uuid: '1-2-3-4', player: { From f16f406528553affd626d4fab650f90b52148870 Mon Sep 17 00:00:00 2001 From: extremeheat Date: Tue, 7 Jan 2025 07:11:38 -0500 Subject: [PATCH 13/13] Update internalTest.js typo --- test/internalTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/internalTest.js b/test/internalTest.js index 69b0535a9..6e5f278cd 100644 --- a/test/internalTest.js +++ b/test/internalTest.js @@ -11,7 +11,7 @@ for (const supportedVersion of mineflayer.testedVersions) { const registry = require('prismarine-registry')(supportedVersion) const version = registry.version const Chunk = require('prismarine-chunk')(supportedVersion) - const isNewPlayerInfoFormat = registry.version['>=']('1.20.3') + const isNewPlayerInfoFormat = registry.version['>=']('1.21.3') function wrapPlayerInfo (n) { if (isNewPlayerInfoFormat) return { _value: n } return n