Path: blob/master/examples/screenshot-with-node-canvas-webgl/screenshot.js
9427 views
/*1*2* A simple a simple Screenshot demo for https://github.com/PrismarineJS/prismarine-viewer3*4*/56const mineflayer = require('mineflayer')7const { Viewer, WorldView, getBufferFromStream } = require('prismarine-viewer').viewer8global.Worker = require('worker_threads').Worker910const THREE = require('three')11const { createCanvas } = require('node-canvas-webgl/lib')12const fs = require('fs').promises13const { Vec3 } = require('vec3')14const { EventEmitter } = require('events')1516if (process.argv.length < 4 || process.argv.length > 6) {17console.log('Usage : node screenshot.js <host> <port> [<name>] [<password>]')18process.exit(1)19}2021const bot = mineflayer.createBot({22host: process.argv[2],23port: parseInt(process.argv[3]),24username: process.argv[4] ? process.argv[4] : 'screenshot',25password: process.argv[5]26})2728bot.on('spawn', async () => {29await bot.waitForChunksToLoad()30const camera = new Camera(bot)31camera.on('ready', async () => {32await camera.takePicture(new Vec3(1, -0.2, 0), 'screenshot1')33})34})3536bot.on('error', (err) => {37console.error(err)38})3940class Camera extends EventEmitter {41constructor (bot) {42super()43this.bot = bot44this.viewDistance = 445this.width = 51246this.height = 51247this.canvas = createCanvas(this.width, this.height)48this.renderer = new THREE.WebGLRenderer({ canvas: this.canvas })49this.viewer = new Viewer(this.renderer)50this._init().then(() => {51this.emit('ready')52})53}5455async _init () {56const botPos = this.bot.entity.position57const center = new Vec3(botPos.x, botPos.y + 10, botPos.z)58this.viewer.setVersion(this.bot.version)5960// Load world61const worldView = new WorldView(this.bot.world, this.viewDistance, center)62this.viewer.listen(worldView)6364this.viewer.camera.position.set(center.x, center.y, center.z)6566await worldView.init(center)67}6869async takePicture (direction, name) {70const cameraPos = new Vec3(this.viewer.camera.position.x, this.viewer.camera.position.y, this.viewer.camera.position.z)71const point = cameraPos.add(direction)72this.viewer.camera.lookAt(point.x, point.y, point.z)73console.info('Waiting for world to load')74await new Promise(resolve => setTimeout(resolve, 5000))75this.renderer.render(this.viewer.scene, this.viewer.camera)7677const imageStream = this.canvas.createJPEGStream({78bufsize: 4096,79quality: 100,80progressive: false81})82const buf = await getBufferFromStream(imageStream)83let stats84try {85stats = await fs.stat('./screenshots')86} catch (e) {87if (!stats?.isDirectory()) {88await fs.mkdir('./screenshots')89}90}91await fs.writeFile(`screenshots/${name}.jpg`, buf)92console.log('saved', name)93}94}959697