File tree Expand file tree Collapse file tree 4 files changed +76
-0
lines changed
Expand file tree Collapse file tree 4 files changed +76
-0
lines changed Original file line number Diff line number Diff line change 1919 "es-toolkit" : " ^1.44.0" ,
2020 "eventemitter3" : " ^5.0.4" ,
2121 "minecraft-data" : " ^3.102.3" ,
22+ "canvas" : " ^3.2.1" ,
2223 "mineflayer" : " ^4.33.0" ,
2324 "mineflayer-armor-manager" : " ^2.0.1" ,
2425 "mineflayer-auto-eat" : " ^5.0.3" ,
Original file line number Diff line number Diff line change 1+ import type { Bot } from 'mineflayer'
2+
3+ import { useLogger } from '../utils/logger'
4+
5+ interface MineflayerViewerOptions {
6+ port : number
7+ firstPerson ?: boolean
8+ }
9+
10+ export function setupMineflayerViewer ( mineflayer : { bot : Bot } , options : MineflayerViewerOptions ) : void {
11+ let isViewerStarted = false
12+
13+ mineflayer . bot . once ( 'spawn' , async ( ) => {
14+ if ( isViewerStarted )
15+ return
16+
17+ isViewerStarted = true
18+
19+ const logger = useLogger ( )
20+ try {
21+ const { mineflayer : mineflayerViewer } = await import ( 'prismarine-viewer' )
22+
23+ mineflayerViewer ( mineflayer . bot , {
24+ port : options . port ,
25+ firstPerson : options . firstPerson ?? true ,
26+ } )
27+
28+ logger . log ( `Mineflayer viewer running at http://localhost:${ options . port } ` )
29+ }
30+ catch ( err ) {
31+ const e = err as NodeJS . ErrnoException
32+ const message = typeof e . message === 'string' ? e . message : ''
33+ const isCanvasMissing = e ?. code === 'MODULE_NOT_FOUND' && message . includes ( '\'canvas\'' )
34+ const isCanvasBinaryMissing = e ?. code === 'MODULE_NOT_FOUND' && message . includes ( 'canvas.node' )
35+
36+ if ( isCanvasMissing || isCanvasBinaryMissing ) {
37+ logger . log ( 'Mineflayer viewer disabled: node-canvas is not available' )
38+ return
39+ }
40+
41+ logger . errorWithError ( 'Failed to start mineflayer viewer' , e as Error )
42+ }
43+ } )
44+ }
Original file line number Diff line number Diff line change @@ -18,6 +18,24 @@ import { useLogger } from '../utils/logger'
1818const __filename = fileURLToPath ( import . meta. url )
1919const __dirname = path . dirname ( __filename )
2020
21+ function createViewerHtml ( targetUrl : string ) : string {
22+ return `<!doctype html>
23+ <html lang="en">
24+ <head>
25+ <meta charset="utf-8" />
26+ <meta name="viewport" content="width=device-width, initial-scale=1" />
27+ <title>Mineflayer Viewer</title>
28+ <style>
29+ html, body { height: 100%; margin: 0; }
30+ iframe { width: 100%; height: 100%; border: 0; }
31+ </style>
32+ </head>
33+ <body>
34+ <iframe src="${ targetUrl } " allow="fullscreen" referrerpolicy="no-referrer"></iframe>
35+ </body>
36+ </html>`
37+ }
38+
2139interface ClientInfo {
2240 ws : WebSocket
2341 id : string
@@ -165,6 +183,16 @@ export class DebugServer {
165183 return
166184 }
167185
186+ if ( req . method === 'GET' && ( req . url === '/viewer' || req . url ?. startsWith ( '/viewer?' ) ) ) {
187+ const html = createViewerHtml ( 'http://localhost:3007' )
188+ res . writeHead ( 200 , {
189+ 'Content-Type' : 'text/html; charset=utf-8' ,
190+ 'Cache-Control' : 'no-cache' ,
191+ } )
192+ res . end ( html )
193+ return
194+ }
195+
168196 // Serve static files from web directory
169197 let filePath = req . url === '/' ? '/index.html' : req . url || '/index.html'
170198
Original file line number Diff line number Diff line change @@ -14,6 +14,7 @@ import { initBot } from './composables/bot'
1414import { config , initEnv } from './composables/config'
1515import { createNeuriAgent } from './composables/neuri'
1616import { DebugService } from './debug'
17+ import { setupMineflayerViewer } from './debug/mineflayer-viewer'
1718import { wrapPlugin } from './libs/mineflayer'
1819import { initLogger , useLogger } from './utils/logger'
1920
@@ -38,6 +39,8 @@ async function main() {
3839 ] ,
3940 } )
4041
42+ setupMineflayerViewer ( bot , { port : 3007 , firstPerson : true } )
43+
4144 // Connect airi server
4245 const airiClient = new Client ( {
4346 name : config . airi . clientName ,
You can’t perform that action at this time.
0 commit comments