viewer: refactor and cleanup

This commit is contained in:
extremeheat 2021-04-03 22:54:42 -04:00
commit 32d52e9878
9 changed files with 363 additions and 394 deletions

View file

@ -1,15 +1,9 @@
/* eslint-disable */
const { Client } = require('bedrock-protocol')
const { Version } = require('bedrock-provider')
const { WorldView } = require('prismarine-viewer/viewer')
const vec3 = require('vec3')
const World = require('prismarine-world')()
const ChunkColumn = require('./Chunk')()
const { Physics, PlayerState } = require('prismarine-physics')
const { performance } = require('perf_hooks')
const PHYSICS_INTERVAL_MS = 50
const PHYSICS_TIMESTEP = PHYSICS_INTERVAL_MS / 1000
const { MovementManager } = require('./movements')
class BotProvider extends WorldView {
chunks = {}
@ -21,72 +15,7 @@ class BotProvider extends WorldView {
this.connect()
this.listenToBot()
this.world = new World()
// Server auth movement : we send inputs, server calculates position & sends back
this.serverMovements = true
this.tick = 0n
}
connect() {
const client = new Client({ hostname: '127.0.0.1', version: '1.16.210', port: 19132, connectTimeout: 100000 })
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: 1 })
client.queue('tick_sync', { request_time: BigInt(Date.now()), response_time: 0n })
})
this.client = client
}
close() {
this.client?.close()
}
listenToBot() {
this.client.on('connect', () => {
console.log('Bot has connected!')
})
this.client.on('start_game', packet => {
this.updatePosition(packet.player_position)
})
this.client.on('spawn', () => {
// server allows client to render chunks & spawn in world
this.emit('spawn', { position: this.lastPos })
this.tickLoop = setInterval(() => {
this.client.queue('tick_sync', { request_time: BigInt(Date.now()), response_time: 0n })
})
})
this.client.on('level_chunk', packet => {
this.handleChunk(packet)
})
this.client.on('move_player', packet => {
if (packet.runtime_id === this.client.entityId) this.updatePosition(packet.position)
})
this.client.on('set_entity_motion', packet => {
if (packet.runtime_id === this.client.entityId) this.updatePosition(packet.position)
})
this.client.on('tick_sync', (packet) => {
this.lastTick = packet.response_time
})
this.movements = new MovementManager(this)
}
handleChunk(packet, render = true) {
@ -102,232 +31,27 @@ class BotProvider extends WorldView {
})
}
updatePlayerCamera(id, pos, yaw, pitch, updateState) {
// TODO: do this properly
window.viewer.viewer.entities.update({
name: 'player',
id,
pos,
width: 0.6,
height: 1.8,
yaw,
pitch
})
if (updateState) {
this.movements.updatePosition(pos, yaw, pitch)
}
}
stopBot() {
clearInterval(this.tickLoop)
}
// Server gives us a new position
updatePosition(pos) {
this.lastPos ??= vec3(pos)
super.updatePosition(this.lastPos)
}
// Ask the server to be in a new position
requestPosition(time, inputState) {
const positionUpdated = !this.lastSentPos || !this.lastPos.equals(this.lastSentPos)
// if (globalThis.logging)console.log('New pos', this.lastSentPos,this.lastPos)
if (positionUpdated) {
this.lastSentPos = this.lastPos.clone()
console.log('We computed', this.lastPos)
this.pushCamera({
position: this.lastSentPos,
input_data: {},
yaw: this.playerState.yaw, pitch: this.playerState.pitch
}, 2)
return
this.client.queue('player_auth_input', {
pitch: this.player.pitch,
yaw: this.player.yaw,
position: {
x: this.lastPos.x,
y: this.lastPos.y,
z: this.lastPos.z
},
move_vector: { // Minecraft coords, N: Z+1, S: Z-1, W: X+1, E: X-1
x: inputState.left ? 1 : (inputState.right ? -1 : 0),
z: inputState.up ? 1 : (inputState.down ? -1 : 0)
},
head_yaw: this.player.headYaw,
input_data: inputState,
input_mode: 'mouse',
play_mode: 'screen',
tick: this.tick,
delta: this.lastSentPos?.minus(this.lastPos) ?? { x: 0, y: 0, z: 0 }
})
this.positionUpdated = false
this.lastSentPos = this.lastPos.clone()
}
}
initPhys(position, velocity, yaw = 0, pitch = 0, headYaw = 0) {
this.lastPos = position ? vec3(position) : vec3(0, 0, 0)
this.lastVel = velocity ? vec3(velocity) : vec3(0, 0, 0)
this.player = {
version: '1.16.1',
inventory: {
slots: []
},
entity: {
effects: {},
position: this.lastPos,
velocity: this.lastVel,
onGround: false,
isInWater: false,
isInLava: false,
isInWeb: false,
isCollidedHorizontally: false,
isCollidedVertically: false,
yaw,
pitch,
headYaw // bedrock
},
events: { // Control events to send next tick
startSprint: false,
stopSprint: false,
startSneak: false,
stopSneak: false
},
jumpTicks: 0,
jumpQueued: false,
downJump: false
}
const mcData = require('minecraft-data')('1.16.1')
this.physics = Physics(mcData, this.world)
this.controls = {
forward: false,
back: false,
left: false,
right: false,
jump: false,
sprint: false,
sneak: false
}
this.playerState = new PlayerState(this.player, this.controls)
}
// This function should be executed each tick (every 0.05 seconds)
// How it works: https://gafferongames.com/post/fix_your_timestep/
timeAccumulator = 0
lastPhysicsFrameTime = null
inputQueue = []
doPhysics() {
const now = performance.now()
const deltaSeconds = (now - this.lastPhysicsFrameTime) / 1000
this.lastPhysicsFrameTime = now
this.timeAccumulator += deltaSeconds
while (this.timeAccumulator >= PHYSICS_TIMESTEP) {
let q = this.inputQueue.shift()
if (q) {
Object.assign(this.playerState.control, q)
if (q.yaw) { this.player.entity.yaw = q.yaw; this.playerState.yaw = q.yaw; }
if (q.pitch) this.player.entity.pitch = q.pitch
}
this.physics.simulatePlayer(this.playerState, this.world.sync).apply(this.player)
this.lastPos = this.playerState.pos
this.requestPosition(PHYSICS_TIMESTEP, {
ascend: false,
descend: false,
// Players bob up and down in water, north jump is true when going up.
// In water this is only true after the player has reached max height before bobbing back down.
north_jump: this.player.jumpTicks > 0, // Jump
jump_down: this.controls.jump, // Jump
sprint_down: this.controls.sprint,
change_height: false,
jumping: this.controls.jump, // Jump
auto_jumping_in_water: false,
sneaking: false,
sneak_down: false,
up: this.controls.forward,
down: this.controls.back,
left: this.controls.left,
right: this.controls.right,
up_left: false,
up_right: false,
want_up: this.controls.jump, // Jump
want_down: false,
want_down_slow: false,
want_up_slow: false,
sprinting: false,
ascend_scaffolding: false,
descend_scaffolding: false,
sneak_toggle_down: false,
persist_sneak: false,
start_sprinting: this.player.events.startSprint || false,
stop_sprinting: this.player.events.stopSprint || false,
start_sneaking: this.player.events.startSneak || false,
stop_sneaking: this.player.events.stopSneak || false,
// Player is Update Aqatic swimming
start_swimming: false,
// Player stops Update Aqatic swimming
stop_swimming: false,
start_jumping: this.player.jumpTicks === 1, // Jump
start_gliding: false,
stop_gliding: false,
})
this.timeAccumulator -= PHYSICS_TIMESTEP
}
}
startPhys() {
console.log('Start phys')
this.physicsLoop = setInterval(() => {
this.doPhysics()
}, PHYSICS_INTERVAL_MS)
}
setControlState(control, state) {
if (this.controls[control] === state) return
if (control === 'sprint') {
this.player.events.startSprint = state
this.player.events.stopSprint = !state
this.controls.sprint = true
} else if (control === 'sneak') {
this.player.events.startSneak = state
this.player.events.stopSneak = !state
this.controls.sprint = true
}
}
pushInputState(state, yaw, pitch) {
const yawRad = d2r(yaw)
const pitchRad = d2r(pitch)
this.inputQueue.push({
forward: state.up,
back: state.down,// TODO: left and right switched ???
left: state.right,
right: state.left,
jump: state.jump_down,
sneak: state.sprint_down,
yaw: yawRad, pitch: pitchRad,
})
globalThis.yaw = [yaw, yawRad]
if (global.logYaw) console.log('Pushed', yaw, pitch)
}
pushCamera(state, id = 1) {
let { x, y, z } = state.position
if (id == 1) y -= 1.62 // account for player bb
const pos = vec3({ x, y, z })
if (state.position) {
viewer.viewer.entities.update({
name: 'player',
id, pos, width: 0.6, height: 1.8,
yaw: id == 1 ? d2r(state.yaw) : state.yaw
})
//viewer.viewer.camera.position.set(x, y, z)
}
if (state.input_data.sneak_down) {
this.player.entity.position = pos
this.playerState.pos = this.player.entity.position
}
}
onCameraMovement(newYaw, newPitch, newHeadYaw) {
this.player.yaw = newYaw
this.player.pitch = newPitch
this.player.headYaw = newHeadYaw
}
stopPhys() {
clearInterval(this.physicsLoop)
this.movements.stopPhys()
}
}
const d2r = deg => (180 - (deg < 0 ? (360 + deg) : deg)) * (Math.PI / 180)
module.exports = { BotProvider }

