我正在尝试创建一个TCP游戏服务器(用于Minecraft的旧版本),并且我想使用Node.js作为服务器软件。我已经创建了一个基本的套接字服务器,我想知道解析数据缓冲区的最佳方法是什么?
这是我的代码:
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")
我认为,解析数据包可能比我正在做的更好。 Minecraft发送到服务器的每个数据包都有其自己的ID,如wiki.vg所述。这是服务器到客户端数据包的示例数据包结构:
如何从Node.js的数据包缓冲区中检索可读数据?例如,我希望能够从数据包中提取玩家名称字符串。但是,对我来说,最重要的是提取十六进制形式的数据包ID。我已经尝试过,但无法这样做。任何有关此操作的帮助或建议,将不胜感激。
此外,我如何能够以与上图相同的格式制作自己的数据包?所有这些都是我努力寻找好的答案的问题。