mineflayer 3.11.0 → 3.13.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.
Files changed (43) hide show
  1. package/.github/FUNDING.yml +0 -2
  2. package/README.md +16 -15
  3. package/docs/README.md +16 -15
  4. package/docs/api.md +25 -16
  5. package/docs/es/README_ES.md +1 -1
  6. package/docs/es/api_es.md +34 -18
  7. package/docs/fr/README_FR.md +1 -1
  8. package/docs/history.md +29 -0
  9. package/docs/ru/README_RU.md +1 -1
  10. package/docs/ru/api_ru.md +1 -1
  11. package/docs/tr/README_TR.md +1 -1
  12. package/docs/zh/README_ZH_CN.md +1 -1
  13. package/examples/chatterbox.js +1 -1
  14. package/examples/discord.js +15 -5
  15. package/examples/python/basic.py +2 -2
  16. package/examples/python/chatterbox.py +1 -1
  17. package/examples/screenshot-with-node-canvas-webgl/screenshot.js +2 -2
  18. package/index.d.ts +99 -97
  19. package/lib/conversions.js +1 -1
  20. package/lib/loader.js +4 -4
  21. package/lib/plugins/bed.js +1 -1
  22. package/lib/plugins/block_actions.js +1 -1
  23. package/lib/plugins/blocks.js +18 -4
  24. package/lib/plugins/chat.js +2 -0
  25. package/lib/plugins/command_block.js +1 -1
  26. package/lib/plugins/creative.js +1 -1
  27. package/lib/plugins/digging.js +2 -17
  28. package/lib/plugins/entities.js +13 -9
  29. package/lib/plugins/explosion.js +3 -1
  30. package/lib/plugins/game.js +7 -0
  31. package/lib/plugins/generic_place.js +5 -10
  32. package/lib/plugins/inventory.js +17 -9
  33. package/lib/plugins/physics.js +16 -5
  34. package/lib/plugins/place_block.js +1 -1
  35. package/lib/plugins/place_entity.js +11 -5
  36. package/lib/plugins/ray_trace.js +10 -0
  37. package/lib/plugins/scoreboard.js +2 -9
  38. package/lib/plugins/sound.js +1 -1
  39. package/lib/plugins/spawn_point.js +1 -1
  40. package/lib/plugins/villager.js +2 -3
  41. package/lib/scoreboard.js +48 -35
  42. package/lib/version.js +1 -1
  43. package/package.json +23 -22
@@ -1,5 +1,4 @@
1
1
  const assert = require('assert')
2
- const { once } = require('events')
3
2
  module.exports = inject
4
3
 
