首页 > 解决方案 > Parsing TCP packet buffers in Node.js

问题描述

I am trying to create a TCP game server (for an old version of Minecraft), and I want to use Node.js as the server software. I have created a basic socket server, and I am wondering what the best way to go about parsing the data buffers would be?

Here's my code right now:

const net = require('net')
const serialize = require('node-serialize');
const server = net.createServer();

server.on('connection', (socket) => {
    socket.on('data', (buffer) => {
        let packetID = buffer.readUInt8(0);
        console.log(`Packet ID: ${packetID}`)

        switch (packetID) {
            case 1: 
                // Login Request
                // Log some info about the request
                let protocol = buffer.readUIntBE(2, 3)
                let playername = buffer.slice(7, buffer.length).toString()
                console.log(`Player name: ${playername}`)
                console.log(`Client protocol version: ${protocol}`)
                console.log(buffer)

                // Send login confirmation packet
                var packetInfo = [0x01, 0]
                var entityID = intToByteArray(1298)
                var seed = intToByteArray(971768181197178410)
                var mode = [0]
                var dimension = [0]
                var difficulty = [1]
                var height = [128]
                var maxPlayers = [8]
                var buff = Buffer.from([].concat.apply([], [packetInfo, entityID, seed, mode, dimension, difficulty, height, maxPlayers]))
                console.log(`Bytes: ${buff.byteLength}`)
                //socket.write(buff)

                // Disconnect/Kick Packet
                var buffr = stringToByteArray("§eKicked from the server (cause world doesn't load yet)")
                var packetbugger = [0xFF, 0, buffr.length / 2, 0]
                var finalbuffr = Buffer.from([].concat.apply([], [packetbugger, buffr]))
                socket.write(finalbuffr)
            case 2: 
                // Handshake
                // Sends a "-"
                console.log(serialize.unserialize(buffer).Username);
                socket.write(Buffer.from([0x02, 0, 1, 0, 0x2d]))
        }
    })

    socket.on('error', (error) => {
        console.error(error)
    })
})

server.listen("25565", "localhost")

I think that there's probably a better way to parse packets than what I am doing. Every packet that Minecraft sends to the server has it's own id, as detailed on wiki.vg. Here's a sample packet structure for a server to client packet: enter image description here

How would I be able to retrieve the readable data from a packet buffer in Node.js? For example, I'd like to be able to extract the player name string from the packet. However, the most important thing for me would be extracting the packet ID in hex form. I have tried, but I am unable to do so. Any help or suggestions as to how to go about this would be massively appreciated.

Also, how would I be able to craft my own packet in the same format as the picture above? All of these are questions I am struggling to find good answers to.

标签: node.jsparsingtcpbufferpacket

解决方案


推荐阅读