Skip to content

Commit 9fe09d6

Browse files
committed
Merge branch 'next' into release
2 parents 0fba636 + 3877d83 commit 9fe09d6

16 files changed

Lines changed: 379 additions & 253 deletions

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@
198198
"pnpm": {
199199
"overrides": {
200200
"mineflayer": "github:zardoy/mineflayer#gen-the-master",
201-
"@nxg-org/mineflayer-physics-util": "1.8.10",
201+
"@nxg-org/mineflayer-physics-util": "1.8.19",
202202
"buffer": "^6.0.3",
203203
"vec3": "0.1.10",
204204
"three": "0.154.0",
@@ -222,8 +222,7 @@
222222
"patchedDependencies": {
223223
"pixelarticons@1.8.1": "patches/pixelarticons@1.8.1.patch",
224224
"mineflayer-item-map-downloader@1.2.0": "patches/mineflayer-item-map-downloader@1.2.0.patch",
225-
"minecraft-protocol": "patches/minecraft-protocol.patch",
226-
"@nxg-org/mineflayer-physics-util": "patches/@nxg-org__mineflayer-physics-util.patch"
225+
"minecraft-protocol": "patches/minecraft-protocol.patch"
227226
},
228227
"ignoredBuiltDependencies": [
229228
"canvas",

patches/@nxg-org__mineflayer-physics-util.patch

Lines changed: 0 additions & 13 deletions
This file was deleted.

patches/minecraft-protocol.patch

Lines changed: 154 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,92 @@
1+
diff --git a/src/client.js b/src/client.js
2+
index e369e77..f6c408d 100644
3+
--- a/src/client.js
4+
+++ b/src/client.js
5+
@@ -75,7 +75,35 @@ class Client extends EventEmitter {
6+
}
7+
const deserializerDirection = this.isServer ? 'toServer' : 'toClient'
8+
e.field = [this.protocolState, deserializerDirection].concat(parts).join('.')
9+
- e.message = e.buffer ? `Parse error for ${e.field} (${e.buffer?.length} bytes, ${e.buffer?.toString('hex').slice(0, 6)}...) : ${e.message}` : `Parse error for ${e.field}: ${e.message}`
10+
+ e.message = e.buffer
11+
+ ? `Parse error for ${e.field} (${e.buffer?.length} bytes, ${e.buffer?.toString('hex').slice(0, 6)}...) : ${e.message}`
12+
+ : `Parse error for ${e.field}: ${e.message}`
13+
+
14+
+ // Non-fatal play-state parse error — e.g. Hypixel sending NBT tag IDs outside
15+
+ // the standard 0-20 range (tag 71 = custom component data introduced in 1.21.4+).
16+
+ // The deserializer stream is destroyed by Node.js on error, so we tear it down
17+
+ // fully, rebuild it via setSerializer, and re-pipe it into the chain so packet
18+
+ // processing continues normally. We emit 'warning' instead of 'error' so nothing
19+
+ // upstream treats this as a fatal connection failure.
20+
+ if (this.protocolState === states.PLAY) {
21+
+ console.warn(`[minecraft-protocol] Non-fatal parse error (connection kept alive): ${e.message}`)
22+
+ this.deserializer.removeAllListeners()
23+
+ if (!this.compressor) {
24+
+ this.splitter.unpipe(this.deserializer)
25+
+ } else {
26+
+ this.decompressor.unpipe(this.deserializer)
27+
+ }
28+
+ this.setSerializer(states.PLAY)
29+
+ if (!this.compressor) {
30+
+ this.splitter.pipe(this.deserializer)
31+
+ } else {
32+
+ this.decompressor.pipe(this.deserializer)
33+
+ }
34+
+ this.emit('warning', e)
35+
+ return
36+
+ }
37+
+
38+
+ // All other parse errors are still fatal — re-pipe attempt then propagate.
39+
if (!this.compressor) { this.splitter.pipe(this.deserializer) } else { this.decompressor.pipe(this.deserializer) }
40+
this.emit('error', e)
41+
})
42+
@@ -111,7 +139,13 @@ class Client extends EventEmitter {
43+
this._hasBundlePacket = false
44+
}
45+
} else {
46+
- emitPacket(parsed)
47+
+ try {
48+
+ emitPacket(parsed)
49+
+ } catch (err) {
50+
+ console.log('Client incorrectly handled packet ' + parsed.metadata.name)
51+
+ console.error(err)
52+
+ // todo investigate why it doesn't close the stream even if unhandled there
53+
+ }
54+
}
55+
})
56+
}
57+
@@ -169,7 +203,10 @@ class Client extends EventEmitter {
58+
}
59+
60+
const onFatalError = (err) => {
61+
- this.emit('error', err)
62+
+ // todo find out what is trying to write after client disconnect
63+
+ if(err.code !== 'ECONNABORTED') {
64+
+ this.emit('error', err)
65+
+ }
66+
endSocket()
67+
}
68+
69+
@@ -198,6 +235,10 @@ class Client extends EventEmitter {
70+
serializer -> framer -> socket -> splitter -> deserializer */
71+
if (this.serializer) {
72+
this.serializer.end()
73+
+ setTimeout(() => {
74+
+ this.socket?.end()
75+
+ this.socket?.emit('end')
76+
+ }, 2000) // allow the serializer to finish writing
77+
} else {
78+
if (this.socket) this.socket.end()
79+
}
80+
@@ -243,6 +284,7 @@ class Client extends EventEmitter {
81+
debug('writing packet ' + this.state + '.' + name)
82+
debug(params)
83+
}
84+
+ this.emit('writePacket', name, params)
85+
this.serializer.write({ name, params })
86+
}
87+
188
diff --git a/src/client/chat.js b/src/client/chat.js
2-
index 0021870994fc59a82f0ac8aba0a65a8be43ef2f4..a53fceb843105ea2a1d88722b3fc7c3b43cb102a 100644
89+
index 0021870..a53fceb 100644
390
--- a/src/client/chat.js
491
+++ b/src/client/chat.js
592
@@ -116,7 +116,7 @@ module.exports = function (client, options) {
@@ -57,7 +144,7 @@ index 0021870994fc59a82f0ac8aba0a65a8be43ef2f4..a53fceb843105ea2a1d88722b3fc7c3b
57144
previousMessages: client._lastSeenMessages.map((e) => ({
58145
messageSender: e.sender,
59146
diff --git a/src/client/encrypt.js b/src/client/encrypt.js
60-
index 63cc2bd9615100bd2fd63dfe14c094aa6b8cd1c9..36df57d1196af9761d920fa285ac48f85410eaef 100644
147+
index 63cc2bd..36df57d 100644
61148
--- a/src/client/encrypt.js
62149
+++ b/src/client/encrypt.js
63150
@@ -25,7 +25,11 @@ module.exports = function (client, options) {
@@ -73,8 +160,72 @@ index 63cc2bd9615100bd2fd63dfe14c094aa6b8cd1c9..36df57d1196af9761d920fa285ac48f8
73160
}
74161

75162
function onJoinServerResponse (err) {
163+
diff --git a/src/client/play.js b/src/client/play.js
164+
index 71ad739..7130b22 100644
165+
--- a/src/client/play.js
166+
+++ b/src/client/play.js
167+
@@ -31,11 +31,37 @@ module.exports = function (client, options) {
168+
169+
client.once('success', onLogin)
170+
171+
+ function pickLocale () {
172+
+ const locales = [
173+
+ ['en_US', 0.60],
174+
+ ['en_GB', 0.10],
175+
+ ['de_DE', 0.12],
176+
+ ['id_ID', 0.10],
177+
+ ['fr_FR', 0.04],
178+
+ ['es_ES', 0.04]
179+
+ ]
180+
+ const roll = Math.random()
181+
+ let cumulative = 0
182+
+ for (const [locale, weight] of locales) {
183+
+ cumulative += weight
184+
+ if (roll < cumulative) return locale
185+
+ }
186+
+ return 'en_US'
187+
+ }
188+
+
189+
function onLogin (packet) {
190+
const mcData = require('minecraft-data')(client.version)
191+
client.uuid = packet.uuid
192+
client.username = packet.username
193+
194+
+ const resolvedProfile = {
195+
+ locale: options.clientProfile?.locale ?? pickLocale(),
196+
+ viewDistance: options.clientProfile?.viewDistance ?? 10,
197+
+ mainHand: options.clientProfile?.mainHand !== undefined
198+
+ ? options.clientProfile.mainHand
199+
+ : (Math.random() < 0.75 ? 1 : 0)
200+
+ }
201+
+
202+
if (mcData.supportFeature('hasConfigurationState')) {
203+
client.write('login_acknowledged', {})
204+
enterConfigState(onReady)
205+
@@ -53,6 +79,21 @@ module.exports = function (client, options) {
206+
client.write('configuration_acknowledged', {})
207+
}
208+
client.state = states.CONFIGURATION
209+
+
210+
+ // Send client information immediately on entering config phase.
211+
+ // Some servers *cough cough hypixel* require this before they will proceed past
212+
+ // configuration state. Without it, you get the socketClosed error.
213+
+ client.write('settings', {
214+
+ locale: resolvedProfile.locale,
215+
+ viewDistance: resolvedProfile.viewDistance,
216+
+ chatFlags: 0,
217+
+ chatColors: true,
218+
+ skinParts: 127,
219+
+ mainHand: resolvedProfile.mainHand,
220+
+ enableTextFiltering: false,
221+
+ enableServerListing: true
222+
+ })
223+
+
224+
client.once('select_known_packs', () => {
225+
client.write('select_known_packs', { packs: [] })
226+
})
76227
diff --git a/src/client/pluginChannels.js b/src/client/pluginChannels.js
77-
index 671eb452f31e6b5fcd57d715f1009d010160c65f..7f69f511c8fb97d431ec5125c851b49be8e2ab76 100644
228+
index 671eb45..7f69f51 100644
78229
--- a/src/client/pluginChannels.js
79230
+++ b/src/client/pluginChannels.js
80231
@@ -57,7 +57,7 @@ module.exports = function (client, options) {
@@ -86,53 +237,3 @@ index 671eb452f31e6b5fcd57d715f1009d010160c65f..7f69f511c8fb97d431ec5125c851b49b
86237
return
87238
}
88239
}
89-
diff --git a/src/client.js b/src/client.js
90-
index e369e77d055ba919e8f9da7b8e8b5dc879c74cf4..54bb9e6644388e9b6bd42b3012951875989cdf0c 100644
91-
--- a/src/client.js
92-
+++ b/src/client.js
93-
@@ -111,7 +111,13 @@ class Client extends EventEmitter {
94-
this._hasBundlePacket = false
95-
}
96-
} else {
97-
- emitPacket(parsed)
98-
+ try {
99-
+ emitPacket(parsed)
100-
+ } catch (err) {
101-
+ console.log('Client incorrectly handled packet ' + parsed.metadata.name)
102-
+ console.error(err)
103-
+ // todo investigate why it doesn't close the stream even if unhandled there
104-
+ }
105-
}
106-
})
107-
}
108-
@@ -169,7 +175,10 @@ class Client extends EventEmitter {
109-
}
110-
111-
const onFatalError = (err) => {
112-
- this.emit('error', err)
113-
+ // todo find out what is trying to write after client disconnect
114-
+ if(err.code !== 'ECONNABORTED') {
115-
+ this.emit('error', err)
116-
+ }
117-
endSocket()
118-
}
119-
120-
@@ -198,6 +207,10 @@ class Client extends EventEmitter {
121-
serializer -> framer -> socket -> splitter -> deserializer */
122-
if (this.serializer) {
123-
this.serializer.end()
124-
+ setTimeout(() => {
125-
+ this.socket?.end()
126-
+ this.socket?.emit('end')
127-
+ }, 2000) // allow the serializer to finish writing
128-
} else {
129-
if (this.socket) this.socket.end()
130-
}
131-
@@ -243,6 +256,7 @@ class Client extends EventEmitter {
132-
debug('writing packet ' + this.state + '.' + name)
133-
debug(params)
134-
}
135-
+ this.emit('writePacket', name, params)
136-
this.serializer.write({ name, params })
137-
}
138-

0 commit comments

Comments
 (0)