client packet verification
This commit is contained in:
parent
8c40910809
commit
57290cd180
4 changed files with 96 additions and 15 deletions
|
|
@ -1,4 +1,4 @@
|
|||
const RakClient = require('@jsprismarine/raknet/client')
|
||||
const RakClient = require('jsp-raknet/client')
|
||||
const { Worker, isMainThread, parentPort } = require('worker_threads')
|
||||
const EncapsulatedPacket = require('@jsprismarine/raknet/protocol/encapsulated_packet')
|
||||
|
||||
|
|
|
|||
|
|
@ -119,18 +119,55 @@ class Client extends Connection {
|
|||
process.exit(1)
|
||||
}
|
||||
|
||||
tryRencode(name, params, actual) {
|
||||
if (name == 'level_chunk') {
|
||||
console.log("Skipping chunk validation, it's broken right now")
|
||||
return
|
||||
}
|
||||
const packet = this.serializer.createPacketBuffer({ name, params })
|
||||
|
||||
console.assert(packet.toString('hex') == actual.toString('hex'))
|
||||
if (packet.toString('hex') !== actual.toString('hex')) {
|
||||
|
||||
const ours = packet.toString('hex').match(/.{1,16}/g).join('\n')
|
||||
const theirs = actual.toString('hex').match(/.{1,16}/g).join('\n')
|
||||
|
||||
fs.writeFileSync('ours.txt', ours)
|
||||
fs.writeFileSync('theirs.txt', theirs)
|
||||
fs.writeFileSync('ours.json', serialize(params))
|
||||
fs.writeFileSync('theirs.json', serialize(this.deserializer.parsePacketBuffer(packet).data.params))
|
||||
|
||||
throw new Error(name + ' Packet comparison failed!')
|
||||
}
|
||||
}
|
||||
|
||||
readPacket(packet) {
|
||||
// console.log('packet', packet)
|
||||
const des = this.deserializer.parsePacketBuffer(packet)
|
||||
const pakData = { name: des.data.name, params: des.data.params }
|
||||
console.log('->', pakData.name, serialize(pakData.params).slice(0, 100))
|
||||
|
||||
// No idea what this exotic 0xA0 packet is, it's not implemented anywhere
|
||||
// and seems empty. Possible gibberish from the raknet impl
|
||||
if (pakData.name == '160' || !pakData.name) { // eslint-ignore-line
|
||||
console.warn('?? Ignoring extraneous packet ', des)
|
||||
return
|
||||
}
|
||||
|
||||
// Packet verifying (decode + re-encode + match test)
|
||||
if (pakData.name) {
|
||||
this.tryRencode(pakData.name, pakData.params, packet)
|
||||
}
|
||||
|
||||
// console.info('->', JSON.stringify(pakData, (k,v) => typeof v == 'bigint' ? v.toString() : v))
|
||||
// Packet dumping
|
||||
try {
|
||||
if (!fs.existsSync(`./packets/${pakData.name}.json`)) {
|
||||
fs.writeFileSync(`./packets/${pakData.name}.json`, serialize(pakData.params, 2))
|
||||
fs.writeFileSync(`./packets/${pakData.name}.txt`, packet.toString('hex'))
|
||||
}
|
||||
} catch {}
|
||||
} catch { }
|
||||
|
||||
switch (des.data.name) {
|
||||
case 'server_to_client_handshake':
|
||||
this.emit('client.server_handshake', des.data.params)
|
||||
|
|
@ -143,6 +180,10 @@ class Client extends Connection {
|
|||
break
|
||||
case 'start_game':
|
||||
fs.writeFileSync('start_game.json', JSON.stringify(des.data.params, (k, v) => typeof v == 'bigint' ? v.toString() : v))
|
||||
break
|
||||
case 'level_chunk':
|
||||
fs.writeFileSync(`./chunks/chunk-${chunks++}.txt`, packet.toString('hex'))
|
||||
break
|
||||
default:
|
||||
// console.log('Sending to listeners')
|
||||
}
|
||||
|
|
@ -151,6 +192,8 @@ class Client extends Connection {
|
|||
}
|
||||
}
|
||||
|
||||
var chunks = 0;
|
||||
|
||||
function serialize(obj = {}, fmt) {
|
||||
return JSON.stringify(obj, (k, v) => typeof v == 'bigint' ? v.toString() : v, fmt)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,42 @@
|
|||
// process.env.DEBUG = 'minecraft-protocol raknet'
|
||||
const { Client } = require('./client')
|
||||
|
||||
const fs = require('fs')
|
||||
// console.log = () =>
|
||||
|
||||
async function test() {
|
||||
const client = new Client({
|
||||
hostname: '127.0.0.1',
|
||||
port: 19132
|
||||
const client = new Client({
|
||||
hostname: '127.0.0.1',
|
||||
port: 19132
|
||||
})
|
||||
|
||||
client.once('resource_packs_info', (packet) => {
|
||||
client.write('resource_pack_client_response', {
|
||||
response_status: 'completed',
|
||||
resourcepackids: []
|
||||
})
|
||||
|
||||
client.once('resource_packs_info', (packet) => {
|
||||
client.write('resource_pack_client_response', {
|
||||
response_status: 'completed',
|
||||
resourcepackids: []
|
||||
})
|
||||
|
||||
client.once('resource_pack_stack', (stack) => {
|
||||
client.write('resource_pack_client_response', {
|
||||
response_status: 'completed',
|
||||
resourcepackids: []
|
||||
})
|
||||
})
|
||||
|
||||
// client.once('resource_packs_info', (packet) => {
|
||||
// client.write('resource_pack_client_response', {
|
||||
// response_status: 'completed',
|
||||
// resourcepackids: []
|
||||
// })
|
||||
// })
|
||||
})
|
||||
|
||||
|
||||
|
||||
// var read = 0;
|
||||
// client.on('level_chunk', (packet) => {
|
||||
// read++
|
||||
// fs.writeFileSync(`level_chunk-${read}.json`, JSON.stringify(packet, null, 2))
|
||||
// })
|
||||
}
|
||||
|
||||
test()
|
||||
|
|
@ -2,8 +2,8 @@ const BinaryStream = require('@jsprismarine/jsbinaryutils').default
|
|||
const BatchPacket = require('./datatypes/BatchPacket')
|
||||
const cipher = require('./transforms/encryption')
|
||||
const { EventEmitter } = require('events')
|
||||
const EncapsulatedPacket = require('@jsprismarine/raknet/protocol/encapsulated_packet')
|
||||
|
||||
const EncapsulatedPacket = require('jsp-raknet/protocol/encapsulated_packet')
|
||||
const debug = require('debug')('minecraft-protocol')
|
||||
|
||||
class Connection extends EventEmitter {
|
||||
startEncryption(iv) {
|
||||
|
|
@ -15,8 +15,10 @@ class Connection extends EventEmitter {
|
|||
|
||||
write(name, params) { // TODO: Batch
|
||||
console.log('Need to encode', name, params)
|
||||
// console.log('<-', name)
|
||||
const batch = new BatchPacket()
|
||||
const packet = this.serializer.createPacketBuffer({ name, params })
|
||||
console.log('Sending buf', packet.toString('hex'))
|
||||
batch.addEncodedPacket(packet)
|
||||
|
||||
if (this.encryptionEnabled) {
|
||||
|
|
@ -45,6 +47,19 @@ class Connection extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a MCPE packet buffer
|
||||
*/
|
||||
sendBuffer(buffer) {
|
||||
const batch = new BatchPacket()
|
||||
batch.addEncodedPacket(buffer)
|
||||
if (this.encryptionEnabled) {
|
||||
this.sendEncryptedBatch(batch)
|
||||
} else {
|
||||
this.sendDecryptedBatch(batch)
|
||||
}
|
||||
}
|
||||
|
||||
sendDecryptedBatch(batch) {
|
||||
const buf = batch.encode()
|
||||
// send to raknet
|
||||
|
|
@ -53,10 +68,11 @@ class Connection extends EventEmitter {
|
|||
|
||||
sendEncryptedBatch(batch) {
|
||||
const buf = batch.stream.getBuffer()
|
||||
console.log('Sending encrypted batch', batch)
|
||||
debug('Sending encrypted batch', batch)
|
||||
this.encrypt(buf)
|
||||
}
|
||||
|
||||
// TODO: Rename this to sendEncapsulated
|
||||
sendMCPE(buffer, immediate) {
|
||||
if (this.worker) {
|
||||
console.log('-> buf', buffer)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue