mineflayer 3.10.0 → 3.12.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/FUNDING.yml +0 -2
- package/.github/workflows/ci.yml +20 -16
- package/README.md +16 -15
- package/docs/README.md +16 -15
- package/docs/api.md +50 -27
- package/docs/es/README_ES.md +1 -1
- package/docs/es/api_es.md +34 -18
- package/docs/fr/README_FR.md +1 -1
- package/docs/history.md +28 -0
- package/docs/ru/README_RU.md +1 -1
- package/docs/ru/api_ru.md +1 -1
- package/docs/tr/README_TR.md +1 -1
- package/docs/zh/README_ZH_CN.md +1 -1
- package/examples/chatterbox.js +1 -1
- package/examples/discord.js +15 -5
- package/examples/plugins/afk.js +50 -37
- package/examples/python/basic.py +2 -2
- package/examples/python/chatterbox.py +1 -1
- package/examples/screenshot-with-node-canvas-webgl/screenshot.js +2 -2
- package/index.d.ts +108 -134
- package/lib/conversions.js +1 -1
- package/lib/features.json +57 -27
- package/lib/loader.js +5 -4
- package/lib/plugins/bed.js +1 -1
- package/lib/plugins/block_actions.js +19 -7
- package/lib/plugins/blocks.js +17 -4
- package/lib/plugins/chat.js +5 -6
- package/lib/plugins/command_block.js +1 -1
- package/lib/plugins/craft.js +10 -18
- package/lib/plugins/creative.js +2 -2
- package/lib/plugins/digging.js +15 -6
- package/lib/plugins/enchantment_table.js +4 -2
- package/lib/plugins/entities.js +13 -8
- package/lib/plugins/explosion.js +3 -1
- package/lib/plugins/fishing.js +2 -2
- package/lib/plugins/game.js +55 -50
- package/lib/plugins/inventory.js +164 -40
- package/lib/plugins/physics.js +16 -5
- package/lib/plugins/place_block.js +7 -6
- package/lib/plugins/ray_trace.js +10 -0
- package/lib/plugins/simple_inventory.js +1 -1
- package/lib/plugins/sound.js +1 -1
- package/lib/plugins/spawn_point.js +1 -1
- package/lib/plugins/villager.js +57 -42
- package/lib/version.js +3 -3
- package/package.json +23 -22
package/lib/plugins/blocks.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const Vec3 = require('vec3')
|
|
1
|
+
const { Vec3 } = require('vec3')
|
|
2
2
|
const assert = require('assert')
|
|
3
3
|
const Painting = require('../painting')
|
|
4
4
|
const { onceWithCleanup, callbackify } = require('../promise_utils')
|
|
@@ -89,7 +89,12 @@ function inject (bot, { version, storageBuilder }) {
|
|
|
89
89
|
}
|
|
90
90
|
let column = bot.world.getColumn(args.x, args.z)
|
|
91
91
|
if (!column) {
|
|
92
|
-
|
|
92
|
+
// Allocates new chunk object while taking world's custom min/max height into account
|
|
93
|
+
if (bot.supportFeature('dimensionDataIsAvailable')) {
|
|
94
|
+
column = new Chunk({ minY: bot.game.dimensionData.min_y, worldHeight: bot.game.dimensionData.height })
|
|
95
|
+
} else {
|
|
96
|
+
column = new Chunk()
|
|
97
|
+
}
|
|
93
98
|
}
|
|
94
99
|
|
|
95
100
|
try {
|
|
@@ -294,11 +299,19 @@ function inject (bot, { version, storageBuilder }) {
|
|
|
294
299
|
bot._client.on('update_light', (packet) => {
|
|
295
300
|
let column = bot.world.getColumn(packet.chunkX, packet.chunkZ)
|
|
296
301
|
if (!column) {
|
|
297
|
-
|
|
302
|
+
if (bot.supportFeature('dimensionDataIsAvailable')) {
|
|
303
|
+
column = new Chunk({ minY: bot.game.dimensionData.min_y, worldHeight: bot.game.dimensionData.height })
|
|
304
|
+
} else {
|
|
305
|
+
column = new Chunk()
|
|
306
|
+
}
|
|
298
307
|
bot.world.setColumn(packet.chunkX, packet.chunkZ, column)
|
|
299
308
|
}
|
|
300
309
|
|
|
301
|
-
|
|
310
|
+
if (bot.supportFeature('dimensionDataIsAvailable')) {
|
|
311
|
+
column.loadParsedLight(packet.skyLight, packet.blockLight, packet.skyLightMask, packet.blockLightMask, packet.emptySkyLightMask, packet.emptyBlockLightMask)
|
|
312
|
+
} else {
|
|
313
|
+
column.loadLight(packet.data, packet.skyLightMask, packet.blockLightMask, packet.emptySkyLightMask, packet.emptyBlockLightMask)
|
|
314
|
+
}
|
|
302
315
|
})
|
|
303
316
|
|
|
304
317
|
bot._client.on('map_chunk', (packet) => {
|
package/lib/plugins/chat.js
CHANGED
|
@@ -4,6 +4,7 @@ module.exports = inject
|
|
|
4
4
|
|
|
5
5
|
function inject (bot, options) {
|
|
6
6
|
const CHAT_LENGTH_LIMIT = options.chatLengthLimit ?? (bot.supportFeature('lessCharsInChat') ? 100 : 256)
|
|
7
|
+
const defaultChatPatterns = options.defaultChatPatterns ?? true
|
|
7
8
|
|
|
8
9
|
const ChatMessage = require('prismarine-chat')(bot.version)
|
|
9
10
|
// chat.pattern.type will emit an event for bot.on() of the same type, eg chatType = whisper will trigger bot.on('whisper')
|
|
@@ -15,6 +16,7 @@ function inject (bot, options) {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
bot.addChatPatternSet = (name, patterns, opts = {}) => {
|
|
19
|
+
if (!patterns.every(p => p instanceof RegExp)) throw new Error('Pattern parameter should be of type RegExp')
|
|
18
20
|
const { repeat = true, parse = false } = opts
|
|
19
21
|
_patterns[_length++] = {
|
|
20
22
|
name,
|
|
@@ -29,6 +31,7 @@ function inject (bot, options) {
|
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
bot.addChatPattern = (name, pattern, opts = {}) => {
|
|
34
|
+
if (!(pattern instanceof RegExp)) throw new Error('Pattern parameter should be of type RegExp')
|
|
32
35
|
const { repeat = true, deprecated = false, parse = false } = opts
|
|
33
36
|
_patterns[_length++] = {
|
|
34
37
|
name,
|
|
@@ -103,12 +106,7 @@ function inject (bot, options) {
|
|
|
103
106
|
addDefaultPatterns()
|
|
104
107
|
|
|
105
108
|
bot._client.on('chat', (packet) => {
|
|
106
|
-
|
|
107
|
-
try {
|
|
108
|
-
msg = new ChatMessage(JSON.parse(packet.message))
|
|
109
|
-
} catch (e) {
|
|
110
|
-
msg = new ChatMessage(packet.message)
|
|
111
|
-
}
|
|
109
|
+
const msg = ChatMessage.fromNotch(packet.message)
|
|
112
110
|
|
|
113
111
|
const ChatPositions = {
|
|
114
112
|
0: 'chat',
|
|
@@ -174,6 +172,7 @@ function inject (bot, options) {
|
|
|
174
172
|
bot.tabComplete = callbackify(tabComplete)
|
|
175
173
|
|
|
176
174
|
function addDefaultPatterns () {
|
|
175
|
+
if (!defaultChatPatterns) return
|
|
177
176
|
const USERNAME_REGEX = '(?:\\(.+\\)|\\[.+\\]|.)*?(\\w+)'
|
|
178
177
|
bot.addChatPattern('whisper', new RegExp(`^${USERNAME_REGEX} whispers(?: to you)?:? (.*)$`), { deprecated: true })
|
|
179
178
|
bot.addChatPattern('whisper', new RegExp(`^\\[${USERNAME_REGEX} -> \\w+\\s?\\] (.*)$`), { deprecated: true })
|
package/lib/plugins/craft.js
CHANGED
|
@@ -114,10 +114,10 @@ function inject (bot, { version }) {
|
|
|
114
114
|
|
|
115
115
|
async function grabResult () {
|
|
116
116
|
assert.strictEqual(window.selectedItem, null)
|
|
117
|
+
// Causes a double-emit on 1.12+ --nickelpro
|
|
117
118
|
// put the recipe result in the output
|
|
118
119
|
const item = new Item(recipe.result.id, recipe.result.count, recipe.result.metadata)
|
|
119
120
|
window.updateSlot(0, item)
|
|
120
|
-
// move the result to inventory
|
|
121
121
|
await bot.putAway(0)
|
|
122
122
|
await updateOutShape()
|
|
123
123
|
}
|
|
@@ -131,28 +131,20 @@ function inject (bot, { version }) {
|
|
|
131
131
|
return
|
|
132
132
|
}
|
|
133
133
|
const slotsToClick = []
|
|
134
|
-
let
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
for (y = 0; y < recipe.outShape.length; ++y) {
|
|
140
|
-
row = recipe.outShape[y]
|
|
141
|
-
for (x = 0; x < row.length; ++x) {
|
|
142
|
-
theSlot = slot(x, y)
|
|
134
|
+
for (let y = 0; y < recipe.outShape.length; ++y) {
|
|
135
|
+
const row = recipe.outShape[y]
|
|
136
|
+
for (let x = 0; x < row.length; ++x) {
|
|
137
|
+
const _slot = slot(x, y)
|
|
138
|
+
let item = null
|
|
143
139
|
if (row[x].id !== -1) {
|
|
144
140
|
item = new Item(row[x].id, row[x].count, row[x].metadata || null)
|
|
145
|
-
slotsToClick.push(
|
|
146
|
-
} else {
|
|
147
|
-
item = null
|
|
141
|
+
slotsToClick.push(_slot)
|
|
148
142
|
}
|
|
149
|
-
window.updateSlot(
|
|
143
|
+
window.updateSlot(_slot, item)
|
|
150
144
|
}
|
|
151
145
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
await bot.putAway(theSlot)
|
|
155
|
-
theSlot = slotsToClick.pop()
|
|
146
|
+
for (const _slot of slotsToClick) {
|
|
147
|
+
await bot.putAway(_slot)
|
|
156
148
|
}
|
|
157
149
|
closeTheWindow()
|
|
158
150
|
}
|
package/lib/plugins/creative.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const assert = require('assert')
|
|
2
|
-
const Vec3 = require('vec3')
|
|
2
|
+
const { Vec3 } = require('vec3')
|
|
3
3
|
const { callbackify, sleep } = require('../promise_utils')
|
|
4
4
|
const { once } = require('events')
|
|
5
5
|
|
|
@@ -23,7 +23,7 @@ function inject (bot, { version }) {
|
|
|
23
23
|
}
|
|
24
24
|
})
|
|
25
25
|
|
|
26
|
-
// WARN: This method should not be called twice on the same slot before first callback
|
|
26
|
+
// WARN: This method should not be called twice on the same slot before first callback succeeds
|
|
27
27
|
async function setInventorySlot (slot, item) {
|
|
28
28
|
assert(slot >= 0 && slot <= 44)
|
|
29
29
|
|
package/lib/plugins/digging.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const nbt = require('prismarine-nbt')
|
|
2
1
|
const { performance } = require('perf_hooks')
|
|
3
2
|
const { createDoneTask, createTask } = require('../promise_utils')
|
|
4
3
|
const BlockFaces = require('prismarine-world').iterators.BlockFace
|
|
@@ -179,12 +178,22 @@ function inject (bot) {
|
|
|
179
178
|
function digTime (block) {
|
|
180
179
|
let type = null
|
|
181
180
|
let enchantments = []
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
181
|
+
|
|
182
|
+
// Retrieve currently held item ID and active enchantments from heldItem
|
|
183
|
+
const currentlyHeldItem = bot.heldItem
|
|
184
|
+
if (currentlyHeldItem) {
|
|
185
|
+
type = currentlyHeldItem.type
|
|
186
|
+
enchantments = currentlyHeldItem.enchants
|
|
187
187
|
}
|
|
188
|
+
|
|
189
|
+
// Append helmet enchantments (because Aqua Affinity actually affects dig speed)
|
|
190
|
+
const headEquipmentSlot = bot.getEquipmentDestSlot('head')
|
|
191
|
+
const headEquippedItem = bot.inventory.slots[headEquipmentSlot]
|
|
192
|
+
if (headEquippedItem) {
|
|
193
|
+
const helmetEnchantments = headEquippedItem.enchants
|
|
194
|
+
enchantments = enchantments.concat(helmetEnchantments)
|
|
195
|
+
}
|
|
196
|
+
|
|
188
197
|
const creative = bot.game.gameMode === 'creative'
|
|
189
198
|
return block.digTime(type, creative, bot.entity.isInWater, !bot.entity.onGround, enchantments, bot.entity.effects)
|
|
190
199
|
}
|
|
@@ -48,8 +48,10 @@ function inject (bot) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
if (slots[0].level >= 0 && slots[1].level >= 0 && slots[2].level >= 0) {
|
|
51
|
-
if (!ready)
|
|
52
|
-
|
|
51
|
+
if (!ready) {
|
|
52
|
+
ready = true
|
|
53
|
+
enchantmentTable.emit('ready')
|
|
54
|
+
}
|
|
53
55
|
} else {
|
|
54
56
|
ready = false
|
|
55
57
|
}
|
package/lib/plugins/entities.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const Vec3 = require('vec3')
|
|
1
|
+
const { Vec3 } = require('vec3')
|
|
2
2
|
const Entity = require('prismarine-entity')
|
|
3
3
|
const conv = require('../conversions')
|
|
4
4
|
const NAMED_ENTITY_HEIGHT = 1.62
|
|
@@ -31,6 +31,11 @@ function inject (bot, { version }) {
|
|
|
31
31
|
const entitiesArray = require('minecraft-data')(version).entitiesArray
|
|
32
32
|
const Item = require('prismarine-item')(version)
|
|
33
33
|
const ChatMessage = require('prismarine-chat')(version)
|
|
34
|
+
// ONLY 1.17 has this destroy_entity packet which is the same thing as entity_destroy packet except the entity is singular
|
|
35
|
+
// 1.17.1 reverted this change so this is just a simpler fix
|
|
36
|
+
bot._client.on('destroy_entity', (packet) => {
|
|
37
|
+
bot._client.emit('entity_destroy', { entityIds: [packet.entityId] })
|
|
38
|
+
})
|
|
34
39
|
|
|
35
40
|
bot.findPlayer = bot.findPlayers = (filter) => {
|
|
36
41
|
const filterFn = (entity) => {
|
|
@@ -478,15 +483,15 @@ function inject (bot, { version }) {
|
|
|
478
483
|
} else if (packet.action === 3 && item.displayName) {
|
|
479
484
|
player.displayName = new ChatMessage(JSON.parse(item.displayName))
|
|
480
485
|
} else if (packet.action === 4) {
|
|
481
|
-
if (player.entity === bot.entity)
|
|
486
|
+
if (player.entity === bot.entity) continue
|
|
482
487
|
|
|
483
488
|
player.entity = null
|
|
484
489
|
delete bot.players[player.username]
|
|
485
490
|
delete bot.uuidToUsername[item.UUID]
|
|
486
491
|
bot.emit('playerLeft', player)
|
|
487
|
-
|
|
492
|
+
continue
|
|
488
493
|
} else {
|
|
489
|
-
|
|
494
|
+
continue
|
|
490
495
|
}
|
|
491
496
|
|
|
492
497
|
bot.emit('playerUpdated', player)
|
|
@@ -526,8 +531,8 @@ function inject (bot, { version }) {
|
|
|
526
531
|
bot.useOn = useOn
|
|
527
532
|
bot.moveVehicle = moveVehicle
|
|
528
533
|
|
|
529
|
-
function swingArm (arm = '
|
|
530
|
-
const hand = arm === '
|
|
534
|
+
function swingArm (arm = 'right', showHand = true) {
|
|
535
|
+
const hand = arm === 'right' ? 0 : 1
|
|
531
536
|
const packet = {}
|
|
532
537
|
if (showHand) packet.hand = hand
|
|
533
538
|
bot._client.write('arm_animation', packet)
|
|
@@ -539,11 +544,11 @@ function inject (bot, { version }) {
|
|
|
539
544
|
}
|
|
540
545
|
|
|
541
546
|
function attack (target, swing = true) {
|
|
542
|
-
|
|
543
|
-
|
|
547
|
+
// arm animation comes before the use_entity packet
|
|
544
548
|
if (swing) {
|
|
545
549
|
swingArm()
|
|
546
550
|
}
|
|
551
|
+
useEntity(target, 1)
|
|
547
552
|
}
|
|
548
553
|
|
|
549
554
|
function mount (target) {
|
package/lib/plugins/explosion.js
CHANGED
|
@@ -77,7 +77,7 @@ function inject (bot) {
|
|
|
77
77
|
// The following modifiers are constant for the input targetEntity and doesnt depend
|
|
78
78
|
// on the source position, so if the goal is to compare between positions they can be
|
|
79
79
|
// ignored to save computations
|
|
80
|
-
if (!rawDamages) {
|
|
80
|
+
if (!rawDamages && targetEntity.attributes['generic.armor']) {
|
|
81
81
|
const armor = getAttributeValue(targetEntity.attributes['generic.armor'])
|
|
82
82
|
const armorToughness = getAttributeValue(targetEntity.attributes[armorThoughnessKey])
|
|
83
83
|
damages = getDamageAfterAbsorb(damages, armor, armorToughness)
|
|
@@ -85,6 +85,8 @@ function inject (bot) {
|
|
|
85
85
|
// TODO: protection enchantment and resistance effects
|
|
86
86
|
|
|
87
87
|
if (targetEntity.type === 'player') damages *= difficultyValues[bot.game.difficulty] * 0.5
|
|
88
|
+
} else if (!rawDamages && !targetEntity.attributes['generic.armor']) {
|
|
89
|
+
return null
|
|
88
90
|
}
|
|
89
91
|
return Math.floor(damages)
|
|
90
92
|
}
|
package/lib/plugins/fishing.js
CHANGED
|
@@ -27,13 +27,13 @@ function inject (bot) {
|
|
|
27
27
|
if (!lastBobber || fishingTask.done) return
|
|
28
28
|
|
|
29
29
|
const pos = lastBobber.position
|
|
30
|
-
|
|
30
|
+
const parts = mcData.particlesByName
|
|
31
|
+
if (packet.particleId === (parts?.fishing ?? parts.bubble).id && packet.particles === 6 && pos.distanceTo(new Vec3(packet.x, pos.y, packet.z)) <= 1.23) {
|
|
31
32
|
bot.activateItem()
|
|
32
33
|
lastBobber = undefined
|
|
33
34
|
fishingTask.finish()
|
|
34
35
|
}
|
|
35
36
|
})
|
|
36
|
-
|
|
37
37
|
bot._client.on('entity_destroy', (packet) => {
|
|
38
38
|
if (!lastBobber) return
|
|
39
39
|
if (packet.entityIds.some(id => id === lastBobber.id)) {
|
package/lib/plugins/game.js
CHANGED
|
@@ -1,78 +1,82 @@
|
|
|
1
|
+
const nbt = require('prismarine-nbt')
|
|
1
2
|
module.exports = inject
|
|
2
3
|
|
|
4
|
+
const difficultyNames = ['peaceful', 'easy', 'normal', 'hard']
|
|
5
|
+
const gameModes = ['survival', 'creative', 'adventure']
|
|
6
|
+
|
|
3
7
|
const dimensionNames = {
|
|
4
8
|
'-1': 'minecraft:nether',
|
|
5
9
|
0: 'minecraft:overworld',
|
|
6
10
|
1: 'minecraft:end'
|
|
7
11
|
}
|
|
8
12
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
function inject (bot) {
|
|
12
|
-
bot.game = {}
|
|
13
|
-
|
|
14
|
-
bot._client.on('custom_payload', (packet) => {
|
|
15
|
-
if (packet.channel === 'minecraft:brand') {
|
|
16
|
-
bot.game.serverBrand = String.fromCharCode.apply(null, packet.data)
|
|
17
|
-
bot.emit('game')
|
|
18
|
-
}
|
|
19
|
-
})
|
|
13
|
+
const parseGameMode = gameModeBits => gameModes[(gameModeBits & 0b11)] // lower two bits
|
|
20
14
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
function inject (bot, options) {
|
|
16
|
+
function getBrandCustomChannelName () {
|
|
17
|
+
if (bot.supportFeature('customChannelMCPrefixed')) {
|
|
18
|
+
return 'MC|Brand'
|
|
19
|
+
} else if (bot.supportFeature('customChannelIdentifier')) {
|
|
20
|
+
return 'minecraft:brand'
|
|
24
21
|
}
|
|
25
|
-
|
|
22
|
+
throw new Error('Unsupported brand channel name')
|
|
23
|
+
}
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
bot.game.levelType =
|
|
25
|
+
function handleRespawnPacketData (packet) {
|
|
26
|
+
bot.game.levelType = packet.levelType ?? (packet.isFlat ? 'flat' : 'default')
|
|
27
|
+
bot.game.hardcore = packet.isHardcore ?? Boolean(packet.gameMode & 0b100)
|
|
29
28
|
bot.game.gameMode = parseGameMode(packet.gameMode)
|
|
30
|
-
bot.game.hardcore = parseHardcore(packet.gameMode)
|
|
31
29
|
if (bot.supportFeature('dimensionIsAnInt')) {
|
|
32
30
|
bot.game.dimension = dimensionNames[packet.dimension]
|
|
33
31
|
} else if (bot.supportFeature('dimensionIsAString')) {
|
|
34
32
|
bot.game.dimension = packet.dimension
|
|
35
33
|
} else if (bot.supportFeature('dimensionIsAWorld')) {
|
|
36
34
|
bot.game.dimension = packet.worldName
|
|
35
|
+
} else {
|
|
36
|
+
throw new Error('Unsupported dimension type in login packet')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (bot.supportFeature('dimensionDataIsAvailable')) {
|
|
40
|
+
bot.game.dimensionData = nbt.simplify(packet.dimension)
|
|
41
|
+
}
|
|
42
|
+
if (packet.difficulty) {
|
|
43
|
+
bot.game.difficulty = difficultyNames[packet.difficulty]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
bot.game = {}
|
|
48
|
+
|
|
49
|
+
const brandChannel = getBrandCustomChannelName()
|
|
50
|
+
bot._client.registerChannel(brandChannel, ['string', []])
|
|
51
|
+
|
|
52
|
+
bot._client.on('login', (packet) => {
|
|
53
|
+
handleRespawnPacketData(packet)
|
|
54
|
+
|
|
55
|
+
bot.game.maxPlayers = packet.maxPlayers
|
|
56
|
+
if (packet.enableRespawnScreen) {
|
|
57
|
+
bot.game.enableRespawnScreen = packet.enableRespawnScreen
|
|
37
58
|
}
|
|
38
59
|
if (packet.viewDistance) {
|
|
39
60
|
bot.game.serverViewDistance = packet.viewDistance
|
|
40
61
|
}
|
|
41
|
-
|
|
42
|
-
bot.game.maxPlayers = packet.maxPlayers
|
|
62
|
+
|
|
43
63
|
bot.emit('login')
|
|
44
64
|
bot.emit('game')
|
|
45
65
|
bot._client.write('held_item_slot', { slotId: 0 })
|
|
46
|
-
let channel
|
|
47
|
-
if (bot.supportFeature('customChannelMCPrefixed')) {
|
|
48
|
-
channel = 'MC|Brand'
|
|
49
|
-
} else if (bot.supportFeature('customChannelNotPrefixed')) {
|
|
50
|
-
channel = 'brand'
|
|
51
|
-
}
|
|
52
|
-
bot._client.write('custom_payload', {
|
|
53
|
-
channel,
|
|
54
|
-
data: Buffer.from('\x07vanilla')
|
|
55
|
-
}) // varint length-prefixed string TODO: encode varint, see GH-253
|
|
56
66
|
|
|
57
|
-
//
|
|
67
|
+
// varint length-prefixed string as data
|
|
68
|
+
bot._client.writeChannel(brandChannel, options.brand)
|
|
58
69
|
})
|
|
59
70
|
|
|
60
71
|
bot._client.on('respawn', (packet) => {
|
|
61
|
-
|
|
62
|
-
if (bot.supportFeature('dimensionIsAnInt')) {
|
|
63
|
-
bot.game.dimension = dimensionNames[packet.dimension]
|
|
64
|
-
} else if (bot.supportFeature('dimensionIsAString')) {
|
|
65
|
-
bot.game.dimension = packet.dimension
|
|
66
|
-
} else if (bot.supportFeature('dimensionIsAWorld')) {
|
|
67
|
-
bot.game.dimension = packet.worldName
|
|
68
|
-
}
|
|
69
|
-
bot.game.difficulty = difficultyNames[packet.difficulty]
|
|
70
|
-
bot.game.gameMode = parseGameMode(packet.gamemode)
|
|
71
|
-
bot.game.hardcore = parseHardcore(packet.gamemode)
|
|
72
|
+
handleRespawnPacketData(packet)
|
|
72
73
|
bot.emit('game')
|
|
73
74
|
})
|
|
74
75
|
|
|
75
76
|
bot._client.on('game_state_change', (packet) => {
|
|
77
|
+
if (packet?.reason === 4 && packet?.gameMode === 1) {
|
|
78
|
+
bot._client.write('client_command', { action: 0 })
|
|
79
|
+
}
|
|
76
80
|
if (packet.reason === 3) {
|
|
77
81
|
bot.game.gameMode = parseGameMode(packet.gameMode)
|
|
78
82
|
bot.emit('game')
|
|
@@ -82,14 +86,15 @@ function inject (bot) {
|
|
|
82
86
|
bot._client.on('difficulty', (packet) => {
|
|
83
87
|
bot.game.difficulty = difficultyNames[packet.difficulty]
|
|
84
88
|
})
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const gameModes = ['survival', 'creative', 'adventure']
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
90
|
+
bot._client.on(brandChannel, (serverBrand) => {
|
|
91
|
+
bot.game.serverBrand = serverBrand
|
|
92
|
+
})
|
|
92
93
|
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
// mimic the vanilla 1.17 client to prevent anticheat kicks
|
|
95
|
+
bot._client.on('ping', (data) => {
|
|
96
|
+
bot._client.write('pong', {
|
|
97
|
+
id: data.id
|
|
98
|
+
})
|
|
99
|
+
})
|
|
95
100
|
}
|