diff --git a/lib/pc/index.js b/lib/pc/index.js index 09c394d..6b09584 100644 --- a/lib/pc/index.js +++ b/lib/pc/index.js @@ -1,6 +1,4 @@ const nbt = require('prismarine-nbt') -// TOOD: remove this -nbt.float = value => ({ type: 'float', value }) const { networkBiomesToMcDataSchema, mcDataSchemaToNetworkBiomes } = require('./transforms') @@ -9,62 +7,73 @@ module.exports = (data, staticData) => { return { loadDimensionCodec (codec) { - const dimensionCodec = nbt.simplify(codec) - - const chat = dimensionCodec['minecraft:chat_type']?.value - if (chat) { - data.chatFormattingById = {} - data.chatFormattingByName = {} - for (const chatType of chat) { - const d = chatType.element?.chat?.decoration ?? chatType.element?.chat - if (!d) continue - const n = { - id: chatType.id, - name: chatType.name, - formatString: staticData.language[d.translation_key] || d.translation_key /* chat type minecraft:raw has the formatString given directly by the translation key */, - parameters: d.parameters, - style: d.style + const handlers = { + chat_type (chat) { + console.log('Registry Chat') + console.dir(chat, { depth: null }) + data.chatFormattingById = {} + data.chatFormattingByName = {} + for (const chatType of chat) { + const d = chatType.element?.chat?.decoration ?? chatType.element?.chat + if (!d) continue + const n = { + id: chatType.id, + name: chatType.name, + formatString: staticData.language[d.translation_key] || d.translation_key /* chat type minecraft:raw has the formatString given directly by the translation key */, + parameters: d.parameters + } + data.chatFormattingById[chatType.id] = n + data.chatFormattingByName[chatType.name] = n } - data.chatFormattingById[chatType.id] = n - data.chatFormattingByName[chatType.name] = n - } - } + console.log('Updated chat', data.chatFormattingById) + }, + dimension_type (dimensions) { + data.dimensionsById = {} + data.dimensionsByName = {} + data.dimensionsArray = [] - const dimensions = dimensionCodec['minecraft:dimension_type']?.value - if (dimensions) { - data.dimensionsById = {} - data.dimensionsByName = {} - for (const { name, id, element } of dimensions) { - const n = name.replace('minecraft:', '') - const d = { - name: n, - minY: element.min_y, - height: element.height + for (const { name, id, element } of dimensions) { + const n = name.replace('minecraft:', '') + const d = { + name: n, + minY: element.min_y, + height: element.height + } + data.dimensionsById[id] = d + data.dimensionsByName[n] = d + data.dimensionsArray.push(d) } - data.dimensionsById[id] = d - data.dimensionsByName[n] = d - } - } + }, + 'worldgen/biome' (biomes) { + data.biomes = [] + data.biomesByName = {} + data.biomesArray = [] - const biomes = dimensionCodec['minecraft:worldgen/biome']?.value - if (!biomes) { - return // no biome data - } + biomes.map(e => networkBiomesToMcDataSchema(e, staticData)) - data.biomes = [] - data.biomesByName = {} - data.biomesArray = [] + const allBiomes = [] + for (const { name, id, element } of biomes) { + data.biomes[id] = element + data.biomesByName[name] = element + allBiomes.push(element) + } + data.biomesArray = allBiomes - biomes.map(e => networkBiomesToMcDataSchema(e, staticData)) + hasDynamicDimensionData = true + } + } - const allBiomes = [] - for (const { name, id, element } of biomes) { - data.biomes[id] = element - data.biomesByName[name] = element - allBiomes.push(element) + if (staticData.supportFeature('segmentedRegistryCodecData')) { + // 1.20.5+ - dimension data is now seperated outside the NBT and is sent through + // multiple registry_data { id: registryName, entries: [key, registryData] } packets... + const entries = codec.entries.map((e, ix) => ({ id: ix, name: e.key, element: nbt.simplify(e.value) })) + handlers[codec.id.replace('minecraft:', '')]?.(entries) + } else { + const dimensionCodec = nbt.simplify(codec) + for (const codecName in dimensionCodec) { + handlers[codecName.replace('minecraft:', '')]?.(dimensionCodec[codecName].value) + } } - data.biomesArray = allBiomes - hasDynamicDimensionData = true }, writeDimensionCodec () { @@ -74,9 +83,10 @@ module.exports = (data, staticData) => { return codec // no dimension codec in 1.15 } else if (data.version['<']('1.16.2')) { return staticData.loginPacket.dimensionCodec - } else if (data.version['>=']('1.16.2')) { + } else if (data.version['<']('1.20.5')) { // Keep the old dimension codec data if it exists (re-encoding) // We don't have this data statically, should probably be added to mcData + if (data.dimensionsArray) { codec['minecraft:dimension_type'] = nbt.comp({ type: nbt.string('minecraft:dimension_type'), @@ -84,7 +94,9 @@ module.exports = (data, staticData) => { data.dimensionsArray.map(dimension => ({ name: dimension.name, id: dimension.id, - element: dimension.element + element: { + min_y: dimension.minY + } })) )) }) @@ -100,9 +112,33 @@ module.exports = (data, staticData) => { }) // 1.19 codec['minecraft:chat_type'] = staticData.loginPacket.dimensionCodec?.value?.['minecraft:chat_type'] + // NBT + return nbt.comp(codec) + } else { + if (data.dimensionsArray) { + codec['minecraft:dimension_type'] = { + id: 'minecraft:dimension_type', + entries: data.dimensionsArray.map(dimension => ({ + key: dimension.name, + value: nbt.comp({ + min_y: dimension.minY + }) + })) + } + } else { + codec['minecraft:dimension_type'] = staticData.loginPacket.dimensionCodec['minecraft:dimension_type'] + } + // if we have dynamic biome data (re-encoding), we can count on biome.effects + // being in place. Otherwise, we need to use static data exclusively, e.g. flying squid. + codec['minecraft:worldgen/biome'] = { + id: 'minecraft:worldgen/biome', + entries: nbt.comp(mcDataSchemaToNetworkBiomes(hasDynamicDimensionData ? data.biomesArray : null, staticData)) + } + // 1.19 + codec['minecraft:chat_type'] = staticData.loginPacket.dimensionCodec?.['minecraft:chat_type'] + // No NBT at root anymore + return codec } - - return nbt.comp(codec) } } } diff --git a/package.json b/package.json index b68c96c..dc9c1a8 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "standard": "^17.0.0" }, "dependencies": { - "minecraft-data": "^3.0.0", + "minecraft-data": "^3.70.0", "prismarine-nbt": "^2.0.0" } } diff --git a/test/mcbedrock.js b/test/mcbedrock.js index f4ca665..95f1cf5 100644 --- a/test/mcbedrock.js +++ b/test/mcbedrock.js @@ -22,7 +22,7 @@ async function main (version = '1.19.63') { } await collectPackets(version, Object.keys(handlers), (name, params) => handlers[name](version, params)) - await new Promise((resolve) => setTimeout(resolve, 6000)) + await new Promise((resolve) => setTimeout(resolve, 12000)) if (!loggedIn) { throw new Error('Did not login') } diff --git a/test/mcbedrock.test.js b/test/mcbedrock.test.js index eee688c..a24516f 100644 --- a/test/mcbedrock.test.js +++ b/test/mcbedrock.test.js @@ -4,7 +4,7 @@ const SUPPORTED_VERSIONS = ['1.17.10', '1.18.0', '1.18.11', '1.18.30', '1.19.1', const test = require('./mcbedrock') describe('mcbedrock', function () { - this.timeout(9000 * 10) + this.timeout(18000 * 10) for (const version of SUPPORTED_VERSIONS) { it('works on ' + version, () => test(version))