mirror of
https://github.com/dscalzi/HeliosLauncher.git
synced 2024-12-22 11:42:14 -08:00
A better solution to read long data.
Assign a once listener to pick up the initial data including the packet type and length. Assign a subsequent listener to read the remainder of the data.
This commit is contained in:
parent
27f95235f8
commit
571b788e25
@ -243,74 +243,65 @@ export function getServerStatus(protocol: number, address: string, port = 25565)
|
|||||||
|
|
||||||
const maxTries = 2
|
const maxTries = 2
|
||||||
let iterations = 0
|
let iterations = 0
|
||||||
|
|
||||||
let inboundPacket!: ClientBoundPacket
|
|
||||||
let packetLength = 0
|
|
||||||
let bytesLeft = -1
|
let bytesLeft = -1
|
||||||
|
|
||||||
socket.on('data', (data) => {
|
socket.once('data', (data) => {
|
||||||
|
|
||||||
if(iterations > maxTries) {
|
const inboundPacket = new ClientBoundPacket(data)
|
||||||
socket.destroy()
|
|
||||||
reject(new Error(`Data read from ${address}:${port} exceeded ${maxTries} iterations, closing connection.`))
|
|
||||||
}
|
|
||||||
|
|
||||||
let doAppend = true
|
|
||||||
|
|
||||||
// First delivery
|
|
||||||
if(bytesLeft == -1) {
|
|
||||||
|
|
||||||
inboundPacket = new ClientBoundPacket(data)
|
|
||||||
|
|
||||||
// First VarInt is packet length.
|
|
||||||
// Length of Packet ID + Data
|
|
||||||
packetLength = inboundPacket.readVarInt()
|
|
||||||
|
|
||||||
// Second VarInt is packet type.
|
|
||||||
const packetType = inboundPacket.readVarInt()
|
|
||||||
|
|
||||||
console.log(packetType, packetLength)
|
|
||||||
|
|
||||||
if(packetType !== 0x00) {
|
|
||||||
// TODO
|
|
||||||
socket.destroy()
|
|
||||||
reject(new Error(`Invalid response. Expected packet type ${0x00}, received ${packetType}!`))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
bytesLeft = packetLength + getVarIntSize(packetLength)
|
|
||||||
doAppend = false
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bytesLeft > 0) {
|
|
||||||
|
|
||||||
++iterations
|
|
||||||
bytesLeft -= data.length
|
|
||||||
if(doAppend) {
|
|
||||||
inboundPacket.append(data)
|
|
||||||
}
|
|
||||||
console.log(bytesLeft, data.toString('utf-8'))
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bytesLeft === 0) {
|
|
||||||
|
|
||||||
// Remainder of Buffer is the server status json.
|
|
||||||
const result = inboundPacket.readString()
|
|
||||||
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(result)
|
|
||||||
socket.end()
|
|
||||||
resolve(unifyStatusResponse(parsed))
|
|
||||||
} catch(err) {
|
|
||||||
socket.destroy()
|
|
||||||
logger.error('Failed to parse server status JSON', err)
|
|
||||||
console.log(result)
|
|
||||||
reject(new Error('Failed to parse server status JSON'))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Length of Packet ID + Data
|
||||||
|
const packetLength = inboundPacket.readVarInt() // First VarInt is packet length.
|
||||||
|
const packetType = inboundPacket.readVarInt() // Second VarInt is packet type.
|
||||||
|
|
||||||
|
if(packetType !== 0x00) {
|
||||||
|
// TODO
|
||||||
|
socket.destroy()
|
||||||
|
reject(new Error(`Invalid response. Expected packet type ${0x00}, received ${packetType}!`))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Size of packetLength VarInt is not included in the packetLength.
|
||||||
|
bytesLeft = packetLength + getVarIntSize(packetLength)
|
||||||
|
|
||||||
|
// Listener to keep reading until we have read all the bytes into the buffer.
|
||||||
|
const packetReadListener = (nextData: Buffer, doAppend: boolean) => {
|
||||||
|
|
||||||
|
if(iterations > maxTries) {
|
||||||
|
socket.destroy()
|
||||||
|
reject(new Error(`Data read from ${address}:${port} exceeded ${maxTries} iterations, closing connection.`))
|
||||||
|
}
|
||||||
|
++iterations
|
||||||
|
|
||||||
|
if(bytesLeft > 0) {
|
||||||
|
bytesLeft -= nextData.length
|
||||||
|
if(doAppend) {
|
||||||
|
inboundPacket.append(nextData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All bytes read, attempt conversion.
|
||||||
|
if(bytesLeft === 0) {
|
||||||
|
|
||||||
|
// Remainder of Buffer is the server status json.
|
||||||
|
const result = inboundPacket.readString()
|
||||||
|
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(result)
|
||||||
|
socket.end()
|
||||||
|
resolve(unifyStatusResponse(parsed))
|
||||||
|
} catch(err) {
|
||||||
|
socket.destroy()
|
||||||
|
logger.error('Failed to parse server status JSON', err)
|
||||||
|
reject(new Error('Failed to parse server status JSON'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the data we just received.
|
||||||
|
packetReadListener(data, false)
|
||||||
|
// Add a listener to keep reading if the data is too long.
|
||||||
|
socket.on('data', (data) => packetReadListener(data, true))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on('error', (err: NodeJS.ErrnoException) => {
|
socket.on('error', (err: NodeJS.ErrnoException) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user