/// <summary> /// Initializes a new instance of the object. /// </summary> /// <param name="masterNode">The masternode the server runs on</param> /// <param name="protocolVersion">Supported protocol version for which to create the configuration.</param> /// <param name="agent">The servers user agent that will be shared with peers.</param> /// <param name="args">The command-line arguments.</param> /// <exception cref="ConfigurationException"> /// Thrown in case of any problems with the configuration file or command line /// arguments. /// </exception> /// <remarks> /// Processing depends on whether a configuration file is passed via the command line. /// There are two main scenarios here: /// - The configuration file is passed via the command line. In this case we need /// to read it earlier so that it can provide defaults for "testnet" and "regtest". /// - Alternatively, if the file name is not supplied then a masternode-specific file /// name would be determined. In this case we first need to determine the masternode. /// </remarks> public ServerSettings(MasterNodeBase masterNode, ProtocolVersion protocolVersion = ProtocolVersion.PROTOCOL_VERSION, string agent = "x42", string[] args = null) { MasterNode = masterNode; // Create the default logger factory and logger. ExtendedLoggerFactory loggerFactory = new ExtendedLoggerFactory(); LoggerFactory = loggerFactory; LoggerFactory.AddConsoleWithFilters(); LoggerFactory.AddNLog(); Logger = LoggerFactory.CreateLogger(typeof(ServerSettings).FullName); ProtocolVersion = protocolVersion; Agent = agent; ConfigReader = new TextFileConfiguration(args ?? new string[] { }); // Log arguments. Logger.LogDebug("Arguments: masternode='{0}', protocolVersion='{1}', agent='{2}', args='{3}'.", string.IsNullOrEmpty(ServerName) ? "(None)" : ServerName, ProtocolVersion, Agent, args == null ? "(None)" : string.Join(" ", args)); // By default, we look for a file named '<masternode>.conf' in the masternode's data directory, // but both the data directory and the configuration file path may be changed using the -datadir and -conf command-line arguments. ConfigurationFile = ConfigReader.GetOrDefault <string>("conf", null, Logger)?.NormalizeDirectorySeparator(); DataDir = ConfigReader.GetOrDefault <string>("datadir", null, Logger)?.NormalizeDirectorySeparator(); DataDirRoot = ConfigReader.GetOrDefault("datadirroot", "x42Server", Logger); // If the configuration file is relative then assume it is relative to the data folder and combine the paths. if (DataDir != null && ConfigurationFile != null) { bool isRelativePath = Path.GetFullPath(ConfigurationFile).Length > ConfigurationFile.Length; if (isRelativePath) { ConfigurationFile = Path.Combine(DataDir, ConfigurationFile); } } // If the configuration file has been specified on the command line then read it now // so that it can provide the defaults for testnet and regtest. if (ConfigurationFile != null) { // If the configuration file was specified on the command line then it must exist. if (!File.Exists(ConfigurationFile)) { throw new ConfigurationException($"Configuration file does not exist at {ConfigurationFile}."); } // Sets the ConfigReader based on the arguments and the configuration file if it exists. ReadConfigurationFile(); } // Set the full data directory path. if (DataDir == null) { // Create the data directories if they don't exist. DataDir = CreateDefaultDataDirectories(ServerName); } else { // Combine the data directory with the masternode's root folder and name. string directoryPath = Path.Combine(DataDir, ServerName); DataDir = Directory.CreateDirectory(directoryPath).FullName; Logger.LogDebug("Data directory initialized with path {0}.", DataDir); } // Set the data folder. DataFolder = new DataFolder(DataDir); // Attempt to load NLog configuration from the DataFolder. loggerFactory.LoadNLogConfiguration(DataFolder); // Get the configuration file name for the masternode if it was not specified on the command line. if (ConfigurationFile == null) { ConfigurationFile = Path.Combine(DataDir, MasterNode.DefaultConfigFilename); Logger.LogDebug("Configuration file set to '{0}'.", ConfigurationFile); if (File.Exists(ConfigurationFile)) { ReadConfigurationFile(); } } // Create the custom logger factory. Log = new LogSettings(); Log.Load(ConfigReader); LoggerFactory.AddFilters(Log, DataFolder); LoggerFactory.ConfigureConsoleFilters(LoggerFactory.GetConsoleSettings(), Log); // Load the configuration. LoadConfiguration(); }