import { join } from 'path'; import { WebServer } from './WebServer/WebServer'; import { homedir } from 'os'; import { Config, ConfigurationManager, } from './Configuration/ConfigurationManager'; import { CameraRunner } from './CameraRunner'; import { UnityRunner } from './Unity/UnityRunner'; import { UnityWebSocket } from './Unity/UnityWebSocket'; import { TwilioHandler } from './Twilio'; import { delay } from './Utils'; import * as ping from 'ping'; import { shutdown } from './Shutdown'; const PREFIX = '[Main]'; export class Main { dataPath = join(homedir(), 'MorphixProductions', 'NTSHControl'); ConfigurationManager = new ConfigurationManager(this); WebServer = new WebServer(this); Twilio = new TwilioHandler(this); CameraRunner = new CameraRunner(this); UnityRunner = new UnityRunner(this); UnityWebSocket = new UnityWebSocket(this); Config: Config; async start() { await this.ConfigurationManager.load(); await this.waitForRouter(); await this.WebServer.listen(); await this.Twilio.load(); await this.CameraRunner.connect(); setTimeout(() => { this.UnityRunner.start(); }, this.Config.unity.executable.startUpDelay ?? 0); } async restart() { console.log('Stopping UnityRunner...'); await this.UnityRunner.stop(); const doReboot = !process.argv.includes('--no-reboot'); console.log(`${doReboot ? 'Rebooting' : 'Restarting'} CameraRunner...`); const succeed = await new Promise((resolve) => { this.CameraRunner.sendCommand( doReboot ? 'reboot' : 'restart', (response: { succeed: boolean; message?: string }) => { if (!response.succeed) { console.error( 'Failed to reboot CameraRunner:', response.message ); this.Twilio.sendError( 'CameraRunner', `Failed to reboot CameraRunner: ${response.message}` ); resolve(false); } else { console.log('CameraRunner rebooted successfully.'); this.Twilio.sendError('CameraRunner', null); resolve(true); } } ); }); if (!succeed) return; await delay(5000); console.log('Starting UnityRunner...'); await this.UnityRunner.start(); console.log('Restart complete.'); } async shutdown() { console.log('Stopping UnityRunner...'); await this.UnityRunner.stop(); const doShutdown = process.argv.includes('--no-shutdown') ? false : true; if (doShutdown) { console.log('Shutting down system...'); shutdown(); } else { console.log('Shutdown skipped due to --no-shutdown flag.'); } process.exit(0); } waitForRouter() { if (this.Config.router?.waitForStartup !== true) return; return new Promise((resolve) => { const check = () => { console.log(PREFIX, 'Waiting for router...'); ping.sys.probe(this.Config.router.ip, async ({ alive }) => { if (alive) { console.log(PREFIX, 'Router is online'); await delay(3000); return resolve(); } await delay(1000); check(); }); }; check(); }); } }