mineflayer 4.3.0 → 4.5.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 +2 -2
- package/docs/README.md +2 -2
- package/docs/api.md +50 -20
- package/docs/es/api_es.md +1 -1
- package/docs/history.md +28 -0
- package/docs/ru/FAQ_RU.md +1 -1
- package/docs/ru/api_ru.md +2 -2
- package/docs/zh/README_ZH_CN.md +1 -1
- package/docs/zh/api.md +1 -1
- package/examples/anvil.js +4 -8
- package/examples/auto_totem.js +2 -3
- package/examples/block_entity.js +2 -7
- package/examples/blockfinder.js +2 -4
- package/examples/chatterbox.js +2 -3
- package/examples/chest.js +7 -12
- package/examples/collectblock.js +1 -7
- package/examples/command_block.js +1 -6
- package/examples/digger.js +1 -2
- package/examples/discord.js +1 -1
- package/examples/farmer.js +3 -8
- package/examples/fisherman.js +2 -7
- package/examples/graffiti.js +2 -7
- package/examples/guard.js +1 -2
- package/examples/inventory.js +4 -6
- package/examples/jumper.js +1 -1
- package/examples/pathfinder/gps.js +1 -2
- package/examples/place_end_crystal/index.js +2 -9
- package/examples/python/basic.py +1 -2
- package/examples/python/chatterbox.py +1 -1
- package/examples/trader.js +4 -8
- package/index.d.ts +23 -29
- package/lib/bossbar.js +2 -2
- package/lib/loader.js +2 -2
- package/lib/plugins/anvil.js +1 -1
- package/lib/plugins/bed.js +16 -1
- package/lib/plugins/block_actions.js +4 -3
- package/lib/plugins/blocks.js +3 -3
- package/lib/plugins/book.js +1 -1
- package/lib/plugins/boss_bar.js +1 -1
- package/lib/plugins/chat.js +63 -12
- package/lib/plugins/chest.js +6 -4
- package/lib/plugins/command_block.js +1 -1
- package/lib/plugins/craft.js +3 -3
- package/lib/plugins/creative.js +2 -2
- package/lib/plugins/entities.js +25 -8
- package/lib/plugins/game.js +14 -5
- package/lib/plugins/generic_place.js +1 -1
- package/lib/plugins/inventory.js +50 -25
- package/lib/plugins/place_entity.js +1 -1
- package/lib/plugins/ray_trace.js +36 -0
- package/lib/plugins/settings.js +1 -1
- package/lib/plugins/tablist.js +1 -1
- package/lib/plugins/team.js +1 -1
- package/lib/plugins/villager.js +9 -7
- package/lib/scoreboard.js +1 -1
- package/lib/team.js +2 -2
- package/lib/version.js +2 -2
- package/package.json +15 -16
package/examples/graffiti.js
CHANGED
|
@@ -23,11 +23,6 @@ const bot = mineflayer.createBot({
|
|
|
23
23
|
password: process.argv[5]
|
|
24
24
|
})
|
|
25
25
|
|
|
26
|
-
let mcData
|
|
27
|
-
bot.once('inject_allowed', () => {
|
|
28
|
-
mcData = require('minecraft-data')(bot.version)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
26
|
bot.on('chat', (username, message) => {
|
|
32
27
|
if (username === bot.username) return
|
|
33
28
|
switch (true) {
|
|
@@ -49,7 +44,7 @@ function watchPaintingOrSign () {
|
|
|
49
44
|
}
|
|
50
45
|
})
|
|
51
46
|
const signBlock = bot.findBlock({
|
|
52
|
-
matching: ['painting', 'sign'].map(name =>
|
|
47
|
+
matching: ['painting', 'sign'].map(name => bot.registry.blocksByName[name].id)
|
|
53
48
|
})
|
|
54
49
|
if (signBlock) {
|
|
55
50
|
bot.chat(`The sign says: ${signBlock.signText}`)
|
|
@@ -62,7 +57,7 @@ function watchPaintingOrSign () {
|
|
|
62
57
|
|
|
63
58
|
function updateSign (message) {
|
|
64
59
|
const signBlock = bot.findBlock({
|
|
65
|
-
matching: ['painting', 'sign'].map(name =>
|
|
60
|
+
matching: ['painting', 'sign'].map(name => bot.registry.blocksByName[name].id)
|
|
66
61
|
})
|
|
67
62
|
if (signBlock) {
|
|
68
63
|
bot.updateSign(signBlock, message.split(' ').slice(1).join(' '))
|
package/examples/guard.js
CHANGED
|
@@ -42,8 +42,7 @@ function stopGuarding () {
|
|
|
42
42
|
|
|
43
43
|
// Pathfinder to the guard position
|
|
44
44
|
function moveToGuardPos () {
|
|
45
|
-
|
|
46
|
-
bot.pathfinder.setMovements(new Movements(bot, mcData))
|
|
45
|
+
bot.pathfinder.setMovements(new Movements(bot))
|
|
47
46
|
bot.pathfinder.setGoal(new goals.GoalBlock(guardPos.x, guardPos.y, guardPos.z))
|
|
48
47
|
}
|
|
49
48
|
|
package/examples/inventory.js
CHANGED
|
@@ -67,7 +67,7 @@ bot.on('chat', async (username, message) => {
|
|
|
67
67
|
function sayItems (items = null) {
|
|
68
68
|
if (!items) {
|
|
69
69
|
items = bot.inventory.items()
|
|
70
|
-
if (
|
|
70
|
+
if (bot.registry.isNewerOrEqualTo('1.9') && bot.inventory.slots[45]) items.push(bot.inventory.slots[45])
|
|
71
71
|
}
|
|
72
72
|
const output = items.map(itemToString).join(', ')
|
|
73
73
|
if (output) {
|
|
@@ -127,10 +127,8 @@ function useEquippedItem () {
|
|
|
127
127
|
|
|
128
128
|
async function craftItem (name, amount) {
|
|
129
129
|
amount = parseInt(amount, 10)
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
const item = mcData.itemsByName[name]
|
|
133
|
-
const craftingTableID = mcData.blocksByName.crafting_table.id
|
|
130
|
+
const item = bot.registry.itemsByName[name]
|
|
131
|
+
const craftingTableID = bot.registry.blocksByName.crafting_table.id
|
|
134
132
|
|
|
135
133
|
const craftingTable = bot.findBlock({
|
|
136
134
|
matching: craftingTableID
|
|
@@ -164,6 +162,6 @@ function itemToString (item) {
|
|
|
164
162
|
|
|
165
163
|
function itemByName (name) {
|
|
166
164
|
const items = bot.inventory.items()
|
|
167
|
-
if (
|
|
165
|
+
if (bot.registry.isNewerOrEqualTo('1.9') && bot.inventory.slots[45]) items.push(bot.inventory.slots[45])
|
|
168
166
|
return items.filter(item => item.name === name)[0]
|
|
169
167
|
}
|
package/examples/jumper.js
CHANGED
|
@@ -63,7 +63,7 @@ bot.on('chat', (username, message) => {
|
|
|
63
63
|
}
|
|
64
64
|
break
|
|
65
65
|
case 'mount':
|
|
66
|
-
entity = bot.nearestEntity((entity) => { return entity.
|
|
66
|
+
entity = bot.nearestEntity((entity) => { return entity.name === 'minecart' })
|
|
67
67
|
if (entity) {
|
|
68
68
|
bot.mount(entity)
|
|
69
69
|
} else {
|
|
@@ -20,8 +20,7 @@ const RANGE_GOAL = 1 // get within this radius of the player
|
|
|
20
20
|
bot.loadPlugin(pathfinder)
|
|
21
21
|
|
|
22
22
|
bot.once('spawn', () => {
|
|
23
|
-
const
|
|
24
|
-
const defaultMove = new Movements(bot, mcData)
|
|
23
|
+
const defaultMove = new Movements(bot)
|
|
25
24
|
|
|
26
25
|
bot.on('chat', (username, message) => {
|
|
27
26
|
if (username === bot.username) return
|
|
@@ -22,14 +22,7 @@ const bot = mineflayer.createBot({
|
|
|
22
22
|
|
|
23
23
|
const MAX_DIST_FROM_BLOCK_TO_PLACE = 4
|
|
24
24
|
|
|
25
|
-
let mcData = null
|
|
26
|
-
bot.once('spawn', () => {
|
|
27
|
-
mcData = require('minecraft-data')(bot.version)
|
|
28
|
-
})
|
|
29
|
-
|
|
30
25
|
bot.on('chat', async (ign, msg) => {
|
|
31
|
-
if (!mcData) mcData = require('minecraft-data')(bot.version)
|
|
32
|
-
|
|
33
26
|
// solve where the bot will place the crystal near
|
|
34
27
|
let findBlocksNearPoint = null
|
|
35
28
|
if (msg === 'place crystal near bot') {
|
|
@@ -44,13 +37,13 @@ bot.on('chat', async (ign, msg) => {
|
|
|
44
37
|
}
|
|
45
38
|
|
|
46
39
|
// find end crystal(s) in inventory
|
|
47
|
-
const item = bot.inventory.findInventoryItem(
|
|
40
|
+
const item = bot.inventory.findInventoryItem(bot.registry.itemsByName.end_crystal.id)
|
|
48
41
|
if (!item) bot.chat("I don't have any ender crystals")
|
|
49
42
|
|
|
50
43
|
// find the crystal
|
|
51
44
|
const block = bot.findBlock({
|
|
52
45
|
point: findBlocksNearPoint,
|
|
53
|
-
matching: ['bedrock', 'obsidian'].map(blockName =>
|
|
46
|
+
matching: ['bedrock', 'obsidian'].map(blockName => bot.registry.blocksByName[blockName].id),
|
|
54
47
|
useExtraInfo: block => {
|
|
55
48
|
const hasAirAbove = bot.blockAt(block.position.offset(0, 1, 0)).name === 'air'
|
|
56
49
|
const botNotStandingOnBlock = block.position.xzDistanceTo(bot.entity.position) > 2
|
package/examples/python/basic.py
CHANGED
|
@@ -17,8 +17,7 @@ print("Started mineflayer")
|
|
|
17
17
|
@On(bot, 'spawn')
|
|
18
18
|
def handle(*args):
|
|
19
19
|
print("I spawned 👋")
|
|
20
|
-
|
|
21
|
-
movements = pathfinder.Movements(bot, mcData)
|
|
20
|
+
movements = pathfinder.Movements(bot)
|
|
22
21
|
|
|
23
22
|
@On(bot, 'chat')
|
|
24
23
|
def handleMsg(this, sender, message, *args):
|
package/examples/trader.js
CHANGED
|
@@ -25,10 +25,6 @@ const bot = mineflayer.createBot({
|
|
|
25
25
|
username: process.argv[4] ? process.argv[4] : 'trader',
|
|
26
26
|
password: process.argv[5]
|
|
27
27
|
})
|
|
28
|
-
let mcData
|
|
29
|
-
bot.once('inject_allowed', () => {
|
|
30
|
-
mcData = require('minecraft-data')(bot.version)
|
|
31
|
-
})
|
|
32
28
|
|
|
33
29
|
bot.on('chat', (username, message) => {
|
|
34
30
|
if (username === bot.username) return
|
|
@@ -50,7 +46,7 @@ bot.on('chat', (username, message) => {
|
|
|
50
46
|
})
|
|
51
47
|
|
|
52
48
|
function showVillagers () {
|
|
53
|
-
const villagers = Object.keys(bot.entities).map(id => bot.entities[id]).filter(e => e.entityType ===
|
|
49
|
+
const villagers = Object.keys(bot.entities).map(id => bot.entities[id]).filter(e => e.entityType === bot.registry.entitiesByName.villager.id)
|
|
54
50
|
const closeVillagersId = villagers.filter(e => bot.entity.position.distanceTo(e.position) < 3).map(e => e.id)
|
|
55
51
|
bot.chat(`found ${villagers.length} villagers`)
|
|
56
52
|
bot.chat(`villager(s) you can trade with: ${closeVillagersId.join(', ')}`)
|
|
@@ -69,7 +65,7 @@ async function showTrades (id) {
|
|
|
69
65
|
case !e:
|
|
70
66
|
bot.chat(`cant find entity with id ${id}`)
|
|
71
67
|
break
|
|
72
|
-
case e.entityType !==
|
|
68
|
+
case e.entityType !== bot.registry.entitiesByName.villager.id:
|
|
73
69
|
bot.chat('entity is not a villager')
|
|
74
70
|
break
|
|
75
71
|
case bot.entity.position.distanceTo(e.position) > 3:
|
|
@@ -91,7 +87,7 @@ async function trade (id, index, count) {
|
|
|
91
87
|
case !e:
|
|
92
88
|
bot.chat(`cant find entity with id ${id}`)
|
|
93
89
|
break
|
|
94
|
-
case e.entityType !==
|
|
90
|
+
case e.entityType !== bot.registry.entitiesByName.villager.id:
|
|
95
91
|
bot.chat('entity is not a villager')
|
|
96
92
|
break
|
|
97
93
|
case bot.entity.position.distanceTo(e.position) > 3:
|
|
@@ -168,7 +164,7 @@ function stringifyItem (item) {
|
|
|
168
164
|
text += ` enchanted with ${(ench || StoredEnchantments).value.value.map((e) => {
|
|
169
165
|
const lvl = e.lvl.value
|
|
170
166
|
const id = e.id.value
|
|
171
|
-
return
|
|
167
|
+
return bot.registry.enchantments[id].displayName + ' ' + lvl
|
|
172
168
|
}).join(' ')}`
|
|
173
169
|
}
|
|
174
170
|
}
|
package/index.d.ts
CHANGED
|
@@ -126,7 +126,7 @@ interface BotEvents {
|
|
|
126
126
|
blockBreakProgressEnd: (block: Block) => Promise<void> | void
|
|
127
127
|
diggingCompleted: (block: Block) => Promise<void> | void
|
|
128
128
|
diggingAborted: (block: Block) => Promise<void> | void
|
|
129
|
-
move: () => Promise<void> | void
|
|
129
|
+
move: (position: Vec3) => Promise<void> | void
|
|
130
130
|
forcedMove: () => Promise<void> | void
|
|
131
131
|
mount: () => Promise<void> | void
|
|
132
132
|
dismount: (vehicle: Entity) => Promise<void> | void
|
|
@@ -165,6 +165,7 @@ export interface Bot extends TypedEmitter<BotEvents> {
|
|
|
165
165
|
player: Player
|
|
166
166
|
players: { [username: string]: Player }
|
|
167
167
|
isRaining: boolean
|
|
168
|
+
thunderState: number
|
|
168
169
|
chatPatterns: ChatPattern[]
|
|
169
170
|
settings: GameSettings
|
|
170
171
|
experience: Experience
|
|
@@ -176,7 +177,7 @@ export interface Bot extends TypedEmitter<BotEvents> {
|
|
|
176
177
|
physicsEnabled: boolean
|
|
177
178
|
time: Time
|
|
178
179
|
quickBarSlot: number
|
|
179
|
-
inventory: Window
|
|
180
|
+
inventory: Window<StorageEvents>
|
|
180
181
|
targetDigBlock: Block
|
|
181
182
|
isSleeping: boolean
|
|
182
183
|
scoreboards: { [name: string]: ScoreBoard }
|
|
@@ -249,7 +250,7 @@ export interface Bot extends TypedEmitter<BotEvents> {
|
|
|
249
250
|
|
|
250
251
|
sleep: (bedBlock: Block) => Promise<void>
|
|
251
252
|
|
|
252
|
-
isABed: (bedBlock: Block) =>
|
|
253
|
+
isABed: (bedBlock: Block) => boolean
|
|
253
254
|
|
|
254
255
|
wake: () => Promise<void>
|
|
255
256
|
|
|
@@ -298,11 +299,11 @@ export interface Bot extends TypedEmitter<BotEvents> {
|
|
|
298
299
|
|
|
299
300
|
placeEntity: (referenceBlock: Block, faceVector: Vec3) => Promise<Entity>
|
|
300
301
|
|
|
301
|
-
activateBlock: (block: Block) => Promise<void>
|
|
302
|
+
activateBlock: (block: Block, direction?: Vec3, cursorPos?: Vec3) => Promise<void>
|
|
302
303
|
|
|
303
|
-
activateEntity: (
|
|
304
|
+
activateEntity: (entity: Entity) => Promise<void>
|
|
304
305
|
|
|
305
|
-
activateEntityAt: (
|
|
306
|
+
activateEntityAt: (entity: Entity, position: Vec3) => Promise<void>
|
|
306
307
|
|
|
307
308
|
consume: () => Promise<void>
|
|
308
309
|
|
|
@@ -337,9 +338,9 @@ export interface Bot extends TypedEmitter<BotEvents> {
|
|
|
337
338
|
pages: string[]
|
|
338
339
|
) => Promise<void>
|
|
339
340
|
|
|
340
|
-
openContainer: (chest: Block | Entity) => Promise<Chest |
|
|
341
|
+
openContainer: (chest: Block | Entity, direction?: Vec3, cursorPos?: Vec3) => Promise<Chest | Dispenser>
|
|
341
342
|
|
|
342
|
-
openChest: (chest: Block | Entity) => Promise<Chest>
|
|
343
|
+
openChest: (chest: Block | Entity, direction?: number, cursorPos?: Vec3) => Promise<Chest>
|
|
343
344
|
|
|
344
345
|
openFurnace: (furnace: Block) => Promise<Furnace>
|
|
345
346
|
|
|
@@ -380,9 +381,9 @@ export interface Bot extends TypedEmitter<BotEvents> {
|
|
|
380
381
|
|
|
381
382
|
transfer: (options: TransferOptions) => Promise<void>
|
|
382
383
|
|
|
383
|
-
openBlock: (block: Block,
|
|
384
|
+
openBlock: (block: Block, direction?: Vec3, cursorPos?: Vec3) => Promise<Window>
|
|
384
385
|
|
|
385
|
-
openEntity: (block: Entity, Class: new () => EventEmitter) => Promise<
|
|
386
|
+
openEntity: (block: Entity, Class: new () => EventEmitter) => Promise<Window>
|
|
386
387
|
|
|
387
388
|
moveSlotItem: (
|
|
388
389
|
sourceSlot: number,
|
|
@@ -444,8 +445,8 @@ export type LevelType =
|
|
|
444
445
|
| 'customized'
|
|
445
446
|
| 'buffet'
|
|
446
447
|
| 'default_1_1'
|
|
447
|
-
export type GameMode = 'survival' | 'creative' | 'adventure'
|
|
448
|
-
export type Dimension = 'minecraft:
|
|
448
|
+
export type GameMode = 'survival' | 'creative' | 'adventure' | 'spectator'
|
|
449
|
+
export type Dimension = 'minecraft:the_nether' | 'minecraft:overworld' | 'minecraft:the_end'
|
|
449
450
|
export type Difficulty = 'peaceful' | 'easy' | 'normal' | 'hard'
|
|
450
451
|
|
|
451
452
|
export interface Player {
|
|
@@ -455,7 +456,10 @@ export interface Player {
|
|
|
455
456
|
gamemode: number
|
|
456
457
|
ping: number
|
|
457
458
|
entity: Entity
|
|
458
|
-
|
|
459
|
+
profileKeys?: {
|
|
460
|
+
publicKey: Buffer
|
|
461
|
+
signature: Buffer
|
|
462
|
+
}
|
|
459
463
|
|
|
460
464
|
export interface ChatPattern {
|
|
461
465
|
pattern: RegExp
|
|
@@ -605,7 +609,7 @@ export class Painting {
|
|
|
605
609
|
interface StorageEvents {
|
|
606
610
|
open: () => void
|
|
607
611
|
close: () => void
|
|
608
|
-
updateSlot: (oldItem: Item | null, newItem: Item) => void
|
|
612
|
+
updateSlot: (oldItem: Item | null, newItem: Item | null) => void
|
|
609
613
|
}
|
|
610
614
|
|
|
611
615
|
interface FurnaceEvents extends StorageEvents {
|
|
@@ -616,9 +620,7 @@ interface ConditionalStorageEvents extends StorageEvents {
|
|
|
616
620
|
ready: () => void
|
|
617
621
|
}
|
|
618
622
|
|
|
619
|
-
export class Chest extends
|
|
620
|
-
window: object | /* prismarine-windows ChestWindow */ null
|
|
621
|
-
|
|
623
|
+
export class Chest extends Window<StorageEvents> {
|
|
622
624
|
constructor ();
|
|
623
625
|
|
|
624
626
|
close (): void;
|
|
@@ -634,13 +636,9 @@ export class Chest extends (EventEmitter as new () => TypedEmitter<StorageEvents
|
|
|
634
636
|
metadata: number | null,
|
|
635
637
|
count: number | null
|
|
636
638
|
): Promise<void>;
|
|
637
|
-
|
|
638
|
-
count (itemType: number, metadata: number | null): number;
|
|
639
|
-
|
|
640
|
-
items (): Item[];
|
|
641
639
|
}
|
|
642
640
|
|
|
643
|
-
export class Furnace extends
|
|
641
|
+
export class Furnace extends Window<FurnaceEvents> {
|
|
644
642
|
fuel: number
|
|
645
643
|
progress: number
|
|
646
644
|
|
|
@@ -673,7 +671,7 @@ export class Furnace extends (EventEmitter as new () => TypedEmitter<FurnaceEven
|
|
|
673
671
|
outputItem (): Item;
|
|
674
672
|
}
|
|
675
673
|
|
|
676
|
-
export class Dispenser extends
|
|
674
|
+
export class Dispenser extends Window<StorageEvents> {
|
|
677
675
|
constructor ();
|
|
678
676
|
|
|
679
677
|
close (): void;
|
|
@@ -689,13 +687,9 @@ export class Dispenser extends (EventEmitter as new () => TypedEmitter<StorageEv
|
|
|
689
687
|
metadata: number | null,
|
|
690
688
|
count: number | null
|
|
691
689
|
): Promise<void>;
|
|
692
|
-
|
|
693
|
-
count (itemType: number, metadata: number | null): number;
|
|
694
|
-
|
|
695
|
-
items (): Item[];
|
|
696
690
|
}
|
|
697
691
|
|
|
698
|
-
export class EnchantmentTable extends
|
|
692
|
+
export class EnchantmentTable extends Window<ConditionalStorageEvents> {
|
|
699
693
|
enchantments: Enchantment[]
|
|
700
694
|
|
|
701
695
|
constructor ();
|
|
@@ -724,7 +718,7 @@ export interface Enchantment {
|
|
|
724
718
|
level: number
|
|
725
719
|
}
|
|
726
720
|
|
|
727
|
-
export class Villager extends
|
|
721
|
+
export class Villager extends Window<ConditionalStorageEvents> {
|
|
728
722
|
trades: VillagerTrade[]
|
|
729
723
|
|
|
730
724
|
constructor ();
|
package/lib/bossbar.js
CHANGED
|
@@ -4,8 +4,8 @@ const divisions = [0, 6, 10, 12, 20]
|
|
|
4
4
|
|
|
5
5
|
module.exports = loader
|
|
6
6
|
|
|
7
|
-
function loader (
|
|
8
|
-
ChatMessage = require('prismarine-chat')(
|
|
7
|
+
function loader (registry) {
|
|
8
|
+
ChatMessage = require('prismarine-chat')(registry)
|
|
9
9
|
return BossBar
|
|
10
10
|
}
|
|
11
11
|
|
package/lib/loader.js
CHANGED
|
@@ -55,7 +55,7 @@ module.exports = {
|
|
|
55
55
|
BossBar: require('./bossbar'),
|
|
56
56
|
supportedVersions,
|
|
57
57
|
testedVersions,
|
|
58
|
-
supportFeature: (feature, version) => require('
|
|
58
|
+
supportFeature: (feature, version) => require('prismarine-registry')(version).supportFeature(feature)
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function createBot (options = {}) {
|
|
@@ -111,7 +111,7 @@ function createBot (options = {}) {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
const latestTestedVersion = testedVersions[testedVersions.length - 1]
|
|
114
|
-
const latestProtocolVersion = require('
|
|
114
|
+
const latestProtocolVersion = require('prismarine-registry')(latestTestedVersion).protocolVersion
|
|
115
115
|
if (version.protocolVersion > latestProtocolVersion) {
|
|
116
116
|
throw new Error(`Version ${version.minecraftVersion} is not supported. Latest supported version is ${latestTestedVersion}.`)
|
|
117
117
|
}
|
package/lib/plugins/anvil.js
CHANGED
|
@@ -5,7 +5,7 @@ const { once } = require('events')
|
|
|
5
5
|
module.exports = inject
|
|
6
6
|
|
|
7
7
|
function inject (bot) {
|
|
8
|
-
const Item = require('prismarine-item')(bot.
|
|
8
|
+
const Item = require('prismarine-item')(bot.registry)
|
|
9
9
|
|
|
10
10
|
const matchWindowType = window => /minecraft:(?:chipped_|damaged_)?anvil/.test(window.type)
|
|
11
11
|
|
package/lib/plugins/bed.js
CHANGED
|
@@ -146,10 +146,25 @@ function inject (bot) {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
bot.activateBlock(bedBlock)
|
|
150
|
+
|
|
151
|
+
await waitUntilSleep()
|
|
150
152
|
}
|
|
151
153
|
}
|
|
152
154
|
|
|
155
|
+
async function waitUntilSleep () {
|
|
156
|
+
return new Promise((resolve, reject) => {
|
|
157
|
+
const timeoutForSleep = setTimeout(() => {
|
|
158
|
+
reject(new Error('bot is not sleeping'))
|
|
159
|
+
}, 3000)
|
|
160
|
+
|
|
161
|
+
bot.once('sleep', () => {
|
|
162
|
+
clearTimeout(timeoutForSleep)
|
|
163
|
+
resolve()
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
}
|
|
167
|
+
|
|
153
168
|
bot._client.on('game_state_change', (packet) => {
|
|
154
169
|
if (packet.reason === 0) {
|
|
155
170
|
// occurs when you can't spawn in your bed and your spawn point gets reset
|
|
@@ -44,7 +44,7 @@ function inject (bot) {
|
|
|
44
44
|
const perpendicularCardinals = Object.keys(FACING_MAP[facing])
|
|
45
45
|
for (const cardinal of perpendicularCardinals) {
|
|
46
46
|
const cardinalOffset = CARDINALS[cardinal]
|
|
47
|
-
if (bot.blockAt(chestBlock.position.plus(cardinalOffset))
|
|
47
|
+
if (bot.blockAt(chestBlock.position.plus(cardinalOffset))?.type === chestBlock.type) {
|
|
48
48
|
return FACING_MAP[cardinal][facing]
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -100,13 +100,14 @@ function inject (bot) {
|
|
|
100
100
|
const destroyStage = packet.destroyStage
|
|
101
101
|
const pt = new Vec3(packet.location.x, packet.location.y, packet.location.z)
|
|
102
102
|
const block = bot.blockAt(pt)
|
|
103
|
+
const entity = bot.entities[packet.entityId]
|
|
103
104
|
|
|
104
105
|
if (destroyStage < 0 || destroyStage > 9) {
|
|
105
106
|
// http://wiki.vg/Protocol#Block_Break_Progress
|
|
106
107
|
// "0-9 to set it, any other value to remove it"
|
|
107
|
-
bot.emit('blockBreakProgressEnd', block)
|
|
108
|
+
bot.emit('blockBreakProgressEnd', block, entity)
|
|
108
109
|
} else {
|
|
109
|
-
bot.emit('blockBreakProgressObserved', block, destroyStage)
|
|
110
|
+
bot.emit('blockBreakProgressObserved', block, destroyStage, entity)
|
|
110
111
|
}
|
|
111
112
|
})
|
|
112
113
|
}
|
package/lib/plugins/blocks.js
CHANGED
|
@@ -21,9 +21,9 @@ const dimensionNames = {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function inject (bot, { version, storageBuilder }) {
|
|
24
|
-
const Block = require('prismarine-block')(
|
|
25
|
-
const Chunk = require('prismarine-chunk')(
|
|
26
|
-
const World = require('prismarine-world')(
|
|
24
|
+
const Block = require('prismarine-block')(bot.registry)
|
|
25
|
+
const Chunk = require('prismarine-chunk')(bot.registry)
|
|
26
|
+
const World = require('prismarine-world')(bot.registry)
|
|
27
27
|
const paintingsByPos = {}
|
|
28
28
|
const paintingsById = {}
|
|
29
29
|
|
package/lib/plugins/book.js
CHANGED
|
@@ -4,7 +4,7 @@ const { once } = require('events')
|
|
|
4
4
|
module.exports = inject
|
|
5
5
|
|
|
6
6
|
function inject (bot) {
|
|
7
|
-
const Item = require('prismarine-item')(bot.
|
|
7
|
+
const Item = require('prismarine-item')(bot.registry)
|
|
8
8
|
|
|
9
9
|
let editBook
|
|
10
10
|
if (bot.supportFeature('editBookIsPluginChannel')) {
|
package/lib/plugins/boss_bar.js
CHANGED
package/lib/plugins/chat.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
const { once } = require('events')
|
|
2
2
|
|
|
3
|
+
const USERNAME_REGEX = '(?:\\(.{1,15}\\)|\\[.{1,15}\\]|.){0,5}?(\\w+)'
|
|
4
|
+
const LEGACY_VANILLA_CHAT_REGEX = new RegExp(`^${USERNAME_REGEX}\\s?[>:\\-»\\]\\)~]+\\s(.*)$`)
|
|
5
|
+
|
|
3
6
|
module.exports = inject
|
|
4
7
|
|
|
5
8
|
function inject (bot, options) {
|
|
6
9
|
const CHAT_LENGTH_LIMIT = options.chatLengthLimit ?? (bot.supportFeature('lessCharsInChat') ? 100 : 256)
|
|
7
10
|
const defaultChatPatterns = options.defaultChatPatterns ?? true
|
|
8
11
|
|
|
9
|
-
const ChatMessage = require('prismarine-chat')(bot.
|
|
12
|
+
const ChatMessage = require('prismarine-chat')(bot.registry)
|
|
10
13
|
// chat.pattern.type will emit an event for bot.on() of the same type, eg chatType = whisper will trigger bot.on('whisper')
|
|
11
14
|
const _patterns = {}
|
|
12
15
|
let _length = 0
|
|
@@ -105,22 +108,43 @@ function inject (bot, options) {
|
|
|
105
108
|
|
|
106
109
|
addDefaultPatterns()
|
|
107
110
|
|
|
111
|
+
// Pre 1.19
|
|
108
112
|
bot._client.on('chat', (packet) => {
|
|
109
113
|
const msg = ChatMessage.fromNotch(packet.message)
|
|
110
|
-
|
|
111
|
-
const ChatPositions = {
|
|
114
|
+
const chatPositions = {
|
|
112
115
|
0: 'chat',
|
|
113
116
|
1: 'system',
|
|
114
117
|
2: 'game_info'
|
|
115
118
|
}
|
|
119
|
+
bot.emit('message', msg, chatPositions[packet.position], packet.sender, /* verified */ null)
|
|
120
|
+
bot.emit('messagestr', msg.toString(), chatPositions[packet.position], msg, packet.sender, /* verified */ null)
|
|
121
|
+
// Position 2 is the action bar
|
|
122
|
+
if (packet.position === 2) bot.emit('actionBar', msg, null)
|
|
123
|
+
})
|
|
116
124
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
125
|
+
// 1.19+
|
|
126
|
+
bot._client.on('player_chat', (packet) => {
|
|
127
|
+
const message = packet.unsignedChatContent || packet.signedChatContent
|
|
128
|
+
let verified = false
|
|
129
|
+
const sender = bot.uuidToUsername[packet.senderUuid]
|
|
130
|
+
if (sender) {
|
|
131
|
+
const { profileKeys } = bot.players[sender]
|
|
132
|
+
if (profileKeys) verified = bot._client.verifyMessage(profileKeys.publicKey, packet)
|
|
133
|
+
}
|
|
134
|
+
const parameters = {
|
|
135
|
+
sender: JSON.parse(packet.senderName),
|
|
136
|
+
content: JSON.parse(message)
|
|
137
|
+
}
|
|
138
|
+
const msg = ChatMessage.fromNetwork(packet.type, parameters)
|
|
139
|
+
Object.assign(msg, parameters)
|
|
140
|
+
bot.emit('message', msg, 'chat', packet.senderUuid, verified)
|
|
141
|
+
bot.emit('messagestr', msg.toString(), 'chat', msg, packet.senderUuid, verified)
|
|
142
|
+
})
|
|
121
143
|
|
|
122
|
-
|
|
123
|
-
|
|
144
|
+
bot._client.on('system_chat', (packet) => {
|
|
145
|
+
const msg = ChatMessage.fromNotch(packet.content)
|
|
146
|
+
bot.emit('message', msg, 'system', null)
|
|
147
|
+
bot.emit('messagestr', msg.toString(), 'system', msg, null)
|
|
124
148
|
})
|
|
125
149
|
|
|
126
150
|
function chatWithHeader (header, message) {
|
|
@@ -129,6 +153,22 @@ function inject (bot, options) {
|
|
|
129
153
|
throw new Error('Incorrect type! Should be a string or number.')
|
|
130
154
|
}
|
|
131
155
|
|
|
156
|
+
if (bot.supportFeature('signedChat')) {
|
|
157
|
+
if (message.startsWith('/')) {
|
|
158
|
+
// We send commands as Chat Command packet in 1.19+
|
|
159
|
+
const command = message.slice(1)
|
|
160
|
+
const timestamp = BigInt(Date.now())
|
|
161
|
+
bot._client.write('chat_command', {
|
|
162
|
+
command,
|
|
163
|
+
timestamp,
|
|
164
|
+
salt: 0n,
|
|
165
|
+
argumentSignatures: [],
|
|
166
|
+
signedPreview: false
|
|
167
|
+
})
|
|
168
|
+
return
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
132
172
|
const lengthLimit = CHAT_LENGTH_LIMIT - header.length
|
|
133
173
|
message.split('\n').forEach((subMessage) => {
|
|
134
174
|
if (!subMessage) return
|
|
@@ -136,7 +176,17 @@ function inject (bot, options) {
|
|
|
136
176
|
let smallMsg
|
|
137
177
|
for (i = 0; i < subMessage.length; i += lengthLimit) {
|
|
138
178
|
smallMsg = header + subMessage.substring(i, i + lengthLimit)
|
|
139
|
-
bot.
|
|
179
|
+
if (bot.supportFeature('signedChat')) {
|
|
180
|
+
const timestamp = BigInt(Date.now())
|
|
181
|
+
bot._client.write('chat_message', {
|
|
182
|
+
message: smallMsg,
|
|
183
|
+
timestamp,
|
|
184
|
+
salt: 0,
|
|
185
|
+
signature: bot._client.profileKeys ? bot._client.signMessage(smallMsg, timestamp) : Buffer.alloc(0)
|
|
186
|
+
})
|
|
187
|
+
} else {
|
|
188
|
+
bot._client.write('chat', { message: smallMsg })
|
|
189
|
+
}
|
|
140
190
|
}
|
|
141
191
|
})
|
|
142
192
|
}
|
|
@@ -172,11 +222,12 @@ function inject (bot, options) {
|
|
|
172
222
|
bot.tabComplete = tabComplete
|
|
173
223
|
|
|
174
224
|
function addDefaultPatterns () {
|
|
225
|
+
// 1.19 changes the chat format to move <sender> prefix from message contents to a seperate field.
|
|
226
|
+
// TODO: new chat lister to handle this
|
|
175
227
|
if (!defaultChatPatterns) return
|
|
176
|
-
const USERNAME_REGEX = '(?:\\(.+\\)|\\[.+\\]|.)*?(\\w+)'
|
|
177
228
|
bot.addChatPattern('whisper', new RegExp(`^${USERNAME_REGEX} whispers(?: to you)?:? (.*)$`), { deprecated: true })
|
|
178
229
|
bot.addChatPattern('whisper', new RegExp(`^\\[${USERNAME_REGEX} -> \\w+\\s?\\] (.*)$`), { deprecated: true })
|
|
179
|
-
bot.addChatPattern('chat',
|
|
230
|
+
bot.addChatPattern('chat', LEGACY_VANILLA_CHAT_REGEX, { deprecated: true })
|
|
180
231
|
}
|
|
181
232
|
|
|
182
233
|
function awaitMessage (...args) {
|
package/lib/plugins/chest.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
const { Vec3 } = require('vec3')
|
|
1
2
|
|
|
2
3
|
module.exports = inject
|
|
3
4
|
|
|
4
5
|
function inject (bot) {
|
|
5
|
-
const allowedWindowTypes = ['minecraft:generic', 'minecraft:chest', 'minecraft:dispenser', 'minecraft:shulker_box', 'minecraft:hopper', 'minecraft:container', 'minecraft:dropper', 'minecraft:trapped_chest']
|
|
6
|
-
|
|
6
|
+
const allowedWindowTypes = ['minecraft:generic', 'minecraft:chest', 'minecraft:dispenser', 'minecraft:ender_chest', 'minecraft:shulker_box', 'minecraft:hopper', 'minecraft:container', 'minecraft:dropper', 'minecraft:trapped_chest', 'minecraft:barrel', 'minecraft:white_shulker_box', 'minecraft:orange_shulker_box', 'minecraft:magenta_shulker_box', 'minecraft:light_blue_shulker_box', 'minecraft:yellow_shulker_box', 'minecraft:lime_shulker_box', 'minecraft:pink_shulker_box', 'minecraft:gray_shulker_box', 'minecraft:light_gray_shulker_box', 'minecraft:cyan_shulker_box', 'minecraft:purple_shulker_box', 'minecraft:blue_shulker_box', 'minecraft:brown_shulker_box', 'minecraft:green_shulker_box', 'minecraft:red_shulker_box', 'minecraft:black_shulker_box']
|
|
7
7
|
function matchWindowType (window) {
|
|
8
8
|
for (const type of allowedWindowTypes) {
|
|
9
9
|
if (window.type.startsWith(type)) return true
|
|
@@ -11,10 +11,12 @@ function inject (bot) {
|
|
|
11
11
|
return false
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
async function openContainer (containerToOpen) {
|
|
14
|
+
async function openContainer (containerToOpen, direction, cursorPos) {
|
|
15
|
+
direction = direction ?? new Vec3(0, 1, 0)
|
|
16
|
+
cursorPos = cursorPos ?? new Vec3(0.5, 0.5, 0.5)
|
|
15
17
|
let chest
|
|
16
18
|
if (containerToOpen.constructor.name === 'Block' && allowedWindowTypes.map(name => name.replace('minecraft:', '')).includes(containerToOpen.name)) {
|
|
17
|
-
chest = await bot.openBlock(containerToOpen)
|
|
19
|
+
chest = await bot.openBlock(containerToOpen, direction, cursorPos)
|
|
18
20
|
} else if (containerToOpen.constructor.name === 'Entity') {
|
|
19
21
|
chest = await bot.openEntity(containerToOpen)
|
|
20
22
|
} else {
|
|
@@ -8,7 +8,7 @@ function inject (bot) {
|
|
|
8
8
|
assert.strictEqual(bot.player.gamemode, 1, new Error('The bot has to be in creative mode to open the command block window'))
|
|
9
9
|
assert.notStrictEqual(pos, null)
|
|
10
10
|
assert.notStrictEqual(command, null)
|
|
11
|
-
assert.strictEqual(bot.blockAt(pos).name
|
|
11
|
+
assert.strictEqual(bot.blockAt(pos).name.includes('command_block'), true, new Error("The block isn't a command block"))
|
|
12
12
|
|
|
13
13
|
// Default values when a command block is placed in vanilla minecraft
|
|
14
14
|
options.trackOutput = options.trackOutput ?? false
|
package/lib/plugins/craft.js
CHANGED
|
@@ -3,9 +3,9 @@ const { once } = require('events')
|
|
|
3
3
|
|
|
4
4
|
module.exports = inject
|
|
5
5
|
|
|
6
|
-
function inject (bot
|
|
7
|
-
const Item = require('prismarine-item')(bot.
|
|
8
|
-
const Recipe = require('prismarine-recipe')(
|
|
6
|
+
function inject (bot) {
|
|
7
|
+
const Item = require('prismarine-item')(bot.registry)
|
|
8
|
+
const Recipe = require('prismarine-recipe')(bot.registry).Recipe
|
|
9
9
|
|
|
10
10
|
async function craft (recipe, count, craftingTable) {
|
|
11
11
|
assert.ok(recipe)
|