Compare commits
25 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa6acab0f3 |
||
|
|
b48518a6e7 |
||
|
|
407756b938 |
||
|
|
0b9c49fedc |
||
|
|
6b1474d2c6 |
||
|
|
6c659feb5d |
||
|
|
06fb3de3a0 |
||
|
|
6f06a8996e |
||
|
|
14daa2d95a |
||
|
|
80751d58a7 |
||
|
|
c66cdd3d62 |
||
|
|
e503c47c79 |
||
|
|
29ba39343a |
||
|
|
e71fd513dd |
||
|
|
b6b0bcdd70 |
||
|
|
d88309507d |
||
|
|
065f41db8c |
||
|
|
9f11f21991 |
||
|
|
47f342ca95 |
||
|
|
328785d8af |
||
|
|
d4a9faf153 |
||
|
|
eeb5e47e35 |
||
|
|
2d7d32dfd1 |
||
|
|
0ed8e32be8 |
||
|
|
75fa085e86 |
16 changed files with 106 additions and 42 deletions
29
HISTORY.md
29
HISTORY.md
|
|
@ -1,3 +1,32 @@
|
||||||
|
## 3.49.0
|
||||||
|
* [1.21.111 (#649)](https://github.com/PrismarineJS/bedrock-protocol/commit/b48518a6e79e72101fe7136433cbd6277339fc5c) (thanks @Slauh)
|
||||||
|
* [Skin Data Changes (#647)](https://github.com/PrismarineJS/bedrock-protocol/commit/407756b93880cdda4fdbff194fc4163ceedf4e82) (thanks @thejfkvis)
|
||||||
|
|
||||||
|
## 3.48.1
|
||||||
|
* [Update login client skinData (#635)](https://github.com/PrismarineJS/bedrock-protocol/commit/6b1474d2c6f93b47dee9d4816de59579f82ed5a9) (thanks @TSL534)
|
||||||
|
|
||||||
|
## 3.48.0
|
||||||
|
* [1.21.100 (#632)](https://github.com/PrismarineJS/bedrock-protocol/commit/06fb3de3a0023d03201dbcee7e9178c269462766) (thanks @extremeheat)
|
||||||
|
|
||||||
|
## 3.47.0
|
||||||
|
* [1.21.93 support (#623)](https://github.com/PrismarineJS/bedrock-protocol/commit/14daa2d95aac90ffcc7b42d625e270020ec2f162) (thanks @CreeperG16)
|
||||||
|
|
||||||
|
## 3.46.0
|
||||||
|
* [1.21.90 support (#617)](https://github.com/PrismarineJS/bedrock-protocol/commit/c66cdd3d62d2fa9c581693d8c70d7b41f355b63e) (thanks @CreeperG16)
|
||||||
|
|
||||||
|
## 3.45.0
|
||||||
|
* [1.21.80 (#602)](https://github.com/PrismarineJS/bedrock-protocol/commit/e71fd513ddbd432983f221980080b61e11576965) (thanks @extremeheat)
|
||||||
|
|
||||||
|
## 3.44.0
|
||||||
|
* [1.21.70 (#594)](https://github.com/PrismarineJS/bedrock-protocol/commit/065f41db8cfc8cbd8106bd9e376c899ec25f3f77) (thanks @CreeperG16)
|
||||||
|
|
||||||
|
## 3.43.1
|
||||||
|
* [Fix server not correctly removing clients (#588)](https://github.com/PrismarineJS/bedrock-protocol/commit/47f342ca958ba87a7719783bd5c855cebdd4aa65) (thanks @EntifiedOptics)
|
||||||
|
|
||||||
|
## 3.43.0
|
||||||
|
* [1.21.60 support (#570)](https://github.com/PrismarineJS/bedrock-protocol/commit/eeb5e47e35f31cc571a9a8a491f5a89b27e637f1) (thanks @CreeperG16)
|
||||||
|
* [Fix version feature handling (#572)](https://github.com/PrismarineJS/bedrock-protocol/commit/0ed8e32be85f05926cd97d5f0317ed004ae5eefa) (thanks @ItsMax123)
|
||||||
|
|
||||||
## 3.42.3
|
## 3.42.3
|
||||||
* [Fix Server `maxPlayers` option (#565)](https://github.com/PrismarineJS/bedrock-protocol/commit/38dc5a256105a44786d5455570d5a130e64ef561) (thanks @extremeheat)
|
* [Fix Server `maxPlayers` option (#565)](https://github.com/PrismarineJS/bedrock-protocol/commit/38dc5a256105a44786d5455570d5a130e64ef561) (thanks @extremeheat)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ Minecraft Bedrock Edition (aka MCPE) protocol library, supporting authentication
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Supports Minecraft Bedrock version 1.16.201, 1.16.210, 1.16.220, 1.17.0, 1.17.10, 1.17.30, 1.17.40, 1.18.0, 1.18.11, 1.18.30, 1.19.1, 1.19.10, 1.19.20, 1.19.21, 1.19.30, 1.19.40, 1.19.41, 1.19.50, 1.19.60, 1.19.62, 1.19.63, 1.19.70, 1.19.80, 1.20.0, 1.20.10, 1.20.30, 1.20.40, 1.20.50, 1.20.61, 1.20.71, 1.20.80, 1.21.0, 1.21.2, 1.21.21, 1.21.30, 1.21.42, 1.21.50
|
- Supports Minecraft Bedrock version 1.16.201, 1.16.210, 1.16.220, 1.17.0, 1.17.10, 1.17.30, 1.17.40, 1.18.0, 1.18.11, 1.18.30, 1.19.1, 1.19.10, 1.19.20, 1.19.21, 1.19.30, 1.19.40, 1.19.41, 1.19.50, 1.19.60, 1.19.62, 1.19.63, 1.19.70, 1.19.80, 1.20.0, 1.20.10, 1.20.30, 1.20.40, 1.20.50, 1.20.61, 1.20.71, 1.20.80, 1.21.0, 1.21.2, 1.21.21, 1.21.30, 1.21.42, 1.21.50, 1.21.60, 1.21.70, 1.21.80, 1.21.90, 1.21.93, 1.21.100, 1.21.111
|
||||||
- Parse and serialize packets as JavaScript objects
|
- Parse and serialize packets as JavaScript objects
|
||||||
- Automatically respond to keep-alive packets
|
- Automatically respond to keep-alive packets
|
||||||
- [Proxy and mitm connections](docs/API.md#proxy-docs)
|
- [Proxy and mitm connections](docs/API.md#proxy-docs)
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ client.on('text', (packet) => {
|
||||||
// names and as explained in the "Protocol doc" section below, fields are all case sensitive!
|
// names and as explained in the "Protocol doc" section below, fields are all case sensitive!
|
||||||
client.on('add_player', (packet) => {
|
client.on('add_player', (packet) => {
|
||||||
client.queue('text', {
|
client.queue('text', {
|
||||||
type: 'chat', needs_translation: false, source_name: client.username, xuid: '', platform_chat_id: '',
|
type: 'chat', needs_translation: false, source_name: client.username, xuid: '', platform_chat_id: '', filtered_message: '',
|
||||||
message: `Hey, ${packet.username} just joined!`
|
message: `Hey, ${packet.username} just joined!`
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
2
index.d.ts
vendored
2
index.d.ts
vendored
|
|
@ -3,7 +3,7 @@ import { Realm } from 'prismarine-realms'
|
||||||
import { ServerDeviceCodeResponse } from 'prismarine-auth'
|
import { ServerDeviceCodeResponse } from 'prismarine-auth'
|
||||||
|
|
||||||
declare module 'bedrock-protocol' {
|
declare module 'bedrock-protocol' {
|
||||||
type Version = '1.21.42' | '1.21.30' | '1.21.2' | '1.21.0' | '1.20.80' | '1.20.71' | '1.20.61' | '1.20.50' | '1.20.40' | '1.20.30' | '1.20.10' | '1.20.0' | '1.19.80' | '1.19.70' | '1.19.63' | '1.19.62' | '1.19.60' | '1.19.51' | '1.19.50' | '1.19.41' | '1.19.40' | '1.19.31' | '1.19.30' | '1.19.22' | '1.19.21' | '1.19.20' | '1.19.11' | '1.19.10' | '1.19.2' | '1.19.1' | '1.18.31' | '1.18.30' | '1.18.12' | '1.18.11' | '1.18.10' | '1.18.2' | '1.18.1' | '1.18.0' | '1.17.41' | '1.17.40' | '1.17.34' | '1.17.30' | '1.17.11' | '1.17.10' | '1.17.0' | '1.16.220' | '1.16.210' | '1.16.201'
|
type Version = '1.21.93' | '1.21.90' | '1.21.80' | '1.21.70' | '1.21.60' | '1.21.50' | '1.21.42' | '1.21.30' | '1.21.2' | '1.21.0' | '1.20.80' | '1.20.71' | '1.20.61' | '1.20.50' | '1.20.40' | '1.20.30' | '1.20.10' | '1.20.0' | '1.19.80' | '1.19.70' | '1.19.63' | '1.19.62' | '1.19.60' | '1.19.51' | '1.19.50' | '1.19.41' | '1.19.40' | '1.19.31' | '1.19.30' | '1.19.22' | '1.19.21' | '1.19.20' | '1.19.11' | '1.19.10' | '1.19.2' | '1.19.1' | '1.18.31' | '1.18.30' | '1.18.12' | '1.18.11' | '1.18.10' | '1.18.2' | '1.18.1' | '1.18.0' | '1.17.41' | '1.17.40' | '1.17.34' | '1.17.30' | '1.17.11' | '1.17.10' | '1.17.0' | '1.16.220' | '1.16.210' | '1.16.201'
|
||||||
|
|
||||||
export interface Options {
|
export interface Options {
|
||||||
// The string version to start the client or server as
|
// The string version to start the client or server as
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "bedrock-protocol",
|
"name": "bedrock-protocol",
|
||||||
"version": "3.42.3",
|
"version": "3.49.0",
|
||||||
"description": "Minecraft Bedrock Edition protocol library",
|
"description": "Minecraft Bedrock Edition protocol library",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"types": "index.d.ts",
|
"types": "index.d.ts",
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,9 @@ class Client extends Connection {
|
||||||
try {
|
try {
|
||||||
const mcData = require('minecraft-data')('bedrock_' + this.options.version)
|
const mcData = require('minecraft-data')('bedrock_' + this.options.version)
|
||||||
this.features = {
|
this.features = {
|
||||||
compressorInHeader: mcData.supportFeature('compressorInPacketHeader')
|
compressorInHeader: mcData.supportFeature('compressorInPacketHeader'),
|
||||||
|
itemRegistryPacket: mcData.supportFeature('itemRegistryPacket'),
|
||||||
|
newLoginIdentityFields: mcData.supportFeature('newLoginIdentityFields')
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`Unsupported version: '${this.options.version}', no data available`)
|
throw new Error(`Unsupported version: '${this.options.version}', no data available`)
|
||||||
|
|
@ -145,9 +147,18 @@ class Client extends Connection {
|
||||||
...this.accessToken // Mojang + Xbox JWT from auth
|
...this.accessToken // Mojang + Xbox JWT from auth
|
||||||
]
|
]
|
||||||
|
|
||||||
const encodedChain = JSON.stringify({ chain })
|
let encodedChain
|
||||||
|
if (this.features.newLoginIdentityFields) { // 1.21.90+
|
||||||
debug('Auth chain', chain)
|
encodedChain = JSON.stringify({
|
||||||
|
Certificate: JSON.stringify({ chain }),
|
||||||
|
// 0 = normal, 1 = ss, 2 = offline
|
||||||
|
AuthenticationType: this.options.offline ? 2 : 0,
|
||||||
|
Token: ''
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
encodedChain = JSON.stringify({ chain })
|
||||||
|
}
|
||||||
|
debug('Auth chain', encodedChain)
|
||||||
|
|
||||||
this.write('login', {
|
this.write('login', {
|
||||||
protocol_version: this.options.protocolVersion,
|
protocol_version: this.options.protocolVersion,
|
||||||
|
|
@ -241,7 +252,9 @@ class Client extends Connection {
|
||||||
break
|
break
|
||||||
case 'start_game':
|
case 'start_game':
|
||||||
this.startGameData = pakData.params
|
this.startGameData = pakData.params
|
||||||
this.startGameData.itemstates.forEach(state => {
|
// fallsthrough
|
||||||
|
case 'item_registry': // 1.21.60+ send itemstates in item_registry packet
|
||||||
|
pakData.params.itemstates?.forEach(state => {
|
||||||
if (state.name === 'minecraft:shield') {
|
if (state.name === 'minecraft:shield') {
|
||||||
this.serializer.proto.setVariable('ShieldItemID', state.runtime_id)
|
this.serializer.proto.setVariable('ShieldItemID', state.runtime_id)
|
||||||
this.deserializer.proto.setVariable('ShieldItemID', state.runtime_id)
|
this.deserializer.proto.setVariable('ShieldItemID', state.runtime_id)
|
||||||
|
|
|
||||||
|
|
@ -28,18 +28,22 @@ class Connection extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
versionLessThan (version) {
|
versionLessThan (version) {
|
||||||
|
if (typeof version === 'string' && !Versions[version]) throw Error('Unknown version: ' + version)
|
||||||
return this.options.protocolVersion < (typeof version === 'string' ? Versions[version] : version)
|
return this.options.protocolVersion < (typeof version === 'string' ? Versions[version] : version)
|
||||||
}
|
}
|
||||||
|
|
||||||
versionGreaterThan (version) {
|
versionGreaterThan (version) {
|
||||||
|
if (typeof version === 'string' && !Versions[version]) throw Error('Unknown version: ' + version)
|
||||||
return this.options.protocolVersion > (typeof version === 'string' ? Versions[version] : version)
|
return this.options.protocolVersion > (typeof version === 'string' ? Versions[version] : version)
|
||||||
}
|
}
|
||||||
|
|
||||||
versionGreaterThanOrEqualTo (version) {
|
versionGreaterThanOrEqualTo (version) {
|
||||||
|
if (typeof version === 'string' && !Versions[version]) throw Error('Unknown version: ' + version)
|
||||||
return this.options.protocolVersion >= (typeof version === 'string' ? Versions[version] : version)
|
return this.options.protocolVersion >= (typeof version === 'string' ? Versions[version] : version)
|
||||||
}
|
}
|
||||||
|
|
||||||
versionLessThanOrEqualTo (version) {
|
versionLessThanOrEqualTo (version) {
|
||||||
|
if (typeof version === 'string' && !Versions[version]) throw Error('Unknown version: ' + version)
|
||||||
return this.options.protocolVersion <= (typeof version === 'string' ? Versions[version] : version)
|
return this.options.protocolVersion <= (typeof version === 'string' ? Versions[version] : version)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,9 +70,17 @@ class Connection extends EventEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_processOutbound (name, params) {
|
||||||
|
if (name === 'item_registry') {
|
||||||
|
this.updateItemPalette(params.itemstates)
|
||||||
|
} else if (name === 'start_game' && params.itemstates) {
|
||||||
|
this.updateItemPalette(params.itemstates)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
write (name, params) {
|
write (name, params) {
|
||||||
this.outLog?.(name, params)
|
this.outLog?.(name, params)
|
||||||
if (name === 'start_game') this.updateItemPalette(params.itemstates)
|
this._processOutbound(name, params)
|
||||||
const batch = new Framer(this)
|
const batch = new Framer(this)
|
||||||
const packet = this.serializer.createPacketBuffer({ name, params })
|
const packet = this.serializer.createPacketBuffer({ name, params })
|
||||||
batch.addEncodedPacket(packet)
|
batch.addEncodedPacket(packet)
|
||||||
|
|
@ -82,7 +94,7 @@ class Connection extends EventEmitter {
|
||||||
|
|
||||||
queue (name, params) {
|
queue (name, params) {
|
||||||
this.outLog?.('Q <- ', name, params)
|
this.outLog?.('Q <- ', name, params)
|
||||||
if (name === 'start_game') this.updateItemPalette(params.itemstates)
|
this._processOutbound(name, params)
|
||||||
const packet = this.serializer.createPacketBuffer({ name, params })
|
const packet = this.serializer.createPacketBuffer({ name, params })
|
||||||
if (name === 'level_chunk') {
|
if (name === 'level_chunk') {
|
||||||
// Skip queue, send ASAP
|
// Skip queue, send ASAP
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ module.exports = (client, server, options) => {
|
||||||
client.createClientUserChain = (privateKey) => {
|
client.createClientUserChain = (privateKey) => {
|
||||||
let payload = {
|
let payload = {
|
||||||
...skinData,
|
...skinData,
|
||||||
SkinGeometryDataEngineVersion: client.versionGreaterThanOrEqualTo('1.17.30') ? '' : undefined,
|
|
||||||
|
|
||||||
ClientRandomId: Date.now(),
|
ClientRandomId: Date.now(),
|
||||||
CurrentInputMode: 1,
|
CurrentInputMode: 1,
|
||||||
|
|
@ -47,19 +46,20 @@ module.exports = (client, server, options) => {
|
||||||
GameVersion: options.version || '1.16.201',
|
GameVersion: options.version || '1.16.201',
|
||||||
GuiScale: -1,
|
GuiScale: -1,
|
||||||
LanguageCode: 'en_GB', // TODO locale
|
LanguageCode: 'en_GB', // TODO locale
|
||||||
|
GraphicsMode: 1, // 1:simple, 2:fancy, 3:advanced, 4:ray_traced
|
||||||
|
|
||||||
PlatformOfflineId: '',
|
PlatformOfflineId: '',
|
||||||
PlatformOnlineId: '', // chat
|
PlatformOnlineId: '', // chat
|
||||||
// PlayFabID is the PlayFab ID produced for the skin. PlayFab is the company that hosts the Marketplace,
|
// PlayFabID is the PlayFab ID produced for the skin. PlayFab is the company that hosts the Marketplace,
|
||||||
// skins and other related features from the game. This ID is the ID of the skin used to store the skin
|
// skins and other related features from the game. This ID is the ID of the skin used to store the skin
|
||||||
// inside of PlayFab.
|
// inside of PlayFab.The playfab ID is always lowercased.
|
||||||
PlayFabId: nextUUID().replace(/-/g, '').slice(0, 16), // 1.16.210
|
PlayFabId: nextUUID().replace(/-/g, '').slice(0, 16).toLowerCase(), // 1.16.210
|
||||||
|
|
||||||
SelfSignedId: nextUUID(),
|
SelfSignedId: nextUUID(),
|
||||||
ServerAddress: `${options.host}:${options.port}`,
|
ServerAddress: `${options.host}:${options.port}`,
|
||||||
|
|
||||||
ThirdPartyName: client.profile.name,
|
ThirdPartyName: client.profile.name, // Gamertag
|
||||||
ThirdPartyNameOnly: false,
|
ThirdPartyNameOnly: client.versionGreaterThanOrEqualTo('1.21.90') ? undefined : false,
|
||||||
UIProfile: 0,
|
UIProfile: 0,
|
||||||
|
|
||||||
IsEditorMode: false,
|
IsEditorMode: false,
|
||||||
|
|
@ -67,9 +67,9 @@ module.exports = (client, server, options) => {
|
||||||
OverrideSkin: client.versionGreaterThanOrEqualTo('1.19.62') ? false : undefined,
|
OverrideSkin: client.versionGreaterThanOrEqualTo('1.19.62') ? false : undefined,
|
||||||
CompatibleWithClientSideChunkGen: client.versionGreaterThanOrEqualTo('1.19.80') ? false : undefined,
|
CompatibleWithClientSideChunkGen: client.versionGreaterThanOrEqualTo('1.19.80') ? false : undefined,
|
||||||
|
|
||||||
MaxViewDistance: client.versionGreaterThanOrEqualTo('1.21.40') ? 0 : undefined,
|
MaxViewDistance: client.versionGreaterThanOrEqualTo('1.21.42') ? 0 : undefined,
|
||||||
MemoryTier: client.versionGreaterThanOrEqualTo('1.21.40') ? 0 : undefined,
|
MemoryTier: client.versionGreaterThanOrEqualTo('1.21.42') ? 0 : undefined,
|
||||||
PlatformType: client.versionGreaterThanOrEqualTo('1.21.40') ? 0 : undefined
|
PlatformType: client.versionGreaterThanOrEqualTo('1.21.42') ? 0 : undefined
|
||||||
}
|
}
|
||||||
const customPayload = options.skinData || {}
|
const customPayload = options.skinData || {}
|
||||||
payload = { ...payload, ...customPayload }
|
payload = { ...payload, ...customPayload }
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@ const mcData = require('minecraft-data')
|
||||||
// Minimum supported version (< will be kicked)
|
// Minimum supported version (< will be kicked)
|
||||||
const MIN_VERSION = '1.16.201'
|
const MIN_VERSION = '1.16.201'
|
||||||
// Currently supported verson. Note, clients with newer versions can still connect as long as data is in minecraft-data
|
// Currently supported verson. Note, clients with newer versions can still connect as long as data is in minecraft-data
|
||||||
const CURRENT_VERSION = '1.21.50'
|
const CURRENT_VERSION = '1.21.111'
|
||||||
|
|
||||||
const Versions = Object.fromEntries(mcData.versions.bedrock.filter(e => e.releaseType === 'release').map(e => [e.minecraftVersion, e.version]))
|
const Versions = Object.fromEntries(mcData.versions.bedrock.filter(e => e.releaseType === 'release').map(e => [e.minecraftVersion, e.version]))
|
||||||
|
|
||||||
// Skip some low priority versions (middle major) on Github Actions to allow faster CI
|
// Skip some low priority versions (middle major) on Github Actions to allow faster CI
|
||||||
const skippedVersionsOnGithubCI = ['1.16.210', '1.17.10', '1.17.30', '1.18.11', '1.19.10', '1.19.20', '1.19.30', '1.19.40', '1.19.50', '1.19.60', '1.19.63', '1.19.70', '1.20.10', '1.20.15', '1.20.30', '1.20.40', '1.20.50', '1.20.61', '1.20.71']
|
const skippedVersionsOnGithubCI = ['1.16.210', '1.17.10', '1.17.30', '1.18.11', '1.19.10', '1.19.20', '1.19.30', '1.19.40', '1.19.50', '1.19.60', '1.19.63', '1.19.70', '1.20.10', '1.20.15', '1.20.30', '1.20.40', '1.20.50', '1.20.61', '1.20.71', '1.21.2', '1.21.20', '1.21.30', '1.21.42', '1.21.50', '1.21.60', '1.21.70', '1.21.80', '1.21.90']
|
||||||
const testedVersions = process.env.CI ? Object.keys(Versions).filter(v => !skippedVersionsOnGithubCI.includes(v)) : Object.keys(Versions)
|
const testedVersions = process.env.CI ? Object.keys(Versions).filter(v => !skippedVersionsOnGithubCI.includes(v)) : Object.keys(Versions)
|
||||||
|
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,8 @@ class Server extends EventEmitter {
|
||||||
try {
|
try {
|
||||||
const mcData = require('minecraft-data')('bedrock_' + version)
|
const mcData = require('minecraft-data')('bedrock_' + version)
|
||||||
this.features = {
|
this.features = {
|
||||||
compressorInHeader: mcData.supportFeature('compressorInPacketHeader')
|
compressorInHeader: mcData.supportFeature('compressorInPacketHeader'),
|
||||||
|
newLoginIdentityFields: mcData.supportFeature('newLoginIdentityFields')
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`Unsupported version: '${version}', no data available`)
|
throw new Error(`Unsupported version: '${version}', no data available`)
|
||||||
|
|
@ -89,12 +90,10 @@ class Server extends EventEmitter {
|
||||||
this.emit('connect', player)
|
this.emit('connect', player)
|
||||||
}
|
}
|
||||||
|
|
||||||
onCloseConnection = (inetAddr, reason) => {
|
onCloseConnection = (conn, reason) => {
|
||||||
this.conLog('Connection closed: ', inetAddr?.address, reason)
|
this.conLog('Connection closed: ', conn.address, reason)
|
||||||
|
this.clients[conn.address]?.close()
|
||||||
delete this.clients[inetAddr]?.connection // Prevent close loop
|
delete this.clients[conn.address]
|
||||||
this.clients[inetAddr?.address ?? inetAddr]?.close()
|
|
||||||
delete this.clients[inetAddr]
|
|
||||||
this.clientCount--
|
this.clientCount--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,11 +78,18 @@ class Player extends Connection {
|
||||||
|
|
||||||
// Parse login data
|
// Parse login data
|
||||||
const tokens = body.params.tokens
|
const tokens = body.params.tokens
|
||||||
const authChain = JSON.parse(tokens.identity)
|
|
||||||
const skinChain = tokens.client
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var { key, userData, skinData } = this.decodeLoginJWT(authChain.chain, skinChain) // eslint-disable-line
|
const skinChain = tokens.client
|
||||||
|
const authChain = JSON.parse(tokens.identity)
|
||||||
|
let chain
|
||||||
|
if (authChain.Certificate) { // 1.21.90+
|
||||||
|
chain = JSON.parse(authChain.Certificate).chain
|
||||||
|
} else if (authChain.chain) {
|
||||||
|
chain = authChain.chain
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid login packet: missing chain or Certificate')
|
||||||
|
}
|
||||||
|
var { key, userData, skinData } = this.decodeLoginJWT(chain, skinChain) // eslint-disable-line
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debug(this.address, e)
|
debug(this.address, e)
|
||||||
this.disconnect('Server authentication error')
|
this.disconnect('Server authentication error')
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,11 @@ async function startTest (version = CURRENT_VERSION, ok) {
|
||||||
// client.queue('inventory_transaction', get('packets/inventory_transaction.json'))
|
// client.queue('inventory_transaction', get('packets/inventory_transaction.json'))
|
||||||
client.queue('player_list', get('packets/player_list.json'))
|
client.queue('player_list', get('packets/player_list.json'))
|
||||||
client.queue('start_game', get('packets/start_game.json'))
|
client.queue('start_game', get('packets/start_game.json'))
|
||||||
|
if (client.versionLessThan('1.21.60')) {
|
||||||
client.queue('item_component', { entries: [] })
|
client.queue('item_component', { entries: [] })
|
||||||
|
} else {
|
||||||
|
client.queue('item_registry', get('packets/item_registry.json'))
|
||||||
|
}
|
||||||
client.queue('set_spawn_position', get('packets/set_spawn_position.json'))
|
client.queue('set_spawn_position', get('packets/set_spawn_position.json'))
|
||||||
client.queue('set_time', { time: 5433771 })
|
client.queue('set_time', { time: 5433771 })
|
||||||
client.queue('set_difficulty', { difficulty: 1 })
|
client.queue('set_difficulty', { difficulty: 1 })
|
||||||
|
|
@ -97,11 +101,11 @@ async function startTest (version = CURRENT_VERSION, ok) {
|
||||||
|
|
||||||
loop = setInterval(() => {
|
loop = setInterval(() => {
|
||||||
client.write('network_chunk_publisher_update', { coordinates: { x: 646, y: 130, z: 77 }, radius: 64 })
|
client.write('network_chunk_publisher_update', { coordinates: { x: 646, y: 130, z: 77 }, radius: 64 })
|
||||||
}, 9500)
|
}, 6500)
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
client.write('play_status', { status: 'player_spawn' })
|
client.write('play_status', { status: 'player_spawn' })
|
||||||
}, 6000)
|
}, 3000)
|
||||||
|
|
||||||
// Respond to tick synchronization packets
|
// Respond to tick synchronization packets
|
||||||
client.on('tick_sync', (packet) => {
|
client.on('tick_sync', (packet) => {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
const { timedTest } = require('./internal')
|
const { timedTest } = require('./internal')
|
||||||
const { testedVersions } = require('../src/options')
|
const { testedVersions } = require('../src/options')
|
||||||
const { sleep } = require('../src/datatypes/util')
|
const { sleep } = require('../src/datatypes/util')
|
||||||
|
require('events').captureRejections = true
|
||||||
|
|
||||||
describe('internal client/server test', function () {
|
describe('internal client/server test', function () {
|
||||||
const vcount = testedVersions.length
|
const vcount = testedVersions.length
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,12 @@ function proxyTest (version, raknetBackend = 'raknet-native', timeout = 1000 * 4
|
||||||
console.debug('Client has authenticated')
|
console.debug('Client has authenticated')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
client.disconnect('Hello world !')
|
client.disconnect('Hello world !')
|
||||||
}, 1000) // allow some time for client to connect
|
}, 500) // allow some time for client to connect
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
console.debug('Server started', server.options.version)
|
console.debug('Server started', server.options.version)
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
await new Promise(resolve => setTimeout(resolve, 500))
|
||||||
|
|
||||||
const relay = new Relay({
|
const relay = new Relay({
|
||||||
version,
|
version,
|
||||||
|
|
@ -46,7 +46,7 @@ function proxyTest (version, raknetBackend = 'raknet-native', timeout = 1000 * 4
|
||||||
await relay.listen()
|
await relay.listen()
|
||||||
|
|
||||||
console.debug('Proxy started', server.options.version)
|
console.debug('Proxy started', server.options.version)
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
await new Promise(resolve => setTimeout(resolve, 500))
|
||||||
|
|
||||||
const client = createClient({ host: '127.0.0.1', port: CLIENT_PORT, version, username: 'Boat', offline: true, raknetBackend, skipPing: true })
|
const client = createClient({ host: '127.0.0.1', port: CLIENT_PORT, version, username: 'Boat', offline: true, raknetBackend, skipPing: true })
|
||||||
console.debug('Client started')
|
console.debug('Client started')
|
||||||
|
|
@ -58,7 +58,7 @@ function proxyTest (version, raknetBackend = 'raknet-native', timeout = 1000 * 4
|
||||||
server.close()
|
server.close()
|
||||||
relay.close()
|
relay.close()
|
||||||
console.log('✔ OK')
|
console.log('✔ OK')
|
||||||
sleep(500).then(res)
|
sleep(200).then(res)
|
||||||
})
|
})
|
||||||
}, timeout, () => { throw Error('timed out') })
|
}, timeout, () => { throw Error('timed out') })
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ describe('proxies client/server', function () {
|
||||||
it('proxies ' + version, async () => {
|
it('proxies ' + version, async () => {
|
||||||
console.debug(version)
|
console.debug(version)
|
||||||
await proxyTest(version)
|
await proxyTest(version)
|
||||||
await sleep(1000)
|
await sleep(100)
|
||||||
console.debug('Done', version)
|
console.debug('Done', version)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ function createProtocol (version) {
|
||||||
const compiler = new ProtoDefCompiler()
|
const compiler = new ProtoDefCompiler()
|
||||||
const protocol = mcData('bedrock_' + version).protocol.types
|
const protocol = mcData('bedrock_' + version).protocol.types
|
||||||
compiler.addTypes(require('../src/datatypes/compiler-minecraft'))
|
compiler.addTypes(require('../src/datatypes/compiler-minecraft'))
|
||||||
compiler.addTypes(require('prismarine-nbt/zigzag').compiler)
|
|
||||||
compiler.addTypesToCompile(protocol)
|
compiler.addTypesToCompile(protocol)
|
||||||
|
|
||||||
fs.writeFileSync('./read.js', 'module.exports = ' + compiler.readCompiler.generate().replace('() =>', 'native =>'))
|
fs.writeFileSync('./read.js', 'module.exports = ' + compiler.readCompiler.generate().replace('() =>', 'native =>'))
|
||||||
|
|
@ -39,7 +38,7 @@ require('minecraft-data/bin/generate_data')
|
||||||
|
|
||||||
// If no argument, build everything
|
// If no argument, build everything
|
||||||
if (!process.argv[2]) {
|
if (!process.argv[2]) {
|
||||||
convert('latest')
|
convert('bedrock', 'latest')
|
||||||
for (const version of versions) {
|
for (const version of versions) {
|
||||||
main(version)
|
main(version)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue