diff --git a/data/1.16.210/protocol.json b/data/1.16.210/protocol.json index 8c34b12..9a61484 100644 --- a/data/1.16.210/protocol.json +++ b/data/1.16.210/protocol.json @@ -840,11 +840,11 @@ } ] ], - "creative": [ + "craft": [ "container", [ { - "name": "inventory_id", + "name": "action", "type": "varint" } ] @@ -858,15 +858,6 @@ } ] ], - "craft": [ - "container", - [ - { - "name": "action", - "type": "varint" - } - ] - ], "craft_slot": [ "container", [ @@ -4870,7 +4861,20 @@ ], "packet_gui_data_pick_item": [ "container", - [] + [ + { + "name": "item_name", + "type": "string" + }, + { + "name": "item_effects", + "type": "string" + }, + { + "name": "hotbar_slot", + "type": "li32" + } + ] ], "packet_adventure_settings": [ "container", @@ -6283,14 +6287,14 @@ }, { "name": "entity_unique_id", - "type": "varint" + "type": "zigzag64" }, { "name": "transition_type", "type": [ "mapper", { - "type": "varint", + "type": "varint64", "mappings": { "0": "entity", "1": "create", @@ -7162,7 +7166,7 @@ "type": [ "switch", { - "compareTo": "types.feet", + "compareTo": "type.feet", "fields": { "true": "zigzag32" }, diff --git a/data/latest/proto.yml b/data/latest/proto.yml index 68a7bbe..0d8db35 100644 --- a/data/latest/proto.yml +++ b/data/latest/proto.yml @@ -845,10 +845,16 @@ packet_set_entity_data: metadata: MetadataDictionary tick: varint +# SetActorMotion is sent by the server to change the client-side velocity of an entity. It is usually used +# in combination with server-side movement calculation. packet_set_entity_motion: !id: 0x28 !bound: both + # EntityRuntimeID is the runtime ID of the entity. The runtime ID is unique for each world session, and + # entities are generally identified in packets using this runtime ID. runtime_entity_id: varint64 + # Velocity is the new velocity the entity gets. This velocity will initiate the client-side movement of + # the entity. velocity: vec3f # SetActorLink is sent by the server to initiate an entity link client-side, meaning one entity will start @@ -1007,10 +1013,19 @@ packet_crafting_event: # Output is a list of items that were obtained as a result of crafting the recipe. result: Item[]varint - +# GUIDataPickItem is sent by the server to make the client 'select' a hot bar slot. It currently appears to +# be broken however, and does not actually set the selected slot to the hot bar slot set in the packet. packet_gui_data_pick_item: !id: 0x36 !bound: client + # ItemName is the name of the item that shows up in the top part of the popup that shows up when + # selecting an item. It is shown as if an item was selected by the player itself. + item_name: string + # ItemEffects is the line under the ItemName, where the effects of the item are usually situated. + item_effects: string + # HotBarSlot is the hot bar slot to be selected/picked. This does not currently work, so it does not + # matter what number this is. + hotbar_slot: li32 # AdventureSettings is sent by the server to update game-play related features, in particular permissions to # access these features for the client. It includes allowing the player to fly, build and mine, and attack @@ -1745,11 +1760,11 @@ packet_update_block_synced: # entity transitions from. # Note that for both possible values for TransitionType, the EntityUniqueID should point to the falling # block entity involved. - entity_unique_id: varint + entity_unique_id: zigzag64 # TransitionType is the type of the transition that happened. It is either BlockToEntityTransition, when # a block placed becomes a falling entity, or EntityToBlockTransition, when a falling entity hits the # ground and becomes a solid block again. - transition_type: varint => + transition_type: varint64 => # For falling sand, when a sand turns to an entity 0: entity # When sand turns back to a new block @@ -2231,7 +2246,7 @@ packet_player_armor_damage: if true: zigzag32 leggings_damage: type.legs ? if true: zigzag32 - boots_damage: types.feet ? + boots_damage: type.feet ? if true: zigzag32 ArmorDamageType: [ "bitflags", diff --git a/data/latest/types.yaml b/data/latest/types.yaml index 6ba41c8..b2d8730 100644 --- a/data/latest/types.yaml +++ b/data/latest/types.yaml @@ -448,7 +448,7 @@ TransactionActions: 100: craft_slot 99999: craft _: source_type? - if container or creative: + if container or craft: inventory_id: varint if world_interaction: flags: varint diff --git a/src/auth/login.js b/src/auth/login.js index 55c7ef9..49913b4 100644 --- a/src/auth/login.js +++ b/src/auth/login.js @@ -3,6 +3,7 @@ const JWT = require('jsonwebtoken') const DataProvider = require('../../data/provider') const ecPem = require('ec-pem') const curve = 'secp384r1' +const { nextUUID } = require('../datatypes/util') module.exports = (client, server, options) => { const skinGeom = fs.readFileSync(DataProvider(options.protocolVersion).getPath('skin_geom.txt'), 'utf-8') @@ -45,10 +46,10 @@ module.exports = (client, server, options) => { CapeImageHeight: 0, CapeImageWidth: 0, CapeOnClassicSkin: false, - ClientRandomId: 1, // TODO make biggeer + ClientRandomId: Date.now(), CurrentInputMode: 1, DefaultInputMode: 1, - DeviceId: '2099de18-429a-465a-a49b-fc4710a17bb3', // TODO random + DeviceId: nextUUID(), DeviceModel: '', DeviceOS: client.session?.deviceOS || 7, GameVersion: options.version || '1.16.201', @@ -64,7 +65,7 @@ module.exports = (client, server, options) => { // inside of PlayFab. PlayFabId: '5eb65f73-af11-448e-82aa-1b7b165316ad.persona-e199672a8c1a87e0-0', // 1.16.210 PremiumSkin: false, - SelfSignedId: '78eb38a6-950e-3ab9-b2cf-dd849e343701', + SelfSignedId: '78eb38a6-950e-3ab9-b2cf-dd849e343702', ServerAddress: `${options.hostname}:${options.port}`, SkinAnimationData: '', SkinColor: '#ffffcd96', diff --git a/src/datatypes/util.js b/src/datatypes/util.js index 4a14e31..b080577 100644 --- a/src/datatypes/util.js +++ b/src/datatypes/util.js @@ -39,4 +39,8 @@ function uuidFrom (string) { return UUID.v3({ namespace: '6ba7b811-9dad-11d1-80b4-00c04fd430c8', name: string }) } -module.exports = { getFiles, sleep, waitFor, serialize, uuidFrom } +function nextUUID () { + return uuidFrom(Date.now().toString()) +} + +module.exports = { getFiles, sleep, waitFor, serialize, uuidFrom, nextUUID } diff --git a/src/rak.js b/src/rak.js index e4a203d..88682d6 100644 --- a/src/rak.js +++ b/src/rak.js @@ -23,12 +23,13 @@ class RakNativeClient extends EventEmitter { this.raknet.on('encapsulated', ({ buffer, address }) => { this.onEncapsulated(buffer, address) }) - this.raknet.on('connected', () => { + + this.raknet.on('connect', () => { this.connected = true this.onConnected() }) - this.raknet.on('disconnected', ({ reason }) => { + this.raknet.on('disconnect', ({ reason }) => { this.connected = false this.onCloseConnection(reason) }) diff --git a/src/server.js b/src/server.js index bf440d3..c2dcdf7 100644 --- a/src/server.js +++ b/src/server.js @@ -3,7 +3,7 @@ const { createDeserializer, createSerializer } = require('./transforms/serialize const { Player } = require('./serverPlayer') const { RakServer } = require('./rak') const Options = require('./options') -const debug = require('debug')('minecraft-protocol') +const debug = globalThis.isElectron ? console.debug : require('debug')('minecraft-protocol') class Server extends EventEmitter { constructor (options) { @@ -62,6 +62,7 @@ class Server extends EventEmitter { this.raknet.onOpenConnection = this.onOpenConnection this.raknet.onCloseConnection = this.onCloseConnection this.raknet.onEncapsulated = this.onEncapsulated + return { hostname, port } } close (disconnectReason) {