mineflayer 4.6.0 → 4.7.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.
@@ -31,6 +31,8 @@ jobs:
31
31
  mcVersion: '1.18.2'
32
32
  - javaVersion: 17
33
33
  mcVersion: '1.19'
34
+ - javaVersion: 17
35
+ mcVersion: '1.19.2'
34
36
  fail-fast: false
35
37
 
36
38
  steps:
package/README.md CHANGED
@@ -189,8 +189,9 @@ The most updated and useful are :
189
189
  * [Auto Crystal](https://github.com/link-discord/mineflayer-autocrystal) - Automatic placing & breaking of end crystals.
190
190
  * [Tool](https://github.com/TheDudeFromCI/mineflayer-tool) - A utility for automatic tool/weapon selection with a high level API.
191
191
  * [Hawkeye](https://github.com/sefirosweb/minecraftHawkEye) - A utility for using auto-aim with bows.
192
- * [GUI](https://github.com/firejoust/mineflayer-GUI) - Eased navigation & management of nested chest-GUI windows
193
- * [Projectile](https://github.com/firejoust/mineflayer-projectile) - Configurable tool for projectile based combat
192
+ * [GUI](https://github.com/firejoust/mineflayer-GUI) - Interact with nested GUI windows using async/await
193
+ * [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
194
195
 
195
196
 
196
197
  But also check out :
package/docs/README.md CHANGED
@@ -189,8 +189,9 @@ The most updated and useful are :
189
189
  * [Auto Crystal](https://github.com/link-discord/mineflayer-autocrystal) - Automatic placing & breaking of end crystals.
190
190
  * [Tool](https://github.com/TheDudeFromCI/mineflayer-tool) - A utility for automatic tool/weapon selection with a high level API.
191
191
  * [Hawkeye](https://github.com/sefirosweb/minecraftHawkEye) - A utility for using auto-aim with bows.
192
- * [GUI](https://github.com/firejoust/mineflayer-GUI) - Eased navigation & management of nested chest-GUI windows
193
- * [Projectile](https://github.com/firejoust/mineflayer-projectile) - Configurable tool for projectile based combat
192
+ * [GUI](https://github.com/firejoust/mineflayer-GUI) - Interact with nested GUI windows using async/await
193
+ * [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
194
195
 
195
196
 
196
197
  But also check out :
package/docs/api.md CHANGED
@@ -1156,7 +1156,8 @@ Emitted for every server message which appears on the Action Bar.
1156
1156
 
1157
1157
  Emitted for every server message, including chats.
1158
1158
 
1159
- * `jsonMsg` - unmodified JSON message from the server
1159
+ * `jsonMsg` - [ChatMessage](https://github.com/PrismarineJS/prismarine-chat) object containing the formatted chat message. Might additionally have the following properties:
1160
+ * unsigned - Unsigned ChatMessage object. Only present in 1.19.2+, and only when the server allows insecure chat and the server modified the chat message without the user's signature
1160
1161
 
1161
1162
  * `position` - (>= 1.8.1): position of Chat message can be
1162
1163
  * chat
@@ -1169,7 +1170,7 @@ Emitted for every server message, including chats.
1169
1170
 
1170
1171
  #### "messagestr" (message, messagePosition, jsonMsg, sender, verified)
1171
1172
 
1172
- Alias for the "message" event but it calls .toString() on the message object to get a string for the message before emitting.
1173
+ Alias for the "message" event but it calls .toString() on the prismarine-message object to get a string for the message before emitting.
1173
1174
 
1174
1175
  * `sender` - UUID of sender if known (1.16+), else null
1175
1176
 
package/docs/history.md CHANGED
@@ -1,4 +1,8 @@
1
- 4.6.0
1
+ ## 4.7.0
2
+
3
+ * 1.19.2 support (@frej4189)
4
+
5
+ ## 4.6.0
2
6
 
3
7
  * Fix unhandled promise rejection in onceWithCleanup (@IceTank) [#2833](https://github.com/PrismarineJS/mineflayer/pull/2833)
4
8
  * Extend every window that is opened with mineflayer specific window functions (@IceTank) [#2768][https://github.com/PrismarineJS/mineflayer/pull/2768]
@@ -1,57 +1,64 @@
1
1
  /*
2
2
  * This example is a very simple way how to connect a discord bot with a mineflayer bot.
3
3
  * For this example you will need discord.js installed. You can install with: npm install discord.js
4
- * This example uses discord.js v13
4
+ * This example uses discord.js v14
5
5
  * You need to do this before running this example:
6
- * - You need to get a discord token
6
+ * - You need to get a discord bot token
7
7
  * - You need to get the id of the channel you want to use
8
- */
8
+ *
9
+ * Original credit to U9G, updated by Jovan04 12/19/2022
10
+ */
9
11
 
10
12
  if (process.argv.length < 6 || process.argv.length > 8) {
11
- console.log('Usage : node discord.js <discord bot token> <channel id> <host> <port> [<name>] [<password>]')
13
+ console.log('Usage : node discord.js <discord bot token> <channel id> <host> <port> [<name>] [<auth>]')
12
14
  process.exit(1)
13
15
  }
14
16
 
15
- // Load discord.js
16
- const {
17
- Client,
18
- Intents
19
- } = require('discord.js')
20
- // Create Discord intentions, required in v13
21
- const intents = new Intents(['GUILDS', 'GUILD_MESSAGES'])
22
- // Create Discord client
23
- const client = new Client({
24
- intents
25
- })
17
+ // load discord.js
18
+ const { Client, GatewayIntentBits } = require('discord.js')
19
+ const { MessageContent, GuildMessages, Guilds } = GatewayIntentBits
26
20
 
27
21
  let channel = process.argv[3]
22
+ const token = process.argv[2]
23
+
24
+ // create new discord client that can see what servers the bot is in, as well as the messages in those servers
25
+ const client = new Client({ intents: [Guilds, GuildMessages, MessageContent] })
26
+ client.login(token)
28
27
 
29
- // Load mineflayer
28
+ // load mineflayer
30
29
  const mineflayer = require('mineflayer')
31
- const bot = mineflayer.createBot({
30
+
31
+ // bot options
32
+ const options = {
32
33
  host: process.argv[4],
33
34
  port: parseInt(process.argv[5]),
34
35
  username: process.argv[6] || 'discord',
35
- password: process.argv[7]
36
+ auth: process.argv[7] || 'offline'
37
+ }
38
+
39
+ // join server
40
+ const bot = mineflayer.createBot(options)
41
+ bot.on('spawn', () => {
42
+ console.log(`Mineflayer bot logged in as ${bot.username}`)
36
43
  })
37
44
 
38
- client.on('ready', () => {
39
- console.log(`The discord bot logged in! Username: ${client.user.username}!`)
40
- // Find the Discord channel messages will be sent to
45
+ // when discord client is ready, send login message
46
+ client.once('ready', (c) => {
47
+ console.log(`Discord bot logged in as ${c.user.tag}`)
41
48
  channel = client.channels.cache.get(channel)
42
49
  if (!channel) {
43
- console.log(`I could not find the channel (${process.argv[3]})!\nUsage : node discord.js <discord bot token> <channel id> <host> <port> [<name>] [<password>]`)
50
+ console.log(`I could not find the channel (${process.argv[3]})!`)
51
+ console.log('Usage : node discord.js <discord bot token> <channel id> <host> <port> [<name>] [<auth>]')
44
52
  process.exit(1)
45
53
  }
46
54
  })
47
55
 
48
- // Redirect Discord messages to in-game chat
49
- client.on('messageCreate', message => {
56
+ client.on('messageCreate', (message) => {
50
57
  // Only handle messages in specified channel
51
58
  if (message.channel.id !== channel.id) return
52
59
  // Ignore messages from the bot itself
53
60
  if (message.author.id === client.user.id) return
54
-
61
+ // console.log(message)
55
62
  bot.chat(`${message.author.username}: ${message.content}`)
56
63
  })
57
64
 
@@ -62,6 +69,3 @@ bot.on('chat', (username, message) => {
62
69
 
63
70
  channel.send(`${username}: ${message}`)
64
71
  })
65
-
66
- // Login Discord bot
67
- client.login(process.argv[2])
@@ -0,0 +1,43 @@
1
+ /*
2
+ * This example is a very simple way of connecting to a telegram group
3
+ * For this example you'll need Telegraf installed. This can be done with `npm install telegraf`
4
+ * You need to do this before running this example:
5
+ * - You need to get a telegram bot token from @botfather
6
+ * - You need to get the id of the group you want to use
7
+ */
8
+
9
+ if (process.argv.length < 6 || process.argv.length > 8) {
10
+ console.log('Usage : node telegram.js <telegram bot token> <group id> <host> <port> [<name>] [<password>]')
11
+ process.exit(1)
12
+ }
13
+
14
+ // Load Telegraf
15
+ const { Telegraf } = require('telegraf')
16
+ const telegram = new Telegraf(process.argv[2])
17
+
18
+ // Load mineflayer
19
+ const mineflayer = require('mineflayer')
20
+ const bot = mineflayer.createBot({
21
+ host: process.argv[4],
22
+ port: parseInt(process.argv[5]),
23
+ username: process.argv[6] || 'telegram',
24
+ password: process.argv[7]
25
+ })
26
+
27
+ telegram.on('text', async (ctx) => {
28
+ // check if message was reveived from chosen group
29
+ if (ctx.update.message.chat.id.toString() === process.argv[3]) {
30
+ // send message to mc server
31
+ bot.chat(`${ctx.update.message.from.first_name} ${ctx.update.message.from.last_name}: ${ctx.update.message.text}`)
32
+ }
33
+ })
34
+
35
+ // Redirect in-game messages to telegram group
36
+ bot.on('chat', (username, message) => {
37
+ // Ignore messages from the bot itself
38
+ if (username === bot.username) return
39
+ telegram.telegram.sendMessage(process.argv[3], username + ': ' + message)
40
+ })
41
+
42
+ // Login telegram bot
43
+ telegram.launch()
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 { Registry } from 'prismarine-registry'
11
12
 
12
13
  export function createBot (options: { client: Client } & Partial<BotOptions>): Bot
13
14
  export function createBot (options: BotOptions): Bot
@@ -192,6 +193,7 @@ export interface Bot extends TypedEmitter<BotEvents> {
192
193
  currentWindow: Window | null
193
194
  simpleClick: simpleClick
194
195
  tablist: Tablist
196
+ registry: Registry
195
197
 
196
198
  connect: (options: BotOptions) => void
197
199
 
@@ -20,7 +20,7 @@ const dimensionNames = {
20
20
  1: 'minecraft:end'
21
21
  }
22
22
 
23
- function inject (bot, { version, storageBuilder }) {
23
+ function inject (bot, { version, storageBuilder, hideErrors }) {
24
24
  const Block = require('prismarine-block')(bot.registry)
25
25
  const Chunk = require('prismarine-chunk')(bot.registry)
26
26
  const World = require('prismarine-world')(bot.registry)
@@ -289,6 +289,10 @@ function inject (bot, { version, storageBuilder }) {
289
289
 
290
290
  if (typeof packet.blockEntities !== 'undefined') {
291
291
  const column = bot.world.getColumn(packet.x, packet.z)
292
+ if (!column) {
293
+ if (!hideErrors) console.warn('Ignoring block entities as chunk failed to load at', packet.x, packet.z)
294
+ return
295
+ }
292
296
  for (const blockEntity of packet.blockEntities) {
293
297
  if (blockEntity.x !== undefined) { // 1.17+
294
298
  column.setBlockEntity(blockEntity, blockEntity.nbtData)
@@ -108,43 +108,49 @@ function inject (bot, options) {
108
108
 
109
109
  addDefaultPatterns()
110
110
 
111
- // Pre 1.19
112
- bot._client.on('chat', (packet) => {
113
- const msg = ChatMessage.fromNotch(packet.message)
114
- const chatPositions = {
115
- 0: 'chat',
116
- 1: 'system',
117
- 2: 'game_info'
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
- })
111
+ bot._client.on('playerChat', (data) => {
112
+ const message = data.formattedMessage
113
+ const verified = data.verified
114
+ let msg
115
+ if (bot.supportFeature('clientsideChatFormatting')) {
116
+ let sender
117
+
118
+ try {
119
+ sender = JSON.parse(data.senderName)
120
+ } catch {
121
+ sender = {
122
+ insertion: data.senderName,
123
+ clickEvent: { action: 'suggest_command', value: `/tell ${data.senderName} ` },
124
+ hoverEvent: { action: 'show_entity', contents: { id: bot.findPlayer(data.senderName).id, name: data.senderName } },
125
+ text: data.senderName
126
+ }
127
+ }
124
128
 
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)
129
+ const parameters = {
130
+ sender,
131
+ content: message ? JSON.parse(message) : { text: data.plainMessage }
132
+ }
133
+ msg = ChatMessage.fromNetwork(data.type, parameters)
134
+
135
+ if (data.unsignedContent) {
136
+ msg.unsigned = ChatMessage.fromNetwork(data.type, { sender, content: JSON.parse(data.unsignedContent) })
137
+ }
138
+ } else {
139
+ msg = ChatMessage.fromNotch(data.formattedMessage)
137
140
  }
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)
141
+ bot.emit('message', msg, 'chat', data.sender, verified)
142
+ bot.emit('messagestr', msg.toString(), 'chat', msg, data.sender, verified)
142
143
  })
143
144
 
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)
145
+ bot._client.on('systemChat', (data) => {
146
+ const msg = ChatMessage.fromNotch(data.formattedMessage)
147
+ const chatPositions = {
148
+ 1: 'system',
149
+ 2: 'game_info'
150
+ }
151
+ bot.emit('message', msg, chatPositions[data.positionid], null)
152
+ bot.emit('messagestr', msg.toString(), chatPositions[data.positionid], msg, null)
153
+ if (data.positionid === 2) bot.emit('actionBar', msg, null)
148
154
  })
149
155
 
150
156
  function chatWithHeader (header, message) {
@@ -163,7 +169,9 @@ function inject (bot, options) {
163
169
  timestamp,
164
170
  salt: 0n,
165
171
  argumentSignatures: [],
166
- signedPreview: false
172
+ signedPreview: false,
173
+ // 1.19.2 Chat Command packet also includes an array of last seen messages
174
+ previousMessages: []
167
175
  })
168
176
  return
169
177
  }
@@ -176,17 +184,7 @@ function inject (bot, options) {
176
184
  let smallMsg
177
185
  for (i = 0; i < subMessage.length; i += lengthLimit) {
178
186
  smallMsg = header + subMessage.substring(i, i + lengthLimit)
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
- }
187
+ bot._client.chat(smallMsg)
190
188
  }
191
189
  })
192
190
  }
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']
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']
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.6.0",
3
+ "version": "4.7.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.15.2",
25
- "minecraft-protocol": "^1.36.0",
25
+ "minecraft-protocol": "^1.38.1",
26
26
  "prismarine-biome": "^1.1.1",
27
27
  "prismarine-block": "^1.13.1",
28
28
  "prismarine-chat": "^1.7.1",