mineflayer 4.13.0 → 4.14.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/docs/api.md +24 -1
- package/docs/history.md +5 -0
- package/docs/mineflayer.ipynb +21 -18
- package/examples/elytra.js +66 -0
- package/index.d.ts +7 -1
- package/lib/plugins/entities.js +113 -9
- package/lib/plugins/physics.js +38 -0
- package/package.json +3 -3
package/docs/api.md
CHANGED
|
@@ -136,6 +136,7 @@
|
|
|
136
136
|
- [bot.foodSaturation](#botfoodsaturation)
|
|
137
137
|
- [bot.oxygenLevel](#botoxygenlevel)
|
|
138
138
|
- [bot.physics](#botphysics)
|
|
139
|
+
- [bot.fireworkRocketDuration](#botfireworkrocketduration)
|
|
139
140
|
- [bot.simpleClick.leftMouse (slot)](#botsimpleclickleftmouse-slot)
|
|
140
141
|
- [bot.simpleClick.rightMouse (slot)](#botsimpleclickrightmouse-slot)
|
|
141
142
|
- [bot.time.doDaylightCycle](#bottimedodaylightcycle)
|
|
@@ -197,6 +198,7 @@
|
|
|
197
198
|
- ["entityEquip" (entity)](#entityequip-entity)
|
|
198
199
|
- ["entitySleep" (entity)](#entitysleep-entity)
|
|
199
200
|
- ["entitySpawn" (entity)](#entityspawn-entity)
|
|
201
|
+
- ["entityElytraFlew" (entity)](#entityelytraflew-entity)
|
|
200
202
|
- ["itemDrop" (entity)](#itemdrop-entity)
|
|
201
203
|
- ["playerCollect" (collector, collected)](#playercollect-collector-collected)
|
|
202
204
|
- ["entityGone" (entity)](#entitygone-entity)
|
|
@@ -223,6 +225,7 @@
|
|
|
223
225
|
- ["blockBreakProgressEnd" (block, entity)](#blockbreakprogressend-block-entity)
|
|
224
226
|
- ["diggingCompleted" (block)](#diggingcompleted-block)
|
|
225
227
|
- ["diggingAborted" (block)](#diggingaborted-block)
|
|
228
|
+
- ["usedFirework"](#usedfirework)
|
|
226
229
|
- ["move"](#move)
|
|
227
230
|
- ["forcedMove"](#forcedmove)
|
|
228
231
|
- ["mount"](#mount)
|
|
@@ -293,6 +296,7 @@
|
|
|
293
296
|
- [bot.unequip(destination)](#botunequipdestination)
|
|
294
297
|
- [bot.tossStack(item)](#bottossstackitem)
|
|
295
298
|
- [bot.toss(itemType, metadata, count)](#bottossitemtype-metadata-count)
|
|
299
|
+
- [bot.elytraFly()](#botelytrafly)
|
|
296
300
|
- [bot.dig(block, [forceLook = true], [digFace])](#botdigblock-forcelook--true-digface)
|
|
297
301
|
- [bot.stopDigging()](#botstopdigging)
|
|
298
302
|
- [bot.digTime(block)](#botdigtimeblock)
|
|
@@ -1037,6 +1041,10 @@ Number in the range [0, 20] respresenting the number of water-icons known as oxy
|
|
|
1037
1041
|
Edit these numbers to tweak gravity, jump speed, terminal velocity, etc.
|
|
1038
1042
|
Do this at your own risk.
|
|
1039
1043
|
|
|
1044
|
+
#### bot.fireworkRocketDuration
|
|
1045
|
+
|
|
1046
|
+
How many physics ticks worth of firework rocket boost are left.
|
|
1047
|
+
|
|
1040
1048
|
#### bot.simpleClick.leftMouse (slot)
|
|
1041
1049
|
|
|
1042
1050
|
abstraction over `bot.clickWindow(slot, 0, 0)`
|
|
@@ -1301,6 +1309,10 @@ Fires when an attribute of an entity changes.
|
|
|
1301
1309
|
#### "entityEquip" (entity)
|
|
1302
1310
|
#### "entitySleep" (entity)
|
|
1303
1311
|
#### "entitySpawn" (entity)
|
|
1312
|
+
#### "entityElytraFlew" (entity)
|
|
1313
|
+
|
|
1314
|
+
An entity started elytra flying.
|
|
1315
|
+
|
|
1304
1316
|
#### "itemDrop" (entity)
|
|
1305
1317
|
#### "playerCollect" (collector, collected)
|
|
1306
1318
|
|
|
@@ -1417,6 +1429,10 @@ This occurs whether the process was completed or aborted.
|
|
|
1417
1429
|
|
|
1418
1430
|
* `block` - the block that still exists
|
|
1419
1431
|
|
|
1432
|
+
#### "usedfirework"
|
|
1433
|
+
|
|
1434
|
+
Fires when the bot uses a firework while elytra flying.
|
|
1435
|
+
|
|
1420
1436
|
#### "move"
|
|
1421
1437
|
|
|
1422
1438
|
Fires when the bot moves. If you want the current position, use
|
|
@@ -1851,6 +1867,11 @@ This function returns a `Promise`, with `void` as its argument once tossing is c
|
|
|
1851
1867
|
to match any metadata
|
|
1852
1868
|
* `count` - how many you want to toss. `null` is an alias for `1`.
|
|
1853
1869
|
|
|
1870
|
+
#### bot.elytraFly()
|
|
1871
|
+
|
|
1872
|
+
This function returns a `Promise`, with `void` as its argument once activating
|
|
1873
|
+
elytra flight is complete. It will throw an Error if it fails.
|
|
1874
|
+
|
|
1854
1875
|
#### bot.dig(block, [forceLook = true], [digFace])
|
|
1855
1876
|
|
|
1856
1877
|
This function returns a `Promise`, with `void` as its argument when the block is broken or you are interrupted.
|
|
@@ -1946,7 +1967,9 @@ Use fishing rod
|
|
|
1946
1967
|
|
|
1947
1968
|
#### bot.activateItem(offHand=false)
|
|
1948
1969
|
|
|
1949
|
-
Activates the currently held item. This is how you eat, shoot bows, throw an
|
|
1970
|
+
Activates the currently held item. This is how you eat, shoot bows, throw an
|
|
1971
|
+
egg, activate firework rockets, etc.
|
|
1972
|
+
|
|
1950
1973
|
Optional parameter is `false` for main hand and `true` for off hand.
|
|
1951
1974
|
|
|
1952
1975
|
#### bot.deactivateItem()
|
package/docs/history.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## 4.14.0
|
|
2
|
+
* [Update Jupyter notebook to install node 18, update the server in example (#3176)](https://github.com/PrismarineJS/mineflayer/commit/e8a967d4e832f72d665781492c037d26169ae5a0) (thanks @extremeheat)
|
|
3
|
+
* [Update index.d.ts (#3175)](https://github.com/PrismarineJS/mineflayer/commit/d4db3991c135344180937b69621c0ee31daa39f0) (thanks @StayWithMeSenpai)
|
|
4
|
+
* [Add elytra flying support and rocket support (#3163)](https://github.com/PrismarineJS/mineflayer/commit/010460e9dd752a56195d8a48f35a62e704dcf99f) (thanks @lkwilson)
|
|
5
|
+
|
|
1
6
|
## 4.13.0
|
|
2
7
|
* [Switch to entity.displayName (#3168)](https://github.com/PrismarineJS/mineflayer/commit/2409ad458b952173de669a7d9cfaeb770effe3ae) (thanks @lkwilson)
|
|
3
8
|
* [Update readme auth doc (#3169)](https://github.com/PrismarineJS/mineflayer/commit/f5d4a288a768ca6717fa4d22c72fb0267428c684) (thanks @extremeheat)
|
package/docs/mineflayer.ipynb
CHANGED
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"source": [
|
|
37
37
|
"# Using mineflayer in Python\n",
|
|
38
38
|
"\n",
|
|
39
|
-
"This is a tutorial on how to use mineflayer in Python. This example will connect you to the PrismarineJS test server. You can join it with prismarine-viewer or your Minecraft client at server IP **
|
|
39
|
+
"This is a tutorial on how to use mineflayer in Python. This example will connect you to the PrismarineJS test server. You can join it with prismarine-viewer or your Minecraft client at server IP **pjs.deptofcraft.com:25565**.\n",
|
|
40
40
|
"\n",
|
|
41
41
|
"If you're new to Jupyter Notebooks, you can press the \"Play\" button at the left of each code block to run it. Make sure that you run the blocks in a correct order."
|
|
42
42
|
]
|
|
@@ -56,32 +56,35 @@
|
|
|
56
56
|
"id": "K2ol06QOhL6s"
|
|
57
57
|
},
|
|
58
58
|
"source": [
|
|
59
|
-
"First, make sure you have Python version 3.
|
|
59
|
+
"First, make sure you have Python version 3.10 and Node.js version 18 or newer installed. You can get Node.js 18 it from https://nodejs.org/en/download or use [Node.js version managers](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm#using-a-node-version-manager-to-install-nodejs-and-npm) like [`nvm`](https://github.com/creationix/nvm) or [`n`](https://github.com/tj/n) to install via the command line. Here we'll use `n` to install Node.js v18, then check our Node and Python versions:"
|
|
60
60
|
]
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
"cell_type": "code",
|
|
64
|
+
"execution_count": 1,
|
|
64
65
|
"metadata": {
|
|
65
66
|
"colab": {
|
|
66
67
|
"base_uri": "https://localhost:8080/"
|
|
67
68
|
},
|
|
68
69
|
"id": "8zCSpx8Bif5m",
|
|
69
|
-
"outputId": "
|
|
70
|
+
"outputId": "90ebac14-fc75-4136-f81d-34c5b2033da0"
|
|
70
71
|
},
|
|
71
|
-
"source": [
|
|
72
|
-
"!python --version\n",
|
|
73
|
-
"!node --version"
|
|
74
|
-
],
|
|
75
|
-
"execution_count": null,
|
|
76
72
|
"outputs": [
|
|
77
73
|
{
|
|
74
|
+
"name": "stdout",
|
|
78
75
|
"output_type": "stream",
|
|
79
76
|
"text": [
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
]
|
|
83
|
-
"name": "stdout"
|
|
77
|
+
"v18.17.1\n",
|
|
78
|
+
"Python 3.10.12\n"
|
|
79
|
+
]
|
|
84
80
|
}
|
|
81
|
+
],
|
|
82
|
+
"source": [
|
|
83
|
+
"# Use `n` to install nodejs 18, if it's not already installed:\n",
|
|
84
|
+
"!curl -fsSL https://raw.githubusercontent.com/tj/n/master/bin/n | bash -s lts > /dev/null\n",
|
|
85
|
+
"# Now write the Node.js and Python version to the console\n",
|
|
86
|
+
"!node --version\n",
|
|
87
|
+
"!python --version"
|
|
85
88
|
]
|
|
86
89
|
},
|
|
87
90
|
{
|
|
@@ -121,7 +124,7 @@
|
|
|
121
124
|
"source": [
|
|
122
125
|
"If all is well, we can import the `javascript` library. We can then import the `require` function which works similarly to the `require` function in Node.js, but does the dependency management for us.\n",
|
|
123
126
|
"\n",
|
|
124
|
-
"You may notice the extra imports : On, Once, off and AsyncTask. These will be discussed later on
|
|
127
|
+
"You may notice the extra imports : On, Once, off and AsyncTask. These will be discussed later on.\n",
|
|
125
128
|
"\n",
|
|
126
129
|
"\n"
|
|
127
130
|
]
|
|
@@ -170,21 +173,21 @@
|
|
|
170
173
|
},
|
|
171
174
|
{
|
|
172
175
|
"cell_type": "code",
|
|
176
|
+
"execution_count": null,
|
|
173
177
|
"metadata": {
|
|
174
178
|
"id": "1gfZSAUCDVMg"
|
|
175
179
|
},
|
|
180
|
+
"outputs": [],
|
|
176
181
|
"source": [
|
|
177
182
|
"random_number = id([]) % 1000 # Give us a random number upto 1000\n",
|
|
178
183
|
"BOT_USERNAME = f'colab_{random_number}'\n",
|
|
179
184
|
"\n",
|
|
180
|
-
"bot = mineflayer.createBot({ 'host': '
|
|
185
|
+
"bot = mineflayer.createBot({ 'host': 'pjs.deptofcraft.com', 'port': 25565, 'username': BOT_USERNAME, 'hideErrors': False })\n",
|
|
181
186
|
"\n",
|
|
182
|
-
"# The spawn event
|
|
187
|
+
"# The spawn event\n",
|
|
183
188
|
"once(bot, 'login')\n",
|
|
184
189
|
"bot.chat('I spawned')"
|
|
185
|
-
]
|
|
186
|
-
"execution_count": null,
|
|
187
|
-
"outputs": []
|
|
190
|
+
]
|
|
188
191
|
},
|
|
189
192
|
{
|
|
190
193
|
"cell_type": "markdown",
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// This example will shoot the player that said "fire" in chat, when it is said in chat.
|
|
2
|
+
const mineflayer = require('mineflayer')
|
|
3
|
+
|
|
4
|
+
if (process.argv.length < 4 || process.argv.length > 6) {
|
|
5
|
+
console.log('Usage : node elytra.js <host> <port> [<name>] [<password>]')
|
|
6
|
+
process.exit(1)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const bot = mineflayer.createBot({
|
|
10
|
+
host: process.argv[2],
|
|
11
|
+
port: parseInt(process.argv[3]),
|
|
12
|
+
username: process.argv[4] ? process.argv[4] : 'elytraer',
|
|
13
|
+
password: process.argv[5]
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
bot.on('error', err => {
|
|
17
|
+
console.log(err)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
bot.on('kicked', err => {
|
|
21
|
+
console.log(err)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
bot.on('spawn', async function () {
|
|
25
|
+
bot.chat(`/give ${bot.username} minecraft:elytra`)
|
|
26
|
+
bot.chat(`/give ${bot.username} minecraft:firework_rocket 64`)
|
|
27
|
+
|
|
28
|
+
await sleep(1000)
|
|
29
|
+
const elytraItem = bot.inventory.slots.find(item => item?.name === 'elytra')
|
|
30
|
+
if (elytraItem == null) {
|
|
31
|
+
console.log('no elytra')
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
await bot.equip(elytraItem, 'torso')
|
|
35
|
+
const fireworkItem = bot.inventory.slots.find(item => item?.name === 'firework_rocket')
|
|
36
|
+
if (fireworkItem == null) {
|
|
37
|
+
console.log('no fireworks')
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
await bot.equip(fireworkItem, 'hand')
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
bot.on('chat', async (username, message) => {
|
|
44
|
+
if (message === 'fly') {
|
|
45
|
+
await bot.look(bot.entity.yaw, 50 * Math.PI / 180)
|
|
46
|
+
bot.setControlState('jump', true)
|
|
47
|
+
bot.setControlState('jump', false)
|
|
48
|
+
await sleep(50)
|
|
49
|
+
|
|
50
|
+
// try to fly
|
|
51
|
+
try {
|
|
52
|
+
await bot.elytraFly()
|
|
53
|
+
} catch (err) {
|
|
54
|
+
bot.chat(`Failed to fly: ${err}`)
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
await sleep(50)
|
|
58
|
+
|
|
59
|
+
// use rocket
|
|
60
|
+
bot.activateItem()
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
function sleep (ms) {
|
|
65
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
66
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { Recipe } from 'prismarine-recipe'
|
|
|
8
8
|
import { Block } from 'prismarine-block'
|
|
9
9
|
import { Entity } from 'prismarine-entity'
|
|
10
10
|
import { ChatMessage } from 'prismarine-chat'
|
|
11
|
+
import { world } from 'prismarine-world'
|
|
11
12
|
import { Registry } from 'prismarine-registry'
|
|
12
13
|
|
|
13
14
|
export function createBot (options: { client: Client } & Partial<BotOptions>): Bot
|
|
@@ -92,6 +93,8 @@ export interface BotEvents {
|
|
|
92
93
|
entityEquip: (entity: Entity) => Promise<void> | void
|
|
93
94
|
entitySleep: (entity: Entity) => Promise<void> | void
|
|
94
95
|
entitySpawn: (entity: Entity) => Promise<void> | void
|
|
96
|
+
entityElytraFlew: (entity: Entity) => Promise<void> | void
|
|
97
|
+
usedFirework: () => Promise<void> | void
|
|
95
98
|
itemDrop: (entity: Entity) => Promise<void> | void
|
|
96
99
|
playerCollect: (collector: Entity, collected: Entity) => Promise<void> | void
|
|
97
100
|
entityAttributes: (entity: Entity) => Promise<void> | void
|
|
@@ -164,6 +167,7 @@ export interface Bot extends TypedEmitter<BotEvents> {
|
|
|
164
167
|
version: string
|
|
165
168
|
entity: Entity
|
|
166
169
|
entities: { [id: string]: Entity }
|
|
170
|
+
fireworkRocketDuration: number
|
|
167
171
|
spawnPoint: Vec3
|
|
168
172
|
game: GameState
|
|
169
173
|
player: Player
|
|
@@ -189,7 +193,7 @@ export interface Bot extends TypedEmitter<BotEvents> {
|
|
|
189
193
|
teamMap: { [name: string]: Team }
|
|
190
194
|
controlState: ControlStateStatus
|
|
191
195
|
creative: creativeMethods
|
|
192
|
-
world:
|
|
196
|
+
world: world.World
|
|
193
197
|
_client: Client
|
|
194
198
|
heldItem: Item | null
|
|
195
199
|
usingHeldItem: boolean
|
|
@@ -260,6 +264,8 @@ export interface Bot extends TypedEmitter<BotEvents> {
|
|
|
260
264
|
|
|
261
265
|
wake: () => Promise<void>
|
|
262
266
|
|
|
267
|
+
elytraFly: () => Promise<void>
|
|
268
|
+
|
|
263
269
|
setControlState: (control: ControlState, state: boolean) => void
|
|
264
270
|
|
|
265
271
|
getControlState: (control: ControlState) => boolean
|
package/lib/plugins/entities.js
CHANGED
|
@@ -358,6 +358,70 @@ function inject (bot) {
|
|
|
358
358
|
}
|
|
359
359
|
})
|
|
360
360
|
|
|
361
|
+
bot.fireworkRocketDuration = 0
|
|
362
|
+
function setElytraFlyingState (entity, elytraFlying) {
|
|
363
|
+
let startedFlying = false
|
|
364
|
+
if (elytraFlying) {
|
|
365
|
+
startedFlying = !entity.elytraFlying
|
|
366
|
+
entity.elytraFlying = true
|
|
367
|
+
} else if (entity.elytraFlying) {
|
|
368
|
+
entity.elytraFlying = false
|
|
369
|
+
}
|
|
370
|
+
if (bot.fireworkRocketDuration !== 0 && entity.id === bot.entity?.id && !elytraFlying) {
|
|
371
|
+
bot.fireworkRocketDuration = 0
|
|
372
|
+
knownFireworks.splice(0, knownFireworks.length)
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (startedFlying) {
|
|
376
|
+
bot.emit('entityElytraFlew', entity)
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const knownFireworks = []
|
|
381
|
+
function handleBotUsedFireworkRocket (fireworkEntityId, fireworkInfo) {
|
|
382
|
+
if (knownFireworks.includes(fireworkEntityId)) return
|
|
383
|
+
knownFireworks.push(fireworkEntityId)
|
|
384
|
+
let flightDur = 1
|
|
385
|
+
if (fireworkInfo?.nbtData != null) {
|
|
386
|
+
let nbt = fireworkInfo.nbtData
|
|
387
|
+
if (nbt.type === 'compound' && nbt.value.Fireworks != null) {
|
|
388
|
+
nbt = nbt.value.Fireworks
|
|
389
|
+
if (nbt.type === 'compound' && nbt.value.Flight != null) {
|
|
390
|
+
nbt = nbt.value.Flight
|
|
391
|
+
if (nbt.type === 'int') {
|
|
392
|
+
flightDur += nbt.value
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
const baseDuration = 10 * flightDur
|
|
398
|
+
const randomDuration = Math.floor(Math.random() * 6) + Math.floor(Math.random() * 7)
|
|
399
|
+
bot.fireworkRocketDuration = baseDuration + randomDuration
|
|
400
|
+
|
|
401
|
+
bot.emit('usedFirework')
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
let fireworkEntityName
|
|
405
|
+
if (bot.supportFeature('fireworkNamePlural')) {
|
|
406
|
+
fireworkEntityName = 'fireworks_rocket'
|
|
407
|
+
} else if (bot.supportFeature('fireworkNameSingular')) {
|
|
408
|
+
fireworkEntityName = 'firework_rocket'
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
let fireworkMetadataIdx
|
|
412
|
+
let fireworkMetadataIsOpt
|
|
413
|
+
if (bot.supportFeature('fireworkMetadataVarInt7')) {
|
|
414
|
+
fireworkMetadataIdx = 7
|
|
415
|
+
fireworkMetadataIsOpt = false
|
|
416
|
+
} else if (bot.supportFeature('fireworkMetadataOptVarInt8')) {
|
|
417
|
+
fireworkMetadataIdx = 8
|
|
418
|
+
fireworkMetadataIsOpt = true
|
|
419
|
+
} else if (bot.supportFeature('fireworkMetadataOptVarInt9')) {
|
|
420
|
+
fireworkMetadataIdx = 9
|
|
421
|
+
fireworkMetadataIsOpt = true
|
|
422
|
+
}
|
|
423
|
+
const hasFireworkSupport = fireworkEntityName !== undefined && fireworkMetadataIdx !== undefined && fireworkMetadataIsOpt !== undefined
|
|
424
|
+
|
|
361
425
|
bot._client.on('entity_metadata', (packet) => {
|
|
362
426
|
// entity metadata
|
|
363
427
|
const entity = fetchEntity(packet.entityId)
|
|
@@ -374,7 +438,25 @@ function inject (bot) {
|
|
|
374
438
|
if (metas.sleeping_pos || metas.pose === 2) {
|
|
375
439
|
bot.emit('entitySleep', entity)
|
|
376
440
|
}
|
|
441
|
+
|
|
442
|
+
if (hasFireworkSupport && fireworkEntityName === entity.name && metas.attached_to_target !== undefined) {
|
|
443
|
+
// fireworkMetadataOptVarInt9 and later is implied by
|
|
444
|
+
// mcDataHasEntityMetadata, so no need to check metadata index and type
|
|
445
|
+
// (eg fireworkMetadataOptVarInt8)
|
|
446
|
+
if (metas.attached_to_target !== 0) {
|
|
447
|
+
const entityId = metas.attached_to_target - 1
|
|
448
|
+
if (entityId === bot.entity?.id) {
|
|
449
|
+
handleBotUsedFireworkRocket(entity.id, metas.fireworks_item)
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
377
454
|
if (metas.shared_flags != null) {
|
|
455
|
+
if (bot.supportFeature('hasElytraFlying')) {
|
|
456
|
+
const elytraFlying = metas.shared_flags & 0x80
|
|
457
|
+
setElytraFlyingState(entity, Boolean(elytraFlying))
|
|
458
|
+
}
|
|
459
|
+
|
|
378
460
|
if (metas.shared_flags & 2) {
|
|
379
461
|
entity.crouching = true
|
|
380
462
|
bot.emit('entityCrouch', entity)
|
|
@@ -396,16 +478,38 @@ function inject (bot) {
|
|
|
396
478
|
bot.emit('entitySleep', entity)
|
|
397
479
|
}
|
|
398
480
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
481
|
+
if (hasFireworkSupport && fireworkEntityName === entity.name) {
|
|
482
|
+
const attachedToTarget = packet.metadata.find(e => e.key === fireworkMetadataIdx)
|
|
483
|
+
if (attachedToTarget !== undefined) {
|
|
484
|
+
let entityId
|
|
485
|
+
if (fireworkMetadataIsOpt) {
|
|
486
|
+
if (attachedToTarget.value !== 0) {
|
|
487
|
+
entityId = attachedToTarget.value - 1
|
|
488
|
+
} // else, not attached to an entity
|
|
489
|
+
} else {
|
|
490
|
+
entityId = attachedToTarget.value
|
|
491
|
+
}
|
|
492
|
+
if (entityId !== undefined && entityId === bot.entity?.id) {
|
|
493
|
+
const fireworksItem = packet.metadata.find(e => e.key === (fireworkMetadataIdx - 1))
|
|
494
|
+
handleBotUsedFireworkRocket(entity.id, fireworksItem?.value)
|
|
495
|
+
}
|
|
496
|
+
}
|
|
402
497
|
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
498
|
+
|
|
499
|
+
const bitField = packet.metadata.find(p => p.key === 0)
|
|
500
|
+
if (bitField !== undefined) {
|
|
501
|
+
if (bot.supportFeature('hasElytraFlying')) {
|
|
502
|
+
const elytraFlying = bitField.value & 0x80
|
|
503
|
+
setElytraFlyingState(entity, Boolean(elytraFlying))
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if ((bitField.value & 2) !== 0) {
|
|
507
|
+
entity.crouching = true
|
|
508
|
+
bot.emit('entityCrouch', entity)
|
|
509
|
+
} else if (entity.crouching) { // prevent the initial entity_metadata packet from firing off an uncrouch event
|
|
510
|
+
entity.crouching = false
|
|
511
|
+
bot.emit('entityUncrouch', entity)
|
|
512
|
+
}
|
|
409
513
|
}
|
|
410
514
|
}
|
|
411
515
|
})
|
package/lib/plugins/physics.js
CHANGED
|
@@ -192,6 +192,44 @@ function inject (bot, { physicsEnabled, maxCatchupTicks }) {
|
|
|
192
192
|
|
|
193
193
|
bot.physics = physics
|
|
194
194
|
|
|
195
|
+
function getEffectLevel (mcData, effectName, effects) {
|
|
196
|
+
const effectDescriptor = mcData.effectsByName[effectName]
|
|
197
|
+
if (!effectDescriptor) {
|
|
198
|
+
return 0
|
|
199
|
+
}
|
|
200
|
+
const effectInfo = effects[effectDescriptor.id]
|
|
201
|
+
if (!effectInfo) {
|
|
202
|
+
return 0
|
|
203
|
+
}
|
|
204
|
+
return effectInfo.amplifier + 1
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
bot.elytraFly = async () => {
|
|
208
|
+
if (bot.entity.elytraFlying) {
|
|
209
|
+
throw new Error('Already elytra flying')
|
|
210
|
+
} else if (bot.entity.onGround) {
|
|
211
|
+
throw new Error('Unable to fly from ground')
|
|
212
|
+
} else if (bot.entity.isInWater) {
|
|
213
|
+
throw new Error('Unable to elytra fly while in water')
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const mcData = require('minecraft-data')(bot.version)
|
|
217
|
+
if (getEffectLevel(mcData, 'Levitation', bot.entity.effects) > 0) {
|
|
218
|
+
throw new Error('Unable to elytra fly with levitation effect')
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const torsoSlot = bot.getEquipmentDestSlot('torso')
|
|
222
|
+
const item = bot.inventory.slots[torsoSlot]
|
|
223
|
+
if (item == null || item.name !== 'elytra') {
|
|
224
|
+
throw new Error('Elytra must be equip to start flying')
|
|
225
|
+
}
|
|
226
|
+
bot._client.write('entity_action', {
|
|
227
|
+
entityId: bot.entity.id,
|
|
228
|
+
actionId: 8,
|
|
229
|
+
jumpBoost: 0
|
|
230
|
+
})
|
|
231
|
+
}
|
|
232
|
+
|
|
195
233
|
bot.setControlState = (control, state) => {
|
|
196
234
|
assert.ok(control in controlState, `invalid control: ${control}`)
|
|
197
235
|
assert.ok(typeof state === 'boolean', `invalid state: ${state}`)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mineflayer",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.14.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,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"minecraft-data": "^3.
|
|
24
|
+
"minecraft-data": "^3.44.0",
|
|
25
25
|
"minecraft-protocol": "^1.44.0",
|
|
26
26
|
"prismarine-biome": "^1.1.1",
|
|
27
27
|
"prismarine-block": "^1.17.0",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"prismarine-entity": "^2.3.0",
|
|
31
31
|
"prismarine-item": "^1.14.0",
|
|
32
32
|
"prismarine-nbt": "^2.0.0",
|
|
33
|
-
"prismarine-physics": "^1.
|
|
33
|
+
"prismarine-physics": "^1.8.0",
|
|
34
34
|
"prismarine-recipe": "^1.3.0",
|
|
35
35
|
"prismarine-registry": "^1.5.0",
|
|
36
36
|
"prismarine-windows": "^2.8.0",
|