CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PrismarineJS

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: PrismarineJS/mineflayer
Path: blob/master/examples/chest.js
Views: 789
1
/*
2
* Watch out, this is a big one!
3
*
4
* This is a demonstration to show you how you can interact with:
5
* - Chests
6
* - Furnaces
7
* - Dispensers
8
* - Enchantment Tables
9
*
10
* and of course with your own inventory.
11
*
12
* Each of the main commands makes the bot interact with the block and open
13
* its window. From there you can send another set of commands to actually
14
* interact with the window and make awesome stuff.
15
*
16
* There's also a bonus example which shows you how to use the /invsee command
17
* to see what items another user has in his inventory and what items he has
18
* equipped.
19
* This last one is usually reserved to Server Ops so make sure you have the
20
* appropriate permission to do it or it won't work.
21
*/
22
const mineflayer = require('mineflayer')
23
24
if (process.argv.length < 4 || process.argv.length > 6) {
25
console.log('Usage : node chest.js <host> <port> [<name>] [<password>]')
26
process.exit(1)
27
}
28
29
const bot = mineflayer.createBot({
30
host: process.argv[2],
31
port: parseInt(process.argv[3]),
32
username: process.argv[4] ? process.argv[4] : 'chest',
33
password: process.argv[5]
34
})
35
36
bot.on('experience', () => {
37
bot.chat(`I am level ${bot.experience.level}`)
38
})
39
40
bot.on('chat', (username, message) => {
41
if (username === bot.username) return
42
switch (true) {
43
case /^list$/.test(message):
44
sayItems()
45
break
46
case /^chest$/.test(message):
47
watchChest(false, ['chest', 'ender_chest', 'trapped_chest'])
48
break
49
case /^furnace$/.test(message):
50
watchFurnace()
51
break
52
case /^dispenser$/.test(message):
53
watchChest(false, ['dispenser'])
54
break
55
case /^enchant$/.test(message):
56
watchEnchantmentTable()
57
break
58
case /^chestminecart$/.test(message):
59
watchChest(true)
60
break
61
case /^invsee \w+( \d)?$/.test(message): {
62
// invsee Herobrine [or]
63
// invsee Herobrine 1
64
const command = message.split(' ')
65
useInvsee(command[0], command[1])
66
break
67
}
68
}
69
})
70
71
function sayItems (items = bot.inventory.items()) {
72
const output = items.map(itemToString).join(', ')
73
if (output) {
74
bot.chat(output)
75
} else {
76
bot.chat('empty')
77
}
78
}
79
80
async function watchChest (minecart, blocks = []) {
81
let chestToOpen
82
if (minecart) {
83
chestToOpen = Object.keys(bot.entities)
84
.map(id => bot.entities[id]).find(e => e.entityType === bot.registry.entitiesByName.chest_minecart &&
85
e.objectData.intField === 1 &&
86
bot.entity.position.distanceTo(e.position) < 3)
87
if (!chestToOpen) {
88
bot.chat('no chest minecart found')
89
return
90
}
91
} else {
92
chestToOpen = bot.findBlock({
93
matching: blocks.map(name => bot.registry.blocksByName[name].id),
94
maxDistance: 6
95
})
96
if (!chestToOpen) {
97
bot.chat('no chest found')
98
return
99
}
100
}
101
const chest = await bot.openContainer(chestToOpen)
102
sayItems(chest.containerItems())
103
chest.on('updateSlot', (slot, oldItem, newItem) => {
104
bot.chat(`chest update: ${itemToString(oldItem)} -> ${itemToString(newItem)} (slot: ${slot})`)
105
})
106
chest.on('close', () => {
107
bot.chat('chest closed')
108
})
109
110
bot.on('chat', onChat)
111
112
function onChat (username, message) {
113
if (username === bot.username) return
114
const command = message.split(' ')
115
switch (true) {
116
case /^close$/.test(message):
117
closeChest()
118
break
119
case /^withdraw \d+ \w+$/.test(message):
120
// withdraw amount name
121
// ex: withdraw 16 stick
122
withdrawItem(command[2], command[1])
123
break
124
case /^deposit \d+ \w+$/.test(message):
125
// deposit amount name
126
// ex: deposit 16 stick
127
depositItem(command[2], command[1])
128
break
129
}
130
}
131
132
function closeChest () {
133
chest.close()
134
bot.removeListener('chat', onChat)
135
}
136
137
async function withdrawItem (name, amount) {
138
const item = itemByName(chest.containerItems(), name)
139
if (item) {
140
try {
141
await chest.withdraw(item.type, null, amount)
142
bot.chat(`withdrew ${amount} ${item.name}`)
143
} catch (err) {
144
bot.chat(`unable to withdraw ${amount} ${item.name}`)
145
}
146
} else {
147
bot.chat(`unknown item ${name}`)
148
}
149
}
150
151
async function depositItem (name, amount) {
152
const item = itemByName(chest.items(), name)
153
if (item) {
154
try {
155
await chest.deposit(item.type, null, amount)
156
bot.chat(`deposited ${amount} ${item.name}`)
157
} catch (err) {
158
bot.chat(`unable to deposit ${amount} ${item.name}`)
159
}
160
} else {
161
bot.chat(`unknown item ${name}`)
162
}
163
}
164
}
165
166
async function watchFurnace () {
167
const furnaceBlock = bot.findBlock({
168
matching: ['furnace', 'lit_furnace'].filter(name => bot.registry.blocksByName[name] !== undefined).map(name => bot.registry.blocksByName[name].id),
169
maxDistance: 6
170
})
171
if (!furnaceBlock) {
172
bot.chat('no furnace found')
173
return
174
}
175
const furnace = await bot.openFurnace(furnaceBlock)
176
let output = ''
177
output += `input: ${itemToString(furnace.inputItem())}, `
178
output += `fuel: ${itemToString(furnace.fuelItem())}, `
179
output += `output: ${itemToString(furnace.outputItem())}`
180
bot.chat(output)
181
182
furnace.on('updateSlot', (slot, oldItem, newItem) => {
183
bot.chat(`furnace update: ${itemToString(oldItem)} -> ${itemToString(newItem)} (slot: ${slot})`)
184
})
185
furnace.on('close', () => {
186
bot.chat('furnace closed')
187
})
188
furnace.on('update', () => {
189
console.log(`fuel: ${Math.round(furnace.fuel * 100)}% progress: ${Math.round(furnace.progress * 100)}%`)
190
})
191
192
bot.on('chat', onChat)
193
194
function onChat (username, message) {
195
if (username === bot.username) return
196
const command = message.split(' ')
197
switch (true) {
198
case /^close$/.test(message):
199
closeFurnace()
200
break
201
case /^(input|fuel) \d+ \w+$/.test(message):
202
// input amount name
203
// ex: input 32 coal
204
putInFurnace(command[0], command[2], command[1])
205
break
206
case /^take (input|fuel|output)$/.test(message):
207
// take what
208
// ex: take output
209
takeFromFurnace(command[0])
210
break
211
}
212
213
function closeFurnace () {
214
furnace.close()
215
bot.removeListener('chat', onChat)
216
}
217
218
async function putInFurnace (where, name, amount) {
219
const item = itemByName(furnace.items(), name)
220
if (item) {
221
const fn = {
222
input: furnace.putInput,
223
fuel: furnace.putFuel
224
}[where]
225
try {
226
await fn.call(furnace, item.type, null, amount)
227
bot.chat(`put ${amount} ${item.name}`)
228
} catch (err) {
229
bot.chat(`unable to put ${amount} ${item.name}`)
230
}
231
} else {
232
bot.chat(`unknown item ${name}`)
233
}
234
}
235
236
async function takeFromFurnace (what) {
237
const fn = {
238
input: furnace.takeInput,
239
fuel: furnace.takeFuel,
240
output: furnace.takeOutput
241
}[what]
242
try {
243
const item = await fn.call(furnace)
244
bot.chat(`took ${item.name}`)
245
} catch (err) {
246
bot.chat('unable to take')
247
}
248
}
249
}
250
}
251
252
async function watchEnchantmentTable () {
253
const enchantTableBlock = bot.findBlock({
254
matching: ['enchanting_table'].map(name => bot.registry.blocksByName[name].id),
255
maxDistance: 6
256
})
257
if (!enchantTableBlock) {
258
bot.chat('no enchantment table found')
259
return
260
}
261
const table = await bot.openEnchantmentTable(enchantTableBlock)
262
bot.chat(itemToString(table.targetItem()))
263
264
table.on('updateSlot', (slot, oldItem, newItem) => {
265
bot.chat(`enchantment table update: ${itemToString(oldItem)} -> ${itemToString(newItem)} (slot: ${slot})`)
266
})
267
table.on('close', () => {
268
bot.chat('enchantment table closed')
269
})
270
table.on('ready', () => {
271
bot.chat(`ready to enchant. choices are ${table.enchantments.map(o => o.level).join(', ')}`)
272
})
273
274
bot.on('chat', onChat)
275
276
function onChat (username, message) {
277
if (username === bot.username) return
278
const command = message.split(' ')
279
switch (true) {
280
case /^close$/.test(message):
281
closeEnchantmentTable()
282
break
283
case /^put \w+$/.test(message):
284
// put name
285
// ex: put diamondsword
286
putItem(command[1])
287
break
288
case /^add lapis$/.test(message):
289
addLapis()
290
break
291
case /^enchant \d+$/.test(message):
292
// enchant choice
293
// ex: enchant 2
294
enchantItem(command[1])
295
break
296
case /^take$/.test(message):
297
takeEnchantedItem()
298
break
299
}
300
301
function closeEnchantmentTable () {
302
table.close()
303
}
304
305
async function putItem (name) {
306
const item = itemByName(table.window.items(), name)
307
if (item) {
308
try {
309
await table.putTargetItem(item)
310
bot.chat(`I put ${itemToString(item)}`)
311
} catch (err) {
312
bot.chat(`error putting ${itemToString(item)}`)
313
}
314
} else {
315
bot.chat(`unknown item ${name}`)
316
}
317
}
318
319
async function addLapis () {
320
const item = itemByType(table.window.items(), ['dye', 'purple_dye', 'lapis_lazuli'].filter(name => bot.registry.itemByName[name] !== undefined)
321
.map(name => bot.registry.itemByName[name].id))
322
if (item) {
323
try {
324
await table.putLapis(item)
325
bot.chat(`I put ${itemToString(item)}`)
326
} catch (err) {
327
bot.chat(`error putting ${itemToString(item)}`)
328
}
329
} else {
330
bot.chat("I don't have any lapis")
331
}
332
}
333
334
async function enchantItem (choice) {
335
choice = parseInt(choice, 10)
336
try {
337
const item = await table.enchant(choice)
338
bot.chat(`enchanted ${itemToString(item)}`)
339
} catch (err) {
340
bot.chat('error enchanting')
341
}
342
}
343
344
async function takeEnchantedItem () {
345
try {
346
const item = await table.takeTargetItem()
347
bot.chat(`got ${itemToString(item)}`)
348
} catch (err) {
349
bot.chat('error getting item')
350
}
351
}
352
}
353
}
354
355
function useInvsee (username, showEquipment) {
356
bot.once('windowOpen', (window) => {
357
const count = window.containerItems().length
358
const what = showEquipment ? 'equipment' : 'inventory items'
359
if (count) {
360
bot.chat(`${username}'s ${what}:`)
361
sayItems(window.containerItems())
362
} else {
363
bot.chat(`${username} has no ${what}`)
364
}
365
})
366
if (showEquipment) {
367
// any extra parameter triggers the easter egg
368
// and shows the other player's equipment
369
bot.chat(`/invsee ${username} 1`)
370
} else {
371
bot.chat(`/invsee ${username}`)
372
}
373
}
374
375
function itemToString (item) {
376
if (item) {
377
return `${item.name} x ${item.count}`
378
} else {
379
return '(nothing)'
380
}
381
}
382
383
function itemByType (items, type) {
384
let item
385
let i
386
for (i = 0; i < items.length; ++i) {
387
item = items[i]
388
if (item && item.type === type) return item
389
}
390
return null
391
}
392
393
function itemByName (items, name) {
394
let item
395
let i
396
for (i = 0; i < items.length; ++i) {
397
item = items[i]
398
if (item && item.name === name) return item
399
}
400
return null
401
}
402
403