mineflayer 4.8.0 → 4.9.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/.github/workflows/ci.yml +2 -0
- package/README.md +14 -12
- package/docs/FAQ.md +1 -1
- package/docs/README.md +14 -12
- package/docs/api.md +22 -7
- package/docs/es/FAQ_ES.md +1 -1
- package/docs/es/README_ES.md +1 -1
- package/docs/fr/FAQ_FR.md +1 -1
- package/docs/fr/README_FR.md +1 -1
- package/docs/history.md +21 -0
- package/docs/ru/FAQ_RU.md +1 -1
- package/docs/ru/README_RU.md +1 -1
- package/docs/tr/README_TR.md +1 -1
- package/docs/tutorial.md +4 -4
- package/docs/zh/FAQ.md +1 -1
- package/docs/zh/README_ZH_CN.md +2 -2
- package/docs/zh/tutorial.md +5 -5
- package/examples/cli/readline.js +50 -0
- package/examples/skin_data.js +26 -0
- package/examples/trader.js +18 -12
- package/examples/viewer/README.md +1 -1
- package/index.d.ts +13 -5
- package/lib/loader.js +2 -1
- package/lib/plugins/bed.js +1 -1
- package/lib/plugins/blocks.js +1 -1
- package/lib/plugins/craft.js +26 -14
- package/lib/plugins/digging.js +2 -1
- package/lib/plugins/entities.js +67 -22
- package/lib/plugins/game.js +10 -6
- package/lib/plugins/health.js +2 -1
- package/lib/plugins/inventory.js +6 -1
- package/lib/plugins/physics.js +4 -0
- package/lib/plugins/place_block.js +6 -2
- package/lib/version.js +1 -1
- package/package.json +4 -4
- package/docs/CNAME +0 -1
package/.github/workflows/ci.yml
CHANGED
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Mineflayer
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/mineflayer)
|
|
4
|
-
[](https://github.com/PrismarineJS/mineflayer/actions?query=workflow%3A%22CI%22)
|
|
5
5
|
[](https://gitpod.io/#https://github.com/PrismarineJS/mineflayer)
|
|
6
6
|
[](https://colab.research.google.com/github/PrismarineJS/mineflayer/blob/master/docs/mineflayer.ipynb)
|
|
7
7
|
[](https://github.com/sponsors/PrismarineJS)
|
|
@@ -39,13 +39,15 @@ First install Node.js >= 14 from [nodejs.org](https://nodejs.org/) then:
|
|
|
39
39
|
|
|
40
40
|
`npm install mineflayer`
|
|
41
41
|
|
|
42
|
+
To update mineflayer (or any Node.js) package and its dependencies, use `npm update --depth 9999`
|
|
43
|
+
|
|
42
44
|
## Documentation
|
|
43
45
|
|
|
44
46
|
| link | description |
|
|
45
47
|
|---|---|
|
|
46
48
|
|[tutorial](tutorial.md) | Begin with Node.js and mineflayer |
|
|
47
49
|
| [FAQ.md](FAQ.md) | Got a question ? go there first |
|
|
48
|
-
| [api.md](api.md) [unstable_api.md](unstable_api.md) | The full API reference |
|
|
50
|
+
| **[api.md](api.md)** <br/>[unstable_api.md](unstable_api.md) | The full API reference |
|
|
49
51
|
| [history.md](history.md) | The changelog for mineflayer |
|
|
50
52
|
| [examples/](https://github.com/PrismarineJS/mineflayer/tree/master/examples) | Checkout all the mineflayer examples |
|
|
51
53
|
|
|
@@ -79,10 +81,10 @@ const mineflayer = require('mineflayer')
|
|
|
79
81
|
const bot = mineflayer.createBot({
|
|
80
82
|
host: 'localhost', // minecraft server ip
|
|
81
83
|
username: 'email@example.com', // minecraft username
|
|
82
|
-
|
|
84
|
+
auth: 'microsoft' // for offline mode servers, you can set this to 'offline'
|
|
83
85
|
// port: 25565, // only set if you need a port that isn't 25565
|
|
84
86
|
// version: false, // only set if you need a specific version or snapshot (ie: "1.8.9" or "1.16.5"), otherwise it's set automatically
|
|
85
|
-
//
|
|
87
|
+
// password: '12345678' // set if you want to use password-based auth (may be unreliable)
|
|
86
88
|
})
|
|
87
89
|
|
|
88
90
|
bot.on('chat', (username, message) => {
|
|
@@ -107,7 +109,7 @@ bot.once('spawn', () => {
|
|
|
107
109
|
```
|
|
108
110
|
And you'll get a *live* view looking like this:
|
|
109
111
|
|
|
110
|
-
[<img src="https://
|
|
112
|
+
[<img src="https://prismarinejs.github.io/prismarine-viewer/test_1.16.1.png" alt="viewer" width="500">](https://prismarinejs.github.io/prismarine-viewer/)
|
|
111
113
|
|
|
112
114
|
#### More Examples
|
|
113
115
|
|
|
@@ -123,7 +125,7 @@ And you'll get a *live* view looking like this:
|
|
|
123
125
|
|[guard](https://github.com/PrismarineJS/mineflayer/blob/master/examples/guard.js) | Make a bot guard a defined area from nearby mobs |
|
|
124
126
|
|[multiple-from-file](https://github.com/PrismarineJS/mineflayer/blob/master/examples/multiple_from_file.js) | Add a text file with accounts and have them all login |
|
|
125
127
|
|
|
126
|
-
And many
|
|
128
|
+
And many more in the [examples](https://github.com/PrismarineJS/mineflayer/tree/master/examples) folder.
|
|
127
129
|
|
|
128
130
|
### Modules
|
|
129
131
|
|
|
@@ -180,19 +182,18 @@ The most updated and useful are :
|
|
|
180
182
|
* [pathfinder](https://github.com/Karang/mineflayer-pathfinder) - advanced A* pathfinding with a lot of configurable features
|
|
181
183
|
* [prismarine-viewer](https://github.com/PrismarineJS/prismarine-viewer) - simple web chunk viewer
|
|
182
184
|
* [web-inventory](https://github.com/ImHarvol/mineflayer-web-inventory) - web based inventory viewer
|
|
183
|
-
* [statemachine](https://github.com/
|
|
185
|
+
* [statemachine](https://github.com/PrismarineJS/mineflayer-statemachine) - A state machine API for more complex bot behaviors
|
|
184
186
|
* [Armor Manager](https://github.com/G07cha/MineflayerArmorManager) - automatic armor management
|
|
185
|
-
* [Collect Block](https://github.com/TheDudeFromCI/mineflayer-collectblock) - Quick and simple block collection API.
|
|
186
187
|
* [Dashboard](https://github.com/wvffle/mineflayer-dashboard) - Frontend dashboard for mineflayer bot
|
|
187
|
-
* [PVP](https://github.com/
|
|
188
|
+
* [PVP](https://github.com/PrismarineJS/mineflayer-pvp) - Easy API for basic PVP and PVE.
|
|
188
189
|
* [Auto Eat](https://github.com/link-discord/mineflayer-auto-eat) - Automatic eating of food.
|
|
189
190
|
* [Auto Crystal](https://github.com/link-discord/mineflayer-autocrystal) - Automatic placing & breaking of end crystals.
|
|
190
191
|
* [Tool](https://github.com/TheDudeFromCI/mineflayer-tool) - A utility for automatic tool/weapon selection with a high level API.
|
|
191
192
|
* [Hawkeye](https://github.com/sefirosweb/minecraftHawkEye) - A utility for using auto-aim with bows.
|
|
192
193
|
* [GUI](https://github.com/firejoust/mineflayer-GUI) - Interact with nested GUI windows using async/await
|
|
193
194
|
* [Projectile](https://github.com/firejoust/mineflayer-projectile) - Get the required launch angle for projectiles
|
|
194
|
-
* [Movement](https://github.com/firejoust/mineflayer-movement) - Smooth and realistic player movement, best suited for PvP
|
|
195
|
-
|
|
195
|
+
* [Movement](https://github.com/firejoust/mineflayer-movement) - Smooth and realistic player movement, best suited for PvP
|
|
196
|
+
* [Collect Block](https://github.com/PrismarineJS/mineflayer-collectblock) - Quick and simple block collection API.
|
|
196
197
|
|
|
197
198
|
But also check out :
|
|
198
199
|
|
|
@@ -206,6 +207,7 @@ The most updated and useful are :
|
|
|
206
207
|
|
|
207
208
|
## Projects Using Mineflayer
|
|
208
209
|
|
|
210
|
+
* [Voyager](https://github.com/MineDojo/Voyager) An Open-Ended Embodied Agent with Large Language Models
|
|
209
211
|
* [rom1504/rbot](https://github.com/rom1504/rbot)
|
|
210
212
|
- [YouTube - building a spiral staircase](https://www.youtube.com/watch?v=UM1ZV5200S0)
|
|
211
213
|
- [YouTube - replicating a building](https://www.youtube.com/watch?v=0cQxg9uDnzA)
|
|
@@ -213,7 +215,7 @@ The most updated and useful are :
|
|
|
213
215
|
* [vogonistic/voxel](https://github.com/vogonistic/mineflayer-voxel) - visualize what
|
|
214
216
|
the bot is up to using voxel.js
|
|
215
217
|
* [JonnyD/Skynet](https://github.com/JonnyD/Skynet) - log player activity onto an online API
|
|
216
|
-
* [MinecraftChat](https://github.com/rom1504/MinecraftChat) (last open source version, built by AlexKvazos) - Minecraft web based chat client
|
|
218
|
+
* [MinecraftChat](https://github.com/rom1504/MinecraftChat) (last open source version, built by AlexKvazos) - Minecraft web based chat client
|
|
217
219
|
* [Cheese Bot](https://github.com/Minecheesecraft/Cheese-Bot) - Plugin based bot with a clean GUI. Made with Node-Webkit.
|
|
218
220
|
* [Chaoscraft](https://github.com/schematical/chaoscraft) - Minecraft bot using genetic algorithms, see [its youtube videos](https://www.youtube.com/playlist?list=PLLkpLgU9B5xJ7Qy4kOyBJl5J6zsDIMceH)
|
|
219
221
|
* [hexatester/minetelegram](https://github.com/hexatester/minetelegram) - Minecraft - Telegram bridge, build on top of mineflayer & telegraf.
|
package/docs/FAQ.md
CHANGED
|
@@ -22,7 +22,7 @@ client.on('end', () => {})
|
|
|
22
22
|
|
|
23
23
|
Spigot servers, in particular some plugins, use custom chat formats, you need to parse it with a custom regex / parser.
|
|
24
24
|
Read and adapt [chat_parsing.js](https://github.com/PrismarineJS/mineflayer/blob/master/examples/chat_parsing.js) to make it work for your particular
|
|
25
|
-
chat plugin. Also read http://
|
|
25
|
+
chat plugin. Also read http://prismarinejs.github.io/mineflayer/#/tutorial?id=custom-chat
|
|
26
26
|
|
|
27
27
|
### How can I collect info from an custom plugin in chat ?
|
|
28
28
|
|
package/docs/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Mineflayer
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/mineflayer)
|
|
4
|
-
[](https://github.com/PrismarineJS/mineflayer/actions?query=workflow%3A%22CI%22)
|
|
5
5
|
[](https://gitpod.io/#https://github.com/PrismarineJS/mineflayer)
|
|
6
6
|
[](https://colab.research.google.com/github/PrismarineJS/mineflayer/blob/master/docs/mineflayer.ipynb)
|
|
7
7
|
[](https://github.com/sponsors/PrismarineJS)
|
|
@@ -39,13 +39,15 @@ First install Node.js >= 14 from [nodejs.org](https://nodejs.org/) then:
|
|
|
39
39
|
|
|
40
40
|
`npm install mineflayer`
|
|
41
41
|
|
|
42
|
+
To update mineflayer (or any Node.js) package and its dependencies, use `npm update --depth 9999`
|
|
43
|
+
|
|
42
44
|
## Documentation
|
|
43
45
|
|
|
44
46
|
| link | description |
|
|
45
47
|
|---|---|
|
|
46
48
|
|[tutorial](tutorial.md) | Begin with Node.js and mineflayer |
|
|
47
49
|
| [FAQ.md](FAQ.md) | Got a question ? go there first |
|
|
48
|
-
| [api.md](api.md) [unstable_api.md](unstable_api.md) | The full API reference |
|
|
50
|
+
| **[api.md](api.md)** <br/>[unstable_api.md](unstable_api.md) | The full API reference |
|
|
49
51
|
| [history.md](history.md) | The changelog for mineflayer |
|
|
50
52
|
| [examples/](https://github.com/PrismarineJS/mineflayer/tree/master/examples) | Checkout all the mineflayer examples |
|
|
51
53
|
|
|
@@ -79,10 +81,10 @@ const mineflayer = require('mineflayer')
|
|
|
79
81
|
const bot = mineflayer.createBot({
|
|
80
82
|
host: 'localhost', // minecraft server ip
|
|
81
83
|
username: 'email@example.com', // minecraft username
|
|
82
|
-
|
|
84
|
+
auth: 'microsoft' // for offline mode servers, you can set this to 'offline'
|
|
83
85
|
// port: 25565, // only set if you need a port that isn't 25565
|
|
84
86
|
// version: false, // only set if you need a specific version or snapshot (ie: "1.8.9" or "1.16.5"), otherwise it's set automatically
|
|
85
|
-
//
|
|
87
|
+
// password: '12345678' // set if you want to use password-based auth (may be unreliable)
|
|
86
88
|
})
|
|
87
89
|
|
|
88
90
|
bot.on('chat', (username, message) => {
|
|
@@ -107,7 +109,7 @@ bot.once('spawn', () => {
|
|
|
107
109
|
```
|
|
108
110
|
And you'll get a *live* view looking like this:
|
|
109
111
|
|
|
110
|
-
[<img src="https://
|
|
112
|
+
[<img src="https://prismarinejs.github.io/prismarine-viewer/test_1.16.1.png" alt="viewer" width="500">](https://prismarinejs.github.io/prismarine-viewer/)
|
|
111
113
|
|
|
112
114
|
#### More Examples
|
|
113
115
|
|
|
@@ -123,7 +125,7 @@ And you'll get a *live* view looking like this:
|
|
|
123
125
|
|[guard](https://github.com/PrismarineJS/mineflayer/blob/master/examples/guard.js) | Make a bot guard a defined area from nearby mobs |
|
|
124
126
|
|[multiple-from-file](https://github.com/PrismarineJS/mineflayer/blob/master/examples/multiple_from_file.js) | Add a text file with accounts and have them all login |
|
|
125
127
|
|
|
126
|
-
And many
|
|
128
|
+
And many more in the [examples](https://github.com/PrismarineJS/mineflayer/tree/master/examples) folder.
|
|
127
129
|
|
|
128
130
|
### Modules
|
|
129
131
|
|
|
@@ -180,19 +182,18 @@ The most updated and useful are :
|
|
|
180
182
|
* [pathfinder](https://github.com/Karang/mineflayer-pathfinder) - advanced A* pathfinding with a lot of configurable features
|
|
181
183
|
* [prismarine-viewer](https://github.com/PrismarineJS/prismarine-viewer) - simple web chunk viewer
|
|
182
184
|
* [web-inventory](https://github.com/ImHarvol/mineflayer-web-inventory) - web based inventory viewer
|
|
183
|
-
* [statemachine](https://github.com/
|
|
185
|
+
* [statemachine](https://github.com/PrismarineJS/mineflayer-statemachine) - A state machine API for more complex bot behaviors
|
|
184
186
|
* [Armor Manager](https://github.com/G07cha/MineflayerArmorManager) - automatic armor management
|
|
185
|
-
* [Collect Block](https://github.com/TheDudeFromCI/mineflayer-collectblock) - Quick and simple block collection API.
|
|
186
187
|
* [Dashboard](https://github.com/wvffle/mineflayer-dashboard) - Frontend dashboard for mineflayer bot
|
|
187
|
-
* [PVP](https://github.com/
|
|
188
|
+
* [PVP](https://github.com/PrismarineJS/mineflayer-pvp) - Easy API for basic PVP and PVE.
|
|
188
189
|
* [Auto Eat](https://github.com/link-discord/mineflayer-auto-eat) - Automatic eating of food.
|
|
189
190
|
* [Auto Crystal](https://github.com/link-discord/mineflayer-autocrystal) - Automatic placing & breaking of end crystals.
|
|
190
191
|
* [Tool](https://github.com/TheDudeFromCI/mineflayer-tool) - A utility for automatic tool/weapon selection with a high level API.
|
|
191
192
|
* [Hawkeye](https://github.com/sefirosweb/minecraftHawkEye) - A utility for using auto-aim with bows.
|
|
192
193
|
* [GUI](https://github.com/firejoust/mineflayer-GUI) - Interact with nested GUI windows using async/await
|
|
193
194
|
* [Projectile](https://github.com/firejoust/mineflayer-projectile) - Get the required launch angle for projectiles
|
|
194
|
-
* [Movement](https://github.com/firejoust/mineflayer-movement) - Smooth and realistic player movement, best suited for PvP
|
|
195
|
-
|
|
195
|
+
* [Movement](https://github.com/firejoust/mineflayer-movement) - Smooth and realistic player movement, best suited for PvP
|
|
196
|
+
* [Collect Block](https://github.com/PrismarineJS/mineflayer-collectblock) - Quick and simple block collection API.
|
|
196
197
|
|
|
197
198
|
But also check out :
|
|
198
199
|
|
|
@@ -206,6 +207,7 @@ The most updated and useful are :
|
|
|
206
207
|
|
|
207
208
|
## Projects Using Mineflayer
|
|
208
209
|
|
|
210
|
+
* [Voyager](https://github.com/MineDojo/Voyager) An Open-Ended Embodied Agent with Large Language Models
|
|
209
211
|
* [rom1504/rbot](https://github.com/rom1504/rbot)
|
|
210
212
|
- [YouTube - building a spiral staircase](https://www.youtube.com/watch?v=UM1ZV5200S0)
|
|
211
213
|
- [YouTube - replicating a building](https://www.youtube.com/watch?v=0cQxg9uDnzA)
|
|
@@ -213,7 +215,7 @@ The most updated and useful are :
|
|
|
213
215
|
* [vogonistic/voxel](https://github.com/vogonistic/mineflayer-voxel) - visualize what
|
|
214
216
|
the bot is up to using voxel.js
|
|
215
217
|
* [JonnyD/Skynet](https://github.com/JonnyD/Skynet) - log player activity onto an online API
|
|
216
|
-
* [MinecraftChat](https://github.com/rom1504/MinecraftChat) (last open source version, built by AlexKvazos) - Minecraft web based chat client
|
|
218
|
+
* [MinecraftChat](https://github.com/rom1504/MinecraftChat) (last open source version, built by AlexKvazos) - Minecraft web based chat client
|
|
217
219
|
* [Cheese Bot](https://github.com/Minecheesecraft/Cheese-Bot) - Plugin based bot with a clean GUI. Made with Node-Webkit.
|
|
218
220
|
* [Chaoscraft](https://github.com/schematical/chaoscraft) - Minecraft bot using genetic algorithms, see [its youtube videos](https://www.youtube.com/playlist?list=PLLkpLgU9B5xJ7Qy4kOyBJl5J6zsDIMceH)
|
|
219
221
|
* [hexatester/minetelegram](https://github.com/hexatester/minetelegram) - Minecraft - Telegram bridge, build on top of mineflayer & telegraf.
|
package/docs/api.md
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
- [vec3](#vec3)
|
|
17
17
|
- [mineflayer.Location](#mineflayerlocation)
|
|
18
18
|
- [Entity](#entity)
|
|
19
|
+
- [Player Skin Data](#player-skin-data)
|
|
19
20
|
- [Block](#block)
|
|
20
21
|
- [Biome](#biome)
|
|
21
22
|
- [Item](#item)
|
|
@@ -405,6 +406,18 @@ Entities represent players, mobs, and objects. They are emitted
|
|
|
405
406
|
in many events, and you can access your own entity with `bot.entity`.
|
|
406
407
|
See [prismarine-entity](https://github.com/PrismarineJS/prismarine-entity)
|
|
407
408
|
|
|
409
|
+
#### Player Skin Data
|
|
410
|
+
|
|
411
|
+
The skin data is stored in the `skinData` property of the player object, if present.
|
|
412
|
+
|
|
413
|
+
```js
|
|
414
|
+
// player.skinData
|
|
415
|
+
{
|
|
416
|
+
url: 'http://textures.minecraft.net/texture/...',
|
|
417
|
+
model: 'slim' // or 'classic'
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
408
421
|
### Block
|
|
409
422
|
|
|
410
423
|
See [prismarine-block](https://github.com/PrismarineJS/prismarine-block)
|
|
@@ -785,6 +798,8 @@ Create and return an instance of the class bot.
|
|
|
785
798
|
* loadInternalPlugins : defaults to true
|
|
786
799
|
* storageBuilder : an optional function, takes as argument version and worldName and return an instance of something with the same API as prismarine-provider-anvil. Will be used to save the world.
|
|
787
800
|
* client : an instance of node-minecraft-protocol, if not specified, mineflayer makes it's own client. This can be used to enable using mineflayer through a proxy of many clients or a vanilla client and a mineflayer client.
|
|
801
|
+
* brand : the brand name for the client to use. Defaults to vanilla. Can be used to simulate custom clients for servers that require it.
|
|
802
|
+
* respawn : when set to false disables bot from automatically respawning, defaults to true.
|
|
788
803
|
* plugins : object : defaults to {}
|
|
789
804
|
- pluginName : false : don't load internal plugin with given name ie. `pluginName`
|
|
790
805
|
- pluginName : true : load internal plugin with given name ie. `pluginName` even though loadInternalplugins is set to false
|
|
@@ -814,15 +829,13 @@ A sync representation of the world. Check the doc at http://github.com/Prismarin
|
|
|
814
829
|
|
|
815
830
|
Fires when a block updates. Both `oldBlock` and `newBlock` provided for
|
|
816
831
|
comparison.
|
|
817
|
-
|
|
818
|
-
Note that `oldBlock` may be `null`.
|
|
832
|
+
`oldBlock` may be `null` with normal block updates.
|
|
819
833
|
|
|
820
834
|
##### world "blockUpdate:(x, y, z)" (oldBlock, newBlock)
|
|
821
835
|
|
|
822
836
|
Fires for a specific point. Both `oldBlock` and `newBlock` provided for
|
|
823
|
-
comparison.
|
|
824
|
-
|
|
825
|
-
Note that `oldBlock` may be `null`.
|
|
837
|
+
comparison. All listeners receive null for `oldBlock` and `newBlock` and get automatically removed when the world is unloaded.
|
|
838
|
+
`oldBlock` may be `null` with normal block updates.
|
|
826
839
|
|
|
827
840
|
|
|
828
841
|
#### bot.entity
|
|
@@ -853,6 +866,8 @@ Whether the bot is using the item that it's holding, for example eating food or
|
|
|
853
866
|
|
|
854
867
|
#### bot.game.dimension
|
|
855
868
|
|
|
869
|
+
The bot's current dimension, such as `overworld`, `the_end` or `the_nether`.
|
|
870
|
+
|
|
856
871
|
#### bot.game.difficulty
|
|
857
872
|
|
|
858
873
|
#### bot.game.gameMode
|
|
@@ -2064,9 +2079,9 @@ These are lower level methods for the inventory, they can be useful sometimes bu
|
|
|
2064
2079
|
|
|
2065
2080
|
This function returns a `Promise`, with `void` as its argument upon completion.
|
|
2066
2081
|
|
|
2067
|
-
The only valid mode option at the moment is 0. Shift clicking or mouse
|
|
2082
|
+
The only valid mode option at the moment is 0. Shift clicking or mouse dragging is not implemented.
|
|
2068
2083
|
|
|
2069
|
-
Click on the current window. See details at https://wiki.vg/Protocol#
|
|
2084
|
+
Click on the current window. See details at https://wiki.vg/Protocol#Click_Container
|
|
2070
2085
|
|
|
2071
2086
|
Prefer using bot.simpleClick.*
|
|
2072
2087
|
|
package/docs/es/FAQ_ES.md
CHANGED
|
@@ -15,7 +15,7 @@ client.on('end', () => {})
|
|
|
15
15
|
## Mi evento de chat no se emite en un servidor personalizado, cómo lo resuelvo?
|
|
16
16
|
|
|
17
17
|
Los servidores spigot, en particular algunos plugins, usan formatos personalizados de chat, tienes que analizarlos con un regex personalizado.
|
|
18
|
-
Lee y modifica [chat_parsing.js](https://github.com/PrismarineJS/mineflayer/blob/master/examples/chat_parsing.js) para que funcione con tu plugin de chat particular. Lee también http://
|
|
18
|
+
Lee y modifica [chat_parsing.js](https://github.com/PrismarineJS/mineflayer/blob/master/examples/chat_parsing.js) para que funcione con tu plugin de chat particular. Lee también http://prismarinejs.github.io/mineflayer/#/tutorial?id=custom-chat
|
|
19
19
|
|
|
20
20
|
### Como puedo recolectar información de un plugin de chat personalizado?
|
|
21
21
|
|
package/docs/es/README_ES.md
CHANGED
|
@@ -104,7 +104,7 @@ bot.once('spawn', () => {
|
|
|
104
104
|
```
|
|
105
105
|
Y podrás ver una representación *en vivo* como esta:
|
|
106
106
|
|
|
107
|
-
[<img src="https://
|
|
107
|
+
[<img src="https://prismarinejs.github.io/prismarine-viewer/test_1.16.1.png" alt="viewer" width="500">](https://prismarinejs.github.io/prismarine-viewer/)
|
|
108
108
|
|
|
109
109
|
#### Más ejemplos
|
|
110
110
|
|
package/docs/fr/FAQ_FR.md
CHANGED
|
@@ -23,7 +23,7 @@ client.on('end', () => {})
|
|
|
23
23
|
|
|
24
24
|
Les serveurs Spigot, en particulier certains plugins, utilisent des formats de chat personnalisés, vous devez les analyser avec une expression rationnelle / un analyseur syntaxique personnalisé.
|
|
25
25
|
Lisez et adaptez [chat_parsing.js](https://github.com/PrismarineJS/mineflayer/blob/master/examples/chat_parsing.js) pour qu'il fonctionne pour vos besoins particuliers.
|
|
26
|
-
plugin de chat. A lire également <http://
|
|
26
|
+
plugin de chat. A lire également <http://prismarinejs.github.io/mineflayer/#/tutorial?id=custom-chat>
|
|
27
27
|
|
|
28
28
|
### Comment puis-je collecter les informations d'un plugin personnalisé dans le chat ?
|
|
29
29
|
|
package/docs/fr/README_FR.md
CHANGED
|
@@ -108,7 +108,7 @@ bot.once('spawn', () => {
|
|
|
108
108
|
```
|
|
109
109
|
et vous obtiendrez un affichage en *direct* qui ressemble à ceci:
|
|
110
110
|
|
|
111
|
-
[<img src="https://
|
|
111
|
+
[<img src="https://prismarinejs.github.io/prismarine-viewer/test_1.16.1.png" alt="viewer" width="500">](https://prismarinejs.github.io/prismarine-viewer/)
|
|
112
112
|
|
|
113
113
|
#### Exemples:
|
|
114
114
|
|
package/docs/history.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
## 4.9.0
|
|
2
|
+
|
|
3
|
+
* Fix bot not updating world height on respawn packet (@frej4189)
|
|
4
|
+
* Persist properties received in player_info packet (@Paulomart)
|
|
5
|
+
* Fix reference error with block updates (@IceTank)
|
|
6
|
+
* Add spectator to gameModes array (@williamd5)
|
|
7
|
+
* Standardize dimensions for all versions (@sefirosweb)
|
|
8
|
+
* Emit inject_allowed after a timeout of 0 (@IceTank)
|
|
9
|
+
* Add window transaction timeout (@firejoust)
|
|
10
|
+
* Made bot auto respawning togglable (@Averagess)
|
|
11
|
+
* support 1.19.4 (@extremeheat)
|
|
12
|
+
|
|
13
|
+
## 4.8.1
|
|
14
|
+
|
|
15
|
+
* Fix client crashing when player_remove contains unknown player (@frej4189)
|
|
16
|
+
* Improve look and fix bug slow craft (@sefirosweb)
|
|
17
|
+
* Fix player entity being unset when player is updated (@frej4189)
|
|
18
|
+
* Fix type (@sefirosweb)
|
|
19
|
+
* Improve crafting stacks (@sefirosweb)
|
|
20
|
+
* add example for using the node:readline module (@Jovan-04)
|
|
21
|
+
|
|
1
22
|
## 4.8.0
|
|
2
23
|
|
|
3
24
|
* Update chat parsing (@frej4189)
|
package/docs/ru/FAQ_RU.md
CHANGED
|
@@ -14,7 +14,7 @@ client.on('end', () => {})
|
|
|
14
14
|
|
|
15
15
|
Сервера Spigot, в частности некоторые плагины, используют разные форматы чата, вам необходимо проанализировать его с помощью регулярного выражения/парсера.
|
|
16
16
|
Посмотрите и измените скрипт [chatAddPattern.js](https://github.com/PrismarineJS/mineflayer/blob/master/examples/chatAddPattern.js), чтобы он работал для вашего плагина чата,
|
|
17
|
-
также прочтите http://
|
|
17
|
+
также прочтите http://prismarinejs.github.io/mineflayer/#/tutorial?id=custom-chat.
|
|
18
18
|
|
|
19
19
|
### Как я могу отправлять команды серверу?
|
|
20
20
|
|
package/docs/ru/README_RU.md
CHANGED
|
@@ -108,7 +108,7 @@ bot.once('spawn', () => {
|
|
|
108
108
|
```
|
|
109
109
|
После запуска, вы в прямом эфире сможете наблюдать за происходящим:
|
|
110
110
|
|
|
111
|
-
[<img src="https://
|
|
111
|
+
[<img src="https://prismarinejs.github.io/prismarine-viewer/test_1.16.1.png" alt="viewer" width="500">](https://prismarinejs.github.io/prismarine-viewer/)
|
|
112
112
|
|
|
113
113
|
#### Больше примеров
|
|
114
114
|
|
package/docs/tr/README_TR.md
CHANGED
|
@@ -104,7 +104,7 @@ bot.once('spawn', () => {
|
|
|
104
104
|
```
|
|
105
105
|
ve şuna benzeyen *canlı* bir görüntü elde edeceksin:
|
|
106
106
|
|
|
107
|
-
[<img src="https://
|
|
107
|
+
[<img src="https://prismarinejs.github.io/prismarine-viewer/test_1.16.1.png" alt="viewer" width="500">](https://prismarinejs.github.io/prismarine-viewer/)
|
|
108
108
|
|
|
109
109
|
#### Daha fazla örnek
|
|
110
110
|
|
package/docs/tutorial.md
CHANGED
|
@@ -417,7 +417,7 @@ bot.once('spawn', () => {
|
|
|
417
417
|
|
|
418
418
|
### Listening for an event
|
|
419
419
|
|
|
420
|
-
The bot object has many useful [events](http://
|
|
420
|
+
The bot object has many useful [events](http://prismarinejs.github.io/mineflayer/#/api?id=events).
|
|
421
421
|
You can listen for an event by using either `bot.on()` method or `bot.once()` method of the bot object, which takes the name of an event and a function.
|
|
422
422
|
To remove specific listener you can use `bot.removeListener()` method.
|
|
423
423
|
|
|
@@ -428,7 +428,7 @@ To remove specific listener you can use `bot.removeListener()` method.
|
|
|
428
428
|
- `bot.removeListener(eventName, listener)`
|
|
429
429
|
Removes the specified `listener` for the event named `eventName`. In order to use this you either need to define your function with `function myNamedFunc() {}` or put your function in a variable with `const myNamedFunc = () => {}`. You can then use `myNamedFunc` in the listener argument.
|
|
430
430
|
|
|
431
|
-
Not only bot object, [`Chest`](http://
|
|
431
|
+
Not only bot object, [`Chest`](http://prismarinejs.github.io/mineflayer/#/api?id=mineflayerchest), [`Furnace`](http://prismarinejs.github.io/mineflayer/#/api?id=mineflayerfurnace), [`Dispenser`](http://prismarinejs.github.io/mineflayer/#/api?id=mineflayerdispenser), [`EnchantmentTable`](http://prismarinejs.github.io/mineflayer/#/api?id=mineflayerenchantmenttable), [`Villager`](http://prismarinejs.github.io/mineflayer/#/api?id=mineflayervillager) object also have their own events!
|
|
432
432
|
|
|
433
433
|
### Promises
|
|
434
434
|
A [promise](https://nodejs.dev/learn/understanding-javascript-promises) is a function that you can use the `await` variable to wait on until it's job is complete. (you can omit the await to not wait for results)
|
|
@@ -557,8 +557,8 @@ In general, you'll want to use `for of` instead of `for in` so make sure you don
|
|
|
557
557
|
|
|
558
558
|
### Creating an event from chat
|
|
559
559
|
|
|
560
|
-
You can create your own event from chat using [`bot.chatAddPattern()`](http://
|
|
561
|
-
[`bot.chatAddPattern()`](http://
|
|
560
|
+
You can create your own event from chat using [`bot.chatAddPattern()`](http://prismarinejs.github.io/mineflayer/#/api?id=botchataddpatternpattern-chattype-description) method. Useful for Bukkit servers where the chat format changes a lot.
|
|
561
|
+
[`bot.chatAddPattern()`](http://prismarinejs.github.io/mineflayer/#/api?id=botchataddpatternpattern-chattype-description) method takes three arguments :
|
|
562
562
|
|
|
563
563
|
- `pattern` - regular expression (regex) to match chat
|
|
564
564
|
- `chatType` - the event the bot emits when the pattern matches. e.g. "chat" or "whisper"
|
package/docs/zh/FAQ.md
CHANGED
|
@@ -15,7 +15,7 @@ client.on('end', () => {})
|
|
|
15
15
|
### 我无法在自定义服务器上获取聊天事件,如何解决?
|
|
16
16
|
|
|
17
17
|
Spigot 服务器, 特别是一些插件, 使用的是自定义聊天格式,您需要使用自定义正则表达式/解析器对其进行解析。
|
|
18
|
-
阅读并改编[chat_parsing.js](https://github.com/PrismarineJS/mineflayer/blob/master/examples/chat_parsing.js)使其适用于您的特定聊天插件. 或者阅读 http://
|
|
18
|
+
阅读并改编[chat_parsing.js](https://github.com/PrismarineJS/mineflayer/blob/master/examples/chat_parsing.js)使其适用于您的特定聊天插件. 或者阅读 http://prismarinejs.github.io/mineflayer/#/tutorial?id=custom-chat
|
|
19
19
|
|
|
20
20
|
### 如何用自定义插件在聊天中收集信息 ?
|
|
21
21
|
|
package/docs/zh/README_ZH_CN.md
CHANGED
|
@@ -101,7 +101,7 @@ bot.on('error', console.log)
|
|
|
101
101
|
### 看看你的bot在做什么
|
|
102
102
|
|
|
103
103
|
感谢 [prismarin-viewer](https://github.com/PrismarineJS/prismarine-viewer)项目,它可以在浏览器窗口显示你的机器人正在做什么。
|
|
104
|
-
只需要运行 `npm install
|
|
104
|
+
只需要运行 `npm install prismarine-viewer` 并将其添加到你的bot代码中。
|
|
105
105
|
|
|
106
106
|
```js
|
|
107
107
|
const { mineflayer: mineflayerViewer } = require('prismarine-viewer')
|
|
@@ -112,7 +112,7 @@ bot.once('spawn', () => {
|
|
|
112
112
|
|
|
113
113
|
然后你会得到一个看起来像这样的*实时视图*:
|
|
114
114
|
|
|
115
|
-
[<img src="https://
|
|
115
|
+
[<img src="https://prismarinejs.github.io/prismarine-viewer/test_1.16.1.png" alt="viewer" width="500">](https://prismarinejs.github.io/prismarine-viewer/)
|
|
116
116
|
|
|
117
117
|
#### 更多示例
|
|
118
118
|
|
package/docs/zh/tutorial.md
CHANGED
|
@@ -417,7 +417,7 @@ bot.once('spawn', () => {
|
|
|
417
417
|
|
|
418
418
|
### Listening for an event
|
|
419
419
|
|
|
420
|
-
The bot object has many useful [events](http://
|
|
420
|
+
The bot object has many useful [events](http://prismarinejs.github.io/mineflayer/#/api?id=events).
|
|
421
421
|
You can listen for an event by using either `bot.on()` method or `bot.once()` method of the bot object, which takes the name of an event and a function.
|
|
422
422
|
To remove specific listener you can use `bot.removeListener()` method.
|
|
423
423
|
|
|
@@ -428,7 +428,7 @@ To remove specific listener you can use `bot.removeListener()` method.
|
|
|
428
428
|
- `bot.removeListener(eventName, listener)`
|
|
429
429
|
Removes the specified `listener` for the event named `eventName`. In order to use this you either need to define your function with `function myNamedFunc() {}` or put your function in a variable with `const myNamedFunc = () => {}`. You can then use `myNamedFunc` in the listener argument.
|
|
430
430
|
|
|
431
|
-
Not only bot object, [`Chest`](http://
|
|
431
|
+
Not only bot object, [`Chest`](http://prismarinejs.github.io/mineflayer/#/api?id=mineflayerchest), [`Furnace`](http://prismarinejs.github.io/mineflayer/#/api?id=mineflayerfurnace), [`Dispenser`](http://prismarinejs.github.io/mineflayer/#/api?id=mineflayerdispenser), [`EnchantmentTable`](http://prismarinejs.github.io/mineflayer/#/api?id=mineflayerenchantmenttable), [`Villager`](http://prismarinejs.github.io/mineflayer/#/api?id=mineflayervillager) object also have their own events!
|
|
432
432
|
|
|
433
433
|
### Callbacks
|
|
434
434
|
A [callback](https://en.wikipedia.org/wiki/Callback_(computer_programming)) is a function that you can give to another function, that is expected to be *called back*, generally when that function ends.
|
|
@@ -491,7 +491,7 @@ The reason the incorrect approach is wrong is because when `bot.craft()` is call
|
|
|
491
491
|
By the time the code reaches the second `bot.craft()`, the first probably hasn't finished yet, which means the wanted resource is not available yet.
|
|
492
492
|
Using callbacks can fix this because they will only be called after the `bot.craft()` is finished.
|
|
493
493
|
|
|
494
|
-
More on the [bot.craft()](https://
|
|
494
|
+
More on the [bot.craft()](https://prismarinejs.github.io/mineflayer/#/api?id=botcraftrecipe-count-craftingtable-callback) method.
|
|
495
495
|
|
|
496
496
|
## 高级
|
|
497
497
|
|
|
@@ -608,8 +608,8 @@ In general, you'll want to use `for of` instead of `for in` so make sure you don
|
|
|
608
608
|
|
|
609
609
|
### 从聊天中创建事件
|
|
610
610
|
|
|
611
|
-
You can create your own event from chat using [`bot.chatAddPattern()`](http://
|
|
612
|
-
[`bot.chatAddPattern()`](http://
|
|
611
|
+
You can create your own event from chat using [`bot.chatAddPattern()`](http://prismarinejs.github.io/mineflayer/#/api?id=botchataddpatternpattern-chattype-description) method. Useful for Bukkit servers where the chat format changes a lot.
|
|
612
|
+
[`bot.chatAddPattern()`](http://prismarinejs.github.io/mineflayer/#/api?id=botchataddpatternpattern-chattype-description) method takes three arguments :
|
|
613
613
|
|
|
614
614
|
- `pattern` - regular expression (regex) to match chat
|
|
615
615
|
- `chatType` - the event the bot emits when the pattern matches. e.g. "chat" or "whisper"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This example is an easy way to connect mineflayer to the node:readline module
|
|
3
|
+
* See: https://nodejs.org/api/readline.html
|
|
4
|
+
* Using this, we can make a simple terminal-to-ingame-chat interface
|
|
5
|
+
*
|
|
6
|
+
* Made by Jovan04 01/24/2023
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
if (process.argv.length < 4 || process.argv.length > 6) {
|
|
10
|
+
console.log('Usage : node readline.js <host> <port> [<name>] [<auth>]')
|
|
11
|
+
process.exit(1)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const mineflayer = require('mineflayer') // load mineflayer library
|
|
15
|
+
const readline = require('node:readline') // load the node.js readline module
|
|
16
|
+
|
|
17
|
+
// bot options
|
|
18
|
+
const options = {
|
|
19
|
+
host: process.argv[2],
|
|
20
|
+
port: parseInt(process.argv[3]),
|
|
21
|
+
username: process.argv[4] || 'readline',
|
|
22
|
+
auth: process.argv[5] || 'offline'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const bot = mineflayer.createBot(options) // join the minecraft server
|
|
26
|
+
|
|
27
|
+
const rl = readline.createInterface({ // creates our readline interface with our console as input and output
|
|
28
|
+
input: process.stdin,
|
|
29
|
+
output: process.stdout
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
bot.once('spawn', () => {
|
|
33
|
+
console.log(`Bot joined the game with username ${bot.username}.`)
|
|
34
|
+
rl.setPrompt('> '); rl.prompt() // gives us a little arrow at the bottom for the input line
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
bot.on('message', (message) => {
|
|
38
|
+
readline.moveCursor(process.stdout, -2, 0) // we move the cursor to the left two places because our cursor is already two positions in (because of the input arrow)
|
|
39
|
+
console.log(message.toAnsi()) // convert our message to ansi to preserve chat formatting
|
|
40
|
+
rl.prompt() // regenerate our little arrow on the input line
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
rl.on('line', (line) => {
|
|
44
|
+
readline.moveCursor(process.stdout, 0, -1) // move cursor up one line
|
|
45
|
+
readline.clearScreenDown(process.stdout) // clear all the lines below the cursor (i.e. the last line we entered)
|
|
46
|
+
bot.chat(line.toString()) // sends the line we entered to ingame chat
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
bot.on('kicked', console.log)
|
|
50
|
+
bot.on('error', console.log)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This script will automatically set if a totem is in the inventory or the off-hand.
|
|
3
|
+
* It checks for a totem every tick.
|
|
4
|
+
*/
|
|
5
|
+
const mineflayer = require('mineflayer')
|
|
6
|
+
|
|
7
|
+
if (process.argv.length < 4 || process.argv.length > 6) {
|
|
8
|
+
console.log('Usage : node skin_data.js <host> <port> [<name>] [<password>]')
|
|
9
|
+
process.exit(1)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const bot = mineflayer.createBot({
|
|
13
|
+
host: process.argv[2],
|
|
14
|
+
port: parseInt(process.argv[3]),
|
|
15
|
+
username: process.argv[4] ? process.argv[4] : 'skin_data',
|
|
16
|
+
password: process.argv[5]
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
setTimeout(() => {
|
|
20
|
+
bot.quit()
|
|
21
|
+
console.log('Skin data:')
|
|
22
|
+
console.log(Object.entries(bot.players).map(([name, player]) => ({
|
|
23
|
+
name,
|
|
24
|
+
skinData: player.skinData
|
|
25
|
+
})))
|
|
26
|
+
}, 10000)
|
package/examples/trader.js
CHANGED
|
@@ -96,7 +96,7 @@ async function trade (id, index, count) {
|
|
|
96
96
|
default: {
|
|
97
97
|
const villager = await bot.openVillager(e)
|
|
98
98
|
const trade = villager.trades[index - 1]
|
|
99
|
-
count = count || trade.
|
|
99
|
+
count = count || trade.maximumNbTradeUses - trade.nbTradeUses
|
|
100
100
|
switch (true) {
|
|
101
101
|
case !trade:
|
|
102
102
|
villager.close()
|
|
@@ -106,11 +106,11 @@ async function trade (id, index, count) {
|
|
|
106
106
|
villager.close()
|
|
107
107
|
bot.chat('trade is disabled')
|
|
108
108
|
break
|
|
109
|
-
case trade.
|
|
109
|
+
case trade.maximumNbTradeUses - trade.nbTradeUses < count:
|
|
110
110
|
villager.close()
|
|
111
111
|
bot.chat('cant trade that often')
|
|
112
112
|
break
|
|
113
|
-
case !hasResources(villager.
|
|
113
|
+
case !hasResources(villager.slots, trade, count):
|
|
114
114
|
villager.close()
|
|
115
115
|
bot.chat('dont have the resources to do that trade')
|
|
116
116
|
break
|
|
@@ -120,7 +120,7 @@ async function trade (id, index, count) {
|
|
|
120
120
|
await bot.trade(villager, index - 1, count)
|
|
121
121
|
bot.chat(`traded ${count} times`)
|
|
122
122
|
} catch (err) {
|
|
123
|
-
bot.chat('an error
|
|
123
|
+
bot.chat('an error occurred while trying to trade')
|
|
124
124
|
console.log(err)
|
|
125
125
|
}
|
|
126
126
|
villager.close()
|
|
@@ -129,23 +129,29 @@ async function trade (id, index, count) {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
function hasResources (window, trade, count) {
|
|
132
|
-
const first = enough(trade.
|
|
133
|
-
const second = !trade.
|
|
132
|
+
const first = enough(trade.inputItem1, count)
|
|
133
|
+
const second = !trade.inputItem2 || enough(trade.inputItem2, count)
|
|
134
134
|
return first && second
|
|
135
135
|
|
|
136
136
|
function enough (item, count) {
|
|
137
|
-
|
|
137
|
+
let c = 0
|
|
138
|
+
window.forEach((element) => {
|
|
139
|
+
if (element && element.type === item.type && element.metadata === item.metadata) {
|
|
140
|
+
c += element.count
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
return c >= item.count * count
|
|
138
144
|
}
|
|
139
145
|
}
|
|
140
146
|
}
|
|
141
147
|
|
|
142
148
|
function stringifyTrades (trades) {
|
|
143
149
|
return trades.map((trade) => {
|
|
144
|
-
let text = stringifyItem(trade.
|
|
145
|
-
if (trade.
|
|
150
|
+
let text = stringifyItem(trade.inputItem1)
|
|
151
|
+
if (trade.inputItem2) text += ` & ${stringifyItem(trade.inputItem2)}`
|
|
146
152
|
if (trade.disabled) text += ' x '; else text += ' » '
|
|
147
|
-
text += stringifyItem(trade.
|
|
148
|
-
return `(${trade.
|
|
153
|
+
text += stringifyItem(trade.outputItem)
|
|
154
|
+
return `(${trade.nbTradeUses}/${trade.maximumNbTradeUses}) ${text}`
|
|
149
155
|
})
|
|
150
156
|
}
|
|
151
157
|
|
|
@@ -158,7 +164,7 @@ function stringifyItem (item) {
|
|
|
158
164
|
const Potion = item.nbt.value.Potion
|
|
159
165
|
const display = item.nbt.value.display
|
|
160
166
|
|
|
161
|
-
if (Potion) text += ` of ${Potion.value.replace(/_/g, ' ').split(':')[1] || '
|
|
167
|
+
if (Potion) text += ` of ${Potion.value.replace(/_/g, ' ').split(':')[1] || 'unknown type'}`
|
|
162
168
|
if (display) text += ` named ${display.value.Name.value}`
|
|
163
169
|
if (ench || StoredEnchantments) {
|
|
164
170
|
text += ` enchanted with ${(ench || StoredEnchantments).value.value.map((e) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
[<img src="https://
|
|
1
|
+
[<img src="https://prismarinejs.github.io/prismarine-viewer/test_1.16.1.png" alt="viewer" width="800">](https://prismarinejs.github.io/prismarine-viewer/)
|
package/index.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export interface BotOptions extends ClientOptions {
|
|
|
28
28
|
client?: Client
|
|
29
29
|
brand?: string
|
|
30
30
|
defaultChatPatterns?: boolean
|
|
31
|
+
respawn?: boolean
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
export type ChatLevel = 'enabled' | 'commandsOnly' | 'disabled'
|
|
@@ -40,7 +41,7 @@ export interface PluginOptions {
|
|
|
40
41
|
|
|
41
42
|
export type Plugin = (bot: Bot, options: BotOptions) => void
|
|
42
43
|
|
|
43
|
-
interface BotEvents {
|
|
44
|
+
export interface BotEvents {
|
|
44
45
|
chat: (
|
|
45
46
|
username: string,
|
|
46
47
|
message: string,
|
|
@@ -104,7 +105,7 @@ interface BotEvents {
|
|
|
104
105
|
playerUpdated: (player: Player) => Promise<void> | void
|
|
105
106
|
playerLeft: (entity: Player) => Promise<void> | void
|
|
106
107
|
blockUpdate: (oldBlock: Block | null, newBlock: Block) => Promise<void> | void
|
|
107
|
-
'blockUpdate:(x, y, z)': (oldBlock: Block | null, newBlock: Block) => Promise<void> | void
|
|
108
|
+
'blockUpdate:(x, y, z)': (oldBlock: Block | null, newBlock: Block | null) => Promise<void> | void
|
|
108
109
|
chunkColumnLoad: (entity: Vec3) => Promise<void> | void
|
|
109
110
|
chunkColumnUnload: (entity: Vec3) => Promise<void> | void
|
|
110
111
|
soundEffectHeard: (
|
|
@@ -122,7 +123,7 @@ interface BotEvents {
|
|
|
122
123
|
) => Promise<void> | void
|
|
123
124
|
noteHeard: (block: Block, instrument: Instrument, pitch: number) => Promise<void> | void
|
|
124
125
|
pistonMove: (block: Block, isPulling: number, direction: number) => Promise<void> | void
|
|
125
|
-
chestLidMove: (block: Block, isOpen: number) => Promise<void> | void
|
|
126
|
+
chestLidMove: (block: Block, isOpen: number, block2: Block | null) => Promise<void> | void
|
|
126
127
|
blockBreakProgressObserved: (block: Block, destroyStage: number) => Promise<void> | void
|
|
127
128
|
blockBreakProgressEnd: (block: Block) => Promise<void> | void
|
|
128
129
|
diggingCompleted: (block: Block) => Promise<void> | void
|
|
@@ -190,6 +191,7 @@ export interface Bot extends TypedEmitter<BotEvents> {
|
|
|
190
191
|
world: any
|
|
191
192
|
_client: Client
|
|
192
193
|
heldItem: Item | null
|
|
194
|
+
usingHeldItem: boolean
|
|
193
195
|
currentWindow: Window | null
|
|
194
196
|
simpleClick: simpleClick
|
|
195
197
|
tablist: Tablist
|
|
@@ -449,7 +451,7 @@ export type LevelType =
|
|
|
449
451
|
| 'buffet'
|
|
450
452
|
| 'default_1_1'
|
|
451
453
|
export type GameMode = 'survival' | 'creative' | 'adventure' | 'spectator'
|
|
452
|
-
export type Dimension = '
|
|
454
|
+
export type Dimension = 'the_nether' | 'overworld' | 'the_end'
|
|
453
455
|
export type Difficulty = 'peaceful' | 'easy' | 'normal' | 'hard'
|
|
454
456
|
|
|
455
457
|
export interface Player {
|
|
@@ -459,12 +461,18 @@ export interface Player {
|
|
|
459
461
|
gamemode: number
|
|
460
462
|
ping: number
|
|
461
463
|
entity: Entity
|
|
464
|
+
skinData: SkinData | undefined
|
|
462
465
|
profileKeys?: {
|
|
463
466
|
publicKey: Buffer
|
|
464
467
|
signature: Buffer
|
|
465
468
|
}
|
|
466
469
|
}
|
|
467
470
|
|
|
471
|
+
export interface SkinData {
|
|
472
|
+
url: string
|
|
473
|
+
model: string | null
|
|
474
|
+
}
|
|
475
|
+
|
|
468
476
|
export interface ChatPattern {
|
|
469
477
|
pattern: RegExp
|
|
470
478
|
type: string
|
|
@@ -558,7 +566,7 @@ export interface FindBlockOptions {
|
|
|
558
566
|
matching: number | number[] | ((block: Block) => boolean)
|
|
559
567
|
maxDistance?: number
|
|
560
568
|
count?: number
|
|
561
|
-
useExtraInfo?: boolean
|
|
569
|
+
useExtraInfo?: boolean | ((block: Block) => boolean)
|
|
562
570
|
}
|
|
563
571
|
|
|
564
572
|
export type EquipmentDestination = 'hand' | 'head' | 'torso' | 'legs' | 'feet' | 'off-hand'
|
package/lib/loader.js
CHANGED
|
@@ -69,6 +69,7 @@ function createBot (options = {}) {
|
|
|
69
69
|
options.loadInternalPlugins = options.loadInternalPlugins ?? true
|
|
70
70
|
options.client = options.client ?? null
|
|
71
71
|
options.brand = options.brand ?? 'vanilla'
|
|
72
|
+
options.respawn = options.respawn ?? true
|
|
72
73
|
const bot = new EventEmitter()
|
|
73
74
|
bot._client = options.client
|
|
74
75
|
bot.end = (reason) => bot._client.end(reason)
|
|
@@ -123,7 +124,7 @@ function createBot (options = {}) {
|
|
|
123
124
|
bot.version = version.minecraftVersion
|
|
124
125
|
options.version = version.minecraftVersion
|
|
125
126
|
bot.supportFeature = bot.registry.supportFeature
|
|
126
|
-
bot.emit('inject_allowed')
|
|
127
|
+
setTimeout(() => bot.emit('inject_allowed'), 0)
|
|
127
128
|
}
|
|
128
129
|
return bot
|
|
129
130
|
}
|
package/lib/plugins/bed.js
CHANGED
|
@@ -131,7 +131,7 @@ function inject (bot) {
|
|
|
131
131
|
throw new Error('the bed is too far')
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
if (bot.gameMode !== 'creative' || bot.supportFeature('creativeSleepNearMobs')) { // If in creative mode the bot should be able to sleep even if there are monster nearby (starting in 1.13)
|
|
134
|
+
if (bot.game.gameMode !== 'creative' || bot.supportFeature('creativeSleepNearMobs')) { // If in creative mode the bot should be able to sleep even if there are monster nearby (starting in 1.13)
|
|
135
135
|
const nwMonsterCorner = headPoint.offset(monsterRange[1], -6, monsterRange[2]) // North-West lower corner
|
|
136
136
|
const seMonsterCorner = headPoint.offset(monsterRange[3], 4, monsterRange[0]) // South-East upper corner
|
|
137
137
|
|
package/lib/plugins/blocks.js
CHANGED
|
@@ -275,7 +275,7 @@ function inject (bot, { version, storageBuilder, hideErrors }) {
|
|
|
275
275
|
bitMap: packet.bitMap,
|
|
276
276
|
heightmaps: packet.heightmaps,
|
|
277
277
|
biomes: packet.biomes,
|
|
278
|
-
skyLightSent: bot.game.dimension === '
|
|
278
|
+
skyLightSent: bot.game.dimension === 'overworld',
|
|
279
279
|
groundUp: packet.groundUp,
|
|
280
280
|
data: packet.chunkData,
|
|
281
281
|
trustEdges: packet.trustEdges,
|
package/lib/plugins/craft.js
CHANGED
|
@@ -6,6 +6,7 @@ module.exports = inject
|
|
|
6
6
|
function inject (bot) {
|
|
7
7
|
const Item = require('prismarine-item')(bot.registry)
|
|
8
8
|
const Recipe = require('prismarine-recipe')(bot.registry).Recipe
|
|
9
|
+
let windowCraftingTable
|
|
9
10
|
|
|
10
11
|
async function craft (recipe, count, craftingTable) {
|
|
11
12
|
assert.ok(recipe)
|
|
@@ -13,19 +14,36 @@ function inject (bot) {
|
|
|
13
14
|
if (recipe.requiresTable && !craftingTable) {
|
|
14
15
|
throw new Error('recipe requires craftingTable')
|
|
15
16
|
}
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
for (let i = 0; i < count; i++) {
|
|
20
|
+
await craftOnce(recipe, craftingTable)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (windowCraftingTable) {
|
|
24
|
+
bot.closeWindow(windowCraftingTable)
|
|
25
|
+
windowCraftingTable = undefined
|
|
26
|
+
}
|
|
27
|
+
} catch (err) {
|
|
28
|
+
if (windowCraftingTable) {
|
|
29
|
+
bot.closeWindow(windowCraftingTable)
|
|
30
|
+
windowCraftingTable = undefined
|
|
31
|
+
}
|
|
32
|
+
throw new Error(err)
|
|
18
33
|
}
|
|
19
34
|
}
|
|
20
35
|
|
|
21
36
|
async function craftOnce (recipe, craftingTable) {
|
|
22
37
|
if (craftingTable) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
38
|
+
if (!windowCraftingTable) {
|
|
39
|
+
bot.activateBlock(craftingTable)
|
|
40
|
+
const [window] = await once(bot, 'windowOpen')
|
|
41
|
+
windowCraftingTable = window
|
|
42
|
+
}
|
|
43
|
+
if (!windowCraftingTable.type.startsWith('minecraft:crafting')) {
|
|
26
44
|
throw new Error('crafting: non craftingTable used as craftingTable')
|
|
27
45
|
}
|
|
28
|
-
await startClicking(
|
|
46
|
+
await startClicking(windowCraftingTable, 3, 3)
|
|
29
47
|
} else {
|
|
30
48
|
await startClicking(bot.inventory, 2, 2)
|
|
31
49
|
}
|
|
@@ -73,7 +91,7 @@ function inject (bot) {
|
|
|
73
91
|
if (ingredient.id === -1) return nextShapeClick()
|
|
74
92
|
if (!window.selectedItem || window.selectedItem.type !== ingredient.id ||
|
|
75
93
|
(ingredient.metadata != null &&
|
|
76
|
-
|
|
94
|
+
window.selectedItem.metadata !== ingredient.metadata)) {
|
|
77
95
|
// we are not holding the item we need. click it.
|
|
78
96
|
const sourceItem = window.findInventoryItem(ingredient.id, ingredient.metadata)
|
|
79
97
|
if (!sourceItem) throw new Error('missing ingredient')
|
|
@@ -89,7 +107,7 @@ function inject (bot) {
|
|
|
89
107
|
const destSlot = extraSlots.pop()
|
|
90
108
|
if (!window.selectedItem || window.selectedItem.type !== ingredient.id ||
|
|
91
109
|
(ingredient.metadata != null &&
|
|
92
|
-
|
|
110
|
+
window.selectedItem.metadata !== ingredient.metadata)) {
|
|
93
111
|
// we are not holding the item we need. click it.
|
|
94
112
|
const sourceItem = window.findInventoryItem(ingredient.id, ingredient.metadata)
|
|
95
113
|
if (!sourceItem) throw new Error('missing ingredient')
|
|
@@ -126,7 +144,6 @@ function inject (bot) {
|
|
|
126
144
|
for (let i = 1; i <= w * h; i++) {
|
|
127
145
|
window.updateSlot(i, null)
|
|
128
146
|
}
|
|
129
|
-
closeTheWindow()
|
|
130
147
|
return
|
|
131
148
|
}
|
|
132
149
|
const slotsToClick = []
|
|
@@ -145,11 +162,6 @@ function inject (bot) {
|
|
|
145
162
|
for (const _slot of slotsToClick) {
|
|
146
163
|
await bot.putAway(_slot)
|
|
147
164
|
}
|
|
148
|
-
closeTheWindow()
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function closeTheWindow () {
|
|
152
|
-
bot.closeWindow(window)
|
|
153
165
|
}
|
|
154
166
|
|
|
155
167
|
function slot (x, y) {
|
package/lib/plugins/digging.js
CHANGED
|
@@ -162,7 +162,8 @@ function inject (bot) {
|
|
|
162
162
|
function onBlockUpdate (oldBlock, newBlock) {
|
|
163
163
|
// vanilla server never actually interrupt digging, but some server send block update when you start digging
|
|
164
164
|
// so ignore block update if not air
|
|
165
|
-
|
|
165
|
+
// All block update listeners receive (null, null) when the world is unloaded. So newBlock can be null.
|
|
166
|
+
if (newBlock?.type !== 0) return
|
|
166
167
|
bot.removeListener(eventName, onBlockUpdate)
|
|
167
168
|
clearInterval(swingInterval)
|
|
168
169
|
clearTimeout(waitTimeout)
|
package/lib/plugins/entities.js
CHANGED
|
@@ -361,28 +361,48 @@ function inject (bot) {
|
|
|
361
361
|
entity.metadata = metadata
|
|
362
362
|
bot.emit('entityUpdate', entity)
|
|
363
363
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
364
|
+
if (bot.supportFeature('mcDataHasEntityMetadata')) {
|
|
365
|
+
const { metadataKeys } = bot.registry.entitiesByName[entity.name] ?? {}
|
|
366
|
+
const metas = Object.fromEntries(packet.metadata.map(e => [metadataKeys[e.key], e.value]))
|
|
367
|
+
if (packet.metadata.some(m => m.type === 'item_stack')) {
|
|
368
|
+
bot.emit('itemDrop', entity)
|
|
369
|
+
}
|
|
370
|
+
if (metas.sleeping_pos || metas.pose === 2) {
|
|
371
|
+
bot.emit('entitySleep', entity)
|
|
372
|
+
}
|
|
373
|
+
if (metas.shared_flags != null) {
|
|
374
|
+
if (metas.shared_flags & 2) {
|
|
375
|
+
entity.crouching = true
|
|
376
|
+
bot.emit('entityCrouch', entity)
|
|
377
|
+
} else if (entity.crouching) { // prevent the initial entity_metadata packet from firing off an uncrouch event
|
|
378
|
+
entity.crouching = false
|
|
379
|
+
bot.emit('entityUncrouch', entity)
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
} else {
|
|
383
|
+
const typeSlot = (bot.supportFeature('itemsAreAlsoBlocks') ? 5 : 6) + (bot.supportFeature('entityMetadataHasLong') ? 1 : 0)
|
|
384
|
+
const slot = packet.metadata.find(e => e.type === typeSlot)
|
|
385
|
+
if (entity.name && (entity.name.toLowerCase() === 'item' || entity.name === 'item_stack') && slot) {
|
|
386
|
+
bot.emit('itemDrop', entity)
|
|
387
|
+
}
|
|
369
388
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
389
|
+
const typePose = bot.supportFeature('entityMetadataHasLong') ? 19 : 18
|
|
390
|
+
const pose = packet.metadata.find(e => e.type === typePose)
|
|
391
|
+
if (pose && pose.value === 2) {
|
|
392
|
+
bot.emit('entitySleep', entity)
|
|
393
|
+
}
|
|
375
394
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
395
|
+
const bitField = packet.metadata.find(p => p.key === 0)
|
|
396
|
+
if (bitField === undefined) {
|
|
397
|
+
return
|
|
398
|
+
}
|
|
399
|
+
if ((bitField.value & 2) !== 0) {
|
|
400
|
+
entity.crouching = true
|
|
401
|
+
bot.emit('entityCrouch', entity)
|
|
402
|
+
} else if (entity.crouching) { // prevent the initial entity_metadata packet from firing off an uncrouch event
|
|
403
|
+
entity.crouching = false
|
|
404
|
+
bot.emit('entityUncrouch', entity)
|
|
405
|
+
}
|
|
386
406
|
}
|
|
387
407
|
})
|
|
388
408
|
|
|
@@ -462,6 +482,7 @@ function inject (bot) {
|
|
|
462
482
|
if (packet.action & 1) {
|
|
463
483
|
obj.username = item.player.name
|
|
464
484
|
obj.displayName = player.displayName || new ChatMessage({ text: '', extra: [{ text: item.player.name }] })
|
|
485
|
+
obj.skinData = extractSkinInformation(item.player.properties)
|
|
465
486
|
}
|
|
466
487
|
|
|
467
488
|
if (packet.action & 4) {
|
|
@@ -484,7 +505,7 @@ function inject (bot) {
|
|
|
484
505
|
Object.assign(player, obj)
|
|
485
506
|
}
|
|
486
507
|
|
|
487
|
-
const playerEntity = Object.values(bot.entities).find(e => e.type === 'player' && e.username ===
|
|
508
|
+
const playerEntity = Object.values(bot.entities).find(e => e.type === 'player' && e.username === player.username)
|
|
488
509
|
player.entity = playerEntity
|
|
489
510
|
|
|
490
511
|
if (playerEntity === bot.entity) {
|
|
@@ -510,6 +531,7 @@ function inject (bot) {
|
|
|
510
531
|
ping: item.ping,
|
|
511
532
|
uuid: item.UUID,
|
|
512
533
|
displayName: new ChatMessage({ text: '', extra: [{ text: item.name }] }),
|
|
534
|
+
skinData: extractSkinInformation(item.properties),
|
|
513
535
|
profileKeys: item.crypto
|
|
514
536
|
? {
|
|
515
537
|
publicKey: item.crypto.publicKey, // DER-encoded public key
|
|
@@ -525,6 +547,7 @@ function inject (bot) {
|
|
|
525
547
|
// Just an Update
|
|
526
548
|
player.gamemode = item.gamemode
|
|
527
549
|
player.ping = item.ping
|
|
550
|
+
player.skinData = extractSkinInformation(item.properties)
|
|
528
551
|
if (item.crypto) {
|
|
529
552
|
player.profileKeys = {
|
|
530
553
|
publicKey: item.crypto.publicKey,
|
|
@@ -579,7 +602,7 @@ function inject (bot) {
|
|
|
579
602
|
for (const uuid of packet.players) {
|
|
580
603
|
const player = bot.uuidToUsername[uuid] ? bot.players[bot.uuidToUsername[uuid]] : null
|
|
581
604
|
|
|
582
|
-
if (player.entity === bot.entity) continue
|
|
605
|
+
if (!player || player.entity === bot.entity) continue
|
|
583
606
|
|
|
584
607
|
player.entity = null
|
|
585
608
|
delete bot.players[player.username]
|
|
@@ -706,3 +729,25 @@ function parseMetadata (metadata, entityMetadata = {}) {
|
|
|
706
729
|
|
|
707
730
|
return entityMetadata
|
|
708
731
|
}
|
|
732
|
+
|
|
733
|
+
function extractSkinInformation (properties) {
|
|
734
|
+
if (!properties) {
|
|
735
|
+
return undefined
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
const props = Object.fromEntries(properties.map((e) => [e.name, e]))
|
|
739
|
+
if (!props.textures || !props.textures.value) {
|
|
740
|
+
return undefined
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
const skinTexture = JSON.parse(Buffer.from(props.textures.value, 'base64').toString('utf8'))
|
|
744
|
+
|
|
745
|
+
const skinTextureUrl = skinTexture?.textures?.SKIN?.url ?? undefined
|
|
746
|
+
const skinTextureModel = skinTexture?.textures?.SKIN?.metadata?.model ?? undefined
|
|
747
|
+
|
|
748
|
+
if (!skinTextureUrl) {
|
|
749
|
+
return undefined
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
return { url: skinTextureUrl, model: skinTextureModel }
|
|
753
|
+
}
|
package/lib/plugins/game.js
CHANGED
|
@@ -2,12 +2,12 @@ const nbt = require('prismarine-nbt')
|
|
|
2
2
|
module.exports = inject
|
|
3
3
|
|
|
4
4
|
const difficultyNames = ['peaceful', 'easy', 'normal', 'hard']
|
|
5
|
-
const gameModes = ['survival', 'creative', 'adventure']
|
|
5
|
+
const gameModes = ['survival', 'creative', 'adventure', 'spectator']
|
|
6
6
|
|
|
7
7
|
const dimensionNames = {
|
|
8
|
-
'-1': '
|
|
9
|
-
0: '
|
|
10
|
-
1: '
|
|
8
|
+
'-1': 'the_nether',
|
|
9
|
+
0: 'overworld',
|
|
10
|
+
1: 'the_end'
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const parseGameMode = gameModeBits => gameModes[(gameModeBits & 0b11)] // lower two bits
|
|
@@ -29,9 +29,9 @@ function inject (bot, options) {
|
|
|
29
29
|
if (bot.supportFeature('dimensionIsAnInt')) {
|
|
30
30
|
bot.game.dimension = dimensionNames[packet.dimension]
|
|
31
31
|
} else if (bot.supportFeature('dimensionIsAString')) {
|
|
32
|
-
bot.game.dimension = packet.dimension
|
|
32
|
+
bot.game.dimension = packet.dimension.replace('minecraft:', '')
|
|
33
33
|
} else if (bot.supportFeature('dimensionIsAWorld')) {
|
|
34
|
-
bot.game.dimension = packet.worldName
|
|
34
|
+
bot.game.dimension = packet.worldName.replace('minecraft:', '')
|
|
35
35
|
} else {
|
|
36
36
|
throw new Error('Unsupported dimension type in login packet')
|
|
37
37
|
}
|
|
@@ -48,6 +48,9 @@ function inject (bot, options) {
|
|
|
48
48
|
bot.game.height = height
|
|
49
49
|
} else if (packet.dimension) { // respawn
|
|
50
50
|
bot.game.dimension = packet.dimension.replace('minecraft:', '')
|
|
51
|
+
const { minY, height } = bot.registry.dimensionsByName[bot.game.dimension]
|
|
52
|
+
bot.game.minY = minY
|
|
53
|
+
bot.game.height = height
|
|
51
54
|
}
|
|
52
55
|
} else if (bot.supportFeature('dimensionDataIsAvailable')) { // 1.18
|
|
53
56
|
const dimensionData = nbt.simplify(packet.dimension)
|
|
@@ -57,6 +60,7 @@ function inject (bot, options) {
|
|
|
57
60
|
bot.game.minY = 0
|
|
58
61
|
bot.game.height = 256
|
|
59
62
|
}
|
|
63
|
+
|
|
60
64
|
if (packet.difficulty) {
|
|
61
65
|
bot.game.difficulty = difficultyNames[packet.difficulty]
|
|
62
66
|
}
|
package/lib/plugins/health.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module.exports = inject
|
|
2
2
|
|
|
3
|
-
function inject (bot) {
|
|
3
|
+
function inject (bot, options) {
|
|
4
4
|
bot.isAlive = true
|
|
5
5
|
|
|
6
6
|
bot._client.on('respawn', (packet) => {
|
|
@@ -24,6 +24,7 @@ function inject (bot) {
|
|
|
24
24
|
bot.isAlive = false
|
|
25
25
|
bot.emit('death')
|
|
26
26
|
}
|
|
27
|
+
if (!options.respawn) return
|
|
27
28
|
bot._client.write('client_command', { payload: 0 })
|
|
28
29
|
} else if (bot.health > 0 && !bot.isAlive) {
|
|
29
30
|
bot.isAlive = true
|
package/lib/plugins/inventory.js
CHANGED
|
@@ -12,6 +12,8 @@ const DIG_CLICK_TIMEOUT = 500
|
|
|
12
12
|
// This number is larger than the eat time of 1.61 seconds to account for latency and low tps.
|
|
13
13
|
// The eat time comes from https://minecraft.fandom.com/wiki/Food#Usage
|
|
14
14
|
const CONSUME_TIMEOUT = 2500
|
|
15
|
+
// milliseconds to wait for the server to respond to a window click transaction
|
|
16
|
+
const WINDOW_TIMEOUT = 5000
|
|
15
17
|
|
|
16
18
|
const ALWAYS_CONSUMABLES = [
|
|
17
19
|
'potion',
|
|
@@ -544,7 +546,10 @@ function inject (bot, { hideErrors }) {
|
|
|
544
546
|
if (!window.transactionRequiresConfirmation(click)) {
|
|
545
547
|
confirmTransaction(window.id, actionId, true)
|
|
546
548
|
}
|
|
547
|
-
const [success] = await response
|
|
549
|
+
const [success] = await withTimeout(response, WINDOW_TIMEOUT)
|
|
550
|
+
.catch(() => {
|
|
551
|
+
throw new Error(`Server didn't respond to transaction for clicking on slot ${slot} on window with id ${window?.id}.`)
|
|
552
|
+
})
|
|
548
553
|
if (!success) {
|
|
549
554
|
throw new Error(`Server rejected transaction for clicking on slot ${slot}, on window with id ${window?.id}.`)
|
|
550
555
|
}
|
package/lib/plugins/physics.js
CHANGED
|
@@ -235,6 +235,10 @@ function inject (bot, { physicsEnabled }) {
|
|
|
235
235
|
const yawChange = Math.round((yaw - bot.entity.yaw) / sensitivity) * sensitivity
|
|
236
236
|
const pitchChange = Math.round((pitch - bot.entity.pitch) / sensitivity) * sensitivity
|
|
237
237
|
|
|
238
|
+
if (yawChange === 0 && pitchChange === 0) {
|
|
239
|
+
return
|
|
240
|
+
}
|
|
241
|
+
|
|
238
242
|
bot.entity.yaw += yawChange
|
|
239
243
|
bot.entity.pitch += pitchChange
|
|
240
244
|
|
|
@@ -13,8 +13,12 @@ function inject (bot) {
|
|
|
13
13
|
[oldBlock, newBlock] = await onceWithCleanup(bot, `blockUpdate:${dest}`, { timeout: 5000 })
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
// blockUpdate emits (null, null) when the world unloads
|
|
17
|
+
if (!oldBlock && !newBlock) {
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
if (oldBlock?.type === newBlock.type) {
|
|
21
|
+
throw new Error(`No block has been placed : the block is still ${oldBlock?.name}`)
|
|
18
22
|
} else {
|
|
19
23
|
bot.emit('blockPlaced', oldBlock, newBlock)
|
|
20
24
|
}
|
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', '1.18', '1.19'],
|
|
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', '1.18.2', '1.19', '1.19.2', '1.19.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', '1.18.2', '1.19', '1.19.2', '1.19.3', '1.19.4']
|
|
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": "4.
|
|
3
|
+
"version": "4.9.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.26.0",
|
|
25
|
-
"minecraft-protocol": "^1.
|
|
25
|
+
"minecraft-protocol": "^1.42.0",
|
|
26
26
|
"prismarine-biome": "^1.1.1",
|
|
27
27
|
"prismarine-block": "^1.13.1",
|
|
28
28
|
"prismarine-chat": "^1.7.1",
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
"vec3": "^0.1.7"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@types/node": "^
|
|
43
|
+
"@types/node": "^20.2.1",
|
|
44
44
|
"doctoc": "^2.0.1",
|
|
45
45
|
"minecraft-wrap": "^1.3.0",
|
|
46
46
|
"mineflayer": "file:.",
|
|
47
47
|
"mocha": "^10.0.0",
|
|
48
48
|
"standard": "^17.0.0",
|
|
49
49
|
"standard-markdown": "^7.1.0",
|
|
50
|
-
"typescript": "^
|
|
50
|
+
"typescript": "^5.0.3"
|
|
51
51
|
}
|
|
52
52
|
}
|
package/docs/CNAME
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
mineflayer.prismarine.js.org
|