diff --git a/HISTORY.md b/HISTORY.md index eef8822..8ac1d94 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +## 3.19.0 +* Add option for port redirection, fix Realm handling (#282) +* Add Port Redirect Functionality (#278) @stevarino +* Add Get-AppxPackage command to FAQ.md (#276) @stevarino +* Remove viewer example + ## 3.18.0 * 1.19.21 support (#266) diff --git a/examples/viewer/client/BotProvider.js b/examples/viewer/client/BotProvider.js deleted file mode 100644 index 4d23377..0000000 --- a/examples/viewer/client/BotProvider.js +++ /dev/null @@ -1,58 +0,0 @@ -const { Version } = require('bedrock-provider') -const { WorldView } = require('prismarine-viewer/viewer') -const World = require('prismarine-world')() -const ChunkColumn = require('./Chunk')() -const { MovementManager } = require('./movements') - -class BotProvider extends WorldView { - chunks = {} - lastSentPos - positionUpdated = true - - constructor () { - super() - this.connect() - this.listenToBot() - this.world = new World() - this.movements = new MovementManager(this) - - this.onKeyDown = () => {} - this.onKeyUp = () => {} - - this.removeAllListeners('mouseClick') - } - - raycast () { - // TODO : fix - } - - get entity () { return this.movements.player.entity } - - handleChunk (packet, render = true) { - const hash = (packet.x << 4) + ',' + (packet.z << 4) - if (this.loadChunk[hash]) return - const cc = new ChunkColumn(Version.v1_4_0, packet.x, packet.z) - cc.networkDecodeNoCache(packet.payload, packet.sub_chunk_count).then(() => { - this.loadedChunks[hash] = true - this.world.setColumn(packet.x, packet.z, cc) - const chunk = cc.serialize() - // console.log('Chunk', chunk) - if (render) this.emitter.emit('loadChunk', { x: packet.x << 4, z: packet.z << 4, chunk }) - }) - } - - updatePlayerCamera (id, position, yaw, pitch, updateState) { - this.emit('playerMove', id, { position, yaw, pitch }) - - if (updateState) { - this.movements.updatePosition(position, yaw, pitch) - } - } - - stopBot () { - clearInterval(this.tickLoop) - this.movements.stopPhys() - } -} - -module.exports = { BotProvider } diff --git a/examples/viewer/client/BotViewer.js b/examples/viewer/client/BotViewer.js deleted file mode 100644 index 57f9d16..0000000 --- a/examples/viewer/client/BotViewer.js +++ /dev/null @@ -1,150 +0,0 @@ -/* global THREE */ -const { Viewer, MapControls } = require('prismarine-viewer/viewer') -// const { Vec3 } = require('vec3') -const { ClientProvider } = require('./ClientProvider') -// const { ProxyProvider } = require('./ProxyProvider') -global.THREE = require('three') - -const MCVER = '1.16.1' - -class BotViewer { - start () { - this.bot = new ClientProvider() - // this.bot = new ProxyProvider() - // Create three.js context, add to page - this.renderer = new THREE.WebGLRenderer() - this.renderer.setPixelRatio(window.devicePixelRatio || 1) - this.renderer.setSize(window.innerWidth, window.innerHeight) - document.body.appendChild(this.renderer.domElement) - - // Create viewer - this.viewer = new Viewer(this.renderer) - this.viewer.setVersion(MCVER) - // Attach controls to viewer - this.controls = new MapControls(this.viewer.camera, this.renderer.domElement) - // Enable damping (inertia) on movement - this.controls.enableDamping = true - this.controls.dampingFactor = 0.09 - console.info('Registered handlers') - // Link WorldView and Viewer - this.viewer.listen(this.bot) - - this.bot.on('spawn', ({ position, firstPerson }) => { - // Initialize viewer, load chunks - this.bot.init(position) - // Start listening for keys - this.registerBrowserEvents() - - if (firstPerson && this.bot.movements) { - this.viewer.camera.position.set(position.x, position.y, position.z) - this.firstPerson = true - this.controls.enabled = false - } else { - this.viewer.camera.position.set(position.x, position.y, position.z) - } - }) - - this.bot.on('playerMove', (id, pos) => { - if (this.firstPerson && id < 10) { - this.setFirstPersonCamera(pos) - return - } - - window.viewer.viewer.entities.update({ - name: 'player', - id, - pos: pos.position, - width: 0.6, - height: 1.8, - yaw: pos.yaw, - pitch: pos.pitch - }) - }) - - const oldFov = this.viewer.camera.fov - const sprintFov = this.viewer.camera.fov + 20 - const sneakFov = this.viewer.camera.fov - 10 - - const onSprint = () => { - this.viewer.camera.fov = sprintFov - this.viewer.camera.updateProjectionMatrix() - } - - const onSneak = () => { - this.viewer.camera.fov = sneakFov - this.viewer.camera.updateProjectionMatrix() - } - - const onRelease = () => { - this.viewer.camera.fov = oldFov - this.viewer.camera.updateProjectionMatrix() - } - - this.bot.on('startSprint', onSprint) - this.bot.on('startSneak', onSneak) - this.bot.on('stopSprint', onRelease) - this.bot.on('stopSneak', onRelease) - - this.controls.update() - - // Browser animation loop - const animate = () => { - window.requestAnimationFrame(animate) - if (this.controls && !this.firstPerson) this.controls.update() - this.viewer.update() - this.renderer.render(this.viewer.scene, this.viewer.camera) - } - animate() - - window.addEventListener('resize', () => { - this.viewer.camera.aspect = window.innerWidth / window.innerHeight - this.viewer.camera.updateProjectionMatrix() - this.renderer.setSize(window.innerWidth, window.innerHeight) - }) - } - - onMouseMove = (e) => { - if (this.firstPerson) { - this.bot.entity.pitch -= e.movementY * 0.005 - this.bot.entity.yaw -= e.movementX * 0.004 - } - } - - onPointerLockChange = () => { - const e = this.renderer.domElement - if (document.pointerLockElement === e) { - e.parentElement.addEventListener('mousemove', this.onMouseMove, { passive: true }) - } else { - e.parentElement.removeEventListener('mousemove', this.onMouseMove, false) - } - } - - onMouseDown = () => { - if (this.firstPerson && !document.pointerLockElement) { - this.renderer.domElement.requestPointerLock() - } - } - - registerBrowserEvents () { - const e = this.renderer.domElement - e.parentElement.addEventListener('keydown', this.bot.onKeyDown) - e.parentElement.addEventListener('keyup', this.bot.onKeyUp) - e.parentElement.addEventListener('mousedown', this.onMouseDown) - document.addEventListener('pointerlockchange', this.onPointerLockChange, false) - } - - unregisterBrowserEvents () { - const e = this.renderer.domElement - e.parentElement.removeEventListener('keydown', this.bot.onKeyDown) - e.parentElement.removeEventListener('keyup', this.bot.onKeyUp) - e.parentElement.removeEventListener('mousemove', this.onMouseMove) - e.parentElement.removeEventListener('mousedown', this.onMouseDown) - document.removeEventListener('pointerlockchange', this.onPointerLockChange, false) - } - - setFirstPersonCamera (entity) { - this.viewer.setFirstPersonCamera(entity.position, entity.yaw, entity.pitch * 2) - } -} - -module.exports = { BotViewer } diff --git a/examples/viewer/client/Chunk.js b/examples/viewer/client/Chunk.js deleted file mode 100644 index 7733cc3..0000000 --- a/examples/viewer/client/Chunk.js +++ /dev/null @@ -1,18 +0,0 @@ -const { ChunkColumn } = require('bedrock-provider') - -const Block = require('prismarine-block')('1.16.1') - -class ChunkColumnWrapped extends ChunkColumn { // pchunk compatiblity wrapper - // Block access - setBlockStateId (pos, stateId) { - super.setBlock(pos.x, pos.y, pos.z, Block.fromStateId(stateId)) - } - - getBlockStateId (pos) { - return super.getBlock(pos.x, pos.y, pos.z)?.stateId - } -} - -module.exports = (version) => { - return ChunkColumnWrapped -} diff --git a/examples/viewer/client/ClientProvider.js b/examples/viewer/client/ClientProvider.js deleted file mode 100644 index 73d7b8f..0000000 --- a/examples/viewer/client/ClientProvider.js +++ /dev/null @@ -1,114 +0,0 @@ -const { Client } = require('bedrock-protocol') -const { BotProvider } = require('./BotProvider') - -const controlMap = { - forward: ['KeyW', 'KeyZ'], - back: 'KeyS', - left: ['KeyA', 'KeyQ'], - right: 'KeyD', - sneak: 'ShiftLeft', - jump: 'Space' -} - -class ClientProvider extends BotProvider { - downKeys = new Set() - - connect () { - const client = new Client({ host: '127.0.0.1', version: '1.16.210', username: 'notch', offline: true, 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 }) - - this.heartbeat = setInterval(() => { - 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.movements.init('server', packet.player_position, /* vel */ null, packet.rotation.z || 0, packet.rotation.x || 0, 0) - }) - - this.client.on('spawn', () => { - this.movements.startPhys() - // server allows client to render chunks & spawn in world - this.emit('spawn', { position: this.lastPos, firstPerson: true }) - - 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.movements.updatePosition(packet.position, packet.yaw, packet.pitch, packet.head_yaw, packet.tick) - } - }) - - 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 - }) - } - - onKeyDown = (evt) => { - const code = evt.code - for (const control in controlMap) { - if (controlMap[control].includes(code)) { - this.movements.setControlState(control, true) - break - } - if (evt.ctrlKey) { - this.movements.setControlState('sprint', true) - } - } - this.downKeys.add(code) - } - - onKeyUp = (evt) => { - const code = evt.code - if (code === 'ControlLeft' && this.downKeys.has('ControlLeft')) { - this.movements.setControlState('sprint', false) - } - for (const control in controlMap) { - if (controlMap[control].includes(code)) { - this.movements.setControlState(control, false) - break - } - } - this.downKeys.delete(code) - } -} - -module.exports = { ClientProvider } diff --git a/examples/viewer/client/ProxyProvider.js b/examples/viewer/client/ProxyProvider.js deleted file mode 100644 index 8ffc599..0000000 --- a/examples/viewer/client/ProxyProvider.js +++ /dev/null @@ -1,89 +0,0 @@ -const { Relay } = require('bedrock-protocol') -const { BotProvider } = require('./BotProvider') -const { diff } = require('./util') - -class ProxyProvider extends BotProvider { - lastPlayerMovePacket - - connect () { - const proxy = new Relay({ - host: '0.0.0.0', - port: 19130, - // logging: true, - destination: { - host: '127.0.0.1', - port: 19132 - } - }) - proxy.listen() - console.info('Waiting for connect') - - proxy.on('join', (client, server) => { - client.on('clientbound', ({ name, params }) => { - if (name === 'level_chunk') { - this.handleChunk(params, true) - } 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.movements.startPhys() - this.emit('spawn', { position: this.movements.lastPos, firstPerson: true }) - console.info('Started physics!') - } else if (name === 'move_player') { - 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') { - this.movements.pushInputState(params.input_data, params.yaw, params.pitch) - this.movements.pushCameraControl(params, 1) - - // Log Movement deltas - { // eslint-disable-line - 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) - const dd = diff(this.firstPlayerMovePacket.delta, params.delta) - if (id || md) { - if (globalThis.logging) console.log('Move', params.position, id, md, dd) - globalThis.movements ??= [] - globalThis.movements.push(params) - } - } - if (!this.firstPlayerMovePacket) { - this.firstPlayerMovePacket = params - for (const key in params.input_data) { - params.input_data[key] = false - } - params.input_data._value = 0n - params.move_vector = { x: 0, z: 0 } - params.delta = { x: 0, y: 0, z: 0 } - } - } - } else if (!name.includes('tick') && !name.includes('level')) { - console.log('Sending', name) - } - }) - console.info('Client and Server Connected!') - }) - - this.proxy = proxy - } - - listenToBot () { - - } - - close () { - this.proxy?.close() - } -} - -module.exports = { ProxyProvider } -globalThis.logging = true diff --git a/examples/viewer/client/app.css b/examples/viewer/client/app.css deleted file mode 100644 index 44c6bea..0000000 --- a/examples/viewer/client/app.css +++ /dev/null @@ -1,22 +0,0 @@ -html { - overflow: hidden; -} - -html, body { - height: 100%; - margin: 0; - padding: 0; - font-family: sans-serif; -} - -a { - text-decoration: none; -} - -canvas { - height: 100%; - width: 100%; - font-size: 0; - margin: 0; - padding: 0; -} diff --git a/examples/viewer/client/index.html b/examples/viewer/client/index.html deleted file mode 100644 index 537be49..0000000 --- a/examples/viewer/client/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - -
-