View file

@ -1,21 +1,16 @@
/* global THREE */
const { Viewer, MapControls } = require('prismarine-viewer/viewer')
const { Vec3 } = require('vec3')
const { BotProvider } = require('./BotProvider')
// const { Vec3 } = require('vec3')
// const { BotProvider } = require('./BotProvider')
const { ProxyProvider } = require('./ProxyProvider')
global.THREE = require('three')
const MCVER = '1.16.1'
class BotViewer {
constructor () {
}
start () {
// this.bot = new BotProvider()
this.bot = new ProxyProvider()
// return
// Create three.js context, add to page
this.renderer = new THREE.WebGLRenderer()
this.renderer.setPixelRatio(window.devicePixelRatio || 1)
@ -61,8 +56,6 @@ class BotViewer {
onKeyDown = (evt) => {
console.log('Key down', evt)
// this.bot.initPhys()
// this.bot.startPhys()
}
registerBrowserEvents () {

View file

@ -1,6 +1,4 @@
const { ChunkColumn, Version } = require('bedrock-provider')
const { SubChunk } = require('bedrock-provider/js/SubChunk')
try { const v8 = require('v8') } catch { }
const { ChunkColumn } = require('bedrock-provider')
const Block = require('prismarine-block')('1.16.1')
@ -13,42 +11,6 @@ class ChunkColumnWrapped extends ChunkColumn { // pchunk compatiblity wrapper
getBlockStateId (pos) {
return super.getBlock(pos.x, pos.y, pos.z)?.stateId
}
// // Serialization
// serialize() {
// if (typeof v8 === 'undefined') {
// return JSON.stringify(this)
// } else {
// const copy = { ...this, sections: [] }
// for (const section of this.sections) {
// copy.sections.push(v8.serialize(section))
// }
// return v8.serialize(copy)
// }
// }
// toJson() { return this.serialize() }
// static deserialize(obj) {
// if (typeof obj === 'string') {
// Oject.assign(this, JSON.parse(obj))
// } else { // Buffer
// const chunk = new ChunkColumnWrapped()
// const des = v8.deserialize(obj)
// Object.assign(chunk, des)
// chunk.sections = []
// for (const section of des.sections) {
// const s = new SubChunk()
// chunk.sections.push(Object.assign(s, v8.deserialize(section)))
// }
// // console.log('Des',obj,chunk)
// return chunk
// }
// }
// static fromJson(obj) {
// return ChunkColumnWrapped.deserialize(obj)
// }
}
module.exports = (version) => {

View file

@ -0,0 +1,68 @@
const { Client } = require('bedrock-protocol')
const { BotProvider } = require('./BotProvider')
class ClientProvider extends BotProvider {
connect () {
const client = new Client({ hostname: '127.0.0.1', version: '1.16.210', port: 19132, connectTimeout: 100000 })
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: 1 })
client.queue('tick_sync', { request_time: BigInt(Date.now()), response_time: 0n })
})
this.client = client
}
close () {
this.client?.close()
}
listenToBot () {
this.client.on('connect', () => {
console.log('Bot has connected!')
})
this.client.on('start_game', packet => {
this.updatePosition(packet.player_position)
})
this.client.on('spawn', () => {
// server allows client to render chunks & spawn in world
this.emit('spawn', { position: this.lastPos })
this.tickLoop = setInterval(() => {
this.client.queue('tick_sync', { request_time: BigInt(Date.now()), response_time: 0n })
})
})
this.client.on('level_chunk', packet => {
this.handleChunk(packet)
})
this.client.on('move_player', packet => {
if (packet.runtime_id === this.client.entityId) this.updatePosition(packet.position)
})
this.client.on('set_entity_motion', packet => {
if (packet.runtime_id === this.client.entityId) this.updatePosition(packet.position)
})
this.client.on('tick_sync', (packet) => {
this.lastTick = packet.response_time
})
}
}
module.exports = { ClientProvider }

View file

@ -1,6 +1,6 @@
const { Relay } = require('bedrock-protocol')
const { BotProvider } = require('./BotProvider')
const vec3 = require('vec3')
const { diff } = require('./util')
class ProxyProvider extends BotProvider {
lastPlayerMovePacket
@ -15,61 +15,36 @@ class ProxyProvider extends BotProvider {
port: 19132
}
})
proxy.listen()
console.info('Waiting for connect')
const maxChunks = 40
proxy.on('join', (client, server) => {
client.on('clientbound', ({ name, params }) => {
if (name == 'level_chunk') {
// maxChunks--
// if (maxChunks >= 0) {
// this.handleChunk(params)
// }
if (name === 'level_chunk') {
this.handleChunk(params, true)
} else if (name == 'start_game') {
this.initPhys(params.player_position, null, params.rotation.z, params.rotation.x, 0)
} else if (name === 'start_game') {
this.movements.init('', params.player_position, null, params.rotation.z, params.rotation.x, 0)
} else if (name === 'play_status') {
// this.emit('spawn', { position: server.startGameData.player_position })
this.startPhys()
this.movements.startPhys()
console.info('Started physics!')
} else if (name === 'move_player') {
console.log('move_player', packet)
// if (packet.runtime_id === server.entityId) {
// this.updatePosition(packet.position)
// if (this.lastServerMovement.x == packet.position.x && this.lastServerMovement.y == packet.position.y && this.lastServerMovement.z == packet.position.z) {
// } else {
// console.log('Server computed', packet.position)
// }
// this.lastServerMovement = { ...packet.position }
// }
console.log('move_player', params)
this.movements.updatePosition(params.position, params.yaw, params.pitch, params.head_yaw, params.tick)
}
if (name.includes('entity') || name.includes('network_chunk_publisher_update') || name.includes('tick') || name.includes('level')) return
console.log('CB', name)
})
client.on('serverbound', ({ name, params }) => {
// { name, params }
if (name == 'player_auth_input') {
// console.log('player_auth_input', this.lastPlayerMovePacket, params)
// this.controls.forward = params.input_data.up
// this.controls.back = params.input_data.down
// this.controls.left = params.input_data.left
// this.controls.right = params.input_data.right
// this.player.entity.pitch = params.pitch
// this.player.entity.yaw = params.yaw
this.pushInputState(params.input_data, params.yaw, params.pitch)
this.pushCamera(params)
this.lastMovePacket = params
if (name === 'player_auth_input') {
this.movements.pushInputState(params.input_data, params.yaw, params.pitch)
this.movements.pushCameraControl(params, 1)
// Log Movement deltas
{
this.lastMovePacket = params
if (this.firstPlayerMovePacket) {
const id = diff(this.firstPlayerMovePacket.input_data, params.input_data)
const md = diff(this.firstPlayerMovePacket.move_vector, params.move_vector)
@ -109,18 +84,5 @@ class ProxyProvider extends BotProvider {
}
}
const difference = (o1, o2) => Object.keys(o2).reduce((diff, key) => {
if (o1[key] === o2[key]) return diff
return {
...diff,
[key]: o2[key]
}
}, {})
// console.log = () => {}
// console.debug = () => {}
const diff = (o1, o2) => { const dif = difference(o1, o2); return Object.keys(dif).length ? dif : null }
module.exports = { ProxyProvider }
globalThis.logging = true

View file

@ -0,0 +1,244 @@
const { Physics, PlayerState } = require('prismarine-physics')
const { performance } = require('perf_hooks')
const { d2r } = require('./util')
const vec3 = require('vec3')
const PHYSICS_INTERVAL_MS = 50
const PHYSICS_TIMESTEP = PHYSICS_INTERVAL_MS / 1000
class MovementManager {
// Server auth movement : we send inputs, server calculates position & sends back
serverMovements = false
constructor (bot) {
this.bot = bot
this.world = bot.world
// Physics tick
this.tick = 0n
}
get lastPos () { return this.player.entity.position.clone() }
set lastPos (newPos) { this.player.entity.position.set(newPos.x, newPos.y, newPos.z) }
get lastRot () { return vec3(this.player.entity.yaw, this.player.entity.pitch, this.player.entity.headYaw) }
set lastRot (rot) {
this.player.entity.yaw = rot.x
this.player.entity.pitch = rot.y
if (rot.z) this.player.entity.headYaw = rot.z
}
// Ask the server to be in a new position
requestPosition (time, inputState) {
const positionUpdated = !this.lastSentPos || !this.lastPos.equals(this.lastSentPos)
const rotationUpdated = !this.lastSentRot || !this.lastRot.equals(this.lastSentRot)
if (positionUpdated) {
this.lastSentPos = this.lastPos.clone()
console.log('We computed', this.lastPos)
this.bot.updatePlayerCamera(2, this.lastSentPos, this.playerState.yaw, this.playerState.pitch)
if (this.serverMovements) {
this.client.queue('player_auth_input', {
pitch: this.player.pitch,
yaw: this.player.yaw,
position: {
x: this.lastPos.x,
y: this.lastPos.y,
z: this.lastPos.z
},
move_vector: { // Minecraft coords, N: Z+1, S: Z-1, W: X+1, E: X-1
x: inputState.left ? 1 : (inputState.right ? -1 : 0),
z: inputState.up ? 1 : (inputState.down ? -1 : 0)
},
head_yaw: this.player.headYaw,
input_data: inputState,
input_mode: 'mouse',
play_mode: 'screen',
tick: this.tick,
delta: this.lastSentPos?.minus(this.lastPos) ?? { x: 0, y: 0, z: 0 }
})
this.positionUpdated = false
}
this.lastSentPos = this.lastPos
this.lastSentRot = this.lastRot
}
}
init (movementAuthority, position, velocity, yaw = 0, pitch = 0, headYaw = 0) {
if (movementAuthority.includes('server')) {
this.serverMovements = true
}
this.player = {
version: '1.16.1',
inventory: {
slots: []
},
entity: {
effects: {},
position: vec3(position),
velocity: vec3(velocity),
onGround: false,
isInWater: false,
isInLava: false,
isInWeb: false,
isCollidedHorizontally: false,
isCollidedVertically: false,
yaw,
pitch,
headYaw // bedrock
},
events: { // Control events to send next tick
startSprint: false,
stopSprint: false,
startSneak: false,
stopSneak: false
},
jumpTicks: 0,
jumpQueued: false,
downJump: false
}
const mcData = require('minecraft-data')('1.16.1')
this.physics = Physics(mcData, this.world)
this.controls = {
forward: false,
back: false,
left: false,
right: false,
jump: false,
sprint: false,
sneak: false
}
}
// This function should be executed each tick (every 0.05 seconds)
// How it works: https://gafferongames.com/post/fix_your_timestep/
timeAccumulator = 0
lastPhysicsFrameTime = null
inputQueue = []
doPhysics () {
const now = performance.now()
const deltaSeconds = (now - this.lastPhysicsFrameTime) / 1000
this.lastPhysicsFrameTime = now
this.timeAccumulator += deltaSeconds
while (this.timeAccumulator >= PHYSICS_TIMESTEP) {
const q = this.inputQueue.shift()
if (q) {
Object.assign(this.playerState.control, q)
if (q.yaw) this.player.entity.yaw = q.yaw
if (q.pitch) this.player.entity.pitch = q.pitch
}
this.playerState = new PlayerState(this.player, this.controls)
this.physics.simulatePlayer(this.playerState, this.world.sync).apply(this.player)
this.lastPos = this.playerState.pos
this.requestPosition(PHYSICS_TIMESTEP, {
ascend: false,
descend: false,
// Players bob up and down in water, north jump is true when going up.
// In water this is only true after the player has reached max height before bobbing back down.
north_jump: this.player.jumpTicks > 0, // Jump
jump_down: this.controls.jump, // Jump
sprint_down: this.controls.sprint,
change_height: false,
jumping: this.controls.jump, // Jump
auto_jumping_in_water: false,
sneaking: false,
sneak_down: false,
up: this.controls.forward,
down: this.controls.back,
left: this.controls.left,
right: this.controls.right,
up_left: false,
up_right: false,
want_up: this.controls.jump, // Jump
want_down: false,
want_down_slow: false,
want_up_slow: false,
sprinting: false,
ascend_scaffolding: false,
descend_scaffolding: false,
sneak_toggle_down: false,
persist_sneak: false,
start_sprinting: this.player.events.startSprint || false,
stop_sprinting: this.player.events.stopSprint || false,
start_sneaking: this.player.events.startSneak || false,
stop_sneaking: this.player.events.stopSneak || false,
// Player is Update Aqatic swimming
start_swimming: false,
// Player stops Update Aqatic swimming
stop_swimming: false,
start_jumping: this.player.jumpTicks === 1, // Jump
start_gliding: false,
stop_gliding: false
})
this.timeAccumulator -= PHYSICS_TIMESTEP
}
}
startPhys () {
console.log('Start phys')
this.physicsLoop = setInterval(() => {
this.doPhysics()
}, PHYSICS_INTERVAL_MS)
}
setControlState (control, state) {
if (this.controls[control] === state) return
if (control === 'sprint') {
this.player.events.startSprint = state
this.player.events.stopSprint = !state
this.controls.sprint = true
} else if (control === 'sneak') {
this.player.events.startSneak = state
this.player.events.stopSneak = !state
this.controls.sprint = true
}
}
stopPhys () {
clearInterval(this.physicsLoop)
}
pushInputState (state, yaw, pitch) {
const yawRad = d2r(yaw)
const pitchRad = d2r(pitch)
this.inputQueue.push({
forward: state.up,
back: state.down, // TODO: left and right switched ???
left: state.right,
right: state.left,
jump: state.jump_down,
sneak: state.sneak_down,
yaw: yawRad,
pitch: pitchRad
})
// debug
globalThis.debugYaw = [yaw, yawRad]
}
pushCameraControl (state, id = 1) {
let { x, y, z } = state.position
if (id === 1) y -= 1.62 // account for player bb
const adjPos = vec3({ x, y, z })
// Sneak resyncs the position for easy testing
this.bot.updatePlayerCamera(id, adjPos, d2r(state.yaw), d2r(state.pitch), state.input_data.sneak_down)
}
// Server gives us a new position
updatePosition (pos, yaw, pitch, headYaw, tick) {
this.lastPos = pos
this.lastRot = { x: yaw, y: pitch, z: headYaw }
if (tick) this.tick = tick
}
onViewerCameraMove (newYaw, newPitch, newHeadYaw) {
this.player.yaw = newYaw
this.player.pitch = newPitch
this.player.headYaw = newHeadYaw
}
}
module.exports = { MovementManager }

View file

@ -0,0 +1,16 @@
const difference = (o1, o2) => Object.keys(o2).reduce((diff, key) => {
if (o1[key] === o2[key]) return diff
return {
...diff,
[key]: o2[key]
}
}, {})
const diff = (o1, o2) => { const dif = difference(o1, o2); return Object.keys(dif).length ? dif : null }
const d2r = deg => (180 - (deg < 0 ? (360 + deg) : deg)) * (Math.PI / 180)
module.exports = {
diff,
d2r
}

View file

@ -24,7 +24,7 @@ class Connection extends EventEmitter {
}
set status (val) {
this.inLog('* new status', val)
debug('* new status', val)
this.#status = val
}
@ -126,7 +126,7 @@ class Connection extends EventEmitter {
sendEncryptedBatch (batch) {
const buf = batch.stream.getBuffer()
debug('Sending encrypted batch', batch)
// debug('Sending encrypted batch', batch)
this.encrypt(buf)
}

View file

@ -104,7 +104,7 @@ async function startServerAndWait (version, withTimeout, options) {
if (!module.parent) {
// if (process.argv.length < 3) throw Error('Missing version argument')
startServer(process.argv[2] || '1.16.201')
startServer(process.argv[2] || '1.16.201', null, process.argv[3] ? { 'server-port': process.argv[3] } : undefined)
}
module.exports = { fetchLatestStable, startServer, startServerAndWait }