private void Run(string[] args) { try { if (args.Length == 0) { args = new[] { "-?" } } ; for (var i = 0; i < args.Length; i++) { switch (args[i].ToUpper()) { case "-EXE": { if (i + 1 < args.Length && args[i + 1][0] != '-') { _exeFile = args[i + 1]; i++; } break; } case "-DBRESET": { _doResetDatabase = true; if (i + 1 < args.Length && args[i + 1][0] != '-') { _newSysopPassword = args[i + 1]; i++; } break; } case "-APIREPORT": _doApiReport = true; break; case "-M": _moduleIdentifier = args[i + 1]; i++; break; case "-K": _menuOptionKey = args[i + 1]; i++; break; case "-P": _modulePath = args[i + 1]; i++; break; case "-?": Console.WriteLine(new ResourceManager().GetString("MBBSEmu.Assets.commandLineHelp.txt")); Console.WriteLine($"Version: {new ResourceManager().GetString("MBBSEmu.Assets.version.txt")}"); return; case "-CONFIG": case "-C": { _isModuleConfigFile = true; //Is there a following argument that doesn't start with '-' //If so, it's the config file name if (i + 1 < args.Length && args[i + 1][0] != '-') { _moduleConfigFileName = args[i + 1]; if (!File.Exists(_moduleConfigFileName)) { Console.Write($"Specified Module Configuration File not found: {_moduleConfigFileName}"); return; } i++; } else { Console.WriteLine("Please specify a Module Configuration File when using the -C command line option"); } break; } case "-S": { //Is there a following argument that doesn't start with '-' //If so, it's the config file name if (i + 1 < args.Length && args[i + 1][0] != '-') { _settingsFileName = args[i + 1]; if (!File.Exists(_settingsFileName)) { Console.WriteLine($"Specified MBBSEmu settings not found: {_settingsFileName}"); return; } i++; } else { Console.WriteLine("Please specify an MBBSEmu configuration file when using the -S command line option"); } break; } case "-CONSOLE": { //Check to see if running Windows and earlier then Windows 8.0 if (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(6, 2)) { throw new ArgumentException("Console not supported on versions of Windows earlier than 8.0"); } _isConsoleSession = true; break; } default: Console.WriteLine($"Unknown Command Line Argument: {args[i]}"); return; } } _serviceResolver = new ServiceResolver(); _logger = _serviceResolver.GetService <ILogger>(); //EXE File Execution if (!string.IsNullOrEmpty(_exeFile)) { var mzFile = new MZFile(_exeFile); var exe = new ExeRuntime(mzFile, null, _serviceResolver.GetService <IClock>(), _logger); exe.Load(); exe.Run(); return; } var configuration = _serviceResolver.GetService <AppSettings>(); var textVariableService = _serviceResolver.GetService <ITextVariableService>(); var resourceManager = _serviceResolver.GetService <IResourceManager>(); var globalCache = _serviceResolver.GetService <IGlobalCache>(); var fileHandler = _serviceResolver.GetService <IFileUtility>(); //Setup Logger from AppSettings LogManager.Configuration.LoggingRules.Clear(); CustomLogger.AddLogLevel("consoleLogger", configuration.ConsoleLogLevel); if (!string.IsNullOrEmpty(configuration.FileLogName)) { var fileLogger = new FileTarget("fileLogger") { FileNameKind = 0, FileName = "${var:mbbsdir}" + configuration.FileLogName, Layout = Layout.FromString("${shortdate} ${time} ${level} ${callsite} ${message}"), }; LogManager.Configuration.AddTarget(fileLogger); CustomLogger.AddLogLevel("fileLogger", configuration.FileLogLevel); } LogManager.ReconfigExistingLoggers(); //Setup Generic Database if (!File.Exists($"BBSGEN.DB")) { _logger.Warn($"Unable to find MajorBBS/WG Generic Database, creating new copy of BBSGEN.DB"); File.WriteAllBytes($"BBSGEN.DB", resourceManager.GetResource("MBBSEmu.Assets.BBSGEN.DB").ToArray()); } globalCache.Set("GENBB-PROCESSOR", new BtrieveFileProcessor(fileHandler, Directory.GetCurrentDirectory(), "BBSGEN.DAT", configuration.BtrieveCacheSize)); //Setup User Database if (!File.Exists($"BBSUSR.DB")) { _logger.Warn($"Unable to find MajorBBS/WG User Database, creating new copy of BBSUSR.DB"); File.WriteAllBytes($"BBSUSR.DB", resourceManager.GetResource("MBBSEmu.Assets.BBSUSR.DB").ToArray()); } globalCache.Set("ACCBB-PROCESSOR", new BtrieveFileProcessor(fileHandler, Directory.GetCurrentDirectory(), "BBSUSR.DAT", configuration.BtrieveCacheSize)); //Database Reset if (_doResetDatabase) { DatabaseReset(); } //Database Sanity Checks var databaseFile = configuration.DatabaseFile; if (!File.Exists($"{databaseFile}")) { _logger.Warn($"SQLite Database File {databaseFile} missing, performing Database Reset to perform initial configuration"); DatabaseReset(); } //Setup Modules if (!string.IsNullOrEmpty(_moduleIdentifier)) { _menuOptionKey ??= "A"; //Load Command Line _moduleConfigurations.Add(new ModuleConfiguration { ModuleIdentifier = _moduleIdentifier, ModulePath = _modulePath, MenuOptionKey = _menuOptionKey }); } else if (_isModuleConfigFile) { //Load Menu Option Keys - 35 total var menuOptionKeyList = "ABCDEFGHIJKLMNOPQRSTUVWYZ0123456789".ToCharArray().ToList(); //Exclude X for logoff //Load Config File var moduleConfiguration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile(_moduleConfigFileName, false, true).Build(); foreach (var m in moduleConfiguration.GetSection("Modules").GetChildren()) { //Check for available MenuOptionKeys if (menuOptionKeyList.Count < 1) { _logger.Error($"Maximum module limit reached -- {m["Identifier"]} not loaded"); continue; } //Check for Non Character/Digit MenuOptionKey if (!string.IsNullOrEmpty(m["MenuOptionKey"]) && (!char.IsLetterOrDigit(m["MenuOptionKey"][0]))) { _logger.Error($"Invalid menu option key (NOT A-Z or 0-9) for {m["Identifier"]}, module not loaded"); continue; } //Check for duplicate MenuOptionKey if (!string.IsNullOrEmpty(m["MenuOptionKey"]) && _moduleConfigurations.Any(x => x.MenuOptionKey == m["MenuOptionKey"])) { _logger.Error($"Duplicate menu option key for {m["Identifier"]}, module not loaded"); continue; } //Check for duplicate module in moduleConfig if (_moduleConfigurations.Any(x => x.ModuleIdentifier == m["Identifier"])) { _logger.Error($"Module {m["Identifier"]} already loaded, duplicate instance not loaded"); continue; } //If MenuOptionKey, remove from allowable list if (!string.IsNullOrEmpty(m["MenuOptionKey"])) { menuOptionKeyList.Remove(char.Parse(m["MenuOptionKey"])); } //Check for missing MenuOptionKey, assign, remove from allowable list if (string.IsNullOrEmpty(m["MenuOptionKey"])) { m["MenuOptionKey"] = menuOptionKeyList[0].ToString(); menuOptionKeyList.RemoveAt(0); } //Load Modules _logger.Info($"Loading {m["Identifier"]}"); _moduleConfigurations.Add(new ModuleConfiguration { ModuleIdentifier = m["Identifier"], ModulePath = m["Path"], MenuOptionKey = m["MenuOptionKey"] }); } } else { _logger.Warn($"You must specify a module to load either via Command Line or Config File"); _logger.Warn($"View help documentation using -? for more information"); return; } //Setup and Run Host var host = _serviceResolver.GetService <IMbbsHost>(); host.Start(_moduleConfigurations); //API Report if (_doApiReport) { host.GenerateAPIReport(); host.Stop(); return; } _runningServices.Add(host); //Setup and Run Telnet Server if (configuration.TelnetEnabled) { var telnetService = _serviceResolver.GetService <ISocketServer>(); var telnetHostIP = configuration.TelnetIPAddress; telnetService.Start(EnumSessionType.Telnet, telnetHostIP, configuration.TelnetPort); _logger.Info($"Telnet listening on IP {telnetHostIP} port {configuration.TelnetPort}"); _runningServices.Add(telnetService); } //Setup and Run Rlogin Server if (configuration.RloginEnabled) { var rloginService = _serviceResolver.GetService <ISocketServer>(); var rloginHostIP = configuration.RloginIPAddress; rloginService.Start(EnumSessionType.Rlogin, rloginHostIP, configuration.RloginPort); _logger.Info($"Rlogin listening on IP {rloginHostIP} port {configuration.RloginPort}"); _runningServices.Add(rloginService); if (configuration.RloginPortPerModule) { var rloginPort = configuration.RloginPort + 1; foreach (var m in _moduleConfigurations) { _logger.Info($"Rlogin {m.ModuleIdentifier} listening on port {rloginPort}"); rloginService = _serviceResolver.GetService <ISocketServer>(); rloginService.Start(EnumSessionType.Rlogin, rloginHostIP, rloginPort++, m.ModuleIdentifier); _runningServices.Add(rloginService); } } } else { _logger.Info("Rlogin Server Disabled (via appsettings.json)"); } _logger.Info($"Started MBBSEmu Build #{new ResourceManager().GetString("MBBSEmu.Assets.version.txt")}"); Console.CancelKeyPress += CancelKeyPressHandler; if (_isConsoleSession) { _ = new LocalConsoleSession(_logger, "CONSOLE", host, textVariableService); } } catch (Exception e) { Console.WriteLine("Critical Exception has occurred:"); Console.WriteLine(e); Environment.Exit(0); } }