mineflayer 4.19.0 → 4.20.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.
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.20.2 (1.8, 1.9, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19 and 1.20)
20
+ * Supports Minecraft 1.8 to 1.20.4 (1.8, 1.9, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19 and 1.20)
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.20.2 (1.8, 1.9, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19 and 1.20)
20
+ * Supports Minecraft 1.8 to 1.20.4 (1.8, 1.9, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19 and 1.20)
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/api.md CHANGED
@@ -1691,6 +1691,8 @@ the event will be called `"chat:name"`, with name being the name passed
1691
1691
 
1692
1692
  returns a number which can be used with bot.removeChatPattern() to only delete this pattern
1693
1693
 
1694
+ - :eyes: cf. [examples/chat_parsing](https://github.com/PrismarineJS/mineflayer/blob/master/examples/chat_parsing.js#L17-L36)
1695
+
1694
1696
  #### bot.addChatPatternSet(name, patterns, chatPatternOptions)
1695
1697
 
1696
1698
  make an event that is called every time all patterns havee been matched to messages,
@@ -1703,6 +1705,8 @@ the event will be called `"chat:name"`, with name being the name passed
1703
1705
 
1704
1706
  returns a number which can be used with bot.removeChatPattern() to only delete this patternset
1705
1707
 
1708
+ - :eyes: cf. [examples/chat_parsing](https://github.com/PrismarineJS/mineflayer/blob/master/examples/chat_parsing.js#L17-L36)
1709
+
1706
1710
  #### bot.removeChatPattern(name)
1707
1711
 
1708
1712
  removes a chat pattern(s)
package/docs/history.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 4.20.0
2
+ * [Update api.md - addChatPattern[Set] link to example of usage (#3304)](https://github.com/PrismarineJS/mineflayer/commit/bb3e5877b7b3b8ab063b39a5b47d103b819da1c2) (thanks @boly38)
3
+ * [Fixed deleted scoreboards not being removed from ScoreBoard.positions (#3306)](https://github.com/PrismarineJS/mineflayer/commit/643023df91bf428d3e7d30e8f2eab97e3238b0b2) (thanks @Ynfuien)
4
+ * [Support 1.20.4 (#3310)](https://github.com/PrismarineJS/mineflayer/commit/aa99daa7d63ee9549f2dda5a79c140e30e19a89b) (thanks @rom1504)
5
+
1
6
  ## 4.19.0
2
7
  * [Clarify readme createBot username handling (#3300)](https://github.com/PrismarineJS/mineflayer/commit/7a2680bc07f53d16626679537ea1f07aae180549) (thanks @extremeheat)
3
8
  * [fix world typing (#3302)](https://github.com/PrismarineJS/mineflayer/commit/5dc36d6cdeaf4be72ea023827d45b9d78e575f66) (thanks @GenerelSchwerz)
package/lib/bossbar.js CHANGED
@@ -1,101 +1,98 @@
1
- let ChatMessage
2
1
  const colors = ['pink', 'blue', 'red', 'green', 'yellow', 'purple', 'white']
3
2
  const divisions = [0, 6, 10, 12, 20]
4
3
 
5
- module.exports = loader
6
-
7
4
  function loader (registry) {
8
- ChatMessage = require('prismarine-chat')(registry)
9
- return BossBar
10
- }
11
-
12
- class BossBar {
13
- constructor (uuid, title, health, dividers, color, flags) {
14
- this._entityUUID = uuid
15
- this._title = new ChatMessage(JSON.parse(title))
16
- this._health = health
17
- this._dividers = divisions[dividers]
18
- this._color = colors[color]
19
- this._shouldDarkenSky = flags & 0x1
20
- this._isDragonBar = flags & 0x2
21
- this._createFog = flags & 0x4
22
- }
23
-
24
- set entityUUID (uuid) {
25
- this._entityUUID = uuid
26
- }
27
-
28
- set title (title) {
29
- this._title = new ChatMessage(JSON.parse(title))
30
- }
31
-
32
- set health (health) {
33
- this._health = health
34
- }
35
-
36
- set dividers (dividers) {
37
- this._dividers = divisions[dividers]
38
- }
39
-
40
- set color (color) {
41
- this._color = colors[color]
42
- }
43
-
44
- set flags (flags) {
45
- this._shouldDarkenSky = flags & 0x1
46
- this._isDragonBar = flags & 0x2
47
- this._createFog = flags & 0x4
48
- }
49
-
50
- get flags () {
51
- return (this._shouldDarkenSky) | (this._isDragonBar << 1) | (this._createFog << 2)
52
- }
53
-
54
- set shouldDarkenSky (darkenSky) {
55
- this._shouldDarkenSky = darkenSky
56
- }
57
-
58
- set isDragonBar (dragonBar) {
59
- this._isDragonBar = dragonBar
60
- }
61
-
62
- get createFog () {
63
- return this._createFog
64
- }
65
-
66
- set createFog (createFog) {
67
- this._createFog = createFog
68
- }
69
-
70
- get entityUUID () {
71
- return this._entityUUID
72
- }
73
-
74
- get title () {
75
- return this._title
76
- }
77
-
78
- get health () {
79
- return this._health
80
- }
81
-
82
- get dividers () {
83
- return this._dividers
84
- }
85
-
86
- get color () {
87
- return this._color
88
- }
89
-
90
- get shouldDarkenSky () {
91
- return this._shouldDarkenSky
92
- }
93
-
94
- get isDragonBar () {
95
- return this._isDragonBar
96
- }
97
-
98
- get shouldCreateFog () {
99
- return this._createFog
5
+ const ChatMessage = require('prismarine-chat')(registry)
6
+ return class BossBar {
7
+ constructor (uuid, title, health, dividers, color, flags) {
8
+ this._entityUUID = uuid
9
+ this._title = ChatMessage.fromNotch(title)
10
+ this._health = health
11
+ this._dividers = divisions[dividers]
12
+ this._color = colors[color]
13
+ this._shouldDarkenSky = flags & 0x1
14
+ this._isDragonBar = flags & 0x2
15
+ this._createFog = flags & 0x4
16
+ }
17
+
18
+ set entityUUID (uuid) {
19
+ this._entityUUID = uuid
20
+ }
21
+
22
+ set title (title) {
23
+ this._title = ChatMessage.fromNotch(title)
24
+ }
25
+
26
+ set health (health) {
27
+ this._health = health
28
+ }
29
+
30
+ set dividers (dividers) {
31
+ this._dividers = divisions[dividers]
32
+ }
33
+
34
+ set color (color) {
35
+ this._color = colors[color]
36
+ }
37
+
38
+ set flags (flags) {
39
+ this._shouldDarkenSky = flags & 0x1
40
+ this._isDragonBar = flags & 0x2
41
+ this._createFog = flags & 0x4
42
+ }
43
+
44
+ get flags () {
45
+ return (this._shouldDarkenSky) | (this._isDragonBar << 1) | (this._createFog << 2)
46
+ }
47
+
48
+ set shouldDarkenSky (darkenSky) {
49
+ this._shouldDarkenSky = darkenSky
50
+ }
51
+
52
+ set isDragonBar (dragonBar) {
53
+ this._isDragonBar = dragonBar
54
+ }
55
+
56
+ get createFog () {
57
+ return this._createFog
58
+ }
59
+
60
+ set createFog (createFog) {
61
+ this._createFog = createFog
62
+ }
63
+
64
+ get entityUUID () {
65
+ return this._entityUUID
66
+ }
67
+
68
+ get title () {
69
+ return this._title
70
+ }
71
+
72
+ get health () {
73
+ return this._health
74
+ }
75
+
76
+ get dividers () {
77
+ return this._dividers
78
+ }
79
+
80
+ get color () {
81
+ return this._color
82
+ }
83
+
84
+ get shouldDarkenSky () {
85
+ return this._shouldDarkenSky
86
+ }
87
+
88
+ get isDragonBar () {
89
+ return this._isDragonBar
90
+ }
91
+
92
+ get shouldCreateFog () {
93
+ return this._createFog
94
+ }
100
95
  }
101
96
  }
97
+
98
+ module.exports = loader
@@ -1,6 +1,6 @@
1
1
  const assert = require('assert')
2
2
  const { sleep } = require('../promise_utils')
3
- const { once } = require('events')
3
+ const { once } = require('../promise_utils')
4
4
 
5
5
  module.exports = inject
6
6
 
@@ -12,7 +12,7 @@ function inject (bot) {
12
12
  async function openAnvil (anvilBlock) {
13
13
  const anvil = await bot.openBlock(anvilBlock)
14
14
  if (!matchWindowType(anvil)) {
15
- throw new Error('This is not a anvil-like window')
15
+ throw new Error('Not a anvil-like window: ' + JSON.stringify(anvil))
16
16
  }
17
17
 
18
18
  function err (name) {
@@ -1,5 +1,5 @@
1
1
  const assert = require('assert')
2
- const { once } = require('events')
2
+ const { once } = require('../promise_utils')
3
3
 
4
4
  module.exports = inject
5
5
 
@@ -144,7 +144,7 @@ function inject (bot, options) {
144
144
  function chatWithHeader (header, message) {
145
145
  if (typeof message === 'number') message = message.toString()
146
146
  if (typeof message !== 'string') {
147
- throw new Error('Incorrect type! Should be a string or number.')
147
+ throw new Error('Chat message type must be a string or number: ' + typeof message)
148
148
  }
149
149
 
150
150
  if (!header && message.startsWith('/')) {
@@ -23,7 +23,7 @@ function inject (bot) {
23
23
  throw new Error('containerToOpen is neither a block nor an entity')
24
24
  }
25
25
 
26
- if (!matchWindowType(chest)) { throw new Error('Non-container window used as a container') }
26
+ if (!matchWindowType(chest)) { throw new Error('Non-container window used as a container: ' + JSON.stringify(chest)) }
27
27
  return chest
28
28
  }
29
29
 
@@ -1,5 +1,5 @@
1
1
  const assert = require('assert')
2
- const { once } = require('events')
2
+ const { once } = require('../promise_utils')
3
3
 
4
4
  module.exports = inject
5
5
 
@@ -12,7 +12,7 @@ function inject (bot) {
12
12
  assert.ok(recipe)
13
13
  count = parseInt(count ?? 1, 10)
14
14
  if (recipe.requiresTable && !craftingTable) {
15
- throw new Error('recipe requires craftingTable')
15
+ throw new Error('Recipe requires craftingTable, but one was not supplied: ' + JSON.stringify(recipe))
16
16
  }
17
17
 
18
18
  try {
@@ -41,7 +41,7 @@ function inject (bot) {
41
41
  windowCraftingTable = window
42
42
  }
43
43
  if (!windowCraftingTable.type.startsWith('minecraft:crafting')) {
44
- throw new Error('crafting: non craftingTable used as craftingTable')
44
+ throw new Error('crafting: non craftingTable used as craftingTable: ' + windowCraftingTable.type)
45
45
  }
46
46
  await startClicking(windowCraftingTable, 3, 3)
47
47
  } else {
@@ -1,7 +1,7 @@
1
1
  const assert = require('assert')
2
2
  const { Vec3 } = require('vec3')
3
3
  const { sleep, onceWithCleanup } = require('../promise_utils')
4
- const { once } = require('events')
4
+ const { once } = require('../promise_utils')
5
5
 
6
6
  module.exports = inject
7
7
 
@@ -70,7 +70,7 @@ function inject (bot) {
70
70
 
71
71
  // last step
72
72
  bot.entity.position = destination
73
- await once(bot, 'move')
73
+ await once(bot, 'move', /* no timeout */ 0)
74
74
  }
75
75
 
76
76
  function startFlying () {
@@ -1,5 +1,5 @@
1
1
  const assert = require('assert')
2
- const { once } = require('events')
2
+ const { once } = require('../promise_utils')
3
3
 
4
4
  module.exports = inject
5
5
 
@@ -9,7 +9,7 @@ function inject (bot) {
9
9
  let ready = false
10
10
  const enchantmentTable = await bot.openBlock(enchantmentTableBlock)
11
11
  if (!enchantmentTable.type.startsWith('minecraft:enchant')) {
12
- throw new Error('This is not an enchantment table')
12
+ throw new Error('Expected minecraft:enchant when opening table but got ' + enchantmentTable.type)
13
13
  }
14
14
 
15
15
  resetEnchantmentOptions()
@@ -597,7 +597,7 @@ function inject (bot) {
597
597
  }
598
598
 
599
599
  if (item.displayName) {
600
- obj.displayName = new ChatMessage(JSON.parse(item.displayName))
600
+ obj.displayName = ChatMessage.fromNotch(item.displayName)
601
601
  } else if (packet.action & 32) obj.displayName = new ChatMessage({ text: '', extra: [{ text: player.username || obj.username }] })
602
602
 
603
603
  if (newPlayer) {
@@ -660,7 +660,7 @@ function inject (bot) {
660
660
  }
661
661
 
662
662
  if (item.displayName) {
663
- player.displayName = new ChatMessage(JSON.parse(item.displayName))
663
+ player.displayName = ChatMessage.fromNotch(item.displayName)
664
664
  }
665
665
 
666
666
  const playerEntity = Object.values(bot.entities).find(e => e.type === 'player' && e.username === item.name)
@@ -681,7 +681,7 @@ function inject (bot) {
681
681
  } else if (packet.action === 3 && !item.displayName) {
682
682
  player.displayName = new ChatMessage({ text: '', extra: [{ text: player.username }] })
683
683
  } else if (packet.action === 3 && item.displayName) {
684
- player.displayName = new ChatMessage(JSON.parse(item.displayName))
684
+ player.displayName = ChatMessage.fromNotch(item.displayName)
685
685
  } else if (packet.action === 4) {
686
686
  if (player.entity === bot.entity) continue
687
687
 
@@ -1,7 +1,6 @@
1
1
  const assert = require('assert')
2
2
  const { Vec3 } = require('vec3')
3
- const { once } = require('events')
4
- const { sleep, createDoneTask, createTask, withTimeout } = require('../promise_utils')
3
+ const { once, sleep, createDoneTask, createTask, withTimeout } = require('../promise_utils')
5
4
 
6
5
  module.exports = inject
7
6
 
@@ -16,6 +16,14 @@ function inject (bot) {
16
16
  if (packet.action === 1) {
17
17
  bot.emit('scoreboardDeleted', scoreboards[packet.name])
18
18
  delete scoreboards[packet.name]
19
+
20
+ for (const position in ScoreBoard.positions) {
21
+ const scoreboard = ScoreBoard.positions[position]
22
+ if (scoreboard.name === packet.name) {
23
+ delete ScoreBoard.positions[position]
24
+ break
25
+ }
26
+ }
19
27
  }
20
28
 
21
29
  if (packet.action === 2) {
@@ -13,14 +13,19 @@ function inject (bot) {
13
13
  }
14
14
 
15
15
  bot._client.on('playerlist_header', (packet) => {
16
- if (packet.header) {
17
- const header = escapeValueNewlines(packet.header)
18
- bot.tablist.header = new ChatMessage(JSON.parse(header))
19
- }
16
+ if (bot.supportFeature('chatPacketsUseNbtComponents')) { // 1.20.3+
17
+ bot.tablist.header = ChatMessage.fromNotch(packet.header)
18
+ bot.tablist.footer = ChatMessage.fromNotch(packet.footer)
19
+ } else {
20
+ if (packet.header) {
21
+ const header = escapeValueNewlines(packet.header)
22
+ bot.tablist.header = ChatMessage.fromNotch(header)
23
+ }
20
24
 
21
- if (packet.footer) {
22
- const footer = escapeValueNewlines(packet.footer)
23
- bot.tablist.footer = new ChatMessage(JSON.parse(footer))
25
+ if (packet.footer) {
26
+ const footer = escapeValueNewlines(packet.footer)
27
+ bot.tablist.footer = ChatMessage.fromNotch(footer)
28
+ }
24
29
  }
25
30
  })
26
31
  }
@@ -1,5 +1,5 @@
1
1
  const assert = require('assert')
2
- const { once } = require('events')
2
+ const { once } = require('../promise_utils')
3
3
 
4
4
  module.exports = inject
5
5
 
@@ -78,7 +78,7 @@ function inject (bot, { version }) {
78
78
  bot._client.on(tradeListPacket, gotTrades)
79
79
  const villager = await villagerPromise
80
80
  if (villager.type !== 'minecraft:villager' && villager.type !== 'minecraft:merchant') {
81
- throw new Error('This is not a villager')
81
+ throw new Error('Expected minecraft:villager or minecraft:mechant type, but got ' + villager.type)
82
82
  }
83
83
 
84
84
  villager.trades = null
@@ -72,6 +72,10 @@ function onceWithCleanup (emitter, event, { timeout = 0, checkCondition = undefi
72
72
  return task.promise
73
73
  }
74
74
 
75
+ function once (emitter, event, timeout = 20000) {
76
+ return onceWithCleanup(emitter, event, { timeout })
77
+ }
78
+
75
79
  function withTimeout (promise, timeout) {
76
80
  return Promise.race([
77
81
  promise,
@@ -82,6 +86,7 @@ function withTimeout (promise, timeout) {
82
86
  }
83
87
 
84
88
  module.exports = {
89
+ once,
85
90
  sleep,
86
91
  createTask,
87
92
  createDoneTask,
package/lib/team.js CHANGED
@@ -1,14 +1,3 @@
1
- let ChatMessage
2
- let MessageBuilder
3
-
4
- module.exports = loader
5
-
6
- function loader (registry) {
7
- ChatMessage = require('prismarine-chat')(registry)
8
- MessageBuilder = ChatMessage.MessageBuilder
9
- return Team
10
- }
11
-
12
1
  function colorString (color) {
13
2
  const formatting = [
14
3
  'black',
@@ -38,56 +27,60 @@ function colorString (color) {
38
27
  return formatting[color]
39
28
  }
40
29
 
41
- class Team {
42
- constructor (team, name, friendlyFire, nameTagVisibility, collisionRule, formatting, prefix, suffix) {
43
- this.team = team
44
- this.update(name, friendlyFire, nameTagVisibility, collisionRule, formatting, prefix, suffix)
45
- this.membersMap = {}
46
- }
30
+ function loader (registry) {
31
+ const ChatMessage = require('prismarine-chat')(registry)
32
+ const MessageBuilder = ChatMessage.MessageBuilder
33
+ return class Team {
34
+ constructor (team, name, friendlyFire, nameTagVisibility, collisionRule, formatting, prefix, suffix) {
35
+ this.team = team
36
+ this.update(name, friendlyFire, nameTagVisibility, collisionRule, formatting, prefix, suffix)
37
+ this.membersMap = {}
38
+ }
47
39
 
48
- parseMessage (value) {
49
- let result
50
- try {
51
- result = new ChatMessage(JSON.parse(value)) // version>1.13-pre7
52
- } catch {
53
- result = MessageBuilder.fromString(value, { colorSeparator: '§' })
54
- if (result === null) {
55
- return new ChatMessage('')
40
+ parseMessage (value) {
41
+ if (registry.supportFeature('teamUsesChatComponents')) { // 1.13+
42
+ return ChatMessage.fromNotch(value)
43
+ } else {
44
+ const result = MessageBuilder.fromString(value, { colorSeparator: '§' })
45
+ if (result === null) {
46
+ return new ChatMessage('')
47
+ }
48
+ return new ChatMessage(result.toJSON())
56
49
  }
57
- return new ChatMessage(result.toJSON())
58
50
  }
59
- return result
60
- }
61
51
 
62
- add (name) {
63
- this.membersMap[name] = ''
64
- return this.membersMap[name]
65
- }
52
+ add (name) {
53
+ this.membersMap[name] = ''
54
+ return this.membersMap[name]
55
+ }
66
56
 
67
- remove (name) {
68
- const removed = this.membersMap[name]
69
- delete this.membersMap[name]
70
- return removed
71
- }
57
+ remove (name) {
58
+ const removed = this.membersMap[name]
59
+ delete this.membersMap[name]
60
+ return removed
61
+ }
72
62
 
73
- update (name, friendlyFire, nameTagVisibility, collisionRule, formatting, prefix, suffix) {
74
- this.name = this.parseMessage(name)
75
- this.friendlyFire = friendlyFire
76
- this.nameTagVisibility = nameTagVisibility
77
- this.collisionRule = collisionRule
78
- this.color = colorString(formatting)
79
- this.prefix = this.parseMessage(prefix)
80
- this.suffix = this.parseMessage(suffix)
81
- }
63
+ update (name, friendlyFire, nameTagVisibility, collisionRule, formatting, prefix, suffix) {
64
+ this.name = this.parseMessage(name)
65
+ this.friendlyFire = friendlyFire
66
+ this.nameTagVisibility = nameTagVisibility
67
+ this.collisionRule = collisionRule
68
+ this.color = colorString(formatting)
69
+ this.prefix = this.parseMessage(prefix)
70
+ this.suffix = this.parseMessage(suffix)
71
+ }
82
72
 
83
- // Return a chat component with prefix + color + name + suffix
84
- displayName (member) {
85
- const name = this.prefix.clone()
86
- name.append(new ChatMessage({ text: member, color: this.color }), this.suffix)
87
- return name
88
- }
73
+ // Return a chat component with prefix + color + name + suffix
74
+ displayName (member) {
75
+ const name = this.prefix.clone()
76
+ name.append(new ChatMessage({ text: member, color: this.color }), this.suffix)
77
+ return name
78
+ }
89
79
 
90
- get members () {
91
- return Object.keys(this.membersMap)
80
+ get members () {
81
+ return Object.keys(this.membersMap)
82
+ }
92
83
  }
93
84
  }
85
+
86
+ module.exports = loader
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
+ 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']
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.19.0",
3
+ "version": "4.20.0",
4
4
  "description": "create minecraft bots with a stable, high level API",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -22,7 +22,7 @@
22
22
  "license": "MIT",
23
23
  "dependencies": {
24
24
  "minecraft-data": "^3.56.0",
25
- "minecraft-protocol": "^1.44.0",
25
+ "minecraft-protocol": "^1.47.0",
26
26
  "prismarine-biome": "^1.1.1",
27
27
  "prismarine-block": "^1.17.0",
28
28
  "prismarine-chat": "^1.7.1",
@@ -33,7 +33,7 @@
33
33
  "prismarine-physics": "^1.8.0",
34
34
  "prismarine-recipe": "^1.3.0",
35
35
  "prismarine-registry": "^1.5.0",
36
- "prismarine-windows": "^2.8.0",
36
+ "prismarine-windows": "^2.9.0",
37
37
  "prismarine-world": "^3.6.0",
38
38
  "protodef": "^1.14.0",
39
39
  "typed-emitter": "^1.0.0",