5
4
  function inject (bot, { version }) {
@@ -8,7 +7,7 @@ function inject (bot, { version }) {
8
7
  *
9
8
  * @param {import('prismarine-block').Block} referenceBlock
10
9
  * @param {import('vec3').Vec3} faceVector
11
- * @param {{half?: 'top'|'bottom', delta?: import('vec3').Vec3, forceLook?: boolean | 'ignore', offhand?: boolean}} options
10
+ * @param {{half?: 'top'|'bottom', delta?: import('vec3').Vec3, forceLook?: boolean | 'ignore', offhand?: boolean, swingArm?: 'right' | 'left', showHand?: boolean}} options
12
11
  */
13
12
  async function _genericPlace (referenceBlock, faceVector, options) {
14
13
  let handToPlaceWith = 0
@@ -40,6 +39,10 @@ function inject (bot, { version }) {
40
39
  // TODO: tell the server that we are sneaking while doing this
41
40
  const pos = referenceBlock.position
42
41
 
42
+ if (options.swingArm) {
43
+ bot.swingArm(options.swingArm, options.showHand)
44
+ }
45
+
43
46
  if (bot.supportFeature('blockPlaceHasHeldItem')) {
44
47
  const packet = {
45
48
  location: pos,
@@ -80,14 +83,6 @@ function inject (bot, { version }) {
80
83
  })
81
84
  }
82
85
 
83
- if (bot.game.gameMode !== 'creative') {
84
- if (handToPlaceWith === 0) {
85
- await once(bot.inventory, `updateSlot:${bot.heldItem.slot}`)
86
- } else {
87
- await once(bot.inventory, 'updateSlot:45')
88
- }
89
- }
90
-
91
86
  return pos
92
87
  }
93
88
  bot._genericPlace = _genericPlace
@@ -118,7 +118,7 @@ function inject (bot, { version, hideErrors }) {
118
118
  bot.usingHeldItem = false
119
119
  }
120
120
 
121
- async function putSelectedItemRange (start, end, window, slot, noWaiting = false) {
121
+ async function putSelectedItemRange (start, end, window, slot) {
122
122
  // put the selected item back indow the slot range in window
123
123
 
124
124
  // try to put it in an item that already exists and just increase
@@ -427,13 +427,24 @@ function inject (bot, { version, hideErrors }) {
427
427
  function confirmTransaction (windowId, actionId, accepted) {
428
428
  // drop the queue entries for all the clicks that the server did not send
429
429
  // transaction packets for.
430
- let click = windowClickQueue.shift()
431
- if (click === undefined) {
430
+ // Also reject transactions that aren't sent from mineflayer
431
+ let click = windowClickQueue[0]
432
+ if (click === undefined || !windowClickQueue.some(clicks => clicks.id === actionId)) {
433
+ // mimic vanilla client and send a rejection for faulty transaction packets
434
+ bot._client.write('transaction', {
435
+ windowId: windowId,
436
+ action: actionId,
437
+ accepted: true
438
+ // bot.emit(`confirmTransaction${click.id}`, false)
439
+ })
432
440
  if (!hideErrors) {
433
441
  console.log(`WARNING : unknown transaction confirmation for window ${windowId}, action ${actionId} and accepted ${accepted}`)
434
442
  }
435
443
  return
436
444
  }
445
+ // shift it later if packets are sent out of order
446
+ click = windowClickQueue.shift()
447
+
437
448
  assert.ok(click.id <= actionId)
438
449
  while (actionId > click.id) {
439
450
  onAccepted()
@@ -534,20 +545,20 @@ function inject (bot, { version, hideErrors }) {
534
545
  }
535
546
  const [success] = await response
536
547
  if (!success) {
537
- throw new Error(`Server rejected transaction for clicking on slot ${slot}, on window ${JSON.stringify(window.slots, null, 2)}.`)
548
+ throw new Error(`Server rejected transaction for clicking on slot ${slot}, on window with id ${window?.id}.`)
538
549
  }
539
550
  } else {
540
551
  await waitForWindowUpdate(window, slot)
541
552
  }
542
553
  }
543
554
 
544
- async function putAway (slot, noWaiting = false) {
555
+ async function putAway (slot) {
545
556
  const window = bot.currentWindow || bot.inventory
546
557
  const promisePutAway = once(window, `updateSlot:${slot}`)
547
558
  await clickWindow(slot, 0, 0)
548
559
  const start = window.inventoryStart
549
560
  const end = window.inventoryEnd
550
- await putSelectedItemRange(start, end, window, null, noWaiting)
561
+ await putSelectedItemRange(start, end, window, null)
551
562
  await promisePutAway
552
563
  }
553
564
 
@@ -564,9 +575,6 @@ function inject (bot, { version, hideErrors }) {
564
575
 
565
576
  bot._client.on('transaction', (packet) => {
566
577
  // confirm transaction
567
- if (packet.action < 0) {
568
- return
569
- }
570
578
  confirmTransaction(packet.windowId, packet.action, packet.accepted)
571
579
  })
572
580
 
@@ -1,4 +1,4 @@
1
- const Vec3 = require('vec3').Vec3
1
+ const { Vec3 } = require('vec3')
2
2
  const assert = require('assert')
3
3
  const math = require('../math')
4
4
  const conv = require('../conversions')
@@ -33,6 +33,7 @@ function inject (bot, { physicsEnabled }) {
33
33
  sneak: false
34
34
  }
35
35
  let lastSentYaw = null
36
+ let lastSentPitch = null
36
37
  let doPhysicsTimer = null
37
38
  let lastPhysicsFrameTime = null
38
39
  let shouldUsePhysics = false
@@ -122,13 +123,16 @@ function inject (bot, { physicsEnabled }) {
122
123
 
123
124
  // Increment the yaw in baby steps so that notchian clients (not the server) can keep up.
124
125
  const dYaw = deltaYaw(bot.entity.yaw, lastSentYaw)
126
+ const dPitch = bot.entity.pitch - (lastSentPitch || 0)
125
127
 
126
128
  // Vanilla doesn't clamp yaw, so we don't want to do it either
127
129
  const maxDeltaYaw = dt * physics.yawSpeed
130
+ const maxDeltaPitch = dt * physics.pitchSpeed
128
131
  lastSentYaw += math.clamp(-maxDeltaYaw, dYaw, maxDeltaYaw)
132
+ lastSentPitch += math.clamp(-maxDeltaPitch, dPitch, maxDeltaPitch)
129
133
 
130
- const yaw = conv.toNotchianYaw(lastSentYaw)
131
- const pitch = conv.toNotchianPitch(bot.entity.pitch)
134
+ const yaw = Math.fround(conv.toNotchianYaw(lastSentYaw))
135
+ const pitch = Math.fround(conv.toNotchianPitch(lastSentPitch))
132
136
  const position = bot.entity.position
133
137
  const onGround = bot.entity.onGround
134
138
 
@@ -225,8 +229,15 @@ function inject (bot, { physicsEnabled }) {
225
229
  }
226
230
  lookingTask = createTask()
227
231
 
228
- bot.entity.yaw = yaw
229
- bot.entity.pitch = pitch
232
+ // this is done to bypass certain anticheat checks that detect the player's sensitivity
233
+ // by calculating the gcd of how much they move the mouse each tick
234
+ const sensitivity = conv.fromNotchianPitch(0.15) // this is equal to 100% sensitivity in vanilla
235
+ const yawChange = Math.round((yaw - bot.entity.yaw) / sensitivity) * sensitivity
236
+ const pitchChange = Math.round((pitch - bot.entity.pitch) / sensitivity) * sensitivity
237
+
238
+ bot.entity.yaw += yawChange
239
+ bot.entity.pitch += pitchChange
240
+
230
241
  if (force) {
231
242
  lastSentYaw = yaw
232
243
  return
@@ -21,7 +21,7 @@ function inject (bot) {
21
21
  }
22
22
 
23
23
  async function placeBlock (referenceBlock, faceVector) {
24
- await placeBlockWithOptions(referenceBlock, faceVector, {})
24
+ await placeBlockWithOptions(referenceBlock, faceVector, { swingArm: 'right' })
25
25
  }
26
26
 
27
27
  bot.placeBlock = callbackify(placeBlock)
@@ -5,6 +5,12 @@ module.exports = inject
5
5
  function inject (bot, { version }) {
6
6
  const Item = require('prismarine-item')(version)
7
7
 
8
+ /**
9
+ *
10
+ * @param {import('prismarine-block').Block} referenceBlock
11
+ * @param {import('vec3').Vec3} faceVector
12
+ * @param {{forceLook?: boolean | 'ignore', offhand?: boolean, swingArm?: 'right' | 'left', showHand?: boolean}} options
13
+ */
8
14
  async function placeEntityWithOptions (referenceBlock, faceVector, options) {
9
15
  if (!bot.heldItem) throw new Error('must be holding an item to place an entity')
10
16
 
@@ -20,14 +26,14 @@ function inject (bot, { version }) {
20
26
  name = bot.heldItem.spawnEggMobName
21
27
  }
22
28
 
23
- const pos = await bot._genericPlace(referenceBlock, faceVector, options)
24
-
25
29
  if (type === 'spawn_egg') {
26
- bot.swingArm(undefined, false)
27
- } else {
28
- bot.swingArm()
30
+ options.showHand = false
29
31
  }
30
32
 
33
+ if (!options.swingArm) options.swingArm = options.offhand ? 'left' : 'right'
34
+
35
+ const pos = await bot._genericPlace(referenceBlock, faceVector, options)
36
+
31
37
  if (type === 'boat') {
32
38
  if (bot.supportFeature('useItemWithOwnPacket')) {
33
39
  bot._client.write('use_item', {
@@ -23,4 +23,14 @@ module.exports = (bot) => {
23
23
 
24
24
  return bot.world.raycast(eyePosition, viewDirection, maxDistance, matcher)
25
25
  }
26
+
27
+ bot.blockAtEntityCursor = (entity = bot.entity, maxDistance = 256, matcher = null) => {
28
+ if (!entity.position || !entity.height || !entity.pitch || !entity.yaw) return null
29
+ const { position, height, pitch, yaw } = entity
30
+
31
+ const eyePosition = position.offset(0, height, 0)
32
+ const viewDirection = getViewDirection(pitch, yaw)
33
+
34
+ return bot.world.raycast(eyePosition, viewDirection, maxDistance, matcher)
35
+ }
26
36
  }
@@ -1,9 +1,7 @@
1
- const ScoreBoard = require('../scoreboard')
2
-
3
1
  module.exports = inject
4
2
 
5
3
  function inject (bot) {
6
- const ChatMessage = require('prismarine-chat')(bot.version)
4
+ const ScoreBoard = require('../scoreboard')(bot)
7
5
  const scoreboards = {}
8
6
 
9
7
  bot._client.on('scoreboard_objective', (packet) => {
@@ -29,12 +27,7 @@ function inject (bot) {
29
27
  bot._client.on('scoreboard_score', (packet) => {
30
28
  const scoreboard = scoreboards[packet.scoreName]
31
29
  if (scoreboard !== undefined && packet.action === 0) {
32
- const { itemName, value } = packet
33
- let displayName = new ChatMessage(itemName)
34
- if (itemName in bot.teamMap) {
35
- displayName = bot.teamMap[itemName].displayName(itemName)
36
- }
37
- const updated = scoreboard.add(itemName, value, displayName)
30
+ const updated = scoreboard.add(packet.itemName, packet.value)
38
31
  bot.emit('scoreUpdated', scoreboard, updated)
39
32
  }
40
33
 
@@ -1,4 +1,4 @@
1
- const Vec3 = require('vec3').Vec3
1
+ const { Vec3 } = require('vec3')
2
2
 
3
3
  module.exports = inject
4
4
 
@@ -1,4 +1,4 @@
1
- const Vec3 = require('vec3').Vec3
1
+ const { Vec3 } = require('vec3')
2
2
 
3
3
  module.exports = inject
4
4
 
@@ -118,7 +118,6 @@ function inject (bot, { version }) {
118
118
  if (!ready) {
119
119
  ready = true
120
120
  villager.emit('ready')
121
- console.log('emit ready')
122
121
  }
123
122
  }
124
123
  }
@@ -205,12 +204,12 @@ function inject (bot, { version }) {
205
204
  }
206
205
  }
207
206
 
208
- await bot.putAway(2, true)
207
+ await bot.putAway(2)
209
208
  }
210
209
 
211
210
  for (const i of [0, 1]) {
212
211
  if (villager.slots[i]) {
213
- await bot.putAway(i, true) // 1.14+ whole stacks of items will automatically be placed , so there might be some left over
212
+ await bot.putAway(i) // 1.14+ whole stacks of items will automatically be placed , so there might be some left over
214
213
  }
215
214
  }
216
215
  }
package/lib/scoreboard.js CHANGED
@@ -4,49 +4,62 @@ const sortItems = (a, b) => {
4
4
  return 1
5
5
  }
6
6
 
7
- class ScoreBoard {
8
- constructor (packet) {
9
- this.name = packet.name
10
- this.setTitle(packet.displayText)
11
- this.itemsMap = {}
12
- }
7
+ module.exports = (bot) => {
8
+ const ChatMessage = require('prismarine-chat')(bot.version)
13
9
 
14
- setTitle (title) {
15
- try {
16
- this.title = JSON.parse(title).text // version>1.13
17
- } catch {
18
- this.title = title
10
+ class ScoreBoard {
11
+ constructor (packet) {
12
+ this.name = packet.name
13
+ this.setTitle(packet.displayText)
14
+ this.itemsMap = {}
19
15
  }
20
- }
21
16
 
22
- add (name, value, displayName) {
23
- this.itemsMap[name] = { name, value, displayName }
24
- return this.itemsMap[name]
25
- }
17
+ setTitle (title) {
18
+ try {
19
+ this.title = JSON.parse(title).text // version>1.13
20
+ } catch {
21
+ this.title = title
22
+ }
23
+ }
26
24
 
27
- remove (name) {
28
- const removed = this.itemsMap[name]
29
- delete this.itemsMap[name]
30
- return removed
31
- }
25
+ add (name, value) {
26
+ this.itemsMap[name] = { name, value }
27
+ this.itemsMap[name] = {
28
+ name,
29
+ value,
30
+ get displayName () {
31
+ if (name in bot.teamMap) {
32
+ return bot.teamMap[name].displayName(name)
33
+ }
34
+ return new ChatMessage(name)
35
+ }
36
+ }
37
+ return this.itemsMap[name]
38
+ }
32
39
 
33
- get items () {
34
- return Object.values(this.itemsMap).sort(sortItems)
40
+ remove (name) {
41
+ const removed = this.itemsMap[name]
42
+ delete this.itemsMap[name]
43
+ return removed
44
+ }
45
+
46
+ get items () {
47
+ return Object.values(this.itemsMap).sort(sortItems)
48
+ }
35
49
  }
36
- }
37
50
 
38
- ScoreBoard.positions = {
39
- get list () {
40
- return this[0]
41
- },
51
+ ScoreBoard.positions = {
52
+ get list () {
53
+ return this[0]
54
+ },
42
55
 
43
- get sidebar () {
44
- return this[1]
45
- },
56
+ get sidebar () {
57
+ return this[1]
58
+ },
46
59
 
47
- get belowName () {
48
- return this[2]
60
+ get belowName () {
61
+ return this[2]
62
+ }
49
63
  }
64
+ return ScoreBoard
50
65
  }
51
-
52
- module.exports = ScoreBoard
package/lib/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  module.exports = {
2
2
  supportedVersions: ['1.8', '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '1.15', '1.16', '1.17'],
3
3
  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']
4
- }
4
+ } // when updating testedVersions, make sure to update CI.yml
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mineflayer",
3
- "version": "3.11.0",
3
+ "version": "3.13.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,31 +21,32 @@
21
21
  },
22
22
  "license": "MIT",
23
23
  "dependencies": {
24
- "minecraft-data": "^2.79.0",
25
- "minecraft-protocol": "^1.17.0",
26
- "prismarine-biome": "^1.1.0",
27
- "prismarine-block": "^1.6.0",
28
- "prismarine-chat": "^1.1.0",
29
- "prismarine-chunk": "^1.24.0",
30
- "prismarine-entity": "^1.0.0",
31
- "prismarine-item": "^1.6.0",
32
- "prismarine-physics": "^1.0.4",
24
+ "minecraft-data": "^2.95.0",
25
+ "minecraft-protocol": "^1.26.5",
26
+ "prismarine-biome": "^1.1.1",
27
+ "prismarine-block": "^1.10.3",
28
+ "prismarine-chat": "^1.3.3",
29
+ "prismarine-chunk": "^1.26.0",
30
+ "prismarine-entity": "^1.2.0",
31
+ "prismarine-item": "^1.11.0",
32
+ "prismarine-nbt": "^2.0.0",
33
+ "prismarine-physics": "^1.3.1",
33
34
  "prismarine-recipe": "^1.1.0",
34
- "prismarine-windows": "^2.3.0",
35
+ "prismarine-windows": "^2.4.2",
35
36
  "prismarine-world": "^3.6.0",
36
- "protodef": "^1.8.0",
37
- "typed-emitter": "^1.2.0",
38
- "vec3": "^0.1.6"
37
+ "protodef": "^1.14.0",
38
+ "typed-emitter": "^1.3.1",
39
+ "vec3": "^0.1.7"
39
40
  },
40
41
  "devDependencies": {
41
- "@types/node": "^16.0.1",
42
- "doctoc": "^2.0.0",
43
- "minecraft-wrap": "^1.2.1",
42
+ "@types/node": "^17.0.0",
43
+ "doctoc": "^2.0.1",
44
+ "minecraft-wrap": "^1.3.0",
44
45
  "mineflayer": "file:.",
45
- "mocha": "^9.0.0",
46
- "standard": "^16.0.1",
47
- "standard-markdown": "^6.0.0",
48
- "ts-standard": "^10.0.0",
49
- "typescript": "^4.3.2"
46
+ "mocha": "^9.1.2",
47
+ "standard": "^16.0.4",
48
+ "standard-markdown": "^7.1.0",
49
+ "ts-standard": "^11.0.0",
50
+ "typescript": "^4.4.3"
50
51
  }
51
52
  }