diff --git a/src/Tgstation.Server.Host/Components/Engine/ByondInstallation.cs b/src/Tgstation.Server.Host/Components/Engine/ByondInstallation.cs index 780fc91a5a..345ee5e743 100644 --- a/src/Tgstation.Server.Host/Components/Engine/ByondInstallation.cs +++ b/src/Tgstation.Server.Host/Components/Engine/ByondInstallation.cs @@ -1,9 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.Linq; using System.Threading.Tasks; -using System.Web; using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Internal; @@ -14,25 +12,25 @@ namespace Tgstation.Server.Host.Components.Engine /// /// Implementation of for . /// - sealed class ByondInstallation : IEngineInstallation + sealed class ByondInstallation : EngineInstallationBase { /// - public EngineVersion Version { get; } + public override EngineVersion Version { get; } /// - public string ServerExePath { get; } + public override string ServerExePath { get; } /// - public string CompilerExePath { get; } + public override string CompilerExePath { get; } /// - public bool PromptsForNetworkAccess { get; } + public override bool PromptsForNetworkAccess { get; } /// - public bool HasStandardOutput { get; } + public override bool HasStandardOutput { get; } /// - public Task InstallationTask { get; } + public override Task InstallationTask { get; } /// /// If map threads are supported by the . @@ -103,7 +101,7 @@ namespace Tgstation.Server.Host.Components.Engine } /// - public string FormatServerArguments( + public override string FormatServerArguments( IDmbProvider dmbProvider, IReadOnlyDictionary parameters, DreamDaemonLaunchParameters launchParameters, @@ -113,10 +111,7 @@ namespace Tgstation.Server.Host.Components.Engine ArgumentNullException.ThrowIfNull(parameters); ArgumentNullException.ThrowIfNull(launchParameters); - var parametersString = String.Join('&', parameters.Select(kvp => $"{HttpUtility.UrlEncode(kvp.Key)}={HttpUtility.UrlEncode(kvp.Value)}")); - - if (!String.IsNullOrEmpty(launchParameters.AdditionalParameters)) - parametersString = $"{parametersString}&{launchParameters.AdditionalParameters}"; + var parametersString = EncodeParameters(parameters, launchParameters); var arguments = String.Format( CultureInfo.InvariantCulture, @@ -142,7 +137,7 @@ namespace Tgstation.Server.Host.Components.Engine } /// - public string FormatCompilerArguments(string dmePath) + public override string FormatCompilerArguments(string dmePath) => $"-clean \"{dmePath ?? throw new ArgumentNullException(nameof(dmePath))}\""; } } diff --git a/src/Tgstation.Server.Host/Components/Engine/EngineInstallationBase.cs b/src/Tgstation.Server.Host/Components/Engine/EngineInstallationBase.cs new file mode 100644 index 0000000000..8bd53be358 --- /dev/null +++ b/src/Tgstation.Server.Host/Components/Engine/EngineInstallationBase.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Web; + +using Tgstation.Server.Api.Models.Internal; +using Tgstation.Server.Host.Components.Deployment; + +namespace Tgstation.Server.Host.Components.Engine +{ + /// + abstract class EngineInstallationBase : IEngineInstallation + { + /// + public abstract EngineVersion Version { get; } + + /// + public abstract string ServerExePath { get; } + + /// + public abstract string CompilerExePath { get; } + + /// + public abstract bool HasStandardOutput { get; } + + /// + public abstract bool PromptsForNetworkAccess { get; } + + /// + public abstract Task InstallationTask { get; } + + /// + /// Encode given parameters for passing as world.params on the command line. + /// + /// of parameters to encode. + /// The active . + /// The formatted parameters . + protected static string EncodeParameters( + IReadOnlyDictionary parameters, + DreamDaemonLaunchParameters launchParameters) + { + var parametersString = String.Join('&', parameters.Select(kvp => $"{HttpUtility.UrlEncode(kvp.Key)}={HttpUtility.UrlEncode(kvp.Value)}")); + + if (!String.IsNullOrEmpty(launchParameters.AdditionalParameters)) + parametersString = $"{parametersString}&{launchParameters.AdditionalParameters}"; + + return parametersString; + } + + /// + public abstract string FormatCompilerArguments(string dmePath); + + /// + public abstract string FormatServerArguments(IDmbProvider dmbProvider, IReadOnlyDictionary parameters, DreamDaemonLaunchParameters launchParameters, string logFilePath); + } +} diff --git a/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstallation.cs b/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstallation.cs index 66a2e11b9d..e6413570f1 100644 --- a/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstallation.cs +++ b/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstallation.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; -using System.Web; using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Internal; @@ -13,25 +11,25 @@ namespace Tgstation.Server.Host.Components.Engine /// /// Implementation of for . /// - sealed class OpenDreamInstallation : IEngineInstallation + sealed class OpenDreamInstallation : EngineInstallationBase { /// - public EngineVersion Version { get; } + public override EngineVersion Version { get; } /// - public string ServerExePath { get; } + public override string ServerExePath { get; } /// - public string CompilerExePath { get; } + public override string CompilerExePath { get; } /// - public bool PromptsForNetworkAccess => false; + public override bool PromptsForNetworkAccess => false; /// - public bool HasStandardOutput => true; + public override bool HasStandardOutput => true; /// - public Task InstallationTask { get; } + public override Task InstallationTask { get; } /// /// Initializes a new instance of the class. @@ -56,39 +54,27 @@ namespace Tgstation.Server.Host.Components.Engine } /// - public string FormatServerArguments(IDmbProvider dmbProvider, IReadOnlyDictionary parameters, DreamDaemonLaunchParameters launchParameters, string logFilePath) + public override string FormatServerArguments( + IDmbProvider dmbProvider, + IReadOnlyDictionary parameters, + DreamDaemonLaunchParameters launchParameters, + string logFilePath) { ArgumentNullException.ThrowIfNull(dmbProvider); ArgumentNullException.ThrowIfNull(parameters); ArgumentNullException.ThrowIfNull(launchParameters); - var parametersString = String.Join(';', parameters.Select(kvp => $"{kvp.Key}={kvp.Value}")); + if (logFilePath != null) + throw new NotSupportedException("OpenDream does not support logging to a file!"); - if (!String.IsNullOrEmpty(launchParameters.AdditionalParameters)) - { - // TGS and BYOND expect url encoded params, OD takes unencoded - var unencodedAdditionalParams = String.Join( - ';', - launchParameters - .AdditionalParameters - .Split('&') - .Select( - singleParam => String.Join( - '=', - singleParam - .Split('=') - .Select( - encodedParam => HttpUtility.UrlDecode(encodedParam))))); - - parametersString = $"{parametersString};{unencodedAdditionalParams}"; - } + var parametersString = EncodeParameters(parameters, launchParameters); var arguments = $"--cvar net.port={launchParameters.Port.Value} --cvar opendream.topic_port=0 --cvar opendream.world_params=\"{parametersString}\" \"{dmbProvider.DmbName}\""; return arguments; } /// - public string FormatCompilerArguments(string dmePath) + public override string FormatCompilerArguments(string dmePath) => $"--suppress-unimplemented --notices-enabled \"{dmePath ?? throw new ArgumentNullException(nameof(dmePath))}\""; } }