'use strict' ; import 'app-module-path/register' ; import program from 'commander' ; import { UserSvcPing } from 'authorities' ; import { getNetIntf , getOrAskNetIntf , INetIntf } from 'interfacepicker' ; import { ServerInstance } from 'serverinstance' ; let masterServer = null ; program . version ( '0.9.5' ) . option ( '-i, --ip-address [ip]' , 'The IP address to be used by the server (do not use --interface with this)' , null ) . option ( '-I, --interface [intf]' , 'The interface to be used by the server (do not use --ip-address with this)' , null ) . option ( '-p, --port-master [port]' , 'The server (TCP) port' , 30001 ) . option ( '-P, --port-holepunch [port]' , 'The server target holepunch (UDP) port' , 30002 ) . option ( '-l, --log-packets' , 'Log the incoming and outgoing packets' ) . parse ( process . argv ) ; function validateEnvVars ( ) { if ( process . env . USERSERVICE_HOST == null ) { throw new Error ( 'USERSERVICE_HOST environment variable is not set.' ) ; } if ( process . env . USERSERVICE_PORT == null ) { throw new Error ( 'USERSERVICE_PORT environment variable is not set.' ) ; } } async function checkServices ( ) { await Promise . all ( [ UserSvcPing . checkNow ( ) , UserSvcPing . checkNow ( ) ] ) ; return UserSvcPing . isAlive ( ) && UserSvcPing . isAlive ( ) ; } /**
 * the entry point of the server
 */ async function startServer ( ) { let desiredIp = null ; if ( program . ipAddress && program . interface ) { console . error ( 'You many only specify --ip-address OR --interface, not both.\n\n' ) ; program . outputHelp ( ) ; process . exit ( 2 ) ; } if ( program . ipAddress ) { desiredIp = program . ipAddress ; } else if ( program . interface ) { const intf = getNetIntf ( program . interface ) ; if ( intf == null ) { console . error ( 'Could not find the desired interface...\n\n' ) ; program . outputHelp ( ) ; process . exit ( 1 ) ; } desiredIp = intf . net . address ; } else { const intf = await getOrAskNetIntf ( ) ; if ( intf == null ) { console . error ( 'User failed to input a valid interface...\n\n' ) ; program . outputHelp ( ) ; process . exit ( 1 ) ; } desiredIp = intf . net . address ; } masterServer = new ServerInstance ( { hostname : desiredIp , portHolepunch : program . portHolepunch , portMaster : program . portMaster , shouldLogPackets : program . logPackets } ) ; masterServer . listen ( ) ; } async function EntryPoint ( ) { validateEnvVars ( ) ; if ( await checkServices ( ) ) { console . warn ( 'Connected to user service' ) ; console . warn ( 'User service is at ' + UserSvcPing . getHost ( ) ) ; await startServer ( ) ; return true ; } console . warn ( 'Could not connect to the user service, waiting 5 seconds until another connection attempt' ) ; console . warn ( 'User service is ' + ( UserSvcPing . isAlive ( ) ? 'online' : 'offline' ) ) ; return false ; } /**
 * wait until the required services are online
 */ const loop = setInterval ( ( ) => { void EntryPoint ( ) . then ( ( res ) => { if ( res === true ) { clearTimeout ( loop ) ; } } ) ; } , 1000 * 5 ) ; process . on ( 'SIGINT' , ( ) => { masterServer . stop ( ) ; } ) . on ( 'SIGTERM' , ( ) => { masterServer . stop ( ) ; } ) ;