mirror of
https://github.com/PrismarineJS/node-minecraft-protocol.git
synced 2024-11-21 10:28:12 -05:00
1.20.5 (#1309)
* 1.20.5 * update examples * Update for 1.20.5 chat_command_signed with seperateSignedChatCommandPacket feature * updates * update java * re-enable packet tests * Update client.js add debug code after decompress * Update client.js * Update ci.yml * Add `arrayWithLengthOffset` type to interpeter * Update minecraft.js * Update compiler-minecraft.js * Update minecraft.js * lint * remote custom ci install * Update package.json * Update packetTest.js add Slot, SlotComponent * Update packetTest.js * Update packetTest.js * Fix lint. * Fix declare_recipes, Slot * Update package.json --------- Co-authored-by: Romain Beaumont <romain.rom1@gmail.com>
This commit is contained in:
parent
7057ad979b
commit
9b029e8b6f
17 changed files with 232 additions and 46 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -52,7 +52,7 @@ jobs:
|
|||
- name: Setup Java JDK
|
||||
uses: actions/setup-java@v1.4.3
|
||||
with:
|
||||
java-version: '17'
|
||||
java-version: '21'
|
||||
distribution: 'adopt'
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
|
|
@ -13,7 +13,7 @@ Parse and serialize minecraft packets, plus authentication and encryption.
|
|||
|
||||
* Supports Minecraft PC version 1.7.10, 1.8.8, 1.9 (15w40b, 1.9, 1.9.1-pre2, 1.9.2, 1.9.4),
|
||||
1.10 (16w20a, 1.10-pre1, 1.10, 1.10.1, 1.10.2), 1.11 (16w35a, 1.11, 1.11.2), 1.12 (17w15a, 17w18b, 1.12-pre4, 1.12, 1.12.1, 1.12.2), and 1.13 (17w50a, 1.13, 1.13.1, 1.13.2-pre1, 1.13.2-pre2, 1.13.2), 1.14 (1.14, 1.14.1, 1.14.3, 1.14.4)
|
||||
, 1.15 (1.15, 1.15.1, 1.15.2) and 1.16 (20w13b, 20w14a, 1.16-rc1, 1.16, 1.16.1, 1.16.2, 1.16.3, 1.16.4, 1.16.5), 1.17 (21w07a, 1.17, 1.17.1), 1.18 (1.18, 1.18.1 and 1.18.2), 1.19 (1.19, 1.19.1, 1.19.2, 1.19.3, 1.19.4), 1.20 (1.20, 1.20.1, 1.20.2, 1.20.3 and 1.20.4)
|
||||
, 1.15 (1.15, 1.15.1, 1.15.2) and 1.16 (20w13b, 20w14a, 1.16-rc1, 1.16, 1.16.1, 1.16.2, 1.16.3, 1.16.4, 1.16.5), 1.17 (21w07a, 1.17, 1.17.1), 1.18 (1.18, 1.18.1 and 1.18.2), 1.19 (1.19, 1.19.1, 1.19.2, 1.19.3, 1.19.4), 1.20, 1.20.1, 1.20.2, 1.20.3, 1.20.4, 1.20.5
|
||||
* Parses all packets and emits events with packet fields as JavaScript
|
||||
objects.
|
||||
* Send a packet by supplying fields as a JavaScript object.
|
||||
|
@ -142,6 +142,7 @@ server.on('playerJoin', function(client) {
|
|||
|
||||
client.write('login', {
|
||||
...loginPacket,
|
||||
enforceSecureChat: false,
|
||||
entityId: client.id,
|
||||
hashedSeed: [0, 0],
|
||||
maxPlayers: server.maxPlayers,
|
||||
|
|
|
@ -30,6 +30,7 @@ server.on('playerJoin', function (client) {
|
|||
// send init data so client will start rendering world
|
||||
client.write('login', {
|
||||
...loginPacket,
|
||||
enforceSecureChat: false,
|
||||
entityId: client.id,
|
||||
isHardcore: false,
|
||||
gameMode: 0,
|
||||
|
|
|
@ -14,6 +14,7 @@ server.on('playerJoin', function (client) {
|
|||
|
||||
client.write('login', {
|
||||
...loginPacket,
|
||||
enforceSecureChat: false,
|
||||
entityId: client.id,
|
||||
isHardcore: false,
|
||||
gameMode: 0,
|
||||
|
|
|
@ -11,6 +11,7 @@ const loginPacket = mcData.loginPacket
|
|||
server.on('playerJoin', function (client) {
|
||||
client.write('login', {
|
||||
...loginPacket,
|
||||
enforceSecureChat: false,
|
||||
entityId: client.id,
|
||||
isHardcore: false,
|
||||
gameMode: 0,
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
"minecraft-wrap": "^1.2.3",
|
||||
"mocha": "^10.0.0",
|
||||
"power-assert": "^1.0.0",
|
||||
"standard": "^17.0.0"
|
||||
"standard": "^17.0.0",
|
||||
"prismarine-registry": "^1.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/readable-stream": "^4.0.0",
|
||||
|
@ -51,7 +52,7 @@
|
|||
"endian-toggle": "^0.0.0",
|
||||
"lodash.get": "^4.1.2",
|
||||
"lodash.merge": "^4.3.0",
|
||||
"minecraft-data": "^3.55.0",
|
||||
"minecraft-data": "^3.71.0",
|
||||
"minecraft-folder-path": "^1.2.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"node-rsa": "^0.4.2",
|
||||
|
@ -59,7 +60,7 @@
|
|||
"prismarine-chat": "^1.10.0",
|
||||
"prismarine-nbt": "^2.5.0",
|
||||
"prismarine-realms": "^1.2.0",
|
||||
"protodef": "^1.8.0",
|
||||
"protodef": "^1.17.0",
|
||||
"readable-stream": "^4.1.0",
|
||||
"uuid-1345": "^1.0.1",
|
||||
"yggdrasil": "^1.4.0"
|
||||
|
|
|
@ -137,6 +137,7 @@ class Client extends EventEmitter {
|
|||
this.splitter.pipe(this.deserializer)
|
||||
} else {
|
||||
this.serializer.pipe(this.compressor)
|
||||
if (globalThis.debugNMP) this.decompressor.on('data', (data) => { console.log('DES>', data.toString('hex')) })
|
||||
this.decompressor.pipe(this.deserializer)
|
||||
}
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ module.exports = function (client, options) {
|
|||
})
|
||||
})
|
||||
|
||||
client.on('message_header', (packet) => {
|
||||
client.on('message_header', (packet) => { // [1.19.2]
|
||||
updateAndValidateChat(packet.senderUuid, packet.previousSignature, packet.signature, packet.messageHash)
|
||||
|
||||
client._lastChatHistory.push({
|
||||
|
@ -369,13 +369,14 @@ module.exports = function (client, options) {
|
|||
|
||||
if (message.startsWith('/')) {
|
||||
const command = message.slice(1)
|
||||
if (mcData.supportFeature('useChatSessions')) {
|
||||
if (mcData.supportFeature('useChatSessions')) { // 1.19.3+
|
||||
const { acknowledged, acknowledgements } = getAcknowledgements()
|
||||
client.write('chat_command', {
|
||||
const canSign = client.profileKeys && client._session
|
||||
client.write((mcData.supportFeature('seperateSignedChatCommandPacket') && canSign) ? 'chat_command_signed' : 'chat_command', {
|
||||
command,
|
||||
timestamp: options.timestamp,
|
||||
salt: options.salt,
|
||||
argumentSignatures: (client.profileKeys && client._session) ? signaturesForCommand(command, options.timestamp, options.salt, options.preview, acknowledgements) : [],
|
||||
argumentSignatures: canSign ? signaturesForCommand(command, options.timestamp, options.salt, options.preview, acknowledgements) : [],
|
||||
messageCount: client._lastSeenMessages.pending,
|
||||
acknowledged
|
||||
})
|
||||
|
|
|
@ -7,11 +7,12 @@ module.exports = function (client, options) {
|
|||
client.on('server_data', (packet) => {
|
||||
client.serverFeatures = {
|
||||
chatPreview: packet.previewsChat,
|
||||
enforcesSecureChat: packet.enforcesSecureChat
|
||||
enforcesSecureChat: packet.enforcesSecureChat // in LoginPacket v>=1.20.5
|
||||
}
|
||||
})
|
||||
|
||||
client.once('login', () => {
|
||||
client.once('login', (packet) => {
|
||||
if (packet.enforcesSecureChat) client.serverFeatures.enforcesSecureChat = packet.enforcesSecureChat
|
||||
const mcData = require('minecraft-data')(client.version)
|
||||
if (mcData.supportFeature('useChatSessions') && client.profileKeys && client.cipher && client.session.selectedProfile.id === client.uuid.replace(/-/g, '')) {
|
||||
client._session = {
|
||||
|
@ -52,6 +53,9 @@ module.exports = function (client, options) {
|
|||
client.write('configuration_acknowledged', {})
|
||||
}
|
||||
client.state = states.CONFIGURATION
|
||||
client.on('select_known_packs', () => {
|
||||
client.write('select_known_packs', { packs: [] })
|
||||
})
|
||||
// Server should send finish_configuration on its own right after sending the client a dimension codec
|
||||
// for login (that has data about world height, world gen, etc) after getting a login success from client
|
||||
client.once('finish_configuration', () => {
|
||||
|
|
|
@ -40,6 +40,27 @@ module.exports = {
|
|||
code += ' if ((item & 128) === 0) return { value: data, size: cursor - offset }\n'
|
||||
code += '}'
|
||||
return compiler.wrapCode(code)
|
||||
}],
|
||||
arrayWithLengthOffset: ['parametrizable', (compiler, array) => {
|
||||
let code = ''
|
||||
if (array.countType) {
|
||||
code += 'const { value: count, size: countSize } = ' + compiler.callType(array.countType) + '\n'
|
||||
} else if (array.count) {
|
||||
code += 'const count = ' + array.count + '\n'
|
||||
code += 'const countSize = 0\n'
|
||||
} else {
|
||||
throw new Error('Array must contain either count or countType')
|
||||
}
|
||||
code += 'if (count > 0xffffff) throw new Error("array size is abnormally large, not reading: " + count)\n'
|
||||
code += 'const data = []\n'
|
||||
code += 'let size = countSize\n'
|
||||
code += `for (let i = 0; i < count + ${array.lengthOffset}; i++) {\n`
|
||||
code += ' const elem = ' + compiler.callType(array.type, 'offset + size') + '\n'
|
||||
code += ' data.push(elem.value)\n'
|
||||
code += ' size += elem.size\n'
|
||||
code += '}\n'
|
||||
code += 'return { value: data, size }'
|
||||
return compiler.wrapCode(code)
|
||||
}]
|
||||
},
|
||||
Write: {
|
||||
|
@ -72,6 +93,19 @@ module.exports = {
|
|||
code += '}\n'
|
||||
code += 'return offset'
|
||||
return compiler.wrapCode(code)
|
||||
}],
|
||||
arrayWithLengthOffset: ['parametrizable', (compiler, array) => {
|
||||
let code = ''
|
||||
if (array.countType) {
|
||||
code += 'offset = ' + compiler.callType('value.length', array.countType) + '\n'
|
||||
} else if (array.count === null) {
|
||||
throw new Error('Array must contain either count or countType')
|
||||
}
|
||||
code += 'for (let i = 0; i < value.length; i++) {\n'
|
||||
code += ' offset = ' + compiler.callType('value[i]', array.type) + '\n'
|
||||
code += '}\n'
|
||||
code += 'return offset'
|
||||
return compiler.wrapCode(code)
|
||||
}]
|
||||
},
|
||||
SizeOf: {
|
||||
|
@ -96,6 +130,25 @@ module.exports = {
|
|||
code += '}\n'
|
||||
code += 'return size'
|
||||
return compiler.wrapCode(code)
|
||||
}],
|
||||
arrayWithLengthOffset: ['parametrizable', (compiler, array) => {
|
||||
let code = ''
|
||||
if (array.countType) {
|
||||
code += 'let size = ' + compiler.callType('value.length', array.countType) + '\n'
|
||||
} else if (array.count) {
|
||||
code += 'let size = 0\n'
|
||||
} else {
|
||||
throw new Error('Array must contain either count or countType')
|
||||
}
|
||||
if (!isNaN(compiler.callType('value[i]', array.type))) {
|
||||
code += 'size += value.length * ' + compiler.callType('value[i]', array.type) + '\n'
|
||||
} else {
|
||||
code += 'for (let i = 0; i < value.length; i++) {\n'
|
||||
code += ' size += ' + compiler.callType('value[i]', array.type) + '\n'
|
||||
code += '}\n'
|
||||
}
|
||||
code += 'return size'
|
||||
return compiler.wrapCode(code)
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,8 @@ module.exports = {
|
|||
compressedNbt: [readCompressedNbt, writeCompressedNbt, sizeOfCompressedNbt],
|
||||
restBuffer: [readRestBuffer, writeRestBuffer, sizeOfRestBuffer],
|
||||
entityMetadataLoop: [readEntityMetadata, writeEntityMetadata, sizeOfEntityMetadata],
|
||||
topBitSetTerminatedArray: [readTopBitSetTerminatedArray, writeTopBitSetTerminatedArray, sizeOfTopBitSetTerminatedArray]
|
||||
topBitSetTerminatedArray: [readTopBitSetTerminatedArray, writeTopBitSetTerminatedArray, sizeOfTopBitSetTerminatedArray],
|
||||
arrayWithLengthOffset: [readArrayWithLengthOffset, writeArrayWithLengthOffset, sizeOfArrayWithLengthOffset]
|
||||
}
|
||||
const PartialReadError = require('protodef').utils.PartialReadError
|
||||
|
||||
|
@ -180,3 +181,36 @@ function sizeOfTopBitSetTerminatedArray (value, { type }) {
|
|||
}
|
||||
return size
|
||||
}
|
||||
|
||||
//
|
||||
const { getCount, sendCount, calcCount, tryDoc } = require('protodef/src/utils')
|
||||
|
||||
function readArrayWithLengthOffset (buffer, offset, typeArgs, rootNode) {
|
||||
const results = {
|
||||
value: [],
|
||||
size: 0
|
||||
}
|
||||
let value
|
||||
let { count, size } = getCount.call(this, buffer, offset, typeArgs, rootNode)
|
||||
offset += size
|
||||
results.size += size
|
||||
for (let i = 0; i < count + typeArgs.lengthOffset; i++) {
|
||||
({ size, value } = tryDoc(() => this.read(buffer, offset, typeArgs.type, rootNode), i))
|
||||
results.size += size
|
||||
offset += size
|
||||
results.value.push(value)
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// no changes
|
||||
function writeArrayWithLengthOffset (value, buffer, offset, typeArgs, rootNode) {
|
||||
offset = sendCount.call(this, value.length, buffer, offset, typeArgs, rootNode)
|
||||
return value.reduce((offset, v, index) => tryDoc(() => this.write(v, buffer, offset, typeArgs.type, rootNode), index), offset)
|
||||
}
|
||||
|
||||
function sizeOfArrayWithLengthOffset (value, typeArgs, rootNode) {
|
||||
let size = calcCount.call(this, value.length, typeArgs, rootNode)
|
||||
size = value.reduce((size, v, index) => tryDoc(() => size + this.sizeOf(v, typeArgs.type, rootNode), index), size)
|
||||
return size + typeArgs
|
||||
}
|
||||
|
|
|
@ -193,7 +193,8 @@ module.exports = function (client, server, options) {
|
|||
if (client.supportFeature('chainedChatWithHashing')) { // 1.19.1+
|
||||
client.write('server_data', {
|
||||
previewsChat: options.enableChatPreview,
|
||||
enforceSecureProfile: options.enforceSecureProfile
|
||||
// Note: in 1.20.5+ user must send this with `login`
|
||||
enforcesSecureChat: options.enforceSecureProfile
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -211,7 +212,14 @@ module.exports = function (client, server, options) {
|
|||
|
||||
function onClientLoginAck () {
|
||||
client.state = states.CONFIGURATION
|
||||
client.write('registry_data', { codec: options.registryCodec || {} })
|
||||
if (client.supportFeature('segmentedRegistryCodecData')) {
|
||||
for (const key in options.registryCodec) {
|
||||
const entry = options.registryCodec[key]
|
||||
client.write('registry_data', entry)
|
||||
}
|
||||
} else {
|
||||
client.write('registry_data', { codec: options.registryCodec || {} })
|
||||
}
|
||||
client.once('finish_configuration', () => {
|
||||
client.state = states.PLAY
|
||||
server.emit('playerJoin', client)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
defaultVersion: '1.20.4',
|
||||
supportedVersions: ['1.7', '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', '1.19.3', '1.19.4', '1.20', '1.20.1', '1.20.2', '1.20.4']
|
||||
defaultVersion: '1.20.5',
|
||||
supportedVersions: ['1.7', '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', '1.19.3', '1.19.4', '1.20', '1.20.1', '1.20.2', '1.20.4', '1.20.5']
|
||||
}
|
||||
|
|
|
@ -107,6 +107,43 @@ for (const supportedVersion of mc.supportedVersions) {
|
|||
auth: 'offline'
|
||||
}))
|
||||
client.on('error', err => done(err))
|
||||
|
||||
client.on('state', (state) => {
|
||||
console.log('Client now in state', state)
|
||||
})
|
||||
|
||||
// ** Dump some server data **
|
||||
fs.rmSync(MC_SERVER_DIR + '_registry_data.json', { force: true })
|
||||
client.on('raw.registry_data', (buffer) => {
|
||||
fs.writeFileSync(MC_SERVER_DIR + '_registry_data.bin', buffer)
|
||||
})
|
||||
client.on('registry_data', (json) => {
|
||||
if (json.codec) { // Pre 1.20.5, codec is 1 json
|
||||
fs.writeFileSync(MC_SERVER_DIR + '_registry_data.json', JSON.stringify(json))
|
||||
} else { // 1.20.5+, codec is many nbt's each with their own ids, merge them
|
||||
let currentData = {}
|
||||
if (fs.existsSync(MC_SERVER_DIR + '_registry_data.json')) {
|
||||
currentData = JSON.parse(fs.readFileSync(MC_SERVER_DIR + '_registry_data.json', 'utf8'))
|
||||
}
|
||||
currentData[json.id] = json
|
||||
fs.writeFileSync(MC_SERVER_DIR + '_registry_data.json', JSON.stringify(currentData))
|
||||
}
|
||||
console.log('Wrote registry data')
|
||||
})
|
||||
client.on('login', (packet) => {
|
||||
fs.writeFileSync(MC_SERVER_DIR + '_login.json', JSON.stringify(packet))
|
||||
if (fs.existsSync(MC_SERVER_DIR + '_registry_data.json')) {
|
||||
// generate a loginPacket.json for minecraft-data
|
||||
const codec = JSON.parse(fs.readFileSync(MC_SERVER_DIR + '_registry_data.json'))
|
||||
fs.writeFileSync(MC_SERVER_DIR + '_loginPacket.json', JSON.stringify({
|
||||
...packet,
|
||||
dimensionCodec: codec.codec || codec
|
||||
}, null, 2))
|
||||
console.log('Wrote loginPacket.json')
|
||||
}
|
||||
})
|
||||
// ** End dumping code **
|
||||
|
||||
const lineListener = function (line) {
|
||||
const match = line.match(/\[Server thread\/INFO\]: (?:\[Not Secure\] )?<(.+?)> (.+)/)
|
||||
if (!match) return
|
||||
|
@ -117,26 +154,14 @@ for (const supportedVersion of mc.supportedVersions) {
|
|||
}
|
||||
wrap.on('line', lineListener)
|
||||
let chatCount = 0
|
||||
|
||||
client.on('login', function (packet) {
|
||||
assert.strictEqual(packet.gameMode, 0)
|
||||
client.chat('hello everyone; I have logged in.')
|
||||
})
|
||||
// Dump some data for easier debugging
|
||||
client.on('raw.registry_data', (buffer) => {
|
||||
fs.writeFileSync(MC_SERVER_DIR + '_registry_data.bin', buffer)
|
||||
})
|
||||
client.on('registry_data', (json) => {
|
||||
fs.writeFileSync(MC_SERVER_DIR + '_registry_data.json', JSON.stringify(json))
|
||||
})
|
||||
client.on('login', (packet) => {
|
||||
fs.writeFileSync(MC_SERVER_DIR + '_login.json', JSON.stringify(packet))
|
||||
if (fs.existsSync(MC_SERVER_DIR + '_registry_data.json')) {
|
||||
// generate a loginPacket.json for minecraft-data
|
||||
fs.writeFileSync(MC_SERVER_DIR + '_loginPacket.json', JSON.stringify({
|
||||
...packet,
|
||||
dimensionCodec: JSON.parse(fs.readFileSync(MC_SERVER_DIR + '_registry_data.json')).codec
|
||||
}, null, 2))
|
||||
if (packet.worldState) { // 1.20.5+
|
||||
assert.strictEqual(packet.worldState.gamemode, 'survival')
|
||||
} else {
|
||||
assert.strictEqual(packet.gameMode, 0)
|
||||
}
|
||||
client.chat('hello everyone; I have logged in.')
|
||||
})
|
||||
client.on('playerChat', function (data) {
|
||||
chatCount += 1
|
||||
|
|
|
@ -29,7 +29,7 @@ module.exports = client => {
|
|||
})
|
||||
client.on('registry_data', (data) => {
|
||||
client.registry ??= Registry(client.version)
|
||||
client.registry.loadDimensionCodec(data.codec)
|
||||
client.registry.loadDimensionCodec(data.codec || data)
|
||||
})
|
||||
|
||||
client.on('playerJoin', () => {
|
||||
|
|
|
@ -18,7 +18,6 @@ function evalCount (count, fields) {
|
|||
const slotValue = {
|
||||
present: true,
|
||||
blockId: 5,
|
||||
itemCount: 56,
|
||||
itemDamage: 2,
|
||||
nbtData: {
|
||||
type: 'compound',
|
||||
|
@ -32,7 +31,14 @@ const slotValue = {
|
|||
test6: { type: 'compound', value: { test: { type: 'int', value: 4 } } },
|
||||
test7: { type: 'intArray', value: [12, 42] }
|
||||
}
|
||||
}
|
||||
},
|
||||
// 1.20.5
|
||||
itemCount: 1,
|
||||
itemId: 1111,
|
||||
addedComponentCount: 0,
|
||||
removedComponentCount: 0,
|
||||
components: [],
|
||||
removeComponents: []
|
||||
}
|
||||
|
||||
const nbtValue = {
|
||||
|
@ -49,6 +55,24 @@ const nbtValue = {
|
|||
}
|
||||
}
|
||||
|
||||
function getFixedPacketPayload (version, packetName) {
|
||||
if (packetName === 'declare_recipes') {
|
||||
if (version['>=']('1.20.5')) {
|
||||
return {
|
||||
recipes: [
|
||||
{
|
||||
name: 'minecraft:crafting_decorated_pot',
|
||||
type: 'minecraft:crafting_decorated_pot',
|
||||
data: {
|
||||
category: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const values = {
|
||||
i32: 123456,
|
||||
i16: -123,
|
||||
|
@ -57,6 +81,7 @@ const values = {
|
|||
varlong: -20,
|
||||
i8: -10,
|
||||
u8: 8,
|
||||
ByteArray: [],
|
||||
string: 'hi hi this is my client string',
|
||||
buffer: function (typeArgs, context) {
|
||||
let count
|
||||
|
@ -124,6 +149,11 @@ const values = {
|
|||
f64: 99999.2222,
|
||||
f32: -333.444,
|
||||
slot: slotValue,
|
||||
Slot: slotValue,
|
||||
SlotComponent: {
|
||||
type: 'hide_tooltip'
|
||||
},
|
||||
SlotComponentType: 0,
|
||||
nbt: nbtValue,
|
||||
optionalNbt: nbtValue,
|
||||
compressedNbt: nbtValue,
|
||||
|
@ -161,8 +191,8 @@ const values = {
|
|||
const i = typeArgs.fields[getField(typeArgs.compareTo, context)]
|
||||
if (i === undefined) {
|
||||
if (typeArgs.default === undefined) {
|
||||
throw new Error("couldn't find the field " + typeArgs.compareTo +
|
||||
' of the compareTo and the default is not defined')
|
||||
typeArgs.default = 'void'
|
||||
// throw new Error("couldn't find the field " + typeArgs.compareTo + ' of the compareTo and the default is not defined')
|
||||
}
|
||||
return getValue(typeArgs.default, context)
|
||||
} else { return getValue(i, context) }
|
||||
|
@ -177,6 +207,7 @@ const values = {
|
|||
})
|
||||
return results
|
||||
},
|
||||
mapper: '',
|
||||
tags: [{ tagName: 'hi', entries: [1, 2, 3, 4, 5] }],
|
||||
ingredient: [slotValue],
|
||||
particleData: null,
|
||||
|
@ -212,6 +243,20 @@ const values = {
|
|||
particle: {
|
||||
particleId: 0,
|
||||
data: null
|
||||
},
|
||||
Particle: {},
|
||||
SpawnInfo: {
|
||||
dimension: 0,
|
||||
name: 'minecraft:overworld',
|
||||
hashedSeed: [
|
||||
572061085,
|
||||
1191958278
|
||||
],
|
||||
gamemode: 'survival',
|
||||
previousGamemode: 255,
|
||||
isDebug: false,
|
||||
isFlat: false,
|
||||
portalCooldown: 0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,24 +319,28 @@ for (const supportedVersion of mc.supportedVersions) {
|
|||
.forEach(function (packetName) {
|
||||
packetInfo = packets[state][direction].types[packetName]
|
||||
packetInfo = packetInfo || null
|
||||
if (packetName.includes('bundle_delimiter')) return // not a real packet
|
||||
if (['packet_set_projectile_power', 'packet_debug_sample_subscription'].includes(packetName)) return
|
||||
it(state + ',' + (direction === 'toServer' ? 'Server' : 'Client') + 'Bound,' + packetName,
|
||||
callTestPacket(packetName.substr(7), packetInfo, state, direction === 'toServer'))
|
||||
callTestPacket(mcData, packetName.substr(7), packetInfo, state, direction === 'toServer'))
|
||||
})
|
||||
})
|
||||
})
|
||||
function callTestPacket (packetName, packetInfo, state, toServer) {
|
||||
function callTestPacket (mcData, packetName, packetInfo, state, toServer) {
|
||||
return function (done) {
|
||||
client.state = state
|
||||
serverClient.state = state
|
||||
testPacket(packetName, packetInfo, state, toServer, done)
|
||||
testPacket(mcData, packetName, packetInfo, state, toServer, done)
|
||||
}
|
||||
}
|
||||
|
||||
function testPacket (packetName, packetInfo, state, toServer, done) {
|
||||
function testPacket (mcData, packetName, packetInfo, state, toServer, done) {
|
||||
// empty object uses default values
|
||||
const packet = getValue(packetInfo, {})
|
||||
const packet = getFixedPacketPayload(mcData.version, packetName) || getValue(packetInfo, {})
|
||||
if (toServer) {
|
||||
console.log('Writing to server', packetName, JSON.stringify(packet))
|
||||
serverClient.once(packetName, function (receivedPacket) {
|
||||
console.log('Recv', packetName)
|
||||
try {
|
||||
assertPacketsMatch(packet, receivedPacket)
|
||||
} catch (e) {
|
||||
|
@ -302,7 +351,9 @@ for (const supportedVersion of mc.supportedVersions) {
|
|||
})
|
||||
client.write(packetName, packet)
|
||||
} else {
|
||||
console.log('Writing to client', packetName, JSON.stringify(packet))
|
||||
client.once(packetName, function (receivedPacket) {
|
||||
console.log('Recv', packetName)
|
||||
assertPacketsMatch(packet, receivedPacket)
|
||||
done()
|
||||
})
|
||||
|
|
|
@ -30,6 +30,9 @@ for (const supportedVersion of mc.supportedVersions) {
|
|||
const version = mcData.version
|
||||
|
||||
const loginPacket = (client, server) => {
|
||||
if (mcData.loginPacket) {
|
||||
return mcData.loginPacket
|
||||
}
|
||||
return {
|
||||
// 1.7
|
||||
entityId: client.id,
|
||||
|
@ -67,7 +70,9 @@ for (const supportedVersion of mc.supportedVersions) {
|
|||
value: {}
|
||||
},
|
||||
worldType: 'minecraft:overworld',
|
||||
death: undefined
|
||||
death: undefined,
|
||||
// 1.20.5
|
||||
enforceSecureChat: false
|
||||
// more to be added
|
||||
}
|
||||
}
|
||||
|
@ -342,7 +347,6 @@ for (const supportedVersion of mc.supportedVersions) {
|
|||
|
||||
player1.on('login', async function (packet) {
|
||||
console.log('ChatTest: Player 1 has joined')
|
||||
assert.strictEqual(packet.gameMode, 1)
|
||||
const player2 = applyClientHelpers(mc.createClient({
|
||||
username: 'player2',
|
||||
host: '127.0.0.1',
|
||||
|
|
Loading…
Reference in a new issue