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:
Daniel Scalzi 2020-08-27 21:08:53 -04:00
parent 27f95235f8
commit 571b788e25
No known key found for this signature in database
GPG Key ID: D18EA3FB4B142A57

View File

@ -243,33 +243,15 @@ 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 // Length of Packet ID + Data
packetLength = inboundPacket.readVarInt() const packetLength = inboundPacket.readVarInt() // First VarInt is packet length.
const packetType = inboundPacket.readVarInt() // Second VarInt is packet type.
// Second VarInt is packet type.
const packetType = inboundPacket.readVarInt()
console.log(packetType, packetLength)
if(packetType !== 0x00) { if(packetType !== 0x00) {
// TODO // TODO
@ -278,21 +260,26 @@ export function getServerStatus(protocol: number, address: string, port = 25565)
return return
} }
// Size of packetLength VarInt is not included in the packetLength.
bytesLeft = packetLength + getVarIntSize(packetLength) bytesLeft = packetLength + getVarIntSize(packetLength)
doAppend = false
// 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) { if(bytesLeft > 0) {
bytesLeft -= nextData.length
++iterations
bytesLeft -= data.length
if(doAppend) { if(doAppend) {
inboundPacket.append(data) inboundPacket.append(nextData)
} }
console.log(bytesLeft, data.toString('utf-8'))
} }
// All bytes read, attempt conversion.
if(bytesLeft === 0) { if(bytesLeft === 0) {
// Remainder of Buffer is the server status json. // Remainder of Buffer is the server status json.
@ -305,11 +292,15 @@ export function getServerStatus(protocol: number, address: string, port = 25565)
} catch(err) { } catch(err) {
socket.destroy() socket.destroy()
logger.error('Failed to parse server status JSON', err) logger.error('Failed to parse server status JSON', err)
console.log(result)
reject(new Error('Failed to parse server status JSON')) 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))
}) })