From dd7159eec0bd01e2f89133192a963d1a6110f7ee Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Tue, 27 Aug 2019 21:46:57 +0200 Subject: [PATCH] Update CommandLineParser. Refactor some code to make it work. --- Robust.Client/CommandLineArgs.cs | 17 +++++++ Robust.Client/GameController.cs | 29 ++++++------ .../GameController.Standalone.cs | 20 ++++----- Robust.Client/Interfaces/IGameController.cs | 1 + Robust.Client/Robust.Client.csproj | 1 + Robust.Lite/LiteGameController.cs | 5 +++ Robust.Server/BaseServer.cs | 22 ++++++--- Robust.Server/CommandLineArgs.cs | 45 ++----------------- Robust.Server/Interfaces/IBaseServer.cs | 2 + Robust.Server/Interfaces/ICommandLineArgs.cs | 16 ------- Robust.Server/Program.cs | 22 +++++---- Robust.Server/Robust.Server.csproj | 2 +- Robust.Server/ServerIoC.cs | 1 - Robust.UnitTesting/GameControllerDummy.cs | 4 ++ Robust.UnitTesting/RobustIntegrationTest.cs | 19 ++------ 15 files changed, 86 insertions(+), 120 deletions(-) create mode 100644 Robust.Client/CommandLineArgs.cs delete mode 100644 Robust.Server/Interfaces/ICommandLineArgs.cs diff --git a/Robust.Client/CommandLineArgs.cs b/Robust.Client/CommandLineArgs.cs new file mode 100644 index 000000000..0fc56e7aa --- /dev/null +++ b/Robust.Client/CommandLineArgs.cs @@ -0,0 +1,17 @@ +using CommandLine; + +namespace Robust.Client +{ + internal sealed class CommandLineArgs + { + [Option("headless", Required = false, HelpText = "Run without graphics/audio.")] + public bool Headless { get; set; } + + [Option("self-contained", Required = false, + HelpText = "Store data relative to executable instead of user-global locations.")] + public bool SelfContained { get; set; } + + [Option("connect", Required = false, HelpText = "Automatically connect to localhost.")] + public bool Connect { get; set; } + } +} diff --git a/Robust.Client/GameController.cs b/Robust.Client/GameController.cs index a4657bcfb..0c48a8a03 100644 --- a/Robust.Client/GameController.cs +++ b/Robust.Client/GameController.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; using System.Globalization; using System.IO; -using System.Reflection; using Robust.Client.Console; using Robust.Client.Interfaces; using Robust.Client.Interfaces.GameObjects; @@ -72,20 +70,25 @@ namespace Robust.Client [Dependency] private readonly ISignalHandler _signalHandler; #pragma warning restore 649 + private CommandLineArgs _commandLineArgs; + public string ContentRootDir { get; set; } = "../../../"; public bool LoadConfigAndUserData { get; set; } = true; + public void SetCommandLineArgs(CommandLineArgs args) + { + _commandLineArgs = args; + } + public void Startup() { SetupLogging(_logManager); - var args = GetCommandLineArgs(); - _taskManager.Initialize(); // Figure out user data directory. - var userDataDir = _getUserDataDir(args); + var userDataDir = GetUserDataDir(); if (LoadConfigAndUserData) { @@ -110,7 +113,8 @@ namespace Robust.Client _resourceCache.MountContentDirectory(@"Resources/"); #else _resourceCache.MountContentDirectory($@"{ContentRootDir}RobustToolbox/Resources/"); - _resourceCache.MountContentDirectory($@"{ContentRootDir}bin/Content.Client/", new ResourcePath("/Assemblies/")); + _resourceCache.MountContentDirectory($@"{ContentRootDir}bin/Content.Client/", + new ResourcePath("/Assemblies/")); _resourceCache.MountContentDirectory($@"{ContentRootDir}Resources/"); #endif @@ -163,7 +167,7 @@ namespace Robust.Client _clyde.Ready(); - if (args.Contains("--connect")) + if (_commandLineArgs?.Connect == true) { _client.ConnectToServer("127.0.0.1", 1212); } @@ -248,17 +252,12 @@ namespace Robust.Client logManager.GetSawmill("discord").Level = LogLevel.Warning; } - public static ICollection GetCommandLineArgs() + private string GetUserDataDir() { - return Environment.GetCommandLineArgs(); - } - - private static string _getUserDataDir(ICollection commandLineArgs) - { - if (commandLineArgs.Contains("--self-contained")) + if (_commandLineArgs?.SelfContained == true) { // Self contained mode. Data is stored in a directory called user_data next to Robust.Client.exe. - var exeDir = Assembly.GetExecutingAssembly().Location; + var exeDir = typeof(GameController).Assembly.Location; if (string.IsNullOrEmpty(exeDir)) { throw new Exception("Unable to locate client exe"); diff --git a/Robust.Client/GameController/GameController.Standalone.cs b/Robust.Client/GameController/GameController.Standalone.cs index 42670ee57..cc697e44a 100644 --- a/Robust.Client/GameController/GameController.Standalone.cs +++ b/Robust.Client/GameController/GameController.Standalone.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using CommandLine; using Robust.Client.Interfaces; using Robust.Shared.Interfaces.Timing; using Robust.Shared.IoC; @@ -16,23 +17,22 @@ namespace Robust.Client [Dependency] private IGameTiming _gameTiming; #pragma warning restore 649 - public static void Main() + public static void Main(string[] args) + { + Parser.Default.ParseArguments(args) + .WithParsed(ParsedMain); + } + + private static void ParsedMain(CommandLineArgs args) { IoCManager.InitThread(); - DisplayMode mode; - if (Environment.GetCommandLineArgs().Contains("--headless")) - { - mode = DisplayMode.Headless; - } - else - { - mode = DisplayMode.Clyde; - } + var mode = args.Headless ? DisplayMode.Headless : DisplayMode.Clyde; InitIoC(mode); var gc = (GameController) IoCManager.Resolve(); + gc.SetCommandLineArgs(args); gc.Startup(); gc.MainLoop(mode); diff --git a/Robust.Client/Interfaces/IGameController.cs b/Robust.Client/Interfaces/IGameController.cs index a6ece0618..20fbf51d1 100644 --- a/Robust.Client/Interfaces/IGameController.cs +++ b/Robust.Client/Interfaces/IGameController.cs @@ -10,6 +10,7 @@ namespace Robust.Client.Interfaces internal interface IGameControllerInternal : IGameController { + void SetCommandLineArgs(CommandLineArgs args); bool LoadConfigAndUserData { get; set; } void Startup(); void MainLoop(GameController.DisplayMode mode); diff --git a/Robust.Client/Robust.Client.csproj b/Robust.Client/Robust.Client.csproj index 5c2dde19f..1dc0d1a56 100644 --- a/Robust.Client/Robust.Client.csproj +++ b/Robust.Client/Robust.Client.csproj @@ -13,6 +13,7 @@ + diff --git a/Robust.Lite/LiteGameController.cs b/Robust.Lite/LiteGameController.cs index 2295781a9..5502ce418 100644 --- a/Robust.Lite/LiteGameController.cs +++ b/Robust.Lite/LiteGameController.cs @@ -42,6 +42,11 @@ namespace Robust.Lite [Dependency] private readonly IInputManager _inputManager; #pragma warning restore 649 + public void SetCommandLineArgs(CommandLineArgs args) + { + // Nada. + } + public bool LoadConfigAndUserData { get; set; } public string ContentRootDir { get; set; } diff --git a/Robust.Server/BaseServer.cs b/Robust.Server/BaseServer.cs index c1636e6cd..d6f01ff8e 100644 --- a/Robust.Server/BaseServer.cs +++ b/Robust.Server/BaseServer.cs @@ -36,11 +36,9 @@ namespace Robust.Server /// /// The master class that runs the rest of the engine. /// - public class BaseServer : IBaseServerInternal + internal sealed class BaseServer : IBaseServerInternal { #pragma warning disable 649 - [Dependency] - private readonly ICommandLineArgs _commandLine; [Dependency] private readonly IConfigurationManager _config; [Dependency] @@ -75,6 +73,7 @@ namespace Robust.Server private readonly IModLoader _modLoader; #pragma warning restore 649 + private CommandLineArgs _commandLineArgs; private FileLogHandler fileLogHandler; private IGameLoop _mainLoop; @@ -112,14 +111,23 @@ namespace Robust.Server fileLogHandler.Dispose(); } + public void SetCommandLineArgs(CommandLineArgs args) + { + _commandLineArgs = args; + } + /// public bool Start() { - // Sets up the configMgr - if (_commandLine.ConfigFile != null) + if (_commandLineArgs?.ConfigFile != null) { - _config.LoadFromFile(_commandLine.ConfigFile); + // If a config file path was passed, use it literally. + // This ensures it's working-directory relative + // (for people passing config file through the terminal or something). + // Otherwise use the one next to the executable. + var configPath = _commandLineArgs.ConfigFile ?? PathHelpers.ExecutableRelativeFile("server_config.toml"); + _config.LoadFromFile(configPath); } //Sets up Logging @@ -159,7 +167,7 @@ namespace Robust.Server return true; } - var dataDir = _commandLine.DataDir; + var dataDir = _commandLineArgs?.DataDir ?? PathHelpers.ExecutableRelativeFile("data"); // Set up the VFS _resources.Initialize(dataDir); diff --git a/Robust.Server/CommandLineArgs.cs b/Robust.Server/CommandLineArgs.cs index 49be4c8dd..893432ff0 100644 --- a/Robust.Server/CommandLineArgs.cs +++ b/Robust.Server/CommandLineArgs.cs @@ -9,51 +9,12 @@ using Robust.Shared.ContentPack; namespace Robust.Server { - public class CommandLineArgs : ICommandLineArgs + internal sealed class CommandLineArgs { [Option("config-file", Required = false, HelpText = "Config file to read from.")] - public string configFile { get; set; } - public string ConfigFile - { - get - { - // If a config file path was passed, use it literally. - // This ensures it's working-directory relative (for people passing config file through the terminal or something). - // Otherwise use the one next to the executable. - return configFile ?? PathHelpers.ExecutableRelativeFile("server_config.toml"); - } - } + public string ConfigFile { get; set; } [Option("data-dir", Required = false, HelpText = "Data directory to read/write to.")] - public string dataDir { get; set; } - - public string DataDir - { - get - { - return dataDir ?? PathHelpers.ExecutableRelativeFile("data"); - } - } - - [HelpOption] - public string GetUsage() - { - string strVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); - var help = new HelpText - { - Heading = new HeadingInfo("Space Station 14 Server", strVersion), - AdditionalNewLineAfterOption = true, - AddDashesToOption = true - }; - help.AddPreOptionsLine("Usage: SpaceStation14_Server.exe [OPTIONS]"); - help.AddOptions(this); - - return help; - } - - public bool Parse(string[] args) - { - return CommandLine.Parser.Default.ParseArguments(args, this); - } + public string DataDir { get; set; } } } diff --git a/Robust.Server/Interfaces/IBaseServer.cs b/Robust.Server/Interfaces/IBaseServer.cs index 2f8c050e8..fd1753bcf 100644 --- a/Robust.Server/Interfaces/IBaseServer.cs +++ b/Robust.Server/Interfaces/IBaseServer.cs @@ -46,5 +46,7 @@ namespace Robust.Server.Interfaces { void OverrideMainLoop(IGameLoop gameLoop); string ContentRootDir { get; set; } + + void SetCommandLineArgs(CommandLineArgs args); } } diff --git a/Robust.Server/Interfaces/ICommandLineArgs.cs b/Robust.Server/Interfaces/ICommandLineArgs.cs deleted file mode 100644 index 7869836f5..000000000 --- a/Robust.Server/Interfaces/ICommandLineArgs.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Robust.Server.Interfaces -{ - public interface ICommandLineArgs - { - /// - /// Parses command line arguments from the environment. - /// This method must be ran before other members are accessed. - /// - /// True if the arguments were parsed correctly, false if the program should terminate immediately (parse error, help used). - bool Parse(string[] args); - - string ConfigFile { get; } - - string DataDir { get; } - } -} diff --git a/Robust.Server/Program.cs b/Robust.Server/Program.cs index ab80d3997..62b3b932f 100644 --- a/Robust.Server/Program.cs +++ b/Robust.Server/Program.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using CommandLine; using Robust.Server.Interfaces; using Robust.Shared.ContentPack; using Robust.Shared.Interfaces.Log; @@ -11,18 +12,24 @@ using Robust.Shared; namespace Robust.Server { - internal static class EntryPoint + internal static class Program { internal static void Main(string[] args) + { + Parser.Default.ParseArguments(args).WithParsed(ParsedMain); + } + + private static void ParsedMain(CommandLineArgs args) { IoCManager.InitThread(); ServerIoC.RegisterIoC(); IoCManager.BuildGraph(); SetupLogging(); InitReflectionManager(); - HandleCommandLineArgs(args); - var server = IoCManager.Resolve(); + var server = IoCManager.Resolve(); + + server.SetCommandLineArgs(args); Logger.Info("Server -> Starting"); @@ -47,15 +54,6 @@ namespace Robust.Server IoCManager.Clear(); } - private static void HandleCommandLineArgs(string[] args) - { - var commandLine = IoCManager.Resolve(); - if (!commandLine.Parse(args)) - { - Environment.Exit(0); - } - } - internal static void InitReflectionManager() { // gets a handle to the shared and the current (server) dll. diff --git a/Robust.Server/Robust.Server.csproj b/Robust.Server/Robust.Server.csproj index cade8c1be..6350cd1b7 100644 --- a/Robust.Server/Robust.Server.csproj +++ b/Robust.Server/Robust.Server.csproj @@ -12,7 +12,7 @@ - + diff --git a/Robust.Server/ServerIoC.cs b/Robust.Server/ServerIoC.cs index 0f1845f4d..b643fa11b 100644 --- a/Robust.Server/ServerIoC.cs +++ b/Robust.Server/ServerIoC.cs @@ -44,7 +44,6 @@ namespace Robust.Server IoCManager.Register(); IoCManager.Register(); - IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); diff --git a/Robust.UnitTesting/GameControllerDummy.cs b/Robust.UnitTesting/GameControllerDummy.cs index 5e526e8a8..d62c25a33 100644 --- a/Robust.UnitTesting/GameControllerDummy.cs +++ b/Robust.UnitTesting/GameControllerDummy.cs @@ -11,6 +11,10 @@ namespace Robust.UnitTesting { } + public void SetCommandLineArgs(CommandLineArgs args) + { + } + public bool LoadConfigAndUserData { get; set; } = true; public void Startup() diff --git a/Robust.UnitTesting/RobustIntegrationTest.cs b/Robust.UnitTesting/RobustIntegrationTest.cs index 4cfc6ac8e..7e39333ac 100644 --- a/Robust.UnitTesting/RobustIntegrationTest.cs +++ b/Robust.UnitTesting/RobustIntegrationTest.cs @@ -15,7 +15,7 @@ using Robust.Shared.Interfaces.Timing; using Robust.Shared.IoC; using Robust.Shared.Timing; using FrameEventArgs = Robust.Shared.Timing.FrameEventArgs; -using ServerEntryPoint = Robust.Server.EntryPoint; +using ServerProgram = Robust.Server.Program; namespace Robust.UnitTesting { @@ -252,14 +252,13 @@ namespace Robust.UnitTesting IoCManager.Register(true); IoCManager.Register(true); IoCManager.Register(true); - IoCManager.Register(true); IoCManager.Register(true); IoCManager.Register(true); IoCManager.Register(true); _options?.InitIoC?.Invoke(); IoCManager.BuildGraph(); - ServerEntryPoint.SetupLogging(); - ServerEntryPoint.InitReflectionManager(); + ServerProgram.SetupLogging(); + ServerProgram.InitReflectionManager(); var server = DependencyCollection.Resolve(); @@ -296,18 +295,6 @@ namespace Robust.UnitTesting _fromInstanceWriter.TryWrite(new ShutDownMessage(null)); } - - private sealed class CommandLineArgs : ICommandLineArgs - { - public bool Parse(string[] args) - { - // No-op. - return true; - } - - public string ConfigFile => null; - public string DataDir => null; - } } public sealed class ClientIntegrationInstance : IntegrationInstance