bedrock-protocol/src/createClient.js
2021-04-23 03:23:43 -04:00

75 lines
2.2 KiB
JavaScript

const { Client } = require('./client')
const { RakClient } = require('./rak')
const assert = require('assert')
const advertisement = require('./server/advertisement')
/** @param {{ version?: number, host: string, port?: number, connectTimeout?: number }} options */
function createClient (options) {
assert(options)
const client = new Client({ port: 19132, ...options })
if (options.skipPing) {
connect(client)
} else { // Try to ping
client.ping().then(data => {
const advert = advertisement.fromServerName(data)
console.log(`Connecting to server ${advert.motd} (${advert.name}), version ${advert.version}`)
// TODO: update connect version based on ping response
connect(client)
}, client)
}
return client
}
function connect (client) {
// Actually connect
client.connect()
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.queue('client_cache_status', { enabled: false })
client.queue('request_chunk_radius', { chunk_radius: client.renderDistance || 1 })
client.queue('tick_sync', { request_time: BigInt(Date.now()), response_time: 0n })
})
const KEEPALIVE_INTERVAL = 10 // Send tick sync packets every 10 ticks
let keepalive
client.tick = 0n
client.once('spawn', () => {
keepalive = setInterval(() => {
// Client fills out the request_time and the server does response_time in its reply.
client.queue('tick_sync', { request_time: client.tick, response_time: 0n })
client.tick += BigInt(KEEPALIVE_INTERVAL)
}, 50 * KEEPALIVE_INTERVAL)
client.on('tick_sync', async packet => {
client.emit('heartbeat', packet.response_time)
client.tick = packet.response_time
})
})
client.once('close', () => {
clearInterval(keepalive)
})
}
async function ping ({ host, port }) {
const con = new RakClient({ host, port })
const ret = await con.ping()
con.close()
return advertisement.fromServerName(ret)
}
module.exports = { createClient, ping }