mineflayer 4.31.0 → 4.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "gh-helpers": "^1.0.0"
4
+ }
5
+ }
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Updator script triggered from minecraft-data repository to auto generate PR
4
+ */
5
+ const fs = require('fs')
6
+ const cp = require('child_process')
7
+ const assert = require('assert')
8
+ const github = require('gh-helpers')()
9
+ const { join } = require('path')
10
+ const exec = (cmd) => github.mock ? console.log('> ', cmd) : (console.log('> ', cmd), cp.execSync(cmd, { stdio: 'inherit' }))
11
+
12
+ console.log('Starting update process...')
13
+ // Sanitize and validate environment variables all non alpha numeric / underscore / dot
14
+ const newVersion = process.env.NEW_MC_VERSION?.replace(/[^a-zA-Z0-9_.]/g, '_')
15
+ const triggerBranch = process.env.MCDATA_BRANCH?.replace(/[^a-zA-Z0-9_.]/g, '_')
16
+ const mcdataPrURL = process.env.MCDATA_PR_URL
17
+ console.log({ newVersion, triggerBranch, mcdataPrURL })
18
+
19
+ assert(newVersion)
20
+ assert(triggerBranch)
21
+
22
+ async function main () {
23
+ const currentSupportedPath = require.resolve('../../lib/version.js')
24
+ const readmePath = join(__dirname, '../../docs/README.md')
25
+ const ciPath = join(__dirname, '../../.github/workflows/ci.yml')
26
+
27
+ // Update the version.js
28
+ const currentSupportedVersion = require('../../lib/version.js')
29
+ const currentContents = fs.readFileSync(currentSupportedPath, 'utf8')
30
+ console.log('Current supported version:', currentContents)
31
+ const latestV = currentSupportedVersion.testedVersions.at(-1)
32
+ const newContents = currentContents.includes(newVersion)
33
+ ? currentContents
34
+ : currentContents
35
+ .replace(`, '${latestV}'`, `, '${latestV}', '${newVersion}'`)
36
+
37
+ // Update the README.md
38
+ const currentContentsReadme = fs.readFileSync(readmePath, 'utf8')
39
+ if (!currentContentsReadme.includes(newVersion)) {
40
+ const newReadmeContents = currentContentsReadme
41
+ .replace(/Minecraft 1\.8 to [0-9A-Za-z._-]+ \(/, `Minecraft 1.8 to ${newVersion} (`)
42
+ .replace(') <!--version-->', `, ${newVersion}) <!--version-->`)
43
+ fs.writeFileSync(readmePath, newReadmeContents)
44
+ console.log('Updated README with new version:', newVersion)
45
+ }
46
+ fs.writeFileSync(currentSupportedPath, newContents)
47
+
48
+ // Update the CI workflow
49
+ const currentContentsCI = fs.readFileSync(ciPath, 'utf8')
50
+ if (!currentContentsCI.includes(newVersion)) {
51
+ const newCIContents = currentContentsCI.replace(
52
+ 'run: npm install', `run: npm install
53
+ - run: cd node_modules && cd minecraft-data && mv minecraft-data minecraft-data-old && git clone -b ${triggerBranch} https://github.com/PrismarineJS/minecraft-data --depth 1 && node bin/generate_data.js
54
+ - 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
55
+ `)
56
+ fs.writeFileSync(ciPath, newCIContents)
57
+ console.log('Updated CI workflow with new version:', newVersion)
58
+ }
59
+
60
+ const branchName = 'pc' + newVersion.replace(/[^a-zA-Z0-9_]/g, '_')
61
+ exec(`git checkout -b ${branchName}`)
62
+ exec('git config user.name "github-actions[bot]"')
63
+ exec('git config user.email "41898282+github-actions[bot]@users.noreply.github.com"')
64
+ exec('git add --all')
65
+ exec(`git commit -m "Update to version ${newVersion}"`)
66
+ exec(`git push origin ${branchName} --force`)
67
+ // createPullRequest(title: string, body: string, fromBranch: string, intoBranch?: string): Promise<{ number: number, url: string }>;
68
+ const pr = await github.createPullRequest(
69
+ `🎈 ${newVersion}`,
70
+ `This automated PR sets up the relevant boilerplate for Minecraft version ${newVersion}.
71
+
72
+ Ref: ${mcdataPrURL}
73
+
74
+ * You can help contribute to this PR by opening a PR against this <code branch>${branchName}</code> branch instead of <code>master</code>.
75
+ `,
76
+ branchName,
77
+ 'master'
78
+ )
79
+ console.log(`Pull request created`, pr)
80
+ }
81
+
82
+ main().catch(err => {
83
+ console.error('Error during update process:', err)
84
+ process.exit(1)
85
+ })
@@ -0,0 +1,54 @@
1
+ name: Update from minecraft-data
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ new_mc_version:
7
+ description: New minecraft version number
8
+ required: true
9
+ type: string
10
+ mcdata_branch:
11
+ description: minecraft-data branch for this version
12
+ required: true
13
+ type: string
14
+ mcdata_pr_url:
15
+ description: minecraft-data PR number to open a PR here against
16
+ required: false
17
+ default: ''
18
+ type: string
19
+ nmp_branch:
20
+ description: minecraft-protocol branch for this version
21
+ required: true
22
+ type: string
23
+ nmp_pr_url:
24
+ description: minecraft-protocol PR number to open a PR here against
25
+ required: false
26
+ default: ''
27
+ type: string
28
+
29
+ jobs:
30
+ update:
31
+ runs-on: ubuntu-latest
32
+
33
+ steps:
34
+ - name: Checkout repository
35
+ uses: actions/checkout@v4
36
+ with:
37
+ token: ${{ secrets.PAT_PASSWORD }}
38
+
39
+ - name: Use Node.js 22.x
40
+ uses: actions/setup-node@v1.4.4
41
+ with:
42
+ node-version: 22.x
43
+
44
+ - run: npm install PrismarineJS/node-minecraft-protocol#${{ github.event.inputs.nmp_branch }}
45
+
46
+ - name: Run updator script
47
+ run: cd .github/helper && npm install && node updator.js
48
+ env:
49
+ GITHUB_TOKEN: ${{ secrets.PAT_PASSWORD }}
50
+ NEW_MC_VERSION: ${{ github.event.inputs.new_mc_version }}
51
+ MCDATA_BRANCH: ${{ github.event.inputs.mcdata_branch }}
52
+ MCDATA_PR_URL: ${{ github.event.inputs.mcdata_pr_url }}
53
+ NMP_BRANCH: ${{ github.event.inputs.nmp_branch }}
54
+ NMP_PR_URL: ${{ github.event.inputs.nmp_pr_url }}
package/README.md CHANGED
@@ -17,7 +17,7 @@ First time using Node.js? You may want to start with the [tutorial](tutorial.md)
17
17
 
18
18
  ## Features
19
19
 
20
- * Supports Minecraft 1.8 to 1.21 (1.8, 1.9, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, and 1.21)
20
+ * Supports Minecraft 1.8 to 1.21 (1.8, 1.9, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.21) <!--version-->
21
21
  * Entity knowledge and tracking.
22
22
  * Block knowledge. You can query the world around you. Milliseconds to find any block.
23
23
  * Physics and movement - handle all bounding boxes
package/docs/README.md CHANGED
@@ -17,7 +17,7 @@ First time using Node.js? You may want to start with the [tutorial](tutorial.md)
17
17
 
18
18
  ## Features
19
19
 
20
- * Supports Minecraft 1.8 to 1.21 (1.8, 1.9, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, and 1.21)
20
+ * Supports Minecraft 1.8 to 1.21 (1.8, 1.9, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.21) <!--version-->
21
21
  * Entity knowledge and tracking.
22
22
  * Block knowledge. You can query the world around you. Milliseconds to find any block.
23
23
  * Physics and movement - handle all bounding boxes
package/docs/history.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 4.33.0
2
+ * [Add update workflow (#3727)](https://github.com/PrismarineJS/mineflayer/commit/9c335366d435b58cfe45bbfbbc534b99ee669dc2) (thanks @extremeheat)
3
+ * [Add support for Minecraft 1.21.8 (#3732)](https://github.com/PrismarineJS/mineflayer/commit/ec8220d7c63b72acb4bf16f30cdf4ba346b83f98) (thanks @rom1504)
4
+
5
+ ## 4.32.0
6
+ * [1.21.6 (#3713)](https://github.com/PrismarineJS/mineflayer/commit/01f537c394fc78bf2e765b28a8b24a30c1d1fd2e) (thanks @extremeheat)
7
+ * [Fix knockback physics crash (#3715)](https://github.com/PrismarineJS/mineflayer/commit/e3f89d17418ece9e9fac4b111d8243dfe1a5d376) (thanks @Omena0)
8
+
1
9
  ## 4.31.0
2
10
  * [Cursor 1 21 5 (#3701)](https://github.com/PrismarineJS/mineflayer/commit/8770129d26a85f9b077d2a8969d45436fa09c3f3) (thanks @rom1504)
3
11
 
package/lib/loader.js CHANGED
@@ -74,6 +74,10 @@ function createBot (options = {}) {
74
74
  const bot = new EventEmitter()
75
75
  bot._client = options.client
76
76
  bot.end = (reason) => bot._client.end(reason)
77
+ bot._warn = function (...message) {
78
+ if (options.hideErrors) return
79
+ console.warn('[mineflayer]', ...message)
80
+ }
77
81
  if (options.logErrors) {
78
82
  bot.on('error', err => {
79
83
  if (!options.hideErrors) {
@@ -167,7 +167,7 @@ function inject (bot) {
167
167
  }
168
168
 
169
169
  bot._client.on('game_state_change', (packet) => {
170
- if (packet.reason === 0) {
170
+ if (packet.reason === 0 || packet.reason === 'no_respawn_block_available') {
171
171
  // occurs when you can't spawn in your bed and your spawn point gets reset
172
172
  bot.emit('spawnReset')
173
173
  }
@@ -116,10 +116,10 @@ function inject (bot, options) {
116
116
  })
117
117
 
118
118
  bot._client.on('game_state_change', (packet) => {
119
- if (packet?.reason === 4 && packet?.gameMode === 1) {
119
+ if ((packet.reason === 4 || packet.reason === 'win_game') && packet.gameMode === 1) {
120
120
  bot._client.write('client_command', { action: 0 })
121
121
  }
122
- if (packet.reason === 3) {
122
+ if ((packet.reason === 3) || (packet.reason === 'change_game_mode')) {
123
123
  bot.game.gameMode = parseGameMode(packet.gameMode)
124
124
  bot.emit('game')
125
125
  }
@@ -232,7 +232,7 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) {
232
232
  }
233
233
  bot._client.write('entity_action', {
234
234
  entityId: bot.entity.id,
235
- actionId: 8,
235
+ actionId: bot.supportFeature('entityActionUsesStringMapper') ? 'start_elytra_flying' : 8,
236
236
  jumpBoost: 0
237
237
  })
238
238
  }
@@ -247,15 +247,27 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) {
247
247
  } else if (control === 'sprint') {
248
248
  bot._client.write('entity_action', {
249
249
  entityId: bot.entity.id,
250
- actionId: state ? 3 : 4,
250
+ actionId: bot.supportFeature('entityActionUsesStringMapper')
251
+ ? (state ? 'start_sprinting' : 'stop_sprinting')
252
+ : (state ? 3 : 4),
251
253
  jumpBoost: 0
252
254
  })
253
255
  } else if (control === 'sneak') {
254
- bot._client.write('entity_action', {
255
- entityId: bot.entity.id,
256
- actionId: state ? 0 : 1,
257
- jumpBoost: 0
258
- })
256
+ if (bot.supportFeature('newPlayerInputPacket')) {
257
+ // In 1.21.6+, sneak is handled via player_input packet
258
+ bot._client.write('player_input', {
259
+ inputs: {
260
+ shift: state
261
+ }
262
+ })
263
+ } else {
264
+ // Legacy entity_action approach for older versions
265
+ bot._client.write('entity_action', {
266
+ entityId: bot.entity.id,
267
+ actionId: state ? 0 : 1,
268
+ jumpBoost: 0
269
+ })
270
+ }
259
271
  }
260
272
  }
261
273
 
@@ -296,7 +308,10 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) {
296
308
  // TODO: emit an explosion event with more info
297
309
  if (bot.physicsEnabled && bot.game.gameMode !== 'creative') {
298
310
  if (explosion.playerKnockback) { // 1.21.3+
299
- bot.entity.velocity.add(explosion.playerMotionX, explosion.playerMotionY, explosion.playerMotionZ)
311
+ // Fixes issue #3635
312
+ bot.entity.velocity.x += explosion.playerKnockback.x
313
+ bot.entity.velocity.y += explosion.playerKnockback.y
314
+ bot.entity.velocity.z += explosion.playerKnockback.z
300
315
  }
301
316
  if ('playerMotionX' in explosion) {
302
317
  bot.entity.velocity.x += explosion.playerMotionX
@@ -1,20 +1,22 @@
1
1
  module.exports = inject
2
+ const states = ['no_respawn_block_available', 'start_raining', 'stop_raining', 'change_game_mode', 'win_game', 'demo_event', 'play_arrow_hit_sound', 'rain_level_change', 'thunder_level_change', 'puffer_fish_sting', 'guardian_elder_effect', 'immediate_respawn', 'limited_crafting', 'level_chunks_load_start']
2
3
 
3
4
  function inject (bot) {
4
5
  bot.isRaining = false
5
6
  bot.thunderState = 0
6
7
  bot.rainState = 0
7
8
  bot._client.on('game_state_change', (packet) => {
8
- if (packet.reason === 1) {
9
+ const reason = states[packet.reason] ?? packet.reason
10
+ if (reason === 'start_raining') {
9
11
  bot.isRaining = true
10
12
  bot.emit('rain')
11
- } else if (packet.reason === 2) {
13
+ } else if (reason === 'stop_raining') {
12
14
  bot.isRaining = false
13
15
  bot.emit('rain')
14
- } else if (packet.reason === 7) {
16
+ } else if (reason === 'rain_level_change') {
15
17
  bot.rainState = packet.gameMode
16
18
  bot.emit('weatherUpdate')
17
- } else if (packet.reason === 8) {
19
+ } else if (reason === 'thunder_level_change') {
18
20
  bot.thunderState = packet.gameMode
19
21
  bot.emit('weatherUpdate')
20
22
  }
@@ -1,41 +1,49 @@
1
1
  module.exports = inject
2
2
 
3
+ // TODO: apply this to all versions and rename scoreboard_team -> teams in minecraft-data
4
+ const TEAM_MODES = ['add', 'remove', 'change', 'join', 'leave']
5
+
3
6
  function inject (bot) {
4
7
  const Team = require('../team')(bot.registry)
5
8
  const teams = {}
6
9
 
7
10
  function teamHandler (packet) {
8
- const { team: teamName, mode } = packet
11
+ const { team: teamName, players = [] } = packet
12
+ const mode = typeof packet.mode === 'number' ? TEAM_MODES[packet.mode] : packet.mode
13
+
9
14
  let team = teams[teamName]
10
- if (mode === 0) {
11
- team = new Team(
12
- packet.team,
13
- packet.name,
14
- packet.friendlyFire,
15
- packet.nameTagVisibility,
16
- packet.collisionRule,
17
- packet.formatting,
18
- packet.prefix,
19
- packet.suffix
20
- )
21
- if (Array.isArray(packet.players)) {
22
- packet.players.forEach(player => {
15
+
16
+ switch (mode) {
17
+ case 'add':
18
+ team = new Team(
19
+ teamName,
20
+ packet.name,
21
+ packet.friendlyFire,
22
+ packet.nameTagVisibility,
23
+ packet.collisionRule,
24
+ packet.formatting,
25
+ packet.prefix,
26
+ packet.suffix
27
+ )
28
+ for (const player of players) {
23
29
  team.add(player)
24
30
  bot.teamMap[player] = team
25
- })
26
- }
27
- teams[teamName] = team
28
- bot.emit('teamCreated', teams[teamName])
29
- }
30
- if (team !== undefined) {
31
- if (mode === 1) {
32
- team.members.forEach(member => {
31
+ }
32
+ teams[teamName] = team
33
+ bot.emit('teamCreated', teams[teamName])
34
+ break
35
+
36
+ case 'remove':
37
+ if (!team) break
38
+ team.members.forEach((member) => {
33
39
  delete bot.teamMap[member]
34
40
  })
35
41
  delete teams[teamName]
36
42
  bot.emit('teamRemoved', teams[teamName])
37
- }
38
- if (mode === 2) {
43
+ break
44
+
45
+ case 'change':
46
+ if (!team) break
39
47
  team.update(
40
48
  packet.name,
41
49
  packet.friendlyFire,
@@ -46,23 +54,28 @@ function inject (bot) {
46
54
  packet.suffix
47
55
  )
48
56
  bot.emit('teamUpdated', teams[teamName])
49
- }
50
- if (Array.isArray(packet.players)) {
51
- if (mode === 3) {
52
- packet.players.forEach((player) => {
53
- team.add(player)
54
- bot.teamMap[player] = team
55
- })
56
- bot.emit('teamMemberAdded', teams[teamName])
57
+ break
58
+
59
+ case 'join':
60
+ if (!team) break
61
+ for (const player of players) {
62
+ team.add(player)
63
+ bot.teamMap[player] = team
57
64
  }
58
- if (mode === 4) {
59
- packet.players.forEach((player) => {
60
- team.remove(player)
61
- delete bot.teamMap[player]
62
- })
63
- bot.emit('teamMemberRemoved', teams[teamName])
65
+ bot.emit('teamMemberAdded', teams[teamName])
66
+ break
67
+
68
+ case 'leave':
69
+ if (!team) break
70
+ for (const player of players) {
71
+ team.remove(player)
72
+ delete bot.teamMap[player]
64
73
  }
65
- }
74
+ bot.emit('teamMemberRemoved', teams[teamName])
75
+ break
76
+
77
+ default:
78
+ bot._warn(`Unknown team mode handling team update: ${mode}`)
66
79
  }
67
80
  }
68
81
 
package/lib/version.js CHANGED
@@ -1,4 +1,4 @@
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', '1.21.4', '1.21.5']
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', '1.21.4', '1.21.5', '1.21.6', '1.21.8']
2
2
  module.exports = {
3
3
 
4
4
  testedVersions,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mineflayer",
3
- "version": "4.31.0",
3
+ "version": "4.33.0",
4
4
  "description": "create minecraft bots with a stable, high level API",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -21,8 +21,8 @@
21
21
  },
22
22
  "license": "MIT",
23
23
  "dependencies": {
24
- "minecraft-data": "^3.76.0",
25
- "minecraft-protocol": "^1.60.0",
24
+ "minecraft-data": "^3.98.0",
25
+ "minecraft-protocol": "^1.61.0",
26
26
  "prismarine-biome": "^1.1.1",
27
27
  "prismarine-block": "^1.22.0",
28
28
  "prismarine-chat": "^1.7.